From 26c7fe3332d925461c01975d6add286986efd6d0 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Sat, 27 Feb 2016 16:03:10 +0000 Subject: [PATCH] Updated from git.drogon.net --- INSTALL | 12 - People | 6 + README.TXT | 2 +- VERSION | 1 + build | 167 +- debian-template/wiringPi/DEBIAN/control | 10 + debian-template/wiringPi/DEBIAN/postinst | 5 + debian-template/wiringPi/DEBIAN/postrm | 2 + debian/.gitignore | 9 + debian/changelog | 6 + debian/compat | 1 + debian/control | 29 + debian/copyright | 15 + debian/libwiringpi-dev.dirs | 2 + debian/libwiringpi-dev.install | 3 + debian/libwiringpi2.install | 1 + debian/libwiringpi2.shlibs | 2 + debian/rules | 49 + debian/wiringpi.dirs | 1 + debian/wiringpi.install | 4 + devLib/Makefile | 137 ++ devLib/ds1302.c | 240 ++ devLib/ds1302.h | 44 + devLib/font.h | 2577 ++++++++++++++++++++++ devLib/gertboard.c | 164 ++ devLib/gertboard.h | 45 + devLib/lcd.c | 495 +++++ devLib/lcd.h | 52 + devLib/lcd128x64.c | 673 ++++++ devLib/lcd128x64.h | 39 + devLib/maxdetect.c | 165 ++ devLib/maxdetect.h | 40 + devLib/piFace.c | 112 + devLib/piFace.h | 32 + devLib/piFaceOld.c | 178 ++ devLib/piGlow.c | 118 + devLib/piGlow.h | 45 + devLib/piNes.c | 113 + devLib/piNes.h | 45 + examples/Gertboard/7segments.c | 221 ++ examples/Gertboard/Makefile | 78 + examples/Gertboard/buttons.c | 83 + examples/Gertboard/gertboard.c | 96 + examples/Gertboard/record.c | 60 + examples/Gertboard/temperature.c | 78 + examples/Gertboard/voltmeter.c | 73 + examples/Gertboard/vumeter.c | 152 ++ examples/Makefile | 146 +- examples/PiFace/Makefile | 88 + examples/PiFace/blink.c | 59 + examples/PiFace/buttons.c | 103 + examples/PiFace/ladder.c | 337 +++ examples/PiFace/metro.c | 111 + examples/PiFace/motor.c | 120 + examples/PiFace/reaction.c | 194 ++ examples/PiGlow/Makefile | 82 + examples/PiGlow/piGlow0.c | 51 + examples/PiGlow/piGlow1.c | 258 +++ examples/PiGlow/piglow.c | 176 ++ examples/blink.c | 8 +- examples/blink.sh | 4 +- examples/blink12.c | 111 + examples/blink12drcs.c | 125 ++ examples/blink6drcs.c | 115 + examples/blink8.c | 57 + examples/clock.c | 201 ++ examples/ds1302.c | 238 ++ examples/isr.c | 63 +- examples/lcd-adafruit.c | 347 +++ examples/lcd.c | 281 ++- examples/lowPower.c | 68 + examples/max31855.c | 60 + examples/okLed.c | 13 +- examples/pwm.c | 79 +- examples/q2w/Makefile | 84 + examples/q2w/binary.c | 79 + examples/q2w/blink-io.c | 61 + examples/q2w/blink.c | 50 + examples/q2w/blink.sh | 37 + examples/q2w/bright.c | 59 + examples/q2w/button.c | 63 + examples/q2w/volts.c | 62 + examples/rht03.c | 69 + examples/softPwm.c | 89 + examples/softTone.c | 54 + examples/speed.c | 114 +- examples/spiSpeed.c | 118 + gpio/Makefile | 81 +- gpio/gpio.1 | 166 +- gpio/gpio.c | 639 ++++-- gpio/pins.c | 33 + gpio/pintest | 187 ++ gpio/readall.c | 336 +++ gpio/version.h | 1 + newVersion | 43 + pins/Makefile | 22 + pins/pins.pdf | Bin 0 -> 9833 bytes pins/pins.tex | 116 + wiringPi/Makefile | 192 +- wiringPi/drcSerial.c | 201 ++ wiringPi/drcSerial.h | 33 + wiringPi/max31855.c | 99 + wiringPi/max31855.h | 33 + wiringPi/max5322.c | 84 + wiringPi/max5322.h | 33 + wiringPi/mcp23008.c | 149 ++ wiringPi/mcp23008.h | 33 + wiringPi/mcp23016.c | 164 ++ wiringPi/mcp23016.h | 33 + wiringPi/mcp23016reg.h | 48 + wiringPi/mcp23017.c | 195 ++ wiringPi/mcp23017.h | 33 + wiringPi/mcp23s08.c | 189 ++ wiringPi/mcp23s08.h | 33 + wiringPi/mcp23s17.c | 236 ++ wiringPi/mcp23s17.h | 33 + wiringPi/mcp23x08.h | 73 + wiringPi/mcp23x0817.h | 87 + wiringPi/mcp3002.c | 76 + wiringPi/mcp3002.h | 33 + wiringPi/mcp3004.c | 76 + wiringPi/mcp3004.h | 33 + wiringPi/mcp3422.c | 110 + wiringPi/mcp3422.h | 43 + wiringPi/mcp4802.c | 76 + wiringPi/mcp4802.h | 33 + wiringPi/pcf8574.c | 126 ++ wiringPi/pcf8574.h | 33 + wiringPi/pcf8591.c | 90 + wiringPi/pcf8591.h | 33 + wiringPi/piHiPri.c | 7 +- wiringPi/sn3218.c | 75 + wiringPi/sn3218.h | 33 + wiringPi/softPwm.c | 62 +- wiringPi/softPwm.h | 1 + wiringPi/softTone.c | 55 +- wiringPi/softTone.h | 3 +- wiringPi/sr595.c | 109 + wiringPi/sr595.h | 34 + wiringPi/wiringPi.c | 1840 ++++++++++----- wiringPi/wiringPi.h | 151 +- wiringPi/wiringPiI2C.c | 158 +- wiringPi/wiringPiI2C.h | 15 +- wiringPi/wiringPiSPI.c | 59 +- wiringPi/wiringPiSPI.h | 9 +- wiringPi/wiringSerial.c | 17 +- wiringPi/wiringSerial.h | 16 +- wiringPi/wiringShift.c | 1 - wiringPi/wiringShift.h | 4 +- wiringPi/wpiExtensions.c | 731 ++++++ wiringPi/wpiExtensions.h | 26 + 151 files changed, 17346 insertions(+), 1343 deletions(-) create mode 100644 VERSION create mode 100644 debian-template/wiringPi/DEBIAN/control create mode 100644 debian-template/wiringPi/DEBIAN/postinst create mode 100644 debian-template/wiringPi/DEBIAN/postrm create mode 100644 debian/.gitignore create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/libwiringpi-dev.dirs create mode 100644 debian/libwiringpi-dev.install create mode 100644 debian/libwiringpi2.install create mode 100644 debian/libwiringpi2.shlibs create mode 100644 debian/rules create mode 100644 debian/wiringpi.dirs create mode 100644 debian/wiringpi.install create mode 100644 devLib/Makefile create mode 100644 devLib/ds1302.c create mode 100644 devLib/ds1302.h create mode 100644 devLib/font.h create mode 100644 devLib/gertboard.c create mode 100644 devLib/gertboard.h create mode 100644 devLib/lcd.c create mode 100644 devLib/lcd.h create mode 100644 devLib/lcd128x64.c create mode 100644 devLib/lcd128x64.h create mode 100644 devLib/maxdetect.c create mode 100644 devLib/maxdetect.h create mode 100644 devLib/piFace.c create mode 100644 devLib/piFace.h create mode 100644 devLib/piFaceOld.c create mode 100644 devLib/piGlow.c create mode 100644 devLib/piGlow.h create mode 100644 devLib/piNes.c create mode 100644 devLib/piNes.h create mode 100644 examples/Gertboard/7segments.c create mode 100644 examples/Gertboard/Makefile create mode 100644 examples/Gertboard/buttons.c create mode 100644 examples/Gertboard/gertboard.c create mode 100644 examples/Gertboard/record.c create mode 100644 examples/Gertboard/temperature.c create mode 100644 examples/Gertboard/voltmeter.c create mode 100644 examples/Gertboard/vumeter.c create mode 100644 examples/PiFace/Makefile create mode 100644 examples/PiFace/blink.c create mode 100644 examples/PiFace/buttons.c create mode 100644 examples/PiFace/ladder.c create mode 100644 examples/PiFace/metro.c create mode 100644 examples/PiFace/motor.c create mode 100644 examples/PiFace/reaction.c create mode 100644 examples/PiGlow/Makefile create mode 100644 examples/PiGlow/piGlow0.c create mode 100644 examples/PiGlow/piGlow1.c create mode 100644 examples/PiGlow/piglow.c create mode 100644 examples/blink12.c create mode 100644 examples/blink12drcs.c create mode 100644 examples/blink6drcs.c create mode 100644 examples/blink8.c create mode 100644 examples/clock.c create mode 100644 examples/ds1302.c create mode 100644 examples/lcd-adafruit.c create mode 100644 examples/lowPower.c create mode 100644 examples/max31855.c create mode 100644 examples/q2w/Makefile create mode 100644 examples/q2w/binary.c create mode 100644 examples/q2w/blink-io.c create mode 100644 examples/q2w/blink.c create mode 100644 examples/q2w/blink.sh create mode 100644 examples/q2w/bright.c create mode 100644 examples/q2w/button.c create mode 100644 examples/q2w/volts.c create mode 100644 examples/rht03.c create mode 100644 examples/softPwm.c create mode 100644 examples/softTone.c create mode 100644 examples/spiSpeed.c create mode 100644 gpio/pins.c create mode 100644 gpio/pintest create mode 100644 gpio/readall.c create mode 100644 gpio/version.h create mode 100644 newVersion create mode 100644 pins/Makefile create mode 100644 pins/pins.pdf create mode 100644 pins/pins.tex create mode 100644 wiringPi/drcSerial.c create mode 100644 wiringPi/drcSerial.h create mode 100644 wiringPi/max31855.c create mode 100644 wiringPi/max31855.h create mode 100644 wiringPi/max5322.c create mode 100644 wiringPi/max5322.h create mode 100644 wiringPi/mcp23008.c create mode 100644 wiringPi/mcp23008.h create mode 100644 wiringPi/mcp23016.c create mode 100644 wiringPi/mcp23016.h create mode 100644 wiringPi/mcp23016reg.h create mode 100644 wiringPi/mcp23017.c create mode 100644 wiringPi/mcp23017.h create mode 100644 wiringPi/mcp23s08.c create mode 100644 wiringPi/mcp23s08.h create mode 100644 wiringPi/mcp23s17.c create mode 100644 wiringPi/mcp23s17.h create mode 100644 wiringPi/mcp23x08.h create mode 100644 wiringPi/mcp23x0817.h create mode 100644 wiringPi/mcp3002.c create mode 100644 wiringPi/mcp3002.h create mode 100644 wiringPi/mcp3004.c create mode 100644 wiringPi/mcp3004.h create mode 100644 wiringPi/mcp3422.c create mode 100644 wiringPi/mcp3422.h create mode 100644 wiringPi/mcp4802.c create mode 100644 wiringPi/mcp4802.h create mode 100644 wiringPi/pcf8574.c create mode 100644 wiringPi/pcf8574.h create mode 100644 wiringPi/pcf8591.c create mode 100644 wiringPi/pcf8591.h create mode 100644 wiringPi/sn3218.c create mode 100644 wiringPi/sn3218.h create mode 100644 wiringPi/sr595.c create mode 100644 wiringPi/sr595.h create mode 100644 wiringPi/wpiExtensions.c create mode 100644 wiringPi/wpiExtensions.h 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/People b/People index 8be8b6d..b339494 100644 --- a/People +++ b/People @@ -25,3 +25,9 @@ CHARLES Thibaut: Xian Stannard Fixing some typos in the man page! + +Andre Crone + Suggested the __WIRING_PI.H__ round wiringPi.h + +Rik Teerling + Pointing out some silly mistooks in the I2C code... 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/VERSION b/VERSION new file mode 100644 index 0000000..3125d73 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +2.31 diff --git a/build b/build index cbb1a4f..c2a589c 100755 --- a/build +++ b/build @@ -1,7 +1,37 @@ -#!/bin/bash +#!/bin/sh -e -check-make-ok() -{ +# build +# Simple wiringPi build and install script +# +# Copyright (c) 2012-2015 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 . +################################################################################# +# +# wiringPi is designed to run on a Raspberry Pi only. +# However if you're clever enough to actually look at this script to +# see why it's not building for you, then good luck. +# +# To everyone else: Stop using cheap alternatives. Support the +# Raspberry Pi Foundation as they're the only ones putting money +# back into education! +################################################################################# + +check_make_ok() { if [ $? != 0 ]; then echo "" echo "Make Failed..." @@ -13,67 +43,120 @@ check-make-ok() fi } +sudo=${WIRINGPI_SUDO-sudo} + 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 + cd ../q2w + echo -n "Quick2Wire: " ; make clean + cd ../PiGlow + echo -n "PiGlow: " ; 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 +# Only if you know what you're doing! + +if [ x$1 = "xdebian" ]; then + here=`pwd` + cd debian-template/wiringPi + rm -rf usr + cd $here/wiringPi + make install-deb + cd $here/devLib + make install-deb INCLUDE='-I. -I../wiringPi' + cd $here/gpio + make install-deb INCLUDE='-I../wiringPi -I../devLib' LDFLAGS=-L../debian-template/wiringPi/usr/lib + cd $here/debian-template + fakeroot dpkg-deb --build wiringPi + mv wiringPi.deb wiringpi-`cat $here/VERSION`-1.deb + exit +fi + +if [ x$1 != "x" ]; then + echo "Usage: $0 [clean | uninstall]" + exit 1 +fi echo "wiringPi Build script" echo "=====================" echo -# Check for I2C being installed... -# ... and if-so, then automatically make the I2C helpers + hardware=`fgrep Hardware /proc/cpuinfo | head -1 | awk '{ print $3 }'` + +# if [ x$hardware != "xBCM2708" ]; then +# echo "" +# echo " +------------------------------------------------------------+" +# echo " | wiringPi is designed to run on the Raspberry Pi only. |" +# echo " | This processor does not appear to be a Raspberry Pi. |" +# echo " +------------------------------------------------------------+" +# echo " | In the unlikely event that you think it is a Raspberry Pi, |" +# echo " | then please accept my apologies and email the contents of |" +# echo " | /proc/cpuinfo to projects@drogon.net. |" +# echo " | - Thanks, Gordon |" +# echo " +------------------------------------------------------------+" +# echo "" +# exit 1 +# fi - 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 - check-make-ok - sudo make install - check-make-ok + $sudo make uninstall + if [ x$1 = "xstatic" ]; then + make -j5 static + check_make_ok + $sudo make install-static + else + make -j5 + check_make_ok + $sudo make install + fi + check_make_ok + + echo + echo "WiringPi Devices Library" + cd ../devLib + $sudo make uninstall + if [ x$1 = "xstatic" ]; then + make -j5 static + check_make_ok + $sudo make install-static + else + make -j5 + check_make_ok + $sudo make install + fi + check_make_ok echo echo "GPIO Utility" cd ../gpio - make - check-make-ok - sudo make install - check-make-ok + make -j5 + check_make_ok + $sudo make install + check_make_ok # echo # echo "Examples" @@ -83,3 +166,11 @@ fi echo echo All Done. +echo "" +echo "NOTE: To compile programs with wiringPi, you need to add:" +echo " -lwiringPi" +echo " to your compile line(s) To use the Gertboard, MaxDetect, etc." +echo " code (the devLib), you need to also add:" +echo " -lwiringPiDev" +echo " to your compile line(s)." +echo "" diff --git a/debian-template/wiringPi/DEBIAN/control b/debian-template/wiringPi/DEBIAN/control new file mode 100644 index 0000000..5d698c8 --- /dev/null +++ b/debian-template/wiringPi/DEBIAN/control @@ -0,0 +1,10 @@ +Package: wiringpi +Version: 2.31 +Section: libraries +Priority: optional +Architecture: armhf +Depends: libc6 +Maintainer: Gordon Henderson +Description: The wiringPi libraries, headers and gpio command + Libraries to allow GPIO access on a Raspberry Pi from C and C++ + programs as well as from the command-line diff --git a/debian-template/wiringPi/DEBIAN/postinst b/debian-template/wiringPi/DEBIAN/postinst new file mode 100644 index 0000000..4997e98 --- /dev/null +++ b/debian-template/wiringPi/DEBIAN/postinst @@ -0,0 +1,5 @@ +#!/bin/sh +set -e +/bin/chown root.root /usr/bin/gpio +/bin/chmod 4755 /usr/bin/gpio +/sbin/ldconfig diff --git a/debian-template/wiringPi/DEBIAN/postrm b/debian-template/wiringPi/DEBIAN/postrm new file mode 100644 index 0000000..4be8c58 --- /dev/null +++ b/debian-template/wiringPi/DEBIAN/postrm @@ -0,0 +1,2 @@ +#!/bin/sh +/sbin/ldconfig diff --git a/debian/.gitignore b/debian/.gitignore new file mode 100644 index 0000000..6296064 --- /dev/null +++ b/debian/.gitignore @@ -0,0 +1,9 @@ +*.debhelper.log +*.substvars +tmp +wiringpi +libwiringpi2 +libwiringpi-dev +files +*.postinst.debhelper +*.postrm.debhelper diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..7f04ad5 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,6 @@ +wiringpi (2.26~iwj) rpi-unstable; urgency=low + + * Initial version with real Debian source package build. + + -- Ian Jackson Sat, 12 Sep 2015 18:31:35 +0100 + diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +8 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..1d6d228 --- /dev/null +++ b/debian/control @@ -0,0 +1,29 @@ +Source: wiringpi +Section: electronics +Priority: optional +Maintainer: Ian Jackson +Standards-Version: 3.8.0 +Homepage: http://wiringpi.com/ +Build-Depends: debhelper (>= 8) + +Package: libwiringpi2 +Section: libs +Architecture: armhf +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: GPIO librariees for Raspberry Pi (runtime). + Runtime for the popular wiringPi library. + +Package: wiringpi +Architecture: armhf +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: gpio utility for Raspberry Pi + The wiringPi gpio command line utility, for GPIO access on a + Raspberry Pi from the command line. + +Package: libwiringpi-dev +Architecture: armhf +Depends: libwiringpi2 (= ${binary:Version}), libc6-dev, ${misc:Depends} +Suggests: wiringpi +Description: GPIO development library for Raspberry Pi + Development libraries to allow GPIO access on a Raspberry Pi from C + and C++ programs. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..de82701 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,15 @@ +wiringPi is Copyright (C) 2012-2015 Gordon Henderson. + +wiringPi is free software; you can redistribute it and/or modify it +under the terms of the GNU Lesser General Public License, as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +wiringPi is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +On all Debian and Raspbian systems, a copy of the GNU Lesser General +Public License version 3 can be found in +`/usr/share/common-licenses/LGPL-3'. diff --git a/debian/libwiringpi-dev.dirs b/debian/libwiringpi-dev.dirs new file mode 100644 index 0000000..4418816 --- /dev/null +++ b/debian/libwiringpi-dev.dirs @@ -0,0 +1,2 @@ +usr/lib +usr/include diff --git a/debian/libwiringpi-dev.install b/debian/libwiringpi-dev.install new file mode 100644 index 0000000..d7ea901 --- /dev/null +++ b/debian/libwiringpi-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/include +debian/tmp/usr/lib/*.so +examples usr/share/doc/libwiringpi-dev diff --git a/debian/libwiringpi2.install b/debian/libwiringpi2.install new file mode 100644 index 0000000..c45ebcf --- /dev/null +++ b/debian/libwiringpi2.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/lib*.so.* diff --git a/debian/libwiringpi2.shlibs b/debian/libwiringpi2.shlibs new file mode 100644 index 0000000..0be8db1 --- /dev/null +++ b/debian/libwiringpi2.shlibs @@ -0,0 +1,2 @@ +libwiringPi 2 libwiringpi2 +libwiringPiDev 2 libwiringpi2 diff --git a/debian/rules b/debian/rules new file mode 100644 index 0000000..423a473 --- /dev/null +++ b/debian/rules @@ -0,0 +1,49 @@ +#!/usr/bin/make -f + +.PHONY: build + +VERSION:=$(shell cat VERSION) +export VERSION + +soname:=$(shell echo $${VERSION%%.*}) +WIRINGPI_SONAME_SUFFIX:=.$(soname) +export soname +export WIRINGPI_SONAME_SUFFIX + +build: + dh $@ + +override_dh_auto_configure: + +override_dh_prep: + dh_prep -Xdebian/tmp + +dirs: + dh_installdirs -A + mkdir debian/tmp + set -e; for p in `dh_listpackages`; do \ + (cd debian/$$p; find -type d) | \ + (cd debian/tmp; xargs mkdir -p) \ + done + +override_dh_clean: + dh_clean + WIRINGPI_SUDO= bash -xe ./build clean + +override_dh_auto_build: dirs + V=1 LDCONFIG=: WIRINGPI_SUDO= WIRINGPI_SUID=0 \ + DESTDIR=`pwd`/debian/tmp/usr \ + PREFIX= WIRINGPI_SUDO= \ + bash -xe ./build + +override_dh_auto_install: + dh_install + set -ex; for l in libwiringPi libwiringPiDev; do \ + ln -sf $$l.so.$${VERSION} \ + debian/libwiringpi$$soname/usr/lib/$$l.so.$$soname; \ + ln -sf $$l.so.$${VERSION} \ + debian/libwiringpi-dev/usr/lib/$$l.so; \ + done + +%: + dh $@ diff --git a/debian/wiringpi.dirs b/debian/wiringpi.dirs new file mode 100644 index 0000000..e772481 --- /dev/null +++ b/debian/wiringpi.dirs @@ -0,0 +1 @@ +usr/bin diff --git a/debian/wiringpi.install b/debian/wiringpi.install new file mode 100644 index 0000000..41ae22d --- /dev/null +++ b/debian/wiringpi.install @@ -0,0 +1,4 @@ +debian/tmp/usr/bin +debian/tmp/usr/man usr/share +README.TXT usr/share/doc/wiringpi +People usr/share/doc/wiringpi diff --git a/devLib/Makefile b/devLib/Makefile new file mode 100644 index 0000000..0fb0033 --- /dev/null +++ b/devLib/Makefile @@ -0,0 +1,137 @@ +# +# Makefile: +# wiringPi device - Wiring Compatable library for the Raspberry Pi +# +# Copyright (c) 2012-2015 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# https://projects.drogon.net/raspberry-pi/wiringpi/ +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + +VERSION=$(shell cat ../VERSION) +DESTDIR?=/usr +PREFIX?=/local + +LDCONFIG?=ldconfig + +ifneq ($V,1) +Q ?= @ +endif + +STATIC=libwiringPiDev.a +DYNAMIC=libwiringPiDev.so.$(VERSION) + +#DEBUG = -g -O0 +DEBUG = -O2 +CC = gcc +INCLUDE = -I. +DEFS = -D_GNU_SOURCE +CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Winline $(INCLUDE) -pipe -fPIC + +LIBS = + +############################################################################### + +SRC = ds1302.c maxdetect.c piNes.c \ + gertboard.c piFace.c \ + lcd128x64.c lcd.c \ + piGlow.c + +OBJ = $(SRC:.c=.o) + +HEADERS = ds1302.h gertboard.h lcd128x64.h lcd.h maxdetect.h piFace.h piGlow.h piNes.h + +all: $(DYNAMIC) + +static: $(STATIC) + +$(STATIC): $(OBJ) + $Q echo "[Link (Static)]" + $Q ar rcs $(STATIC) $(OBJ) + $Q ranlib $(STATIC) +# @size $(STATIC) + +$(DYNAMIC): $(OBJ) + $Q echo "[Link (Dynamic)]" + $Q $(CC) -shared -Wl,-soname,libwiringPiDev.so$(WIRINGPI_SONAME_SUFFIX) -o libwiringPiDev.so.$(VERSION) -lpthread $(OBJ) + +.c.o: + $Q echo [Compile] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ + +.PHONY: clean +clean: + $Q echo "[Clean]" + $Q rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPiDev.* + +.PHONY: tags +tags: $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) + + +.PHONY: install +install: $(DYNAMIC) + $Q echo "[Install Headers]" + $Q install -m 0755 -d $(DESTDIR)$(PREFIX)/include + $Q install -m 0644 $(HEADERS) $(DESTDIR)$(PREFIX)/include + $Q echo "[Install Dynamic Lib]" + $Q install -m 0755 -d $(DESTDIR)$(PREFIX)/lib + $Q install -m 0755 libwiringPiDev.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libwiringPiDev.so.$(VERSION) + $Q ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPiDev.so.$(VERSION) $(DESTDIR)/lib/libwiringPiDev.so + $Q $(LDCONFIG) + +.PHONY: install-static +install-static: $(STATIC) + $Q echo "[Install Headers]" + $Q install -m 0755 -d $(DESTDIR)$(PREFIX)/include + $Q install -m 0644 $(HEADERS) $(DESTDIR)$(PREFIX)/include + $Q echo "[Install Static Lib]" + $Q install -m 0755 -d $(DESTDIR)$(PREFIX)/lib + $Q install -m 0755 libwiringPiDev.a $(DESTDIR)$(PREFIX)/lib + +.PHONY: install-deb +install-deb: $(DYNAMIC) + $Q echo "[Install Headers: deb]" + $Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/include + $Q install -m 0644 $(HEADERS) ~/wiringPi/debian-template/wiringPi/usr/include + $Q echo "[Install Dynamic Lib: deb]" + install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/lib + install -m 0755 libwiringPiDev.so.$(VERSION) ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPiDev.so.$(VERSION) + ln -sf ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPiDev.so.$(VERSION) ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPiDev.so + +.PHONY: uninstall +uninstall: + $Q echo "[UnInstall]" + $Q cd $(DESTDIR)$(PREFIX)/include/ && rm -f $(HEADERS) + $Q cd $(DESTDIR)$(PREFIX)/lib/ && rm -f libwiringPiDev.* + $Q $(LDCONFIG) + + +.PHONY: 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 +piGlow.o: piGlow.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/devLib/ds1302.h b/devLib/ds1302.h new file mode 100644 index 0000000..e82b3ed --- /dev/null +++ b/devLib/ds1302.h @@ -0,0 +1,44 @@ +/* + * ds1302.h: + * Real Time clock + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern unsigned int ds1302rtcRead (const int reg) ; +extern void ds1302rtcWrite (const int reg, const unsigned int data) ; + +extern unsigned int ds1302ramRead (const int addr) ; +extern void ds1302ramWrite (const int addr, const unsigned int data) ; + +extern void ds1302clockRead (int clockData [8]) ; +extern void ds1302clockWrite (const int clockData [8]) ; + +extern void ds1302trickleCharge (const int diodes, const int resistors) ; + +extern void ds1302setup (const int clockPin, const int dataPin, const int csPin) ; + +#ifdef __cplusplus +} +#endif diff --git a/devLib/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/devLib/gertboard.c b/devLib/gertboard.c new file mode 100644 index 0000000..5aeaef7 --- /dev/null +++ b/devLib/gertboard.c @@ -0,0 +1,164 @@ +/* + * gertboard.c: + * Access routines for the SPI devices on the Gertboard + * Copyright (c) 2012 Gordon Henderson + * + * The Gertboard has: + * + * An MCP3002 dual-channel A to D convertor connected + * to the SPI bus, selected by chip-select A, and: + * + * An MCP4802 dual-channel D to A convertor connected + * to the SPI bus, selected via chip-select B. + * + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + + +#include +#include +#include +#include +#include + +#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 + + +/* + * gertboardAnalogWrite: + * Write an 8-bit data value to the MCP4802 Analog to digital + * convertor on the Gertboard. + ********************************************************************************* + */ + +void gertboardAnalogWrite (const int chan, const int value) +{ + uint8_t spiData [2] ; + uint8_t chanBits, dataBits ; + + if (chan == 0) + chanBits = 0x30 ; + else + chanBits = 0xB0 ; + + chanBits |= ((value >> 4) & 0x0F) ; + dataBits = ((value << 4) & 0xF0) ; + + spiData [0] = chanBits ; + spiData [1] = dataBits ; + + wiringPiSPIDataRW (SPI_D2A, spiData, 2) ; +} + + +/* + * gertboardAnalogRead: + * Return the analog value of the given channel (0/1). + * The A/D is a 10-bit device + ********************************************************************************* + */ + +int gertboardAnalogRead (const int chan) +{ + uint8_t spiData [2] ; + + uint8_t chanBits ; + + if (chan == 0) + chanBits = 0b11010000 ; + else + chanBits = 0b11110000 ; + + spiData [0] = chanBits ; + spiData [1] = 0 ; + + wiringPiSPIDataRW (SPI_A2D, spiData, 2) ; + + return ((spiData [0] << 7) | (spiData [1] >> 1)) & 0x3FF ; +} + + +/* + * gertboardSPISetup: + * Initialise the SPI bus, etc. + ********************************************************************************* + */ + +int gertboardSPISetup (void) +{ + if (wiringPiSPISetup (SPI_A2D, SPI_ADC_SPEED) < 0) + return -1 ; + + if (wiringPiSPISetup (SPI_D2A, SPI_DAC_SPEED) < 0) + return -1 ; + + return 0 ; +} + + +/* + * New wiringPi node extension methods. + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, const int chan) +{ + return gertboardAnalogRead (chan - node->pinBase) ; +} + +static void myAnalogWrite (struct wiringPiNodeStruct *node, const int chan, const int value) +{ + gertboardAnalogWrite (chan - node->pinBase, value) ; +} + + +/* + * gertboardAnalogSetup: + * Create a new wiringPi device node for the analog devices on the + * Gertboard. We create one node with 2 pins - each pin being read + * and write - although the operations actually go to different + * hardware devices. + ********************************************************************************* + */ + +int gertboardAnalogSetup (const int pinBase) +{ + struct wiringPiNodeStruct *node ; + int x ; + + if (( x = gertboardSPISetup ()) != 0) + return x; + + node = wiringPiNewNode (pinBase, 2) ; + node->analogRead = myAnalogRead ; + node->analogWrite = myAnalogWrite ; + + return 0 ; +} diff --git a/devLib/gertboard.h b/devLib/gertboard.h new file mode 100644 index 0000000..3fa1919 --- /dev/null +++ b/devLib/gertboard.h @@ -0,0 +1,45 @@ +/* + * gertboard.h: + * Access routines for the SPI devices on the Gertboard + * Copyright (c) 2012 Gordon Henderson + * + * The Gertboard has an MCP4802 dual-channel D to A convertor + * connected to the SPI bus, selected via chip-select B. + * + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +// Old routines + +extern void gertboardAnalogWrite (const int chan, const int value) ; +extern int gertboardAnalogRead (const int chan) ; +extern int gertboardSPISetup (void) ; + +// New + +extern int gertboardAnalogSetup (const int pinBase) ; + +#ifdef __cplusplus +} +#endif diff --git a/devLib/lcd.c b/devLib/lcd.c new file mode 100644 index 0000000..6c0e474 --- /dev/null +++ b/devLib/lcd.c @@ -0,0 +1,495 @@ +/* + * lcd.c: + * 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 . + *********************************************************************** + */ + +#include +#include +#include + +#include + +#include "lcd.h" + +#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_CTRL 0x08 +#define LCD_CDSHIFT 0x10 +#define LCD_FUNC 0x20 +#define LCD_CGRAM 0x40 +#define LCD_DGRAM 0x80 + +// Bits in the entry register + +#define LCD_ENTRY_SH 0x01 +#define LCD_ENTRY_ID 0x02 + +// Bits in the control register + +#define LCD_BLINK_CTRL 0x01 +#define LCD_CURSOR_CTRL 0x02 +#define LCD_DISPLAY_CTRL 0x04 + +// Bits in the function register + +#define LCD_FUNC_F 0x04 +#define LCD_FUNC_N 0x08 +#define LCD_FUNC_DL 0x10 + +#define LCD_CDSHIFT_RL 0x04 + +struct lcdDataStruct +{ + 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: + * Toggle the strobe (Really the "E") pin to the device. + * According to the docs, data is latched on the falling edge. + ********************************************************************************* + */ + +static void strobe (const struct lcdDataStruct *lcd) +{ + +// Note timing changes for new version of delayMicroseconds () + + digitalWrite (lcd->strbPin, 1) ; delayMicroseconds (50) ; + digitalWrite (lcd->strbPin, 0) ; delayMicroseconds (50) ; +} + + +/* + * sentDataCmd: + * Send an data or command byte to the display. + ********************************************************************************* + */ + +static void sendDataCmd (const struct lcdDataStruct *lcd, unsigned char data) +{ + register unsigned char myData = data ; + unsigned char i, d4 ; + + if (lcd->bits == 4) + { + d4 = (myData >> 4) & 0x0F; + for (i = 0 ; i < 4 ; ++i) + { + digitalWrite (lcd->dataPins [i], (d4 & 1)) ; + d4 >>= 1 ; + } + strobe (lcd) ; + + d4 = myData & 0x0F ; + for (i = 0 ; i < 4 ; ++i) + { + digitalWrite (lcd->dataPins [i], (d4 & 1)) ; + d4 >>= 1 ; + } + } + else + { + for (i = 0 ; i < 8 ; ++i) + { + digitalWrite (lcd->dataPins [i], (myData & 1)) ; + myData >>= 1 ; + } + } + strobe (lcd) ; +} + + +/* + * putCommand: + * Send a command byte to the display + ********************************************************************************* + */ + +static void putCommand (const struct lcdDataStruct *lcd, unsigned char command) +{ + digitalWrite (lcd->rsPin, 0) ; + sendDataCmd (lcd, command) ; + delay (2) ; +} + +static void put4Command (const struct lcdDataStruct *lcd, unsigned char command) +{ + register unsigned char myCommand = command ; + register unsigned char i ; + + digitalWrite (lcd->rsPin, 0) ; + + for (i = 0 ; i < 4 ; ++i) + { + digitalWrite (lcd->dataPins [i], (myCommand & 1)) ; + myCommand >>= 1 ; + } + strobe (lcd) ; +} + + +/* + ********************************************************************************* + * User Callable code below here + ********************************************************************************* + */ + +/* + * lcdHome: lcdClear: + * Home the cursor or clear the screen. + ********************************************************************************* + */ + +void lcdHome (const int fd) +{ + struct lcdDataStruct *lcd = lcds [fd] ; + + putCommand (lcd, LCD_HOME) ; + lcd->cx = lcd->cy = 0 ; + delay (5) ; +} + +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) ; +} + + +/* + * lcdSendCommand: + * Send any arbitary command to the display + ********************************************************************************* + */ + +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. + * Ignore invalid locations. + ********************************************************************************* + */ + +void lcdPosition (const int fd, int x, int y) +{ + 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. We implement a very + * simple terminal here - with line wrapping, but no scrolling. Yet. + ********************************************************************************* + */ + +void lcdPutchar (const int fd, unsigned char data) +{ + struct lcdDataStruct *lcd = lcds [fd] ; + + digitalWrite (lcd->rsPin, 1) ; + 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])) ; + } +} + + +/* + * lcdPuts: + * Send a string to be displayed on the display + ********************************************************************************* + */ + +void lcdPuts (const int fd, const char *string) +{ + while (*string) + lcdPutchar (fd, *string++) ; +} + + +/* + * lcdPrintf: + * Printf to an LCD display + ********************************************************************************* + */ + +void lcdPrintf (const int fd, const char *message, ...) +{ + va_list argp ; + char buffer [1024] ; + + va_start (argp, message) ; + vsnprintf (buffer, 1023, message, argp) ; + va_end (argp) ; + + lcdPuts (fd, buffer) ; +} + + +/* + * lcdInit: + * Take a lot of parameters and initialise the LCD, and return a handle to + * that LCD, or -1 if any error. + ********************************************************************************* + */ + +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 ; + + unsigned char func ; + int i ; + int lcdFd = -1 ; + struct lcdDataStruct *lcd ; + + if (initialised == 0) + { + initialised = 1 ; + for (i = 0 ; i < MAX_LCDS ; ++i) + lcds [i] = NULL ; + } + +// Simple sanity checks + + if (! ((bits == 4) || (bits == 8))) + return -1 ; + + if ((rows < 0) || (rows > 20)) + return -1 ; + + if ((cols < 0) || (cols > 20)) + return -1 ; + +// Create a new LCD: + + for (i = 0 ; i < MAX_LCDS ; ++i) + { + if (lcds [i] == NULL) + { + lcdFd = i ; + break ; + } + } + + if (lcdFd == -1) + return -1 ; + + lcd = (struct lcdDataStruct *)malloc (sizeof (struct lcdDataStruct)) ; + if (lcd == NULL) + return -1 ; + + lcd->rsPin = rs ; + lcd->strbPin = 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 ; + lcd->dataPins [2] = d2 ; + lcd->dataPins [3] = d3 ; + lcd->dataPins [4] = d4 ; + lcd->dataPins [5] = d5 ; + lcd->dataPins [6] = d6 ; + lcd->dataPins [7] = d7 ; + + lcds [lcdFd] = lcd ; + + digitalWrite (lcd->rsPin, 0) ; pinMode (lcd->rsPin, OUTPUT) ; + digitalWrite (lcd->strbPin, 0) ; pinMode (lcd->strbPin, OUTPUT) ; + + for (i = 0 ; i < bits ; ++i) + { + digitalWrite (lcd->dataPins [i], 0) ; + pinMode (lcd->dataPins [i], OUTPUT) ; + } + delay (35) ; // mS + + +// 4-bit mode? +// OK. This is a PIG and it's not at all obvious from the documentation I had, +// so I guess some others have worked through either with better documentation +// or more trial and error... Anyway here goes: +// +// It seems that the controller needs to see the FUNC command at least 3 times +// consecutively - in 8-bit mode. If you're only using 8-bit mode, then it appears +// that you can get away with one func-set, however I'd not rely on it... +// +// So to set 4-bit mode, you need to send the commands one nibble at a time, +// the same three times, but send the command to set it into 8-bit mode those +// three times, then send a final 4th command to set it into 4-bit mode, and only +// then can you flip the switch for the rest of the library to work in 4-bit +// mode which sends the commands as 2 x 4-bit values. + + if (bits == 4) + { + func = LCD_FUNC | LCD_FUNC_DL ; // Set 8-bit mode 3 times + put4Command (lcd, func >> 4) ; delay (35) ; + put4Command (lcd, func >> 4) ; delay (35) ; + put4Command (lcd, func >> 4) ; delay (35) ; + func = LCD_FUNC ; // 4th set: 4-bit mode + put4Command (lcd, func >> 4) ; delay (35) ; + lcd->bits = 4 ; + } + else + { + func = LCD_FUNC | LCD_FUNC_DL ; + putCommand (lcd, func ) ; delay (35) ; + putCommand (lcd, func ) ; delay (35) ; + putCommand (lcd, func ) ; delay (35) ; + } + + if (lcd->rows > 1) + { + func |= LCD_FUNC_N ; + putCommand (lcd, func) ; delay (35) ; + } + +// Rest of the initialisation sequence + + 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 100644 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 100644 index 0000000..a1fd742 --- /dev/null +++ b/devLib/maxdetect.h @@ -0,0 +1,40 @@ +/* + * maxdetect.h: + * Driver for the MaxDetect series sensors + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + + +#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/devLib/piGlow.c b/devLib/piGlow.c new file mode 100644 index 0000000..44e3db8 --- /dev/null +++ b/devLib/piGlow.c @@ -0,0 +1,118 @@ +/* + * piGlow.c: + * Easy access to the Pimoroni PiGlow board. + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include + +#include "piGlow.h" + +#define PIGLOW_BASE 577 + +static int leg0 [6] = { 6, 7, 8, 5, 4, 9 } ; +static int leg1 [6] = { 17, 16, 15, 13, 11, 10 } ; +static int leg2 [6] = { 0, 1, 2, 3, 14, 12 } ; + + +/* + * piGlow1: + * Light up an individual LED + ********************************************************************************* + */ + +void piGlow1 (const int leg, const int ring, const int intensity) +{ + int *legLeds ; + + if ((leg < 0) || (leg > 2)) return ; + if ((ring < 0) || (ring > 5)) return ; + + /**/ if (leg == 0) + legLeds = leg0 ; + else if (leg == 1) + legLeds = leg1 ; + else + legLeds = leg2 ; + + analogWrite (PIGLOW_BASE + legLeds [ring], intensity) ; +} + +/* + * piGlowLeg: + * Light up all 6 LEDs on a leg + ********************************************************************************* + */ + +void piGlowLeg (const int leg, const int intensity) +{ + int i ; + int *legLeds ; + + if ((leg < 0) || (leg > 2)) + return ; + + /**/ if (leg == 0) + legLeds = leg0 ; + else if (leg == 1) + legLeds = leg1 ; + else + legLeds = leg2 ; + + for (i = 0 ; i < 6 ; ++i) + analogWrite (PIGLOW_BASE + legLeds [i], intensity) ; +} + + +/* + * piGlowRing: + * Light up 3 LEDs in a ring. Ring 0 is the outermost, 5 the innermost + ********************************************************************************* + */ + +void piGlowRing (const int ring, const int intensity) +{ + if ((ring < 0) || (ring > 5)) + return ; + + analogWrite (PIGLOW_BASE + leg0 [ring], intensity) ; + analogWrite (PIGLOW_BASE + leg1 [ring], intensity) ; + analogWrite (PIGLOW_BASE + leg2 [ring], intensity) ; +} + +/* + * piGlowSetup: + * Initialise the board & remember the pins we're using + ********************************************************************************* + */ + +void piGlowSetup (int clear) +{ + sn3218Setup (PIGLOW_BASE) ; + + if (clear) + { + piGlowLeg (0, 0) ; + piGlowLeg (1, 0) ; + piGlowLeg (2, 0) ; + } +} diff --git a/devLib/piGlow.h b/devLib/piGlow.h new file mode 100644 index 0000000..a4d89d0 --- /dev/null +++ b/devLib/piGlow.h @@ -0,0 +1,45 @@ +/* + * piglow.h: + * Easy access to the Pimoroni PiGlow board. + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + + +#define PIGLOW_RED 0 +#define PIGLOW_ORANGE 1 +#define PIGLOW_YELLOW 2 +#define PIGLOW_GREEN 3 +#define PIGLOW_BLUE 4 +#define PIGLOW_WHITE 5 + + +#ifdef __cplusplus +extern "C" { +#endif + +extern void piGlow1 (const int leg, const int ring, const int intensity) ; +extern void piGlowLeg (const int leg, const int intensity) ; +extern void piGlowRing (const int ring, const int intensity) ; +extern void piGlowSetup (int clear) ; + +#ifdef __cplusplus +} +#endif diff --git a/devLib/piNes.c b/devLib/piNes.c new file mode 100644 index 0000000..a115050 --- /dev/null +++ b/devLib/piNes.c @@ -0,0 +1,113 @@ +/* + * piNes.c: + * Driver for the NES Joystick controller on the Raspberry Pi + * Copyright (c) 2012 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include + +#include "piNes.h" + +#define MAX_NES_JOYSTICKS 8 + +#define NES_RIGHT 0x01 +#define NES_LEFT 0x02 +#define NES_DOWN 0x04 +#define NES_UP 0x08 +#define NES_START 0x10 +#define NES_SELECT 0x20 +#define NES_B 0x40 +#define NES_A 0x80 + + +#define PULSE_TIME 25 + +// Data to store the pins for each controller + +struct nesPinsStruct +{ + unsigned int cPin, dPin, lPin ; +} ; + +static struct nesPinsStruct nesPins [MAX_NES_JOYSTICKS] ; + +static int joysticks = 0 ; + + +/* + * setupNesJoystick: + * Create a new NES joystick interface, program the pins, etc. + ********************************************************************************* + */ + +int setupNesJoystick (int dPin, int cPin, int lPin) +{ + if (joysticks == MAX_NES_JOYSTICKS) + return -1 ; + + nesPins [joysticks].dPin = dPin ; + nesPins [joysticks].cPin = cPin ; + nesPins [joysticks].lPin = lPin ; + + digitalWrite (lPin, LOW) ; + digitalWrite (cPin, LOW) ; + + pinMode (lPin, OUTPUT) ; + pinMode (cPin, OUTPUT) ; + pinMode (dPin, INPUT) ; + + return joysticks++ ; +} + + +/* + * readNesJoystick: + * Do a single scan of the NES Joystick. + ********************************************************************************* + */ + +unsigned int readNesJoystick (int joystick) +{ + unsigned int value = 0 ; + int i ; + + struct nesPinsStruct *pins = &nesPins [joystick] ; + +// Toggle Latch - which presents the first bit + + digitalWrite (pins->lPin, HIGH) ; delayMicroseconds (PULSE_TIME) ; + digitalWrite (pins->lPin, LOW) ; delayMicroseconds (PULSE_TIME) ; + +// Read first bit + + value = digitalRead (pins->dPin) ; + +// Now get the next 7 bits with the clock + + for (i = 0 ; i < 7 ; ++i) + { + digitalWrite (pins->cPin, HIGH) ; delayMicroseconds (PULSE_TIME) ; + digitalWrite (pins->cPin, LOW) ; delayMicroseconds (PULSE_TIME) ; + value = (value << 1) | digitalRead (pins->dPin) ; + } + + return value ^ 0xFF ; +} diff --git a/devLib/piNes.h b/devLib/piNes.h new file mode 100644 index 0000000..897f181 --- /dev/null +++ b/devLib/piNes.h @@ -0,0 +1,45 @@ +/* + * piNes.h: + * Driver for the NES Joystick controller on the Raspberry Pi + * Copyright (c) 2012 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#define MAX_NES_JOYSTICKS 8 + +#define NES_RIGHT 0x01 +#define NES_LEFT 0x02 +#define NES_DOWN 0x04 +#define NES_UP 0x08 +#define NES_START 0x10 +#define NES_SELECT 0x20 +#define NES_B 0x40 +#define NES_A 0x80 + +#ifdef __cplusplus +extern "C" { +#endif + +extern int setupNesJoystick (int dPin, int cPin, int lPin) ; +extern unsigned int readNesJoystick (int joystick) ; + +#ifdef __cplusplus +} +#endif diff --git a/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..1939ad6 --- /dev/null +++ b/examples/Gertboard/Makefile @@ -0,0 +1,78 @@ +# +# Makefile: +# Gertboard - Examples using wiringPi +# +# Copyright (c) 2013 Gordon Henderson +################################################################################# + +ifneq ($V,1) +Q ?= @ +endif + +#DEBUG = -g -O0 +DEBUG = -O3 +CC = gcc +INCLUDE = -I/usr/local/include +CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe + +LDFLAGS = -L/usr/local/lib +LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm + +# Should not alter anything below this line +############################################################################### + +SRC = gertboard.c \ + buttons.c 7segments.c \ + voltmeter.c temperature.c vumeter.c \ + record.c + +OBJ = $(SRC:.c=.o) + +BINS = $(SRC:.c=) + +all: $(BINS) + +gertboard: gertboard.o + $Q echo [link] + $Q $(CC) -o $@ gertboard.o $(LDFLAGS) $(LDLIBS) + +buttons: buttons.o + $Q echo [link] + $Q $(CC) -o $@ buttons.o $(LDFLAGS) $(LDLIBS) + +7segments: 7segments.o + $Q echo [link] + $Q $(CC) -o $@ 7segments.o $(LDFLAGS) $(LDLIBS) + +voltmeter: voltmeter.o + $Q echo [link] + $Q $(CC) -o $@ voltmeter.o $(LDFLAGS) $(LDLIBS) + +temperature: temperature.o + $Q echo [link] + $Q $(CC) -o $@ temperature.o $(LDFLAGS) $(LDLIBS) + +vumeter: vumeter.o + $Q echo [link] + $Q $(CC) -o $@ vumeter.o $(LDFLAGS) $(LDLIBS) + +record: record.o + $Q echo [link] + $Q $(CC) -o $@ record.o $(LDFLAGS) $(LDLIBS) + +.c.o: + $Q echo [CC] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ + +clean: + $Q echo [Clean] + $Q rm -f $(OBJ) *~ core tags $(BINS) + +tags: $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) + +depend: + makedepend -Y $(SRC) + +# DO NOT DELETE diff --git a/examples/Gertboard/buttons.c b/examples/Gertboard/buttons.c new file mode 100644 index 0000000..5f76764 --- /dev/null +++ b/examples/Gertboard/buttons.c @@ -0,0 +1,83 @@ +/* + * buttons.c: + * Read the Gertboard buttons. Each one will act as an on/off + * tiggle switch for 3 different LEDs + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * 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/gertboard.c b/examples/Gertboard/gertboard.c new file mode 100644 index 0000000..aefcb12 --- /dev/null +++ b/examples/Gertboard/gertboard.c @@ -0,0 +1,96 @@ +/* + * gertboard.c: + * Simple test for the SPI bus on the Gertboard + * + * Hardware setup: + * D/A port 0 jumpered to A/D port 0. + * + * We output a sine wave on D/A port 0 and sample A/D port 0. We then + * plot the input value on the terminal as a sort of vertical scrolling + * oscilloscipe. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * 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 + +// Gertboard D to A is an 8-bit unit. + +#define B_SIZE 256 + +#include +#include + +int main (void) +{ + double angle ; + int i, inputValue ; + int buffer [B_SIZE] ; + int cols ; + struct winsize w ; + + + printf ("Raspberry Pi Gertboard SPI test program\n") ; + printf ("=======================================\n") ; + + ioctl (fileno (stdin), TIOCGWINSZ, &w); + cols = w.ws_col - 2 ; + +// Always initialise wiringPi. Use wiringPiSys() if you don't need +// (or want) to run as root + + wiringPiSetupSys () ; + +// Initialise the Gertboard analog hardware at pin 100 + + gertboardAnalogSetup (100) ; + +// Generate a Sine Wave and store in our buffer + + for (i = 0 ; i < B_SIZE ; ++i) + { + angle = ((double)i / (double)B_SIZE) * M_PI * 2.0 ; + buffer [i] = (int)rint ((sin (angle)) * 127.0 + 128.0) ; + } + +// Loop, output the sine wave on analog out port 0, read it into A-D port 0 +// and display it on the screen + + for (;;) + { + for (i = 0 ; i < B_SIZE ; ++i) + { + analogWrite (100, buffer [i]) ; + + inputValue = analogRead (100) ; + +// We don't need to wory about the scale or sign - the analog hardware is +// a 10-bit value, so 0-1023. Just scale this to our terminal + + printf ("%*s\n", (inputValue * cols) / 1023, "*") ; + delay (2) ; + } + } + + return 0 ; +} diff --git a/examples/Gertboard/record.c b/examples/Gertboard/record.c new file mode 100644 index 0000000..71d8718 --- /dev/null +++ b/examples/Gertboard/record.c @@ -0,0 +1,60 @@ +/* + * record.c: + * Record some audio via the Gertboard + * + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + */ + +#include +#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..4278b6d 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -3,7 +3,7 @@ # wiringPi - Wiring Compatable library for the Raspberry Pi # https://projects.drogon.net/wiring-pi # -# Copyright (c) 2012 Gordon Henderson +# Copyright (c) 2012-2015 Gordon Henderson ################################################################################# # This file is part of wiringPi: # Wiring Compatable library for the Raspberry Pi @@ -22,6 +22,9 @@ # along with wiringPi. If not, see . ################################################################################# +ifneq ($V,1) +Q ?= @ +endif #DEBUG = -g -O0 DEBUG = -O3 @@ -30,110 +33,137 @@ 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 \ + blink12drcs.c \ + pwm.c \ + speed.c wfi.c isr.c isr-osc.c \ + lcd.c lcd-adafruit.c clock.c \ + nes.c \ + softPwm.c softTone.c \ + delayTest.c serialRead.c serialTest.c okLed.c ds1302.c \ + lowPower.c \ + max31855.c \ + rht03.c OBJ = $(SRC:.c=.o) BINS = $(SRC:.c=) all: - @cat README.TXT - @echo " $(BINS)" | fmt - @echo "" + $Q cat README.TXT + $Q echo " $(BINS)" | fmt + $Q echo "" really-all: $(BINS) blink: blink.o - @echo [link] - @$(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS) -test1: test1.o - @echo [link] - @$(CC) -o $@ test1.o $(LDFLAGS) $(LDLIBS) - -test2: test2.o - @echo [link] - @$(CC) -o $@ test2.o $(LDFLAGS) $(LDLIBS) +blink8: blink8.o + $Q echo [link] + $Q $(CC) -o $@ blink8.o $(LDFLAGS) $(LDLIBS) + +blink12drcs: blink12drcs.o + $Q echo [link] + $Q $(CC) -o $@ blink12drcs.o $(LDFLAGS) $(LDLIBS) + +blink12: blink12.o + $Q echo [link] + $Q $(CC) -o $@ blink12.o $(LDFLAGS) $(LDLIBS) speed: speed.o - @echo [link] - @$(CC) -o $@ speed.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ speed.o $(LDFLAGS) $(LDLIBS) lcd: lcd.o - @echo [link] - @$(CC) -o $@ lcd.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ lcd.o $(LDFLAGS) $(LDLIBS) + +lcd-adafruit: lcd-adafruit.o + $Q echo [link] + $Q $(CC) -o $@ lcd-adafruit.o $(LDFLAGS) $(LDLIBS) + +clock: clock.o + $Q echo [link] + $Q $(CC) -o $@ clock.o $(LDFLAGS) $(LDLIBS) wfi: wfi.o - @echo [link] - @$(CC) -o $@ wfi.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ wfi.o $(LDFLAGS) $(LDLIBS) isr: isr.o - @echo [link] - @$(CC) -o $@ isr.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ isr.o $(LDFLAGS) $(LDLIBS) 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) + $Q echo [link] + $Q $(CC) -o $@ isr-osc.o $(LDFLAGS) $(LDLIBS) nes: nes.o - @echo [link] - @$(CC) -o $@ nes.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ nes.o $(LDFLAGS) $(LDLIBS) + +rht03: rht03.o + $Q echo [link] + $Q $(CC) -o $@ rht03.o $(LDFLAGS) $(LDLIBS) pwm: pwm.o - @echo [link] - @$(CC) -o $@ pwm.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ pwm.o $(LDFLAGS) $(LDLIBS) + +softPwm: softPwm.o + $Q echo [link] + $Q $(CC) -o $@ softPwm.o $(LDFLAGS) $(LDLIBS) + +softTone: softTone.o + $Q echo [link] + $Q $(CC) -o $@ softTone.o $(LDFLAGS) $(LDLIBS) delayTest: delayTest.o - @echo [link] - @$(CC) -o $@ delayTest.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ delayTest.o $(LDFLAGS) $(LDLIBS) serialRead: serialRead.o - @echo [link] - @$(CC) -o $@ serialRead.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ serialRead.o $(LDFLAGS) $(LDLIBS) serialTest: serialTest.o - @echo [link] - @$(CC) -o $@ serialTest.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ serialTest.o $(LDFLAGS) $(LDLIBS) okLed: okLed.o - @echo [link] - @$(CC) -o $@ okLed.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ okLed.o $(LDFLAGS) $(LDLIBS) tone: tone.o - @echo [link] - @$(CC) -o $@ tone.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ tone.o $(LDFLAGS) $(LDLIBS) -servo: servo.o - @echo [link] - @$(CC) -o $@ servo.o $(LDFLAGS) $(LDLIBS) +ds1302: ds1302.o + $Q echo [link] + $Q $(CC) -o $@ ds1302.o $(LDFLAGS) $(LDLIBS) +max31855: max31855.o + $Q echo [link] + $Q $(CC) -o $@ max31855.o $(LDFLAGS) $(LDLIBS) .c.o: - @echo [CC] $< - @$(CC) -c $(CFLAGS) $< -o $@ + $Q echo [CC] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ clean: - rm -f $(OBJ) *~ core tags $(BINS) + $Q echo "[Clean]" + $Q rm -f $(OBJ) *~ core tags $(BINS) tags: $(SRC) - @echo [ctags] - @ctags $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) depend: makedepend -Y $(SRC) diff --git a/examples/PiFace/Makefile b/examples/PiFace/Makefile new file mode 100644 index 0000000..4685adc --- /dev/null +++ b/examples/PiFace/Makefile @@ -0,0 +1,88 @@ +# +# 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 . +################################################################################# + +ifneq ($V,1) +Q ?= @ +endif + +#DEBUG = -g -O0 +DEBUG = -O3 +CC = gcc +INCLUDE = -I/usr/local/include +CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe + +LDFLAGS = -L/usr/local/lib +LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm + +# Should not alter anything below this line +############################################################################### + +SRC = blink.c buttons.c reaction.c ladder.c metro.c motor.c + +OBJ = $(SRC:.c=.o) + +BINS = $(SRC:.c=) + +all: $(BINS) + +blink: blink.o + $Q echo [link] + $Q $(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS) + +buttons: buttons.o + $Q echo [link] + $Q $(CC) -o $@ buttons.o $(LDFLAGS) $(LDLIBS) + +reaction: reaction.o + $Q echo [link] + $Q $(CC) -o $@ reaction.o $(LDFLAGS) $(LDLIBS) + +ladder: ladder.o + $Q echo [link] + $Q $(CC) -o $@ ladder.o $(LDFLAGS) $(LDLIBS) + +metro: metro.o + $Q echo [link] + $Q $(CC) -o $@ metro.o $(LDFLAGS) $(LDLIBS) + +motor: motor.o + $Q echo [link] + $Q $(CC) -o $@ motor.o $(LDFLAGS) $(LDLIBS) + +.c.o: + $Q echo [CC] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ + +clean: + $Q echo "[Clean]" + $Q rm -f $(OBJ) *~ core tags $(BINS) + +tags: $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) + +depend: + makedepend -Y $(SRC) + +# DO NOT DELETE diff --git a/examples/PiFace/blink.c b/examples/PiFace/blink.c new file mode 100644 index 0000000..ffb8a2e --- /dev/null +++ b/examples/PiFace/blink.c @@ -0,0 +1,59 @@ +/* + * blink.c: + * Simple "blink" test for the PiFace interface board. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * 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 100644 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/PiGlow/Makefile b/examples/PiGlow/Makefile new file mode 100644 index 0000000..acd4818 --- /dev/null +++ b/examples/PiGlow/Makefile @@ -0,0 +1,82 @@ +# +# Makefile: +# wiringPi - Wiring Compatable library for the Raspberry Pi +# https://projects.drogon.net/wiring-pi +# +# Copyright (c) 2012-2015 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 . +################################################################################# + +ifneq ($V,1) +Q ?= @ +endif + +#DEBUG = -g -O0 +DEBUG = -O3 +CC = gcc +INCLUDE = -I/usr/local/include +CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe + +LDFLAGS = -L/usr/local/lib +LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm + +# Should not alter anything below this line +############################################################################### + +SRC = piGlow0.c piGlow1.c piglow.c + +OBJ = $(SRC:.c=.o) + +BINS = $(SRC:.c=) + +all: $(BINS) + +piGlow0: piGlow0.o + $Q echo [link] + $Q $(CC) -o $@ piGlow0.o $(LDFLAGS) $(LDLIBS) + +piGlow1: piGlow1.o + $Q echo [link] + $Q $(CC) -o $@ piGlow1.o $(LDFLAGS) $(LDLIBS) + +piglow: piglow.o + $Q echo [link] + $Q $(CC) -o $@ piglow.o $(LDFLAGS) $(LDLIBS) + +.c.o: + $Q echo [CC] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ + +clean: + $Q echo "[Clean]" + $Q rm -f $(OBJ) *~ core tags $(BINS) + +tags: $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) + +install: piglow + $Q echo Installing piglow into /usr/local/bin + $Q cp -a piglow /usr/local/bin/piglow + $Q chmod 755 /usr/local/bin/piglow + $Q echo Done. Remember to load the I2C drivers! + +depend: + makedepend -Y $(SRC) + +# DO NOT DELETE diff --git a/examples/PiGlow/piGlow0.c b/examples/PiGlow/piGlow0.c new file mode 100644 index 0000000..d3fe4b9 --- /dev/null +++ b/examples/PiGlow/piGlow0.c @@ -0,0 +1,51 @@ +/* + * piglow.c: + * Very simple demonstration of the PiGlow board. + * This uses the SN3218 directly - soon there will be a new PiGlow + * devLib device which will handle the PiGlow board on a more easy + * to use manner... + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include + +#define LED_BASE 533 + +int main (void) +{ + int i, j ; + + wiringPiSetupSys () ; + + sn3218Setup (LED_BASE) ; + + for (;;) + { + for (i = 0 ; i < 256 ; ++i) + for (j = 0 ; j < 18 ; ++j) + analogWrite (LED_BASE + j, i) ; + + for (i = 255 ; i >= 0 ; --i) + for (j = 0 ; j < 18 ; ++j) + analogWrite (LED_BASE + j, i) ; + } +} diff --git a/examples/PiGlow/piGlow1.c b/examples/PiGlow/piGlow1.c new file mode 100644 index 0000000..a00b31e --- /dev/null +++ b/examples/PiGlow/piGlow1.c @@ -0,0 +1,258 @@ +/* + * piGlow1.c: + * Very simple demonstration of the PiGlow board. + * This uses the piGlow devLib. + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#include +#include + +#define PIGLOW_BASE 533 + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (!TRUE) +#endif + + +/* + * keypressed: clearKeypressed: + * Simple but effective ways to tell if the enter key has been pressed + ********************************************************************************* + */ + +static int keypressed (void) +{ + struct pollfd polls ; + + polls.fd = fileno (stdin) ; + polls.events = POLLIN ; + + return poll (&polls, 1, 0) != 0 ; +} + +static void clearKeypressed (void) +{ + while (keypressed ()) + (void)getchar () ; +} + + +/* + * pulseLed: + * Pulses the LED at position leg, ring from off to a max. value, + * then off again + ********************************************************************************* + */ + +static void pulseLed (int leg, int ring) +{ + int i ; + + for (i = 0 ; i < 140 ; ++i) + { + piGlow1 (leg, ring, i) ; + delay (1) ; + } + delay (10) ; + for (i = 140 ; i >= 0 ; --i) + { + piGlow1 (leg, ring, i) ; + delay (1) ; + } +} + +/* + * pulseLeg: + * Same as above, but a whole leg at a time + ********************************************************************************* + */ + +static void pulseLeg (int leg) +{ + int i ; + + for (i = 0 ; i < 140 ; ++i) + { + piGlowLeg (leg, i) ; delay (1) ; + } + delay (10) ; + for (i = 140 ; i >= 0 ; --i) + { + piGlowLeg (leg, i) ; delay (1) ; + } +} + + +/* + * pulse Ring: + * Same as above, but a whole ring at a time + ********************************************************************************* + */ + +static void pulseRing (int ring) +{ + int i ; + + for (i = 0 ; i < 140 ; ++i) + { + piGlowRing (ring, i) ; delay (1) ; + } + delay (10) ; + for (i = 140 ; i >= 0 ; --i) + { + piGlowRing (ring, i) ; delay (1) ; + } +} + +#define LEG_STEPS 3 + +static int legSequence [] = +{ + 4, 12, 99, + 99, 4, 12, + 12, 99, 4, +} ; + + +#define RING_STEPS 16 + +static int ringSequence [] = +{ + 0, 0, 0, 0, 0, 64, + 0, 0, 0, 0, 64, 64, + 0, 0, 0, 64, 64, 0, + 0, 0, 64, 64, 0, 0, + 0, 64, 64, 0, 0, 0, + 64, 64, 0, 0, 0, 0, + 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 64, 0, 0, 0, 0, 0, + 64, 64, 0, 0, 0, 0, + 0, 64, 64, 0, 0, 0, + 0, 0, 64, 64, 0, 0, + 0, 0, 0, 64, 64, 0, + 0, 0, 0, 0, 64, 64, + 0, 0, 0, 0, 0, 64, + 0, 0, 0, 0, 0, 0, +} ; + +/* + * main: + * Our little demo prgoram + ********************************************************************************* + */ + +int main (void) +{ + int i ; + int step, ring, leg ; + +// Always initialise wiringPi: +// Use the Sys method if you don't need to run as root + + wiringPiSetupSys () ; + +// Initialise the piGlow devLib with our chosen pin base + + piGlowSetup (1) ; + +// LEDs, one at a time + + printf ("LEDs, one at a time\n") ; + for (; !keypressed () ;) + for (leg = 0 ; leg < 3 ; ++leg) + { + for (ring = 0 ; ring < 6 ; ++ring) + { + pulseLed (leg, ring) ; + if (keypressed ()) + break ; + } + if (keypressed ()) + break ; + } + clearKeypressed () ; + +// Rings, one at a time + + printf ("Rings, one at a time\n") ; + for (; !keypressed () ;) + for (ring = 0 ; ring < 6 ; ++ring) + { + pulseRing (ring) ; + if (keypressed ()) + break ; + } + clearKeypressed () ; + +// Legs, one at a time + + printf ("Legs, one at a time\n") ; + for (; !keypressed () ;) + for (leg = 0 ; leg < 3 ; ++leg) + { + pulseLeg (leg) ; + if (keypressed ()) + break ; + } + clearKeypressed () ; + + delay (1000) ; + +// Sequence - alternating rings, legs and random + + printf ("Sequence now\n") ; + for (; !keypressed () ;) + { + for (i = 0 ; i < 20 ; ++i) + for (step = 0 ; step < LEG_STEPS ; ++step) + { + for (leg = 0 ; leg < 3 ; ++leg) + piGlowLeg (leg, legSequence [step * 3 + leg]) ; + delay (80) ; + } + + for (i = 0 ; i < 10 ; ++i) + for (step = 0 ; step < RING_STEPS ; ++step) + { + for (ring = 0 ; ring < 6 ; ++ring) + piGlowRing (ring, ringSequence [step * 6 + ring]) ; + delay (80) ; + } + + for (i = 0 ; i < 1000 ; ++i) + { + leg = random () % 3 ; + ring = random () % 6 ; + piGlow1 (leg, ring, random () % 256) ; + delay (5) ; + piGlow1 (leg, ring, 0) ; + } + } + + return 0 ; +} diff --git a/examples/PiGlow/piglow.c b/examples/PiGlow/piglow.c new file mode 100644 index 0000000..e6a2db3 --- /dev/null +++ b/examples/PiGlow/piglow.c @@ -0,0 +1,176 @@ +/* + * piglow.c: + * Very simple demonstration of the PiGlow board. + * This uses the piGlow devLib. + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (!TRUE) +#endif + +#include +#include + +static void failUsage (void) +{ + fprintf (stderr, "Usage examples:\n") ; + fprintf (stderr, " piglow off # All off\n") ; + fprintf (stderr, " piglow red 50 # Light the 3 red LEDs to 50%%\n") ; + fprintf (stderr, " colours are: red, yellow, orange, green, blue and white\n") ; + fprintf (stderr, " piglow all 75 # Light all to 75%%\n") ; + fprintf (stderr, " piglow leg 0 25 # Light leg 0 to 25%%\n") ; + fprintf (stderr, " piglow ring 3 100 # Light ring 3 to 100%%\n") ; + fprintf (stderr, " piglow led 2 5 100 # Light the single LED on Leg 2, ring 5 to 100%%\n") ; + + exit (EXIT_FAILURE) ; +} + +static int getPercent (char *typed) +{ + int percent ; + + percent = atoi (typed) ; + if ((percent < 0) || (percent > 100)) + { + fprintf (stderr, "piglow: percent value out of range\n") ; + exit (EXIT_FAILURE) ; + } + return (percent * 255) / 100 ; +} + + +/* + * main: + * Our little demo prgoram + ********************************************************************************* + */ + +int main (int argc, char *argv []) +{ + int percent ; + int ring, leg ; + +// Always initialise wiringPi: +// Use the Sys method if you don't need to run as root + + wiringPiSetupSys () ; + +// Initialise the piGlow devLib + + piGlowSetup (FALSE) ; + + if (argc == 1) + failUsage () ; + + if ((argc == 2) && (strcasecmp (argv [1], "off") == 0)) + { + for (leg = 0 ; leg < 3 ; ++leg) + piGlowLeg (leg, 0) ; + return 0 ; + } + + if (argc == 3) + { + percent = getPercent (argv [2]) ; + + /**/ if (strcasecmp (argv [1], "red") == 0) + piGlowRing (PIGLOW_RED, percent) ; + else if (strcasecmp (argv [1], "yellow") == 0) + piGlowRing (PIGLOW_YELLOW, percent) ; + else if (strcasecmp (argv [1], "orange") == 0) + piGlowRing (PIGLOW_ORANGE, percent) ; + else if (strcasecmp (argv [1], "green") == 0) + piGlowRing (PIGLOW_GREEN, percent) ; + else if (strcasecmp (argv [1], "blue") == 0) + piGlowRing (PIGLOW_BLUE, percent) ; + else if (strcasecmp (argv [1], "white") == 0) + piGlowRing (PIGLOW_WHITE, percent) ; + else if (strcasecmp (argv [1], "all") == 0) + for (ring = 0 ; ring < 6 ; ++ring) + piGlowRing (ring, percent) ; + else + { + fprintf (stderr, "piglow: invalid colour\n") ; + exit (EXIT_FAILURE) ; + } + return 0 ; + } + + if (argc == 4) + { + /**/ if (strcasecmp (argv [1], "leg") == 0) + { + leg = atoi (argv [2]) ; + if ((leg < 0) || (leg > 2)) + { + fprintf (stderr, "piglow: leg value out of range\n") ; + exit (EXIT_FAILURE) ; + } + percent = getPercent (argv [3]) ; + piGlowLeg (leg, percent) ; + } + else if (strcasecmp (argv [1], "ring") == 0) + { + ring = atoi (argv [2]) ; + if ((ring < 0) || (ring > 5)) + { + fprintf (stderr, "piglow: ring value out of range\n") ; + exit (EXIT_FAILURE) ; + } + percent = getPercent (argv [3]) ; + piGlowRing (ring, percent) ; + } + return 0 ; + } + + if (argc == 5) + { + if (strcasecmp (argv [1], "led") != 0) + failUsage () ; + + leg = atoi (argv [2]) ; + if ((leg < 0) || (leg > 2)) + { + fprintf (stderr, "piglow: leg value out of range\n") ; + exit (EXIT_FAILURE) ; + } + ring = atoi (argv [3]) ; + if ((ring < 0) || (ring > 5)) + { + fprintf (stderr, "piglow: ring value out of range\n") ; + exit (EXIT_FAILURE) ; + } + percent = getPercent (argv [4]) ; + piGlow1 (leg, ring, percent) ; + return 0 ; + } + + failUsage () ; + return 0 ; +} + + diff --git a/examples/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/blink.sh b/examples/blink.sh index 2aa378a..3975bb7 100644 --- a/examples/blink.sh +++ b/examples/blink.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/sh -e # # blink.sh: # Standard "blink" program in wiringPi. Blinks an LED connected @@ -25,7 +25,7 @@ # LED Pin - wiringPi pin 0 is BCM_GPIO 17. -LED=0 +PIN=0 gpio mode $PIN out diff --git a/examples/blink12.c b/examples/blink12.c new file mode 100644 index 0000000..c9b3d50 --- /dev/null +++ b/examples/blink12.c @@ -0,0 +1,111 @@ +/* + * 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. + *********************************************************************** + * 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 + +// Simple sequencer data +// Triplets of LED, On/Off and delay + +int data [] = +{ + 0, 1, 1, + 1, 1, 1, + 0, 0, 0, 2, 1, 1, + 1, 0, 0, 3, 1, 1, + 2, 0, 0, 4, 1, 1, + 3, 0, 0, 5, 1, 1, + 4, 0, 0, 6, 1, 1, + 5, 0, 0, 7, 1, 1, + 6, 0, 0, 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 + + 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, + 4, 0, 0, 2, 1, 1, + 3, 0, 0, 1, 1, 1, + 2, 0, 0, 0, 1, 1, + 1, 0, 1, + 0, 0, 1, + + 0, 0, 1, // Extra delay + + 0, 9, 0, // End marker + +} ; + + +int main (void) +{ + int pin ; + int dataPtr ; + int l, s, d ; + + printf ("Raspberry Pi - 12-LED Sequence\n") ; + printf ("==============================\n") ; + printf ("\n") ; + printf ("Connect LEDs up to the first 8 GPIO pins, then pins 11, 10, 13, 12 in\n") ; + printf (" that order, then sit back and watch the show!\n") ; + + wiringPiSetup () ; + + for (pin = 0 ; pin < 14 ; ++pin) + pinMode (pin, OUTPUT) ; + + dataPtr = 0 ; + + for (;;) + { + l = data [dataPtr++] ; // LED + s = data [dataPtr++] ; // State + d = data [dataPtr++] ; // Duration (10ths) + + if (s == 9) // 9 -> End Marker + { + dataPtr = 0 ; + continue ; + } + + digitalWrite (l, s) ; + delay (d * 100) ; + } + + return 0 ; +} diff --git a/examples/blink12drcs.c b/examples/blink12drcs.c new file mode 100644 index 0000000..6ee11fd --- /dev/null +++ b/examples/blink12drcs.c @@ -0,0 +1,125 @@ +/* + * blink12drcs.c: + * Simple sequence over the first 12 GPIO pins - LEDs + * Aimed at the Gertboard, but it's fairly generic. + * This version uses DRC totalk to the ATmega on the Gertboard + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * 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 + +#define GERT_BASE 100 + +static int pinMap [] = +{ + 0, 1, 2, 3, // Pi Native + GERT_BASE + 2, GERT_BASE + 3, GERT_BASE + 4, GERT_BASE + 5, + GERT_BASE + 6, GERT_BASE + 7, GERT_BASE + 8, GERT_BASE + 9, +} ; + +// Simple sequencer data +// Triplets of LED, On/Off and delay + + +int data [] = +{ + 0, 1, 1, + 1, 1, 1, + 0, 0, 0, 2, 1, 1, + 1, 0, 0, 3, 1, 1, + 2, 0, 0, 4, 1, 1, + 3, 0, 0, 5, 1, 1, + 4, 0, 0, 6, 1, 1, + 5, 0, 0, 7, 1, 1, + 6, 0, 0, 8, 1, 1, + 7, 0, 0, 9, 1, 1, + 8, 0, 0, 10, 1, 1, + 9, 0, 0, 11, 1, 1, + 10, 0, 1, + 11, 0, 1, + + 0, 0, 1, // Extra delay + +// Back again + + 11, 1, 1, + 10, 1, 1, + 11, 0, 0, 9, 1, 1, + 10, 0, 0, 8, 1, 1, + 9, 0, 0, 7, 1, 1, + 8, 0, 0, 6, 1, 1, + 7, 0, 0, 5, 1, 1, + 6, 0, 0, 4, 1, 1, + 5, 0, 0, 3, 1, 1, + 4, 0, 0, 2, 1, 1, + 3, 0, 0, 1, 1, 1, + 2, 0, 0, 0, 1, 1, + 1, 0, 1, + 0, 0, 1, + + 0, 0, 1, // Extra delay + + 0, 9, 0, // End marker + +} ; + + +int main (void) +{ + int pin ; + int dataPtr ; + int l, s, d ; + + printf ("Raspberry Pi - 12-LED Sequence\n") ; + printf ("==============================\n") ; + printf ("\n") ; + printf ("Connect LEDs up to the first 4 Pi pins and 8 pins on the ATmega\n") ; + printf (" from PD2 through PB1 in that order,\n") ; + printf (" then sit back and watch the show!\n") ; + + wiringPiSetup () ; + drcSetupSerial (GERT_BASE, 20, "/dev/ttyAMA0", 115200) ; + + for (pin = 0 ; pin < 12 ; ++pin) + pinMode (pinMap [pin], OUTPUT) ; + + dataPtr = 0 ; + + for (;;) + { + l = data [dataPtr++] ; // LED + s = data [dataPtr++] ; // State + d = data [dataPtr++] ; // Duration (10ths) + + if (s == 9) // 9 -> End Marker + { + dataPtr = 0 ; + continue ; + } + + digitalWrite (pinMap [l], s) ; + delay (d * analogRead (GERT_BASE) / 4) ; + } + + return 0 ; +} diff --git a/examples/blink6drcs.c b/examples/blink6drcs.c new file mode 100644 index 0000000..32f4921 --- /dev/null +++ b/examples/blink6drcs.c @@ -0,0 +1,115 @@ +/* + * blink6drcs.c: + * Simple sequence over 6 pins on a remote DRC board. + * Aimed at the Gertduino, but it's fairly generic. + * This version uses DRC to talk to the ATmega on the Gertduino + * + * Copyright (c) 2012-2014 Gordon Henderson. + *********************************************************************** + * 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 + +#define GERT_BASE 100 + +static int pinMap [] = +{ + GERT_BASE + 6, GERT_BASE + 5, GERT_BASE + 3, GERT_BASE + 10, GERT_BASE + 9, GERT_BASE + 13, +} ; + +// Simple sequencer data +// Triplets of LED, On/Off and delay + + +int data [] = +{ + 0, 1, 1, + 1, 1, 1, + 0, 0, 0, 2, 1, 1, + 1, 0, 0, 3, 1, 1, + 2, 0, 0, 4, 1, 1, + 3, 0, 0, 5, 1, 1, + 4, 0, 1, + 5, 0, 1, + + 0, 0, 1, // Extra delay + +// Back again + + 5, 1, 1, + 4, 1, 1, + 5, 0, 0, 3, 1, 1, + 4, 0, 0, 2, 1, 1, + 3, 0, 0, 1, 1, 1, + 2, 0, 0, 0, 1, 1, + 1, 0, 1, + 0, 0, 1, + + 0, 0, 1, // Extra delay + + 0, 9, 0, // End marker + +} ; + + +int main (void) +{ + int pin ; + int dataPtr ; + int l, s, d ; + + printf ("Raspberry Pi - 6-LED Sequence\n") ; + printf ("=============================\n") ; + printf ("\n") ; + printf (" Use the 2 buttons to temporarily speed up the sequence\n") ; + + wiringPiSetupSys () ; // Not using the Pi's GPIO here + drcSetupSerial (GERT_BASE, 20, "/dev/ttyAMA0", 115200) ; + + for (pin = 0 ; pin < 6 ; ++pin) + pinMode (pinMap [pin], OUTPUT) ; + + pinMode (GERT_BASE + 16, INPUT) ; // Buttons + pinMode (GERT_BASE + 17, INPUT) ; + + pullUpDnControl (GERT_BASE + 16, PUD_UP) ; + pullUpDnControl (GERT_BASE + 17, PUD_UP) ; + + dataPtr = 0 ; + + for (;;) + { + l = data [dataPtr++] ; // LED + s = data [dataPtr++] ; // State + d = data [dataPtr++] ; // Duration (10ths) + + if (s == 9) // 9 -> End Marker + { + dataPtr = 0 ; + continue ; + } + + digitalWrite (pinMap [l], s) ; + delay (d * digitalRead (GERT_BASE + 16) * 15 + digitalRead (GERT_BASE + 17) * 20) ; + } + + return 0 ; +} diff --git a/examples/blink8.c b/examples/blink8.c new file mode 100644 index 0000000..602d3c0 --- /dev/null +++ b/examples/blink8.c @@ -0,0 +1,57 @@ +/* + * 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. + *********************************************************************** + * 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 + +int main (void) +{ + int i, led ; + + printf ("Raspberry Pi - 8-LED Sequencer\n") ; + printf ("==============================\n") ; + printf ("\n") ; + printf ("Connect LEDs to the first 8 GPIO pins and watch ...\n") ; + + wiringPiSetup () ; + + for (i = 0 ; i < 8 ; ++i) + pinMode (i, OUTPUT) ; + + for (;;) + { + for (led = 0 ; led < 8 ; ++led) + { + digitalWrite (led, 1) ; + delay (100) ; + } + + for (led = 0 ; led < 8 ; ++led) + { + digitalWrite (led, 0) ; + delay (100) ; + } + } +} 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/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-adafruit.c b/examples/lcd-adafruit.c new file mode 100644 index 0000000..47c9b9b --- /dev/null +++ b/examples/lcd-adafruit.c @@ -0,0 +1,347 @@ +/* + * lcd-adafruit.c: + * Text-based LCD driver test code + * This is designed to drive the Adafruit RGB LCD Plate + * with the additional 5 buttons for the Raspberry Pi + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==2) +#endif + + +// Defines for the Adafruit Pi LCD interface board + +#define AF_BASE 100 +#define AF_RED (AF_BASE + 6) +#define AF_GREEN (AF_BASE + 7) +#define AF_BLUE (AF_BASE + 8) + +#define AF_E (AF_BASE + 13) +#define AF_RW (AF_BASE + 14) +#define AF_RS (AF_BASE + 15) + +#define AF_DB4 (AF_BASE + 12) +#define AF_DB5 (AF_BASE + 11) +#define AF_DB6 (AF_BASE + 10) +#define AF_DB7 (AF_BASE + 9) + +#define AF_SELECT (AF_BASE + 0) +#define AF_RIGHT (AF_BASE + 1) +#define AF_DOWN (AF_BASE + 2) +#define AF_UP (AF_BASE + 3) +#define AF_LEFT (AF_BASE + 4) + + +// User-Defined character test + +static unsigned char newChar [8] = +{ + 0b00100, + 0b00100, + 0b00000, + 0b00100, + 0b01110, + 0b11011, + 0b11011, + 0b10001, +} ; + +// Global lcd handle: + +static int lcdHandle ; + +/* + * usage: + ********************************************************************************* + */ + +int usage (const char *progName) +{ + fprintf (stderr, "Usage: %s colour\n", progName) ; + return EXIT_FAILURE ; +} + + +/* + * scrollMessage: + ********************************************************************************* + */ + +static const char *message = + " " + "Wiring Pi by Gordon Henderson. HTTP://WIRINGPI.COM/" + " " ; + +void scrollMessage (int line, int width) +{ + char buf [32] ; + static int position = 0 ; + static int timer = 0 ; + + if (millis () < timer) + return ; + + timer = millis () + 200 ; + + strncpy (buf, &message [position], width) ; + buf [width] = 0 ; + lcdPosition (lcdHandle, 0, line) ; + lcdPuts (lcdHandle, buf) ; + + if (++position == (strlen (message) - width)) + position = 0 ; +} + + +/* + * setBacklightColour: + * The colour outputs are inverted. + ********************************************************************************* + */ + +static void setBacklightColour (int colour) +{ + colour &= 7 ; + + digitalWrite (AF_RED, !(colour & 1)) ; + digitalWrite (AF_GREEN, !(colour & 2)) ; + digitalWrite (AF_BLUE, !(colour & 4)) ; +} + + +/* + * adafruitLCDSetup: + * Setup the Adafruit board by making sure the additional pins are + * set to the correct modes, etc. + ********************************************************************************* + */ + +static void adafruitLCDSetup (int colour) +{ + int i ; + +// Backlight LEDs + + pinMode (AF_RED, OUTPUT) ; + pinMode (AF_GREEN, OUTPUT) ; + pinMode (AF_BLUE, OUTPUT) ; + setBacklightColour (colour) ; + +// Input buttons + + for (i = 0 ; i <= 4 ; ++i) + { + pinMode (AF_BASE + i, INPUT) ; + pullUpDnControl (AF_BASE + i, PUD_UP) ; // Enable pull-ups, switches close to 0v + } + +// Control signals + + pinMode (AF_RW, OUTPUT) ; digitalWrite (AF_RW, LOW) ; // Not used with wiringPi - always in write mode + +// The other control pins are initialised with lcdInit () + + lcdHandle = lcdInit (2, 16, 4, AF_RS, AF_E, AF_DB4,AF_DB5,AF_DB6,AF_DB7, 0,0,0,0) ; + + if (lcdHandle < 0) + { + fprintf (stderr, "lcdInit failed\n") ; + exit (EXIT_FAILURE) ; + } +} + + +/* + * waitForEnter: + * On the Adafruit display, wait for the select button + ********************************************************************************* + */ + +static void waitForEnter (void) +{ + printf ("Press SELECT to continue: ") ; fflush (stdout) ; + + while (digitalRead (AF_SELECT) == HIGH) // Wait for push + delay (1) ; + + while (digitalRead (AF_SELECT) == LOW) // Wait for release + delay (1) ; + + printf ("OK\n") ; +} + + +/* + * speedTest: + * Test the update speed of the display + ********************************************************************************* + */ + +static void speedTest (void) +{ + unsigned int start, end, taken ; + int times ; + + lcdClear (lcdHandle) ; + start = millis () ; + for (times = 0 ; times < 10 ; ++times) + { + lcdPuts (lcdHandle, "0123456789ABCDEF") ; + lcdPuts (lcdHandle, "0123456789ABCDEF") ; + } + end = millis () ; + taken = (end - start) / 10; + + lcdClear (lcdHandle) ; + lcdPosition (lcdHandle, 0, 0) ; lcdPrintf (lcdHandle, "Speed: %dmS", taken) ; + lcdPosition (lcdHandle, 0, 1) ; lcdPrintf (lcdHandle, "For full update") ; + + waitForEnter () ; + + lcdClear (lcdHandle) ; + lcdPosition (lcdHandle, 0, 0) ; lcdPrintf (lcdHandle, "Time: %dmS", taken / 32) ; + lcdPosition (lcdHandle, 0, 1) ; lcdPrintf (lcdHandle, "Per character") ; + + waitForEnter () ; + + lcdClear (lcdHandle) ; + lcdPosition (lcdHandle, 0, 0) ; lcdPrintf (lcdHandle, "%d cps...", 32000 / taken) ; + + waitForEnter () ; +} + + +/* + * The works + ********************************************************************************* + */ + +int main (int argc, char *argv[]) +{ + int colour ; + int cols = 16 ; + int waitForRelease = FALSE ; + + struct tm *t ; + time_t tim ; + + char buf [32] ; + + if (argc != 2) + return usage (argv [0]) ; + + printf ("Raspberry Pi Adafruit LCD test\n") ; + printf ("==============================\n") ; + + colour = atoi (argv [1]) ; + + wiringPiSetupSys () ; + mcp23017Setup (AF_BASE, 0x20) ; + + adafruitLCDSetup (colour) ; + + lcdPosition (lcdHandle, 0, 0) ; lcdPuts (lcdHandle, "Gordon Henderson") ; + lcdPosition (lcdHandle, 0, 1) ; lcdPuts (lcdHandle, " wiringpi.com ") ; + + waitForEnter () ; + + lcdPosition (lcdHandle, 0, 1) ; lcdPuts (lcdHandle, "Adafruit RGB LCD") ; + + waitForEnter () ; + + lcdCharDef (lcdHandle, 2, newChar) ; + + lcdClear (lcdHandle) ; + lcdPosition (lcdHandle, 0, 0) ; + lcdPuts (lcdHandle, "User Char: ") ; + lcdPutchar (lcdHandle, 2) ; + + lcdCursor (lcdHandle, TRUE) ; + lcdCursorBlink (lcdHandle, TRUE) ; + + waitForEnter () ; + + lcdCursor (lcdHandle, FALSE) ; + lcdCursorBlink (lcdHandle, FALSE) ; + + speedTest () ; + + lcdClear (lcdHandle) ; + + for (;;) + { + scrollMessage (0, cols) ; + + tim = time (NULL) ; + t = localtime (&tim) ; + + sprintf (buf, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ; + + lcdPosition (lcdHandle, (cols - 8) / 2, 1) ; + lcdPuts (lcdHandle, buf) ; + +// Check buttons to cycle colour + +// If Up or Down are still pushed, then skip + + if (waitForRelease) + { + if ((digitalRead (AF_UP) == LOW) || (digitalRead (AF_DOWN) == LOW)) + continue ; + else + waitForRelease = FALSE ; + } + + if (digitalRead (AF_UP) == LOW) // Pushed + { + colour = colour + 1 ; + if (colour == 8) + colour = 0 ; + setBacklightColour (colour) ; + waitForRelease = TRUE ; + } + + if (digitalRead (AF_DOWN) == LOW) // Pushed + { + colour = colour - 1 ; + if (colour == -1) + colour = 7 ; + setBacklightColour (colour) ; + waitForRelease = TRUE ; + } + + } + + return 0 ; +} diff --git a/examples/lcd.c b/examples/lcd.c index 6024917..510f562 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,239 @@ #include #include -int main (void) -{ - int i, j ; - int fd1, fd2 ; +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==2) +#endif - char message1 [256] ; - char message2 [256] ; - char buf1 [30] ; - char buf2 [30] ; +static unsigned char newChar [8] = +{ + 0b11111, + 0b10001, + 0b10001, + 0b10101, + 0b11111, + 0b10001, + 0b10001, + 0b11111, +} ; + + +// Global lcd handle: + +static int lcdHandle ; + +/* + * usage: + ********************************************************************************* + */ + +int usage (const char *progName) +{ + fprintf (stderr, "Usage: %s bits cols rows\n", progName) ; + return EXIT_FAILURE ; +} + + +/* + * scrollMessage: + ********************************************************************************* + */ + +static const char *message = + " " + "Wiring Pi by Gordon Henderson. HTTP://WIRINGPI.COM/" + " " ; + +void scrollMessage (int line, int width) +{ + char buf [32] ; + static int position = 0 ; + static int timer = 0 ; + + if (millis () < timer) + return ; + + timer = millis () + 200 ; + + strncpy (buf, &message [position], width) ; + buf [width] = 0 ; + lcdPosition (lcdHandle, 0, line) ; + lcdPuts (lcdHandle, buf) ; + + if (++position == (strlen (message) - width)) + position = 0 ; +} + + +/* + * pingPong: + * Bounce a character - only on 4-line displays + ********************************************************************************* + */ + +static void pingPong (int lcd, int cols) +{ + static int position = 0 ; + static int dir = 0 ; + + if (dir == 0) // Setup + { + dir = 1 ; + lcdPosition (lcdHandle, 0, 3) ; + lcdPutchar (lcdHandle, '*') ; + return ; + } + + lcdPosition (lcdHandle, position, 3) ; + lcdPutchar (lcdHandle, ' ') ; + position += dir ; + + if (position == cols) + { + dir = -1 ; + --position ; + } + + if (position < 0) + { + dir = 1 ; + ++position ; + } + + lcdPosition (lcdHandle, position, 3) ; + lcdPutchar (lcdHandle, '#') ; +} + + +/* + * waitForEnter: + ********************************************************************************* + */ + +static void waitForEnter (void) +{ + printf ("Press ENTER to continue: ") ; + (void)fgetc (stdin) ; +} + + +/* + * The works + ********************************************************************************* + */ + +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) + lcdHandle = lcdInit (rows, cols, 4, 11,10, 4,5,6,7,0,0,0,0) ; + else + lcdHandle = lcdInit (rows, cols, 8, 11,10, 0,1,2,3,4,5,6,7) ; - lcdPosition (fd2, 0, 0) ; lcdPuts (fd2, "Gordon Henderson") ; - lcdPosition (fd2, 0, 1) ; lcdPuts (fd2, "----------------") ; + if (lcdHandle < 0) + { + fprintf (stderr, "%s: lcdInit failed\n", argv [0]) ; + return -1 ; + } - sleep (2) ; + lcdPosition (lcdHandle, 0, 0) ; lcdPuts (lcdHandle, "Gordon Henderson") ; + lcdPosition (lcdHandle, 0, 1) ; lcdPuts (lcdHandle, " wiringpi.com ") ; - 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. ") ; + waitForEnter () ; + + if (rows > 1) + { + lcdPosition (lcdHandle, 0, 1) ; lcdPuts (lcdHandle, " wiringpi.com ") ; + + if (rows == 4) + { + lcdPosition (lcdHandle, 0, 2) ; + for (i = 0 ; i < ((cols - 1) / 2) ; ++i) + lcdPuts (lcdHandle, "=-") ; + lcdPuts (lcdHandle, "=3") ; + + lcdPosition (lcdHandle, 0, 3) ; + for (i = 0 ; i < ((cols - 1) / 2) ; ++i) + lcdPuts (lcdHandle, "-=") ; + lcdPuts (lcdHandle, "-4") ; + } + } + + waitForEnter () ; + + lcdCharDef (lcdHandle, 2, newChar) ; + + lcdClear (lcdHandle) ; + lcdPosition (lcdHandle, 0, 0) ; + lcdPuts (lcdHandle, "User Char: ") ; + lcdPutchar (lcdHandle, 2) ; + + lcdCursor (lcdHandle, TRUE) ; + lcdCursorBlink (lcdHandle, TRUE) ; + + waitForEnter () ; + + lcdCursor (lcdHandle, FALSE) ; + lcdCursorBlink (lcdHandle, FALSE) ; + lcdClear (lcdHandle) ; 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 ; + scrollMessage (0, cols) ; + + if (rows == 1) + continue ; - 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) ; - tim = time (NULL) ; - t = localtime (&tim) ; + sprintf (buf, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ; - sprintf (buf1, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ; - lcdPosition (fd1, 5, 2) ; - lcdPuts (fd1, buf1) ; + lcdPosition (lcdHandle, (cols - 8) / 2, 1) ; + lcdPuts (lcdHandle, buf) ; - sprintf (buf1, "%02d/%02d/%02d", t->tm_mday, t->tm_mon + 1, t->tm_year+1900) ; - lcdPosition (fd1, 4, 3) ; - lcdPuts (fd1, buf1) ; + if (rows == 2) + continue ; - delay (250) ; - } + sprintf (buf, "%02d/%02d/%04d", t->tm_mday, t->tm_mon + 1, t->tm_year+1900) ; + + lcdPosition (lcdHandle, (cols - 10) / 2, 2) ; + lcdPuts (lcdHandle, buf) ; + + pingPong (lcd, cols) ; } return 0 ; diff --git a/examples/lowPower.c b/examples/lowPower.c new file mode 100644 index 0000000..e901e7f --- /dev/null +++ b/examples/lowPower.c @@ -0,0 +1,68 @@ +/* + * lowPower.c: + * Check the Pi's LOW-Power signal. + * + * This is a demonstration program that could be turned into some sort + * of logger via e.g. syslog - however it's also probably something + * that might be better handled by a future kernel - who knows. + * + * Copyright (c) 2014 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 + + +#define LOW_POWER 35 + +/* + * lowPower: + * This is an ISR that waits for the low-power signal going low and + * prints the result. + ********************************************************************************* + */ + +void lowPower (void) +{ + time_t t ; + + time (&t) ; + printf ("%s: LOW POWER DETECTED\n", ctime (&t)) ; +} + + +/* + ********************************************************************************* + * main + ********************************************************************************* + */ + +int main (void) +{ + wiringPiSetupGpio () ; // GPIO mode as it's an internal pin + + wiringPiISR (LOW_POWER, INT_EDGE_FALLING, &lowPower) ; + + for (;;) + delay (1000) ; + + return 0 ; +} diff --git a/examples/max31855.c b/examples/max31855.c new file mode 100644 index 0000000..36b3cf6 --- /dev/null +++ b/examples/max31855.c @@ -0,0 +1,60 @@ +/* + * max31855.c: + * SPI Thermocouple interface chip + * + * Copyright (c) 2015 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include +#include + +#include +#include + +int main (int argc, char *argv []) +{ + int i = 0 ; + + wiringPiSetup () ; + max31855Setup (200, 0) ; + max31855Setup (400, 1) ; + + for (;;) + { + if (i == 0) + { + printf ("+------+------+------+------++------+------+------+------+\n") ; + printf ("| Raw | Err | C | F || Raw | Err | C | F |\n") ; + printf ("+------+------+------+------++------+------+------+------+\n") ; + } + + printf ("| %4d | %4d | %4d | %4d |", analogRead (200), analogRead (201), analogRead (202), analogRead (203)) ; + printf ("| %4d | %4d | %4d | %4d |\n", analogRead (400), analogRead (401), analogRead (402), analogRead (403)) ; + delay (500) ; + + if (++i == 10) + i = 0 ; + + } + +} diff --git a/examples/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 +#include +#include +#include -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 } ; - -int main () +int main (void) { - int i, j ; - char buf [80] ; + int bright ; + + printf ("Raspberry Pi wiringPi PWM test program\n") ; if (wiringPiSetup () == -1) - { - fprintf (stdout, "oops: %s\n", strerror (errno)) ; - return 1 ; - } + exit (1) ; - 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) ; - -// Down fast - - for (i = 100 ; i > 0 ; --i) - { - for (j = 0 ; j < NUM_LEDS ; ++j) - softPwmWrite (ledMap [j], i) ; - delay (10) ; - } - - fgets (buf, 80, stdin) ; + pinMode (1, PWM_OUTPUT) ; for (;;) { - for (i = 0 ; i < NUM_LEDS ; ++i) - softPwmWrite (ledMap [i], values [i]) ; + for (bright = 0 ; bright < 1024 ; ++bright) + { + pwmWrite (1, bright) ; + delay (1) ; + } - delay (50) ; - - i = values [0] ; - for (j = 0 ; j < NUM_LEDS - 1 ; ++j) - values [j] = values [j + 1] ; - values [NUM_LEDS - 1] = i ; + for (bright = 1023 ; bright >= 0 ; --bright) + { + pwmWrite (1, bright) ; + delay (1) ; + } } + + return 0 ; } diff --git a/examples/q2w/Makefile b/examples/q2w/Makefile new file mode 100644 index 0000000..6f50fa0 --- /dev/null +++ b/examples/q2w/Makefile @@ -0,0 +1,84 @@ +# +# Makefile: +# wiringPi - Wiring Compatable library for the Raspberry Pi +# https://projects.drogon.net/wiring-pi +# +# Copyright (c) 2012-2013 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# Wiring Compatable library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + +ifneq ($V,1) +Q ?= @ +endif + +#DEBUG = -g -O0 +DEBUG = -O3 +CC = gcc +INCLUDE = -I/usr/local/include +CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe + +LDFLAGS = -L/usr/local/lib +LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm + +############################################################################### + +SRC = blink.c button.c blink-io.c volts.c bright.c + +OBJ = $(SRC:.c=.o) + +BINS = $(SRC:.c=) + +all: $(BINS) + +blink: blink.o + $Q echo [link] + $Q $(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS) + +blink-io: blink-io.o + $Q echo [link] + $Q $(CC) -o $@ blink-io.o $(LDFLAGS) $(LDLIBS) + +button: button.o + $Q echo [link] + $Q $(CC) -o $@ button.o $(LDFLAGS) $(LDLIBS) + +volts: volts.o + $Q echo [link] + $Q $(CC) -o $@ volts.o $(LDFLAGS) $(LDLIBS) + +bright: bright.o + $Q echo [link] + $Q $(CC) -o $@ bright.o $(LDFLAGS) $(LDLIBS) + + +.c.o: + $Q echo [CC] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ + +clean: + $Q echo "[Clean]" + $Q rm -f $(OBJ) *~ core tags $(BINS) + +tags: $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) + +depend: + makedepend -Y $(SRC) + +# DO NOT DELETE diff --git a/examples/q2w/binary.c b/examples/q2w/binary.c new file mode 100644 index 0000000..3c987c6 --- /dev/null +++ b/examples/q2w/binary.c @@ -0,0 +1,79 @@ +/* + * binary.c: + * Using the Quick 2 wire 16-bit GPIO expansion board to output + * a binary counter. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * 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 + +#define Q2W_BASE 100 + +int main (void) +{ + int i, bit ; + +// Enable the on-goard GPIO + + wiringPiSetup () ; + +// Add in the mcp23017 on the q2w board + + mcp23017Setup (Q2W_BASE, 0x20) ; + + printf ("Raspberry Pi - quite2Wire MCP23017 Test\n") ; + +// On-board button Input: + + pinMode (0, INPUT) ; + +// First 10 pins on q2w board as outputs: + + for (i = 0 ; i < 10 ; ++i) + pinMode (Q2W_BASE + i, OUTPUT) ; + +// Last pin as an input with the internal pull-up enabled + + pinMode (Q2W_BASE + 15, INPUT) ; + pullUpDnControl (Q2W_BASE + 15, PUD_UP) ; + +// Loop, outputting a binary number, +// Go faster with the button, or stop if the +// on-board button is pushed + + for (;;) + { + for (i = 0 ; i < 1024 ; ++i) + { + for (bit = 0 ; bit < 10 ; ++bit) + digitalWrite (Q2W_BASE + bit, i & (1 << bit)) ; + + while (digitalRead (0) == HIGH) // While pushed + delay (1) ; + + if (digitalRead (Q2W_BASE + 15) == HIGH) // Not Pushed + delay (100) ; + } + } + return 0 ; +} diff --git a/examples/q2w/blink-io.c b/examples/q2w/blink-io.c new file mode 100644 index 0000000..4dd4276 --- /dev/null +++ b/examples/q2w/blink-io.c @@ -0,0 +1,61 @@ +/* + * blink-io.c: + * Simple "blink" test for the Quick2Wire 16-pin IO board. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * 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 + +#define LED 1 +#define Q2W_BASE 100 + +int main (void) +{ + +// Enable the on-goard GPIO + + wiringPiSetup () ; + +// Add in the mcp23017 on the q2w board + + mcp23017Setup (Q2W_BASE, 0x20) ; + + printf ("Raspberry Pi - Quick2Wire MCP23017 Blink Test\n") ; + +// Blink the on-board LED as well as one on the mcp23017 + + pinMode (LED, OUTPUT) ; + pinMode (Q2W_BASE + 0, OUTPUT) ; + + for (;;) + { + digitalWrite (LED, HIGH) ; + digitalWrite (Q2W_BASE + 0, HIGH) ; + delay (500) ; + digitalWrite (LED, LOW) ; + digitalWrite (Q2W_BASE + 0, LOW) ; + delay (500) ; + } + + return 0 ; +} diff --git a/examples/q2w/blink.c b/examples/q2w/blink.c new file mode 100644 index 0000000..62b694a --- /dev/null +++ b/examples/q2w/blink.c @@ -0,0 +1,50 @@ +/* + * blink.c: + * Simple "blink" test for the Quick2Wire interface board. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * 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 + +#define LED 1 + +int main (void) +{ + +// Enable the on-goard GPIO + + wiringPiSetup () ; + + printf ("Raspberry Pi - Quick2Wire Mainboard LED Blink Test\n") ; + + pinMode (LED, OUTPUT) ; + + for (;;) + { + digitalWrite (LED, HIGH) ; + delay (500) ; + digitalWrite (LED, LOW) ; + delay (500) ; + } + + return 0 ; +} diff --git a/examples/q2w/blink.sh b/examples/q2w/blink.sh new file mode 100644 index 0000000..bb6107a --- /dev/null +++ b/examples/q2w/blink.sh @@ -0,0 +1,37 @@ +#!/bin/sh -e +# +# blink.sh: +# Standard "blink" program in wiringPi. Blinks an LED connected +# to the LED on the Quick2Wire board +# +# Copyright (c) 2012-2013 Gordon Henderson. +####################################################################### +# 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 . +####################################################################### + +# LED Pin - wiringPi pin 1 is BCM_GPIO 18. + +LED=1 + +gpio mode $LED out + +while true; do + gpio write $LED 1 + sleep 0.5 + gpio write $LED 0 + sleep 0.5 +done diff --git a/examples/q2w/bright.c b/examples/q2w/bright.c new file mode 100644 index 0000000..2318834 --- /dev/null +++ b/examples/q2w/bright.c @@ -0,0 +1,59 @@ +/* + * bright.c: + * Vary the Q2W LED brightness with the analog card + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * 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 + +#define LED 1 +#define Q2W_ABASE 120 + +int main (void) +{ + int value ; + +// Enable the on-goard GPIO + + wiringPiSetup () ; + +// Add in the pcf8591 on the q2w board + + pcf8591Setup (Q2W_ABASE, 0x48) ; + + printf ("Raspberry Pi - Quick2Wire Analog Test\n") ; + +// Setup the LED + + pinMode (LED, PWM_OUTPUT) ; + pwmWrite (LED, 0) ; + + for (;;) + { + value = analogRead (Q2W_ABASE + 0) ; + pwmWrite (LED, value * 4) ; + delay (10) ; + } + + return 0 ; +} diff --git a/examples/q2w/button.c b/examples/q2w/button.c new file mode 100644 index 0000000..1781f02 --- /dev/null +++ b/examples/q2w/button.c @@ -0,0 +1,63 @@ +/* + * button.c: + * Simple button test for the Quick2Wire interface board. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * 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 + +#define BUTTON 0 +#define LED1 1 +#define LED2 7 + +int main (void) +{ + +// Enable the on-goard GPIO + + wiringPiSetup () ; + + printf ("Raspberry Pi - Quick2Wire Mainboard Button & LED Test\n") ; + + pinMode (BUTTON, INPUT) ; + pinMode (LED1, OUTPUT) ; + pinMode (LED2, OUTPUT) ; + + digitalWrite (LED1, HIGH) ; // On-board LED on + digitalWrite (LED2, LOW) ; // 2nd LED off + + for (;;) + { + if (digitalRead (BUTTON) == HIGH) // Swap LED states + { + digitalWrite (LED1, LOW) ; + digitalWrite (LED2, HIGH) ; + while (digitalRead (BUTTON) == HIGH) + delay (1) ; + digitalWrite (LED1, HIGH) ; + digitalWrite (LED2, LOW) ; + } + delay (1) ; + } + + return 0 ; +} diff --git a/examples/q2w/volts.c b/examples/q2w/volts.c new file mode 100644 index 0000000..e091093 --- /dev/null +++ b/examples/q2w/volts.c @@ -0,0 +1,62 @@ +/* + * volts.c: + * Read in all 4 analogs on the Q2W analog board. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * 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 + +#define LED 1 +#define Q2W_ABASE 120 + +int main (void) +{ + int value, pin ; + +// Enable the on-goard GPIO + + wiringPiSetup () ; + + pinMode (LED, OUTPUT) ; // On-board LED + +// Add in the pcf8591 on the q2w board + + pcf8591Setup (Q2W_ABASE, 0x48) ; + + printf ("Raspberry Pi - Quick2Wire Voltmeter\n") ; + + for (;;) + { + for (pin = 0 ; pin < 4 ; ++pin) + { + value = analogRead (Q2W_ABASE + pin) ; + printf (" %5.2f", (double)value * 3.3 / 255.0) ; + } + printf ("\r") ; fflush (stdout) ; + + delay (100) ; + digitalWrite (LED, !digitalRead (LED)) ; // Flicker the LED + } + + return 0 ; +} diff --git a/examples/rht03.c b/examples/rht03.c new file mode 100644 index 0000000..566e954 --- /dev/null +++ b/examples/rht03.c @@ -0,0 +1,69 @@ +/* + * rht03.c: + * Driver for the MaxDetect series sensors + * + * 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 + +#define RHT03_PIN 0 + +/* + *********************************************************************** + * The main program + *********************************************************************** + */ + +int main (void) +{ + int temp, rh ; + int newTemp, newRh ; + + temp = rh = newTemp = newRh = 0 ; + + wiringPiSetup () ; + piHiPri (55) ; + + for (;;) + { + delay (100) ; + + if (!readRHT03 (RHT03_PIN, &newTemp, &newRh)) + continue ; + + if ((temp != newTemp) || (rh != newRh)) + { + temp = newTemp ; + rh = newRh ; + if ((temp & 0x8000) != 0) // Negative + { + temp &= 0x7FFF ; + temp = -temp ; + } + 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/softTone.c b/examples/softTone.c new file mode 100644 index 0000000..2f46783 --- /dev/null +++ b/examples/softTone.c @@ -0,0 +1,54 @@ +/* + * softTone.c: + * Test of the softTone module in wiringPi + * Plays a scale out on pin 3 - connect pizeo disc to pin 3 & 0v + * + * 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 PIN 3 + +int scale [8] = { 262, 294, 330, 349, 392, 440, 494, 525 } ; + +int main () +{ + int i ; + + wiringPiSetup () ; + + softToneCreate (PIN) ; + + for (;;) + { + for (i = 0 ; i < 8 ; ++i) + { + printf ("%3d\n", i) ; + softToneWrite (PIN, scale [i]) ; + 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 + +void speedTest (int pin, int maxCount) +{ + int count, sum, perSec, i ; + unsigned int start, end ; + + sum = 0 ; + + for (i = 0 ; i < PASSES ; ++i) + { + start = millis () ; + for (count = 0 ; count < maxCount ; ++count) + digitalWrite (pin, 1) ; + end = millis () ; + printf (" %6d", end - start) ; + fflush (stdout) ; + sum += (end - start) ; + } + + digitalWrite (pin, 0) ; + printf (". Av: %6dmS", sum / PASSES) ; + perSec = (int)(double)maxCount / (double)((double)sum / (double)PASSES) * 1000.0 ; + printf (": %7d/sec\n", perSec) ; +} int main (void) { - int i ; - uint32_t start, end, count, sum, perSec ; - - printf ("Raspberry Pi wiringPi speed test program\n") ; + printf ("Raspberry Pi wiringPi GPIO speed test program\n") ; + printf ("=============================================\n") ; // Start the standard way - if (wiringPiSetup () == -1) - exit (1) ; - - printf ("Native wiringPi method: (%8d iterations)\n", FAST_COUNT) ; - + printf ("\nNative wiringPi method: (%8d iterations)\n", FAST_COUNT) ; + wiringPiSetup () ; pinMode (0, OUTPUT) ; + speedTest (0, FAST_COUNT) ; - sum = 0 ; - for (i = 0 ; i < 3 ; ++i) - { - printf (" Pass: %d: ", i) ; - fflush (stdout) ; - - start = millis () ; - for (count = 0 ; count < FAST_COUNT ; ++count) - digitalWrite (0, 1) ; - end = millis () ; - printf (" %8dmS\n", end - start) ; - sum += (end - start) ; - } - digitalWrite (0, 0) ; - printf (" Average: %8dmS", sum / 3) ; - perSec = (int)(double)FAST_COUNT / (double)((double)sum / 3.0) * 1000.0 ; - printf (": %6d/sec\n", perSec) ; - - - printf ("Native GPIO method: (%8d iterations)\n", FAST_COUNT) ; - - if (wiringPiSetupGpio () == -1) - exit (1) ; +// GPIO + printf ("\nNative GPIO method: (%8d iterations)\n", FAST_COUNT) ; + wiringPiSetupGpio () ; pinMode (17, OUTPUT) ; + speedTest (17, FAST_COUNT) ; - sum = 0 ; - for (i = 0 ; i < 3 ; ++i) - { - printf (" Pass: %d: ", i) ; - fflush (stdout) ; - - 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) ; +// Phys + printf ("\nPhysical pin GPIO method: (%8d iterations)\n", FAST_COUNT) ; + wiringPiSetupPhys () ; + pinMode (11, OUTPUT) ; + speedTest (11, FAST_COUNT) ; // Switch to SYS mode: - if (wiringPiSetupSys () == -1) - exit (1) ; - - printf ("/sys/class/gpio method: (%8d iterations)\n", SLOW_COUNT) ; - - sum = 0 ; - for (i = 0 ; i < 3 ; ++i) - { - printf (" Pass: %d: ", i) ; - fflush (stdout) ; - - 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/examples/spiSpeed.c b/examples/spiSpeed.c new file mode 100644 index 0000000..0208f0a --- /dev/null +++ b/examples/spiSpeed.c @@ -0,0 +1,118 @@ +/* + * spiSpeed.c: + * Code to measure the SPI speed/latency. + * Copyright (c) 2014 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 + +#define TRUE (1==1) +#define FALSE (!TRUE) + +#define SPI_CHAN 0 +#define NUM_TIMES 100 +#define MAX_SIZE (1024*1024) + +static int myFd ; + + +void spiSetup (int speed) +{ + if ((myFd = wiringPiSPISetup (SPI_CHAN, speed)) < 0) + { + fprintf (stderr, "Can't open the SPI bus: %s\n", strerror (errno)) ; + exit (EXIT_FAILURE) ; + } +} + + +int main (void) +{ + int speed, times, size ; + unsigned int start, end ; + int spiFail ; + unsigned char *myData ; + double timePerTransaction, perfectTimePerTransaction, dataSpeed ; + + if ((myData = malloc (MAX_SIZE)) == NULL) + { + fprintf (stderr, "Unable to allocate buffer: %s\n", strerror (errno)) ; + exit (EXIT_FAILURE) ; + } + + wiringPiSetup () ; + + for (speed = 1 ; speed <= 32 ; speed *= 2) + { + printf ("+-------+--------+----------+----------+-----------+------------+\n") ; + printf ("| MHz | Size | mS/Trans | TpS | Mb/Sec | Latency mS |\n") ; + printf ("+-------+--------+----------+----------+-----------+------------+\n") ; + + spiFail = FALSE ; + spiSetup (speed * 1000000) ; + for (size = 1 ; size <= MAX_SIZE ; size *= 2) + { + printf ("| %5d | %6d ", speed, size) ; + + start = millis () ; + for (times = 0 ; times < NUM_TIMES ; ++times) + if (wiringPiSPIDataRW (SPI_CHAN, myData, size) == -1) + { + printf ("SPI failure: %s\n", strerror (errno)) ; + spiFail = TRUE ; + break ; + } + end = millis () ; + + if (spiFail) + break ; + + timePerTransaction = ((double)(end - start) / (double)NUM_TIMES) / 1000.0 ; + dataSpeed = (double)(size * 8) / (1024.0 * 1024.0) / timePerTransaction ; + perfectTimePerTransaction = ((double)(size * 8)) / ((double)(speed * 1000000)) ; + + printf ("| %8.3f ", timePerTransaction * 1000.0) ; + printf ("| %8.1f ", 1.0 / timePerTransaction) ; + printf ("| %9.5f ", dataSpeed) ; + printf ("| %8.5f ", (timePerTransaction - perfectTimePerTransaction) * 1000.0) ; + printf ("|\n") ; + + } + + close (myFd) ; + printf ("+-------+--------+----------+----------+-----------+------------+\n") ; + printf ("\n") ; + } + + return 0 ; +} diff --git a/gpio/Makefile b/gpio/Makefile index a043962..7dcd090 100644 --- a/gpio/Makefile +++ b/gpio/Makefile @@ -1,9 +1,10 @@ # # Makefile: -# wiringPi - Wiring Compatable library for the Raspberry Pi +# The gpio command: +# A swiss-army knige of GPIO shenanigans. # https://projects.drogon.net/wiring-pi # -# Copyright (c) 2012 Gordon Henderson +# Copyright (c) 2012-2015 Gordon Henderson ################################################################################# # This file is part of wiringPi: # Wiring Compatable library for the Raspberry Pi @@ -22,59 +23,79 @@ # along with wiringPi. If not, see . ################################################################################# +DESTDIR?=/usr +PREFIX?=/local + +ifneq ($V,1) +Q ?= @ +endif #DEBUG = -g -O0 DEBUG = -O2 CC = gcc -INCLUDE = -I/usr/local/include +INCLUDE = -I$(DESTDIR)$(PREFIX)/include CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe -LDFLAGS = -L/usr/local/lib -LIBS = -lwiringPi -lpthread -lm +LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib +LIBS = -lwiringPi -lwiringPiDev -lpthread # May not need to alter anything below this line ############################################################################### -SRC = gpio.c +SRC = gpio.c readall.c pins.c OBJ = $(SRC:.c=.o) all: gpio -gpio: gpio.o - @echo [Link] - @$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS) - +version.h: ../VERSION + $Q echo Need to run newVersion above. + +gpio: $(OBJ) + $Q echo [Link] + $Q $(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS) + .c.o: - @echo [Compile] $< - @$(CC) -c $(CFLAGS) $< -o $@ + $Q echo [Compile] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ -.PHONEY: clean +.PHONY: clean clean: - rm -f $(OBJ) gpio *~ core tags *.bak + $Q echo "[Clean]" + $Q rm -f $(OBJ) gpio *~ core tags *.bak -.PHONEY: tags +.PHONY: tags tags: $(SRC) - @echo [ctags] - @ctags $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) -.PHONEY: install -install: - @echo "[Install]" - @cp gpio /usr/local/bin - @chown root.root /usr/local/bin/gpio - @chmod 4755 /usr/local/bin/gpio - @mkdir -p /usr/local/man/man1 - @cp gpio.1 /usr/local/man/man1 +.PHONY: install +install: gpio + $Q echo "[Install]" + $Q cp gpio $(DESTDIR)$(PREFIX)/bin +ifneq ($(WIRINGPI_SUID),0) + $Q chown root.root $(DESTDIR)$(PREFIX)/bin/gpio + $Q chmod 4755 $(DESTDIR)$(PREFIX)/bin/gpio +endif + $Q mkdir -p $(DESTDIR)$(PREFIX)/man/man1 + $Q cp gpio.1 $(DESTDIR)$(PREFIX)/man/man1 -.PHONEY: uninstall +.PHONY: install-deb +install-deb: gpio + $Q echo "[Install: deb]" + $Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/bin + $Q install -m 0755 gpio ~/wiringPi/debian-template/wiringPi/usr/bin + +.PHONY: uninstall uninstall: - @echo "[UnInstall]" - @rm -f /usr/local/bin/gpio - @rm -f /usr/local/man/man1/gpio.1 + $Q echo "[UnInstall]" + $Q rm -f $(DESTDIR)$(PREFIX)/bin/gpio + $Q rm -f $(DESTDIR)$(PREFIX)/man/man1/gpio.1 -.PHONEY: depend +.PHONY: depend depend: makedepend -Y $(SRC) # DO NOT DELETE + +gpio.o: version.h diff --git a/gpio/gpio.1 b/gpio/gpio.1 index ec65519..e5fe181 100644 --- a/gpio/gpio.1 +++ b/gpio/gpio.1 @@ -1,19 +1,23 @@ -.TH "GPIO" "21st October 2012" "Command-Line access to Raspberry Pi and PiFace GPIO" +.TH GPIO 1 "September 2015" wiringPi "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/pwmTone ... .PP .B gpio .B [ \-p ] -.B read/write/wb +.B read/write/toggle/wb .B ... .PP .B gpio @@ -27,10 +31,18 @@ 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 .B gpio +.B usbp +high | low +.PP +.B gpio .B pwm-bal/pwm-ms .PP .B gpio @@ -73,12 +85,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 @@ -90,6 +118,28 @@ respective logic levels. Write the given value (0 or 1) to the pin. You need to set the pin to output mode first. +.TP +.B aread +Read the analog value of the given pin. This needs to be uses in +conjunction with a -x flag to add in an extension that handles analog +inputs. respective logic levels. + +e.g. gpio -x mcp3002:200:0 aread 200 + +will read the first analog input on an mcp3002 SPI ADC chip. + +.TP +.B awrite +Write the analog value to the given pin. This needs to be used in +conjunction with a -x flag to add in an extension that handles analog +inputs. respective logic levels. + +e.g. gpio -x mcp4802:200:0 awrite 200 128 + +will write the value 128 to the first DAC port on an mcp4802 chip on +the Pi's SPI bus 0. + + .TP .B wb Write the given byte to the 8 main GPIO pins. You can prefix it with 0x @@ -102,6 +152,10 @@ Output a table of all GPIO pins values. The values represent the actual values r if the pin is in input mode, or the last value written if the pin is in output mode. +The readall command is usable with an extension module (via the -x parameter), +but it's unable to determine pin modes or states, so will perform both a +digital and analog read on each pin in-turn. + .TP .B pwm Write a PWM value (0-1023) to the given pin. The pin needs to be put @@ -118,6 +172,8 @@ Set a pin into \fIinput\fR, \fIoutput\fR or \fIpwm\fR mode. Can also use the literals \fIup\fR, \fIdown\fR or \fItri\fR to set the internal pull-up, pull-down or tristate (off) controls. +The ALT modes can also be set using \fIalt0\fR, \fIalt1\fR, ... \fIalt5\fR. + .TP .B unexportall Un-Export all the GPIO pins in the /sys/class/gpio directory. @@ -129,9 +185,11 @@ Print a list (if any) of all the exported GPIO pins and their current values. .TP .B export Export a GPIO pin in the \fI/sys/class/gpio\fR directory. Use like the -mode command above however only \fIin\fR and \fIout\fR are supported at -this time. Note that the pin number is the \fBBCM_GPIO\fR number and -not the wiringPi number. +mode command above however only \fIin\fR, \fIout\fR, \fIhigh\fR and +\fRlow\fR are supported at this time. Note that the pin number is the +\fBBCM_GPIO\fR number and not the wiringPi number. The \fIhigh\fR and +\fIlow\fR commands pre-set the output value at the same time as the +export to output mode. Once a GPIO pin has been exported, the \fBgpio\fR program changes the ownership of the \fI/sys/class/gpio/gpioX/value\fR and if present in @@ -157,6 +215,12 @@ requiring root/sudo. .B unexport 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 @@ -165,6 +229,13 @@ Change the pad driver value for the given pad group to the supplied drive value. Group is 0, 1 or 2 and value is 0-7. Do not use unless you are absolutely sure you know what you're doing. +.TP +.B usbp +high | low + +Change the USB current limiter to high (1.2 amps) or low (the default, 600mA) +This is only applicable to the model B+ + .TP .B pwm-bal/pwm-ms Change the PWM mode to balanced (the default) or mark:space ratio (traditional) @@ -177,15 +248,27 @@ Change the PWM range register. The default is 1024. .B load i2c [baudrate] This loads the i2c or drivers into the kernel and changes the permissions on the associated /dev/ entries so that the current user has access to -them. Optionally it will set the I2C baudrate to that supplied (or as -close as the Pi can manage) The default speed is 100Kb/sec. +them. Optionally it will set the I2C baudrate to that supplied in Kb/sec +(or as close as the Pi can manage) The default speed is 100Kb/sec. + +Note: On recent kernels with the device tree enabled you should use the +raspi-config program to load/unload the I2C device at boot time. +(or disable the device tree to continue to use this method) .TP -.B load spi [buffer size in KB] +.B load spi This loads the spi drivers into the kernel and changes the permissions on the associated /dev/ entries so that the current user has access to -them. Optionally it will set the SPI buffer size to that supplied. The -default is 4KB. +them. It used to have the ability to change the buffer size from the +default of 4096 bytes to an arbitrary value, however for some time the +Pi Foundation have compiled the SPI device driver into the kernel and +this has fixed the buffer size. The way to change it now is to edit +the /boot/cmdline.txt file and add on spdev.bufsiz=8192 to set it to +e.g. 8192 bytes then reboot. + +Note: On recent kernels with the device tree enabled you should use the +raspi-config program to load/unload the SPI device at boot time. +(or disable the device tree to continue to use this method) .TP .B gbr @@ -203,41 +286,12 @@ SPI digital to analogue converter. The board jumpers need to be in-place to do this operation. -.SH "WiringPi vs. BCM_GPIO Pin numbering" +.SH "WiringPi vs. BCM_GPIO Pin numbering vs. Physical pin numbering" .PP -.TS -r r r l. -WiringPi GPIO-r1 GPIO-r2 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 -17 - 28 -18 - 29 -19 - 30 -20 - 31 -.TE - -Note that "r1" and "r2" above refers to the board revision. Normally -wiringPi detects the correct board revision with use for it's own -numbering scheme, but if you are using a Revision 2 board with some -of the pins which change numbers between revisions you will need -to alter your software. +The quickest way to get a list of the pin differences is to run the command +.TP +gpio readall .SH FILES @@ -267,12 +321,24 @@ When using the \fIexport\fR, \fIedge\fR or \fIunexport\fR commands, the pin numbers are \fBalways\fR native BCM_GPIO numbers and never wiringPi pin numbers. +As of kernels 4.1.7, a user-level GPIO access mechanism is available, +however wiringPi will not use this by default - because at this time +there appears to be issues when trying to program the PWM or clock output +hardware. If you can live without PWM or GPIO clocks and you want to use +the GPIO from a non-root program, then you need to make sure that the +module \fIbcm2835_gpiomem\fR is loaded at boot time. This should happen +automatically when you enable the device tree in raspi-config. You may +also need some additional information in /etc/udev/rules.d/ to change the +mode and ownership of the /dev/gpiomem file. Finally, you need to set +the environment variable \fIWIRINGPI_GPIOMEM\fR. This will go-away +in future releases once the /dev/gpiomem interface is fully operational. + .SH "SEE ALSO" .LP WiringPi's home page .IP -https://projects.drogon.net/raspberry-pi/wiringpi/ +http://wiringpi.com/ .SH AUTHOR @@ -284,7 +350,7 @@ Please report bugs to .SH COPYRIGHT -Copyright (c) 2012 Gordon Henderson +Copyright (c) 2012-2015 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..6c95b21 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-2015 Gordon Henderson *********************************************************************** * This file is part of wiringPi: * https://projects.drogon.net/raspberry-pi/wiringpi/ @@ -26,42 +26,81 @@ #include #include #include +#include #include #include #include -#include #include +#include +#include #include +#include + #include +#include + +#include "version.h" extern int wiringPiDebug ; +// External functions I can't be bothered creating a separate .h file for: + +extern void doReadall (void) ; +extern void doPins (void) ; + #ifndef TRUE # define TRUE (1==1) # define FALSE (1==2) #endif -#define VERSION "1.12" +#define PI_USB_POWER_CONTROL 38 +#define I2CDETECT "/usr/sbin/i2cdetect" -static int wpMode ; +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 unload spi/i2c\n" + " gpio i2cd/i2cdetect\n" + " gpio usbp high/low\n" " gpio gbr \n" " gpio gbw " ; // No trailing newline needed here. +#ifdef NOT_FOR_NOW +/* + * decodePin: + * Decode a pin "number" which can actually be a pin name to represent + * one of the Pi's on-board pins. + ********************************************************************************* + */ + +static int decodePin (const char *str) +{ + +// The first case - see if it's a number: + + if (isdigit (str [0])) + return atoi (str) ; + + return 0 ; +} +#endif + + /* * changeOwner: * Change the ownership of the file to the real userId of the calling @@ -77,12 +116,9 @@ static void changeOwner (char *cmd, char *file) if (chown (file, uid, gid) != 0) { if (errno == ENOENT) // Warn that it's not there - fprintf (stderr, "%s: Warning: File not present: %s\n", cmd, file) ; + fprintf (stderr, "%s: Warning (not an error, do not report): File not present: %s\n", cmd, file) ; else - { - fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ; - exit (1) ; - } + fprintf (stderr, "%s: Warning (not an error): Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ; } } @@ -127,9 +163,25 @@ static int moduleLoaded (char *modName) ********************************************************************************* */ +static void checkDevTree (char *argv []) +{ + struct stat statBuf ; + + if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ... + { + fprintf (stderr, +"%s: Unable to load/unload modules as this Pi has the device tree enabled.\n" +" You need to run the raspi-config program (as root) and select the\n" +" modules (SPI or I2C) that you wish to load/unload there and reboot.\n" +" There is more information here:\n" +" https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=97314\n", argv [0]) ; + exit (1) ; + } +} + static void _doLoadUsage (char *argv []) { - fprintf (stderr, "Usage: %s load [SPI bufferSize in KB | I2C baudrate in Kb/sec]\n", argv [0]) ; + fprintf (stderr, "Usage: %s load [I2C baudrate in Kb/sec]\n", argv [0]) ; exit (1) ; } @@ -140,6 +192,8 @@ static void doLoad (int argc, char *argv []) char *file1, *file2 ; char args1 [32], args2 [32] ; + checkDevTree (argv) ; + if (argc < 3) _doLoadUsage (argv) ; @@ -152,7 +206,10 @@ static void doLoad (int argc, char *argv []) file1 = "/dev/spidev0.0" ; file2 = "/dev/spidev0.1" ; if (argc == 4) - sprintf (args1, " bufsiz=%d", atoi (argv [3]) * 1024) ; + { + fprintf (stderr, "%s: Unable to set the buffer size now. Load aborted. Please see the man page.\n", argv [0]) ; + exit (1) ; + } else if (argc > 4) _doLoadUsage (argv) ; } @@ -172,13 +229,13 @@ static void doLoad (int argc, char *argv []) if (!moduleLoaded (module1)) { - sprintf (cmd, "modprobe %s%s", module1, args1) ; + sprintf (cmd, "/sbin/modprobe %s%s", module1, args1) ; system (cmd) ; } if (!moduleLoaded (module2)) { - sprintf (cmd, "modprobe %s%s", module2, args2) ; + sprintf (cmd, "/sbin/modprobe %s%s", module2, args2) ; system (cmd) ; } @@ -196,46 +253,82 @@ static void doLoad (int argc, char *argv []) /* - * doReadall: - * Read all the GPIO pins + * doUnLoad: + * Un-Load either the spi or i2c modules and change device ownerships, etc. ********************************************************************************* */ -static char *pinNames [] = +static void _doUnLoadUsage (char *argv []) { - "GPIO 0", "GPIO 1", "GPIO 2", "GPIO 3", "GPIO 4", "GPIO 5", "GPIO 6", "GPIO 7", - "SDA ", "SCL ", - "CE0 ", "CE1 ", "MOSI ", "MISO ", "SCLK ", - "TxD ", "RxD ", - "GPIO 8", "GPIO 9", "GPIO10", "GPIO11", -} ; + fprintf (stderr, "Usage: %s unload \n", argv [0]) ; + exit (1) ; +} -static char *alts [] = +static void doUnLoad (int argc, char *argv []) { - "IN ", "OUT ", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3" -} ; + char *module1, *module2 ; + char cmd [80] ; -static void doReadall (void) -{ - int pin ; + checkDevTree (argv) ; - printf ("+----------+------+--------+------+-------+\n") ; - printf ("| wiringPi | GPIO | Name | Mode | Value |\n") ; - printf ("+----------+------+--------+------+-------+\n") ; + if (argc != 3) + _doUnLoadUsage (argv) ; - for (pin = 0 ; pin < 64 ; ++pin) + /**/ if (strcasecmp (argv [2], "spi") == 0) { - if (wpiPinToGpio (pin) == -1) - continue ; + module1 = "spidev" ; + module2 = "spi_bcm2708" ; + } + else if (strcasecmp (argv [2], "i2c") == 0) + { + module1 = "i2c_dev" ; + module2 = "i2c_bcm2708" ; + } + else + _doUnLoadUsage (argv) ; - printf ("| %6d | %3d | %s | %s | %s |\n", - pin, wpiPinToGpio (pin), - pinNames [pin], - alts [getAlt (pin)], - digitalRead (pin) == HIGH ? "High" : "Low ") ; + if (moduleLoaded (module1)) + { + sprintf (cmd, "/sbin/rmmod %s", module1) ; + system (cmd) ; } - printf ("+----------+------+--------+------+-------+\n") ; + if (moduleLoaded (module2)) + { + sprintf (cmd, "/sbin/rmmod %s", module2) ; + system (cmd) ; + } +} + + +/* + * 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)) ; + } @@ -252,9 +345,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 @@ -363,19 +454,23 @@ void doExport (int argc, char *argv []) exit (1) ; } - /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0)) + /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0)) fprintf (fd, "in\n") ; - else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0)) + else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0)) fprintf (fd, "out\n") ; + else if ((strcasecmp (mode, "high") == 0) || (strcasecmp (mode, "up") == 0)) + fprintf (fd, "high\n") ; + else if ((strcasecmp (mode, "low") == 0) || (strcasecmp (mode, "down") == 0)) + fprintf (fd, "low\n") ; else { - fprintf (stderr, "%s: Invalid mode: %s. Should be in or out\n", argv [1], mode) ; + fprintf (stderr, "%s: Invalid mode: %s. Should be in, out, high or low\n", argv [1], mode) ; exit (1) ; } fclose (fd) ; -// Change ownership so the current user can actually use it! +// Change ownership so the current user can actually use it sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; changeOwner (argv [0], fName) ; @@ -386,6 +481,52 @@ void doExport (int argc, char *argv []) } +/* + * doWfi: + * gpio wfi pin mode + * Wait for Interrupt on a given pin. + * Slight cheat here - it's easier to actually use ISR now (which calls + * gpio to set the pin modes!) then we simply sleep, and expect the thread + * to exit the program. Crude but effective. + ********************************************************************************* + */ + +static void wfi (void) + { exit (0) ; } + +void doWfi (int argc, char *argv []) +{ + int pin, mode ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s wfi pin mode\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + + /**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ; + else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ; + else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ; + else + { + fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ; + exit (1) ; + } + + if (wiringPiISR (pin, mode, &wfi) < 0) + { + fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ; + exit (1) ; + } + + for (;;) + delay (9999) ; +} + + + /* * doEdge: * gpio edge pin mode @@ -499,7 +640,7 @@ void doUnexport (int argc, char *argv []) ********************************************************************************* */ -void doUnexportall (int argc, char *argv []) +void doUnexportall (char *progName) { FILE *fd ; int pin ; @@ -508,7 +649,7 @@ void doUnexportall (int argc, char *argv []) { if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL) { - fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ; + fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ; exit (1) ; } fprintf (fd, "%d\n", pin) ; @@ -517,6 +658,20 @@ void doUnexportall (int argc, char *argv []) } +/* + * doReset: + * Reset the GPIO pins - as much as we can do + ********************************************************************************* + */ + +static void doReset (char *progName) +{ + printf ("GPIO Reset is dangerous and has been removed from the gpio command.\n") ; + printf (" - Please write a shell-script to reset the GPIO pins into the state\n") ; + printf (" that you need them in for your applications.\n") ; +} + + /* * doMode: * gpio mode pin mode ... @@ -536,18 +691,25 @@ 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) ; - else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ; - else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ; - else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ; - else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ; - else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ; - else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ; + /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ; + else if (strcasecmp (mode, "input") == 0) pinMode (pin, INPUT) ; + else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ; + else if (strcasecmp (mode, "output") == 0) pinMode (pin, OUTPUT) ; + else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ; + else if (strcasecmp (mode, "pwmTone") == 0) pinMode (pin, PWM_TONE_OUTPUT) ; + else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ; + else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ; + else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ; + else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ; + else if (strcasecmp (mode, "off") == 0) pullUpDnControl (pin, PUD_OFF) ; + else if (strcasecmp (mode, "alt0") == 0) pinModeAlt (pin, 0b100) ; + else if (strcasecmp (mode, "alt1") == 0) pinModeAlt (pin, 0b101) ; + else if (strcasecmp (mode, "alt2") == 0) pinModeAlt (pin, 0b110) ; + else if (strcasecmp (mode, "alt3") == 0) pinModeAlt (pin, 0b111) ; + else if (strcasecmp (mode, "alt4") == 0) pinModeAlt (pin, 0b011) ; + else if (strcasecmp (mode, "alt5") == 0) pinModeAlt (pin, 0b010) ; else { fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/clock/up/down/tri\n", argv [1], mode) ; @@ -591,6 +753,58 @@ static void doPadDrive (int argc, char *argv []) } +/* + * doUsbP: + * Control USB Power - High (1.2A) or Low (600mA) + * gpio usbp high/low + ********************************************************************************* + */ + +static void doUsbP (int argc, char *argv []) +{ + int model, rev, mem, maker, overVolted ; + + if (argc != 3) + { + fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ; + exit (1) ; + } + +// Make sure we're on a B+ + + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; + + if (model != PI_MODEL_BP) + { + fprintf (stderr, "USB power contol is applicable to B+ boards only.\n") ; + exit (1) ; + } + +// Need to force BCM_GPIO mode: + + wiringPiSetupGpio () ; + + if ((strcasecmp (argv [2], "high") == 0) || (strcasecmp (argv [2], "hi") == 0)) + { + digitalWrite (PI_USB_POWER_CONTROL, 1) ; + pinMode (PI_USB_POWER_CONTROL, OUTPUT) ; + printf ("Switched to HIGH current USB (1.2A)\n") ; + return ; + } + + if ((strcasecmp (argv [2], "low") == 0) || (strcasecmp (argv [2], "lo") == 0)) + { + digitalWrite (PI_USB_POWER_CONTROL, 0) ; + pinMode (PI_USB_POWER_CONTROL, OUTPUT) ; + printf ("Switched to LOW current USB (600mA)\n") ; + return ; + } + + fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ; + exit (1) ; +} + + /* * doGbw: * gpio gbw channel value @@ -604,7 +818,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 +827,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)) + if ((value < 0) || (value > 255)) { - 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 +868,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 +900,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 +913,31 @@ static void doWrite (int argc, char *argv []) digitalWrite (pin, HIGH) ; } + +/* + * doAwriterite: + * gpio awrite pin value + ********************************************************************************* + */ + +static void doAwrite (int argc, char *argv []) +{ + int pin, val ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + + val = atoi (argv [3]) ; + + analogWrite (pin, val) ; +} + + /* * doWriteByte: * gpio write value @@ -742,19 +977,75 @@ void doRead (int argc, char *argv []) } pin = atoi (argv [2]) ; - - if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) - { - printf ("0\n") ; - return ; - } - 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 []) +{ + if (argc != 3) + { + fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ; + exit (1) ; + } + + printf ("%d\n", analogRead (atoi (argv [2]))) ; +} + + +/* + * 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)) ; +} + + +/* + * doPwmTone: + * Output a tone in a PWM pin + ********************************************************************************* + */ + +void doPwmTone (int argc, char *argv []) +{ + int pin, freq ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s pwmTone \n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + freq = atoi (argv [3]) ; + + pwmToneWrite (pin, freq) ; +} + + /* * doClock: * Output a clock on a pin @@ -773,9 +1064,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 +1088,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) ; @@ -863,6 +1148,56 @@ static void doPwmClock (int argc, char *argv []) } +/* + * doVersion: + * Handle the ever more complicated version command + ********************************************************************************* + */ + +static void doVersion (char *argv []) +{ + int model, rev, mem, maker, warranty ; + struct stat statBuf ; + + printf ("gpio version: %s\n", VERSION) ; + printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ; + printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ; + printf ("For details type: %s -warranty\n", argv [0]) ; + printf ("\n") ; + piBoardId (&model, &rev, &mem, &maker, &warranty) ; + +/************* + if (model == PI_MODEL_UNKNOWN) + { + printf ("Your Raspberry Pi has an unknown model type. Please report this to\n") ; + printf (" projects@drogon.net\n") ; + printf ("with a copy of your /proc/cpuinfo if possible\n") ; + } + else +***************/ + + { + printf ("Raspberry Pi Details:\n") ; + printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n", + piModelNames [model], piRevisionNames [rev], piMemorySize [mem], piMakerNames [maker], warranty ? "[Out of Warranty]" : "") ; + +// Check for device tree + + if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ... + printf (" Device tree is enabled.\n") ; + + if (stat ("/dev/gpiomem", &statBuf) == 0) // User level GPIO is GO + { + printf (" This Raspberry Pi supports user-level GPIO access.\n") ; + printf (" -> See the man-page for more details\n") ; + } + else + printf (" * Root or sudo required for GPIO access.\n") ; + + } +} + + /* * main: * Start here @@ -885,27 +1220,35 @@ 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) +// Version & Warranty +// Wish I could remember why I have both -R and -V ... + + if ((strcmp (argv [1], "-R") == 0) || (strcmp (argv [1], "-V") == 0)) { - printf ("gpio version: %s\n", VERSION) ; - printf ("Copyright (c) 2012 Gordon Henderson\n") ; - printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ; - printf ("For details type: %s -warranty\n", argv [0]) ; - printf ("\n") ; - printf ("This Raspberry Pi is a revision %d board.\n", piBoardRev ()) ; + printf ("%d\n", piBoardRev ()) ; + return 0 ; + } + +// Version and information + + if (strcmp (argv [1], "-v") == 0) + { + doVersion (argv) ; return 0 ; } if (strcasecmp (argv [1], "-warranty") == 0) { printf ("gpio version: %s\n", VERSION) ; - printf ("Copyright (c) 2012 Gordon Henderson\n") ; + printf ("Copyright (c) 2012-2015 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,12 +1277,13 @@ 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: - if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; } + if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; } + if (strcasecmp (argv [1], "unload" ) == 0) { doUnLoad (argc, argv) ; return 0 ; } // Gertboard commands @@ -948,13 +1292,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 +1302,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 +1330,69 @@ 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 (!loadWPiExtension (argv [0], argv [2], TRUE)) // 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], "pwmTone" ) == 0) doPwmTone (argc, argv) ; + else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ; + else if (strcasecmp (argv [1], "usbp" ) == 0) doUsbP (argc, argv) ; + else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ; + else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ; + else if (strcasecmp (argv [1], "pins" ) == 0) doPins () ; + 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/pins.c b/gpio/pins.c new file mode 100644 index 0000000..d889a45 --- /dev/null +++ b/gpio/pins.c @@ -0,0 +1,33 @@ +/* + * pins.c: + * Just display a handy Pi pinnout diagram. + * Copyright (c) 2012-2015 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + + +#include + +void doPins (void) +{ + printf ("The pins command has been deprecated - sorry. Please use the\n") ; + printf (" gpio readall\n") ; + printf ("command to get a list of the pinnouts for your Pi.\n") ; +} + diff --git a/gpio/pintest b/gpio/pintest new file mode 100644 index 0000000..4da3d94 --- /dev/null +++ b/gpio/pintest @@ -0,0 +1,187 @@ +#!/bin/bash +# +# pintest +# Test the Pi's GPIO port +# Copyright (c) 2013-2015 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() +{ + cat <. + *********************************************************************** + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +extern int wpMode ; + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==2) +#endif + +/* + * doReadallExternal: + * A relatively crude way to read the pins on an external device. + * We don't know the input/output mode of pins, but we can tell + * if it's an analog pin or a digital one... + ********************************************************************************* + */ + +static void doReadallExternal (void) +{ + int pin ; + + printf ("+------+---------+--------+\n") ; + printf ("| Pin | Digital | Analog |\n") ; + printf ("+------+---------+--------+\n") ; + + for (pin = wiringPiNodes->pinBase ; pin <= wiringPiNodes->pinMax ; ++pin) + printf ("| %4d | %4d | %4d |\n", pin, digitalRead (pin), analogRead (pin)) ; + + printf ("+------+---------+--------+\n") ; +} + + +/* + * doReadall: + * Read all the GPIO pins + * We also want to use this to read the state of pins on an externally + * connected device, so we need to do some fiddling with the internal + * wiringPi node structures - since the gpio command can only use + * one external device at a time, we'll use that to our advantage... + ********************************************************************************* + */ + +static char *alts [] = +{ + "IN", "OUT", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3" +} ; + +static int physToWpi [64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 8, -1, + 9, -1, + 7, 15, + -1, 16, + 0, 1, + 2, -1, + 3, 4, + -1, 5, + 12, -1, + 13, 6, + 14, 10, + -1, 11, // 25, 26 + 30, 31, // Actually I2C, but not used + 21, -1, + 22, 26, + 23, -1, + 24, 27, + 25, 28, + -1, 29, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + 17, 18, + 19, 20, + -1, -1, -1, -1, -1, -1, -1, -1, -1 +} ; + +static char *physNames [64] = +{ + NULL, + + " 3.3v", "5v ", + " SDA.1", "5V ", + " SCL.1", "0v ", + "GPIO. 7", "TxD ", + " 0v", "RxD ", + "GPIO. 0", "GPIO. 1", + "GPIO. 2", "0v ", + "GPIO. 3", "GPIO. 4", + " 3.3v", "GPIO. 5", + " MOSI", "0v ", + " MISO", "GPIO. 6", + " SCLK", "CE0 ", + " 0v", "CE1 ", + " SDA.0", "SCL.0 ", + "GPIO.21", "0v ", + "GPIO.22", "GPIO.26", + "GPIO.23", "0v ", + "GPIO.24", "GPIO.27", + "GPIO.25", "GPIO.28", + " 0v", "GPIO.29", + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + "GPIO.17", "GPIO.18", + "GPIO.19", "GPIO.20", + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +} ; + + +/* + * readallPhys: + * Given a physical pin output the data on it and the next pin: + *| BCM | wPi | Name | Mode | Val| Physical |Val | Mode | Name | wPi | BCM | + ********************************************************************************* + */ + +static void readallPhys (int physPin) +{ + int pin ; + + if (physPinToGpio (physPin) == -1) + printf (" | | ") ; + else + printf (" | %3d | %3d", physPinToGpio (physPin), physToWpi [physPin]) ; + + printf (" | %s", physNames [physPin]) ; + + if (physToWpi [physPin] == -1) + printf (" | | ") ; + else + { + /**/ if (wpMode == WPI_MODE_GPIO) + pin = physPinToGpio (physPin) ; + else if (wpMode == WPI_MODE_PHYS) + pin = physPin ; + else + pin = physToWpi [physPin] ; + + printf (" | %4s", alts [getAlt (pin)]) ; + printf (" | %d", digitalRead (pin)) ; + } + +// Pin numbers: + + printf (" | %2d", physPin) ; + ++physPin ; + printf (" || %-2d", physPin) ; + +// Same, reversed + + if (physToWpi [physPin] == -1) + printf (" | | ") ; + else + { + /**/ if (wpMode == WPI_MODE_GPIO) + pin = physPinToGpio (physPin) ; + else if (wpMode == WPI_MODE_PHYS) + pin = physPin ; + else + pin = physToWpi [physPin] ; + + printf (" | %d", digitalRead (pin)) ; + printf (" | %-4s", alts [getAlt (pin)]) ; + } + + printf (" | %-5s", physNames [physPin]) ; + + if (physToWpi [physPin] == -1) + printf (" | | ") ; + else + printf (" | %-3d | %-3d", physToWpi [physPin], physPinToGpio (physPin)) ; + + printf (" |\n") ; +} + + +void cmReadall (void) +{ + int pin ; + + printf ("+-----+------+-------+ +-----+------+-------+\n") ; + printf ("| Pin | Mode | Value | | Pin | Mode | Value |\n") ; + printf ("+-----+------+-------+ +-----+------+-------+\n") ; + + for (pin = 0 ; pin < 28 ; ++pin) + { + printf ("| %3d ", pin) ; + printf ("| %-4s ", alts [getAlt (pin)]) ; + printf ("| %s ", digitalRead (pin) == HIGH ? "High" : "Low ") ; + printf ("| ") ; + printf ("| %3d ", pin + 28) ; + printf ("| %-4s ", alts [getAlt (pin + 28)]) ; + printf ("| %s ", digitalRead (pin + 28) == HIGH ? "High" : "Low ") ; + printf ("|\n") ; + } + + printf ("+-----+------+-------+ +-----+------+-------+\n") ; +} + + +/* + * abReadall: + * Read all the pins on the model A or B. + ********************************************************************************* + */ + +void abReadall (int model, int rev) +{ + int pin ; + char *type ; + + if (model == PI_MODEL_A) + type = " A" ; + else + if (rev == PI_VERSION_2) + type = "B2" ; + else + type = "B1" ; + + printf (" +-----+-----+---------+------+---+-Model %s-+---+------+---------+-----+-----+\n", type) ; + printf (" | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |\n") ; + printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ; + for (pin = 1 ; pin <= 26 ; pin += 2) + readallPhys (pin) ; + + if (rev == PI_VERSION_2) // B version 2 + { + printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ; + for (pin = 51 ; pin <= 54 ; pin += 2) + readallPhys (pin) ; + } + + printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ; + printf (" | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |\n") ; + printf (" +-----+-----+---------+------+---+-Model %s-+---+------+---------+-----+-----+\n", type) ; +} + + +/* + * piPlusReadall: + * Read all the pins on the model A+ or the B+ + ********************************************************************************* + */ + +static void plus2header (int model) +{ + /**/ if (model == PI_MODEL_AP) + printf (" +-----+-----+---------+------+---+--A Plus--+---+------+---------+-----+-----+\n") ; + else if (model == PI_MODEL_BP) + printf (" +-----+-----+---------+------+---+--B Plus--+---+------+---------+-----+-----+\n") ; + else if (model == PI_MODEL_ZERO) + printf (" +-----+-----+---------+------+---+-Pi Zero--+---+------+---------+-----+-----+\n") ; + else + printf (" +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+\n") ; +} + + +void piPlusReadall (int model) +{ + int pin ; + + plus2header (model) ; + + printf (" | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |\n") ; + printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ; + for (pin = 1 ; pin <= 40 ; pin += 2) + readallPhys (pin) ; + printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ; + printf (" | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |\n") ; + + plus2header (model) ; +} + + +void doReadall (void) +{ + int model, rev, mem, maker, overVolted ; + + if (wiringPiNodes != NULL) // External readall + { + doReadallExternal () ; + return ; + } + + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; + + /**/ if ((model == PI_MODEL_A) || (model == PI_MODEL_B)) + abReadall (model, rev) ; + else if ((model == PI_MODEL_BP) || (model == PI_MODEL_AP) || (model == PI_MODEL_2) || (model == PI_MODEL_ZERO)) + piPlusReadall (model) ; + else if (model == PI_MODEL_CM) + cmReadall () ; + else + printf ("Oops - unable to determine board type... model: %d\n", model) ; +} diff --git a/gpio/version.h b/gpio/version.h new file mode 100644 index 0000000..290ab36 --- /dev/null +++ b/gpio/version.h @@ -0,0 +1 @@ +#define VERSION "2.31" diff --git a/newVersion b/newVersion new file mode 100644 index 0000000..bab6dc5 --- /dev/null +++ b/newVersion @@ -0,0 +1,43 @@ +#!/bin/sh -e +# +# newVersion: +# Utility to create the version.h include file for the gpio command. +# and the Debian package +# +# Copyright (c) 2012-2015 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 . +################################################################################# + +echo Updating to version: `cat VERSION` + +rm -f gpio/version.h +echo "#define VERSION \"`cat VERSION`\"" > gpio/version.h + +rm -f debian-template/wiringPi/DEBIAN/control +cat > debian-template/wiringPi/DEBIAN/control < +Description: The wiringPi libraries, headers and gpio command + Libraries to allow GPIO access on a Raspberry Pi from C and C++ + programs as well as from the command-line +EOF diff --git a/pins/Makefile b/pins/Makefile new file mode 100644 index 0000000..9535fb5 --- /dev/null +++ b/pins/Makefile @@ -0,0 +1,22 @@ + +SRC = pins.tex + +ifneq ($V,1) +Q ?= @ +endif + + +all: ${SRC} + $Q echo Generating DVI + $Q latex pins.tex + +pins.dvi: pins.tex + $Q latex pins.tex + +pdf: pins.dvi + $Q dvipdf pins.dvi + + +.PHONY: clean +clean: + $Q rm -f *.dvi *.aux *.log *.ps *.toc *.bak *~ diff --git a/pins/pins.pdf b/pins/pins.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bd9629d62044179a5532a68a0eb0dbd7b3ac2dd1 GIT binary patch literal 9833 zcmb_Cc_378*T_;MLM3a4VkqOzj4_PtJ0YQvbuhy)W|$dkk|% z*#n}Y0vO}TZgh7j285UcdPEW(PlW<{Bpe;DgLk30;?>k3G&&WJ^MV8<*WI#zAX3VE zE{_@*QrC|^a!e(%T5@JylXu>bWHlnu$mZl?UKGQuy>&wk9@W0?VRh*IEt^#Hh&z3U zf+T&_+tNE;I*N`OijJ;5S)Fa^@2y%!i#SwO9PA8NUW+UIPFwD{b$0`4HT#^B(#G*o zGgk(i&E2B@#G=DqQek44`&k~bZ0Yk_Q=fYD>5b)e6{3Rh$+gw*+w7ZJj<3cjpZltvFgXAlYnodLHi&PdDTlBufBm9nlBm)& zSK7-g90+^25%iryXgDIABx-+y9*{QWdQblR7~oES^5V8(PZM(Q6Pto2QgDUb5-_+L zTpqGx?ZcLD{@&}9&nv6F4h3QZtGmCR4t#c+<#x-{@B9THB7H}FRt8r3KFr9Pj0{#( zq>gEuDVsWo_4i_DpI_Z>>+nJK)!to~2L~+Lcd-q3$PSOd9Fq$!QN3h!1xrzrjiu5X z*3Wc0oo>j>`KbxmsG}0BHADh>t^yWYI#zqasZVbc?yfcFDJ25-Qf1|-VxSVJ7 zYd2-SPv(T7L_a&~3@knJq%oqtiNz&3`;y4kLrTY*B=)9|DatW*ttJG^BsN5n+9Rc; zjz&ul^i6buj9LEI@hlBw$Mu9H9yeXVYZb=WJ!uOK&EJ{Q7d;+j^_NH9MmgS%bzccx z?)=CRFm=`B24UCZ+QfVI=4z&xy6VGER=l3wP6_wLjv9S^M8~GyNJ{V!?j7cn#=knA z+4D%|oP)Hp(83_saO10I8lOa9YH5`O-oU^xso6u>9#|jhV0+{A1(de`jr56=t0%{0 z2;xhtb=2wb4%m*2!G`LAWaN+1NG38 zMQoJ{{U0 zvSQnWzimwUFP{s0-YWm~-Lj`0A71NjR-`zq>Gr!-;?FI$x(QK6`7BDMa907Nt}^@Z zD<$yj9$t#9XO4vL+R+M+i%2Wf=gVU?P)K?$=EJ9_0IT0|h&k$5;z-p1@;9M`wAsY}54i-54~7L8(`v?P(P0K0wX(Q>kb^}+|A=Dv*x zo{zs%O~~_FdlP^ANImDZHyf~+haVat%|eH*<=)_zD^Cb#t)QKD%T`+3#9|#$e1=*N zqG(g--N$61T|Y0&dc9E#vj5lt7xvivMD8nJSZ~{L80wCENM6N@FuVqNqU$nz zpmcd9L$&WpkAX$VF1uyAbI^qv!m|)`P^eXD@}djJk^3CPC>X;>UG^Qh@3YqF>ELpC zE0Le4)r`gTGV_qTqU{TUFCcb!Y_hwC+D#3|63VupTX8m$H`FnIKuVzyUP+3FM8Rbv z;Lwcw_%hZMh^;W)7x2UPP5Xx=yQD{2;hw| zPr@+tu>zBj8UV4e{mL%B-ICXwc+oT=`ym&fc2RcxV~jz2=*}_p?!}sS>un$0m4y~r zipsStVrx(JDX&K#C~=?G6?bDzs6U(A8XzSdm?HwwdPA7lDwJ$ro$tbVtTmqd#x7uu?C$*oMx>NV+H6n;|i$TegEai8tnVAfjwvp^LE z{nvt@ZHE;(U$}*YTa|vf)!RUs5^$zXdost>CN>Q=tX1!Koj%0E(<%$im=jLsf8PCd z+VRHZuwxY(#@EdvlyviBhwMOIs0&aQYQ=2l9Rv{_06jDL_Ik0)_E^OuILBV(r&Ik? z*^diT>vLQLnbZ@DimYqvc^y0*r7!V3-4Wd|?G!%0_k5GI1;>5fl`yfy7I$W#zGcSH zt;?wa(eN&DO_y)L&4md;lG|qUjh!iCYlyXh3#XF8YA@QL+`3ZEK<}X27Ve@TXxq%h zn6po;U#2zMvo6hmZ#y|TM2`RH1^a{ik9<-ODmqvjbqqy(cz9e}-+XfXfso-RH?5>u z{`p$YHw_N2MV46P8moHRNMj+gV=qSsZ;~5WM#A<_I6mhJKwjzcR18gZ{8afuWa0d7 z<~ZxOdf)Bd6fG&RjPpQ?qVTT`m6TypcUBZ&<8SNGPU-3^(^boHp{pb_&iEg zu_f6CyWvGOD(@+u5ck(?a9@uMY*Y@-%}ZzU~?tBUS8yO zaC^v$QoSQb;VSr!*G8Y6Q=C66yk!hjEqE4@; zq$>PRdg^lZwSA(e4CMh)vfIX=Un%pN8jpzdD?^%=`)F`SH+V6J7sn!u6NVl<+W}{f z;O(vvNo-PK1_;eFjf5H}H$RcU^qX$}7>16X%i{XiudHi9F1G zbDuNjntM7$lw%FIsFBgv)*{*C)GoG8=HI{VJH}M~ox5~x;cjBDl39WF{vsf>hn zUZ%@<{+9?_)fX4*YiDxb8l30c;vJ32L`vP{7M~!9-qWkdaJkxM{5nfJ^?)+@qFDl| z@N;W__mJ4Tr7xEqvU11q=9etOiSKfQ$7@ZYMaTEd-;}^jbWRYc4y{Fxqg#{(GSkw1 z%ugLKposC}$7hbUS{p?6mQ=pdN%IC0rf5HddE3Yt$LIN(>Q)30Utmm+57P2R`g^=8g-fek3Qo0xvxBn`y;rmqT(HA{Is#|fd zFT@)0((hiMsGmJ&jSN;)&W}tvJ7&#W#ByW(fqgj@)tyf16V}yW3nxsnK5X)~A9|7S zR_fY0US5d|UU5O$;X4x}Tu)nNKjIcMoX3i+mA?dhlK!50BRS_nzgDZC+_}uyNSSrg zn6vja)@0j?_U5|r$Mgys(mMC)$-LGeIXxJC_K|=@Oe1{$dfUhLr@nYy0$Iu`r=7+u5Ji^68O)Vv;tyXFM#U?{49(%SfYh>toIr%+Adb?kw6x zieCtMNkf(&sqvk#z|o@xKOi5Uzzkd?)F0pzd;G$udhe%*^Jp1-<%#I4M!RTtPrMQd zW?s8@-c%R$go!3vJPg+z8KXXLnKjv~`dnXU_pIcz%IKn36&&6x#+Z+Tun%ySgymOA z&$LU0nqU2wiI>`quJL4>$ho;skl**eI(bXF*sGT7l)c!8Tiw^Z15bu52s9O2AZCqc z&6n<+KkDPR)Nm}#rm>9^dPX>88}kOyW@qZ7jO7X zKiQajR)h+)jHZhoJTDh$wnlmk-KZo#<67dl5N24*0qdWA&zTg2Dex^YHR{w&`@}jh z?Fg(~wQ`)mz8Pt2{U!-q@wvYnzwOm(5)6%#>(CbQtg(K)Y;)V|I=abmPXgAFWkh5u zV6PL~l)~QrrMJgtreFHA9hT2}e`MXTfm}Uw&1tWDFx!Z{*6Gd2&i%|E*E{${{@K(X zKG8n2D%&ago}8;5Izf=OjYfF2jhz?AgNKXNQYm9A^ZUbOPw-_e<*F~0j8@&8@L6c= zroZwW343A|J!bd$?OmI^dJcEzMd}scxiiN$Zn5ca+dJB>aG}*^{hg!}2yzlphwoO8 zSDbp2hO)*_R6v)DLg@b z<>Q>?^?_+VsnS`n#1kp{1-nFIZclw15+mOzWxcEWJ@9ISy<_``71up#Dc}5=>cb=2 zb>}c&T|H(6x=MP>u4 z6;X_TVCFS{5dzavEZjdrt18t#)5OA(`~JYJu3n)BcF}yP{qS_s?pyP~sPl(zTR>_A ze<4(`hX0M1tl_qTg}aGORq`vsYgftg34UcORa~qfLyf$g64l-1r*$uO#qE*MBt9Tn z3Hi!t)*GxECSDbK^2j1AV8U{+l-mzwk2QmT9Lzy|QsqCaPgk(;>fyCNbnA3ljHA(| zYi1Ue0{T;uFZc>=lijktQlLUnYy9{EmFDO>`%!{+Z<5$0KYI*>HIvo~UcL@oD49@3 z^a^Lu<>EBiY&GgiJwL@kc6}&S?d9%#D(NNPo8iU2CqSWGlc`kZ!`E=`10yiXx4E8g z;oMR}2lsrsNX@z!fb^-o+!kN8|7=}e#=d9eGwB`^*6{1m%GjWd+18^?BeUr8I)`?V z;FX5U*SM1e$hmxm8e0+URkT&|*?j!hAdZ)ZO6t{i@1_hkK(# z7OByqu>jP0g$p%a2kjAMiWHsd@^(3v8To>V&nuZe%8gO$H93ad62*C`eD0j!7w27l zXpwRFrFm5cVea(XJCob=hquJ|9Vt;j^L6gnncu!I*O7bHNG5jw=l4nz(E$NM-Z8fd z-@cJiW-83z_x!4gR-gAVT#u}%@xsKy3v=qrn0V2f<`Z1O#RQEvrRmN#98ll9XviB= zj0dHlCstA5iHW&$GObe-#@No@}u`5 zn|(wJX7@g&6|M~X_s>OLxiWgoViVpIqA%?XU(7m+8~4k~7#ht9a6M_G?J>Cx;kO*2 zm==wi`N$1O9XQBWOHN*cw41Vr1(%;GWiD-Gsws}FX;T^l2I8_iTIbrwOb6JH&qJnX zot(>yu6;gIDWEzfN#`rXYxt3z?#*6QHhZ0w_wYU@=YrlS_m_;LY?VR*rYDQT<-5WM zTPlT*Tc3;7cO|iMVbs>V{D&@~o5$no1!V_1x@Z+x#r>U=B|go9g84^tB!sY0b(iJs zE0tb#9p*b)Y1AL+=+~y%f9!HVS0JQl!CKayFseO2mm@rFLOOk~xs!*)`DLY|W+0@R zEodg0M^E{oS8(-Y>%Gn~n`{I*uenU+!$fa|3b1;ek`~h~Y05=`nZ8U>%2kzb?HsL0 z`EKC3AZvSHvRKgYV|z|%Da8x_UFyLLC6CnzYum-rvnxk2Q;yg7+}YmLq&4|?EmlW; ze3i;5@Hq4JD=9|*?N zD85t|JPqswno%h(7I?ZX0QL%@fF(YF4$|oc(Df}gNs*`@BzhE(9QlJDYz_k2;62EZ z24yrA%^@J@r+f^QA5BJ(8z>-jQ$iXPI81b_Q!gXJHj$ls(tDYbEQ z9Esxgi^WgrP4IM_D>ws1ZniJ~V4(P~4F1{%1UO=50!6B+{S9|I+b(%&fl5M2vL!!xu67~n~McskJqx49dD0RuHl2HUGd zvKth+sW`yG*O|^RBSTf7e804~Ir~$DO*8+Z19XT40v*)j6`Aq zE21mion{MFK%yDH5C-Yre;9MWVgDB6_be3gAI|^9^XJN&68zxv2L$p1@6W$rBp}fY zZ~m!sa0_HjGL88A{(n(E!?=G}<8NcawJ0RlKQ;EhFxgb?pB7};|1Z^VTEZ0Pg$Mp= zAT2PGZQ)2L9EHL{6%dM03>IzA=+3**pz`t%K$GUe2xbrp#v#tz08eyt|9Q(;fHB7) zg#d^o;0@b-_>yXTG>M@{D6z%<+i@} zBt3BfjVAE1!fjc5CMIl0*4f?pC1=$t`^_&&4BCIwb~v`}tj%6F-lVkd{nsDmEIx+Q zwNKSvCuu)0xoA3+I6iyjLt=jDh34rPe51+C`Z~3F>{LtRvK@=T7A8%e`L5dGVKz>E zwXsVNw)*&meod@BK7UmV|`grW=eXKf8U@@io;lb82+ zo`RiMmniuo>e|_6D{J4%<9FJpI=!(sL@#wn?JKm-#<=ft`Bc;3P$U)JUE`^wn?^i; zPM(D+EK*9o!B!qss{Fk5^H!$La4x5P1}rz99>33*&phV@x8@+6aYF27{U*$A{xrPh zB31`GM+=p7(qPGqpyz$LD63VbN!YW4NR8%sSDT1 z*0-P4#;;VQzU^Y4>~8Tsy;{4iY2V~~C;bMw>n&O70rT&^%kPO$uDbHT?=e4eZYEt&I$-X(zq2LrtS)H}y{fla z>~{5==AAx3aO32n{Z428h`PFac0~(ISOQ6Ho#jl;De1vPR(yIC`UWas(a)EQZYiIT zq(5C6>p^rUsil(*Y|_#DbGzE+n_IP&2{WwUq-Gqy*9?g4+!y$*+km|FNrnDp*?GmQ zaMQG-?K(Wst7q0&%UmbKDK2U0!z-h18HdVmY@cnjulSs^uBb@rbkjV{J!D-dJ1oAa zrt(f1RZuL2mgSK{T1k+XXtt^$If1MPB=xb=A-L1+A-W17dO@-PZ; zS|Qeq4#8+C=1*s(2oIdwG14!DWYT=-bN@O3Gy^WOjbaHi=PWI!I_?06VnwRn_LqF{ ziM`k7I2ejgn79=!WS}7CQ|g$++4gzfHQzci{M_grjW44Y^|{jf?+3p1C>+q8a7g=b z{>rIrz%X{+^RWgSAd;JZms&itRuBvm_w^rG6+J?9Gu`w4_=gh{cXJwNye&2EHV>)z zxl*jIz)S5435#&$>}}?8dCvW%mY&gs;zv>y%={W&>5Vp5N%zTNhjJuicCJa?ocnrH z6U|W=7DPBCF>$p$<<+&5C##iC>t$Mo|Y!}m> zT<2D;?l}dW_9r9>^XR}&lFR%X8+Z|g-LjKpd~HmrxZzTt3K%d&{C$3yvY>lDR;!PV0cLEiJO z22rl8=Hf}L!7$UTir4q*WusrAN~V=NJ9_$`4dk_2&D5hB9#j@et!zm|b1jfRUQyDQ zAPa`vD#*W=f40=p!lAD}`D0}biv9G4TUb@C1IuB;D4M_gMl#p=yrk4HW#kg{goD1b z?LE8eQ#Wgj6MKx$#78{Ua2)VtT4VFt4iquUjDIaPH*2XsA6LJstiO`5wTbZ`8CdCe z23AoI@W#1#;^|Olyc?0M3Y)EX0)rA=Rbf^NCI}O6ZM-|tAc%^$2r{*F3G#Hoy28}e zAS&uOu*Sv1190AO!sZKT8WenZsY+;@8|z6h5CW6~yu7`@VhINXOSS)}*0Vot4#DLQR$#h%*oJ`vXuD2-&(fT(T znI^X>lbj313m{qpNI3-XYoT8cdm@DlWh{(yrufoTVa_hDNCaL%3GVEQz`&76yek|5 zUT~Z<##PY;O~7DX@xNB`{zJllSqhv0*OCWS0FIQw8s62{1y5Cl>6;lt_1!5n`i~M1 zswAg~gaJQy{$CIXw8+2TJ7~tAn^ysGluf`Qmk_7}9zN7i2&6n50e;YyNQ^QXp^QYI zPyzmi1X>%U(gweA0Dc4E|EBr_=?^Lj)e6aw8JJQDqoW0T`g1}Xr2k~X8l)dj$l@C=D)prMhVoUSg)1Pav)2l_P5+Z!x2 zadgnt0ni~~YAWC)ok%C))iz^JlSKb9AQ2fcq)ft*-Be)#a92D5=S!l))VztHdxOUN zp?(rk?Z;q~4)}}LzcJ1x2#jgaPQdSsp$38em#+UFqrcK5n0!@X{){B}k2K6UZU4-| zzk*u&-^H{HSco%%1yndAT%>iB8DWNyN1%}yGy;q;1Of(rKr}EC{~wH>?k~L=J9g5Z zb~4caG=4z-mJBOP|FWOV?;~~q6;A+9ct}MEBfI^$pcn-Oc?Bo|`V*#r0y`C(Q&93R z7#1lHp1&B^UoZufJb2Xq8w{cN4;TW$I5+=~^V8XZTaZyFaXk48WwC3TPJLH-B9#x3Fi literal 0 HcmV?d00001 diff --git a/pins/pins.tex b/pins/pins.tex new file mode 100644 index 0000000..c3753e9 --- /dev/null +++ b/pins/pins.tex @@ -0,0 +1,116 @@ +\documentclass[12pt,a4paper]{article} +\parskip 1ex +\parindent 0em +\thispagestyle{empty} +\pagestyle{plain} +\pagenumbering{arabic} +\setlength{\topmargin}{0pt} +\setlength{\headheight}{0pt} +\setlength{\headsep}{0pt} +\setlength{\topskip}{0pt} +\setlength{\textheight}{240mm} +\setlength{\footskip}{5ex} +\setlength{\oddsidemargin}{0pt} +\setlength{\evensidemargin}{0pt} +\setlength{\textwidth}{160mm} +\usepackage[dvips]{graphics,color} +\usepackage{helvet} +\renewcommand{\familydefault}{\sfdefault} +\begin{document} +\begin{sffamily} +\definecolor{rtb-black}{rgb} {0.0, 0.0, 0.0} +\definecolor{rtb-navy}{rgb} {0.0, 0.0, 0.5} +\definecolor{rtb-green}{rgb} {0.0, 0.5, 0.0} +\definecolor{rtb-teal}{rgb} {0.0, 0.5, 0.5} +\definecolor{rtb-maroon}{rgb} {0.5, 0.0, 0.0} +\definecolor{rtb-purple}{rgb} {0.5, 0.0, 0.5} +\definecolor{rtb-olive}{rgb} {0.5, 0.5, 0.0} +\definecolor{rtb-silver}{rgb} {0.7, 0.7, 0.7} +\definecolor{rtb-grey}{rgb} {0.5, 0.5, 0.5} +\definecolor{rtb-blue}{rgb} {0.0, 0.0, 1.0} +\definecolor{rtb-lime}{rgb} {0.0, 1.0, 0.0} +\definecolor{rtb-aqua}{rgb} {0.0, 1.0, 1.0} +\definecolor{rtb-red}{rgb} {1.0, 0.0, 0.0} +\definecolor{rtb-fuchsia}{rgb}{1.0, 0.0, 1.0} +\definecolor{rtb-yellow}{rgb} {1.0, 1.0, 0.0} +\definecolor{rtb-white}{rgb} {1.0, 1.0, 1.0} + +\begin{center} +\bfseries{WiringPi: GPIO Pin Numbering Tables}\\ +\tt{http://wiringpi.com/} +\end{center} + +\begin{center} +\begin{tabular}{|c|c|c||p{8mm}|p{8mm}||c|c|c|c|} +\hline +\multicolumn{8}{|c|}{\bfseries{P1: The Main GPIO connector}}\\ +\hline +\hline +WiringPi Pin & BCM GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & BCM GPIO & WiringPi Pin\\ +\hline +\hline + & & \textcolor{rtb-red}{3.3v} & \raggedleft{1} & 2 & \textcolor{rtb-maroon}{5v} & & \\ +\hline +8 & Rv1:0 - Rv2:2 & \textcolor{rtb-aqua}{SDA} & \raggedleft{3} & 4 & \textcolor{rtb-maroon}{5v} & & \\ +\hline +9 & Rv1:1 - Rv2:3 & \textcolor{rtb-aqua}{SCL} & \raggedleft{5} & 6 & \textcolor{rtb-black}{0v} & & \\ +\hline +7 & 4 & \textcolor{rtb-green}{GPIO7} & \raggedleft{7} & 8 & \textcolor{rtb-yellow}{TxD} & 14 & 15\\ +\hline + & & \textcolor{rtb-black}{0v} & \raggedleft{9} & 10 & \textcolor{rtb-yellow}{RxD} & 15 & 16\\ +\hline +0 & 17 & \textcolor{rtb-green}{GPIO0} & \raggedleft{11} & 12 & \textcolor{rtb-green}{GPIO1} & 18 & 1\\ +\hline +2 & Rv1:21 - Rv2:27 & \textcolor{rtb-green}{GPIO2} & \raggedleft{13} & 14 & \textcolor{rtb-black}{0v} & & \\ +\hline +3 & 22 & \textcolor{rtb-green}{GPIO3} & \raggedleft{15} & 16 & \textcolor{rtb-green}{GPIO4} & 23 & 4\\ +\hline + & & \textcolor{rtb-red}{3.3v} & \raggedleft{17} & 18 & \textcolor{rtb-green}{GPIO5} & 24 & 5\\ +\hline +12 & 10 & \textcolor{rtb-teal}{MOSI} & \raggedleft{19} & 20 & \textcolor{rtb-black}{0v} & & \\ +\hline +13 & 9 & \textcolor{rtb-teal}{MISO} & \raggedleft{21} & 22 & \textcolor{rtb-green}{GPIO6} & 25 & 6\\ +\hline +14 & 11 & \textcolor{rtb-teal}{SCLK} & \raggedleft{23} & 24 & \textcolor{rtb-teal}{CE0} & 8 & 10\\ +\hline + & & \textcolor{rtb-black}{0v} & \raggedleft{25} & 26 & \textcolor{rtb-teal}{CE1} & 7 & 11\\ +\hline +\hline +WiringPi Pin & BCM GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & BCM GPIO & WiringPi Pin\\ +\hline +\end{tabular} +\end{center} + +Note the differences between Revision 1 and Revision 2 Raspberry +Pi's. The Revision 2 is readily identifiable by the presence of the 2 +mounting holes. + +The revision 2 Raspberry Pi has an additional GPIO connector, P5, which is next to the main P1 GPIO +connector: + +\begin{center} +\begin{tabular}{|c|c|c||p{8mm}|p{8mm}||c|c|c|c|} +\hline +\multicolumn{8}{|c|}{\bfseries{P5: Secondary GPIO connector (Rev. 2 Pi only)}}\\ +\hline +\hline +WiringPi Pin & BCM GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & BCM GPIO & WiringPi Pin\\ +\hline +\hline + & & \textcolor{rtb-maroon}{5v} & \raggedleft{1} & 2 & \textcolor{rtb-red}{3.3v} & & \\ +\hline +17 & 28 & \textcolor{rtb-green}{GPIO8} & \raggedleft{3} & 4 & \textcolor{rtb-green}{GPIO9} & 29 & 18 \\ +\hline +19 & 30 & \textcolor{rtb-green}{GPIO10} & \raggedleft{5} & 6 & \textcolor{rtb-green}{GPIO11} & 31 & 20 \\ +\hline + & & \textcolor{rtb-black}{0v} & \raggedleft{7} & 8 & \textcolor{rtb-black}{0v} & & \\ +\hline +\hline +WiringPi Pin & BCM GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & BCM GPIO & WiringPi Pin\\ +\hline +\end{tabular} +\end{center} + + +\end{sffamily} +\end{document} diff --git a/wiringPi/Makefile b/wiringPi/Makefile index c6a4555..6bbcc5d 100644 --- a/wiringPi/Makefile +++ b/wiringPi/Makefile @@ -1,8 +1,8 @@ -# ; +# # Makefile: # wiringPi - Wiring Compatable library for the Raspberry Pi # -# Copyright (c) 2012 Gordon Henderson +# Copyright (c) 2012-2015 Gordon Henderson ################################################################################# # This file is part of wiringPi: # https://projects.drogon.net/raspberry-pi/wiringpi/ @@ -21,12 +21,15 @@ # along with wiringPi. If not, see . ################################################################################# -DYN_VERS_MAJ=1 -DYN_VERS_MIN=0 +VERSION=$(shell cat ../VERSION) +DESTDIR?=/usr +PREFIX?=/local -VERSION=$(DYN_VERS_MAJ).$(DYN_VERS_MIN) -DESTDIR=/usr -PREFIX=/local +LDCONFIG?=ldconfig + +ifneq ($V,1) +Q ?= @ +endif STATIC=libwiringPi.a DYNAMIC=libwiringPi.so.$(VERSION) @@ -35,118 +38,145 @@ DYNAMIC=libwiringPi.so.$(VERSION) DEBUG = -O2 CC = gcc INCLUDE = -I. -CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe -fPIC +DEFS = -D_GNU_SOURCE +CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Winline $(INCLUDE) -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 = wiringPi.c \ + wiringSerial.c wiringShift.c \ + piHiPri.c piThread.c \ + wiringPiSPI.c wiringPiI2C.c \ + softPwm.c softTone.c \ + mcp23008.c mcp23016.c mcp23017.c \ + mcp23s08.c mcp23s17.c \ + sr595.c \ + pcf8574.c pcf8591.c \ + mcp3002.c mcp3004.c mcp4802.c mcp3422.c \ + max31855.c max5322.c \ + sn3218.c \ + drcSerial.c \ + wpiExtensions.c + +HEADERS = wiringPi.h \ + wiringSerial.h wiringShift.h \ + wiringPiSPI.h wiringPiI2C.h \ + softPwm.h softTone.h \ + mcp23008.h mcp23016.h mcp23017.h \ + mcp23s08.h mcp23s17.h \ + sr595.h \ + pcf8574.h pcf8591.h \ + mcp3002.h mcp3004.h mcp4802.h mcp3422.h \ + max31855.h max5322.h \ + sn3218.h \ + drcSerial.h \ + wpiExtensions.h -SRC_I2C = wiringPiI2C.c OBJ = $(SRC:.c=.o) -OBJ_I2C = $(SRC_I2C:.c=.o) - all: $(DYNAMIC) static: $(STATIC) $(STATIC): $(OBJ) - @echo "[Link (Static)]" - @ar rcs $(STATIC) $(OBJ) - @ranlib $(STATIC) + $Q echo "[Link (Static)]" + $Q ar rcs $(STATIC) $(OBJ) + $Q ranlib $(STATIC) # @size $(STATIC) $(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) + $Q echo "[Link (Dynamic)]" + $Q $(CC) -shared -Wl,-soname,libwiringPi.so$(WIRINGPI_SONAME_SUFFIX) -o libwiringPi.so.$(VERSION) -lpthread $(OBJ) .c.o: - @echo [Compile] $< - @$(CC) -c $(CFLAGS) $< -o $@ + $Q echo [Compile] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ -.PHONEY: clean + +.PHONY: clean clean: - rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPi.* + $Q echo "[Clean]" + $Q rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPi.* -.PHONEY: tags +.PHONY: tags tags: $(SRC) - @echo [ctags] - @ctags $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) -.PHONEY: install + +.PHONY: install install: $(DYNAMIC) - @echo "[Install]" - @install -m 0755 -d $(DESTDIR)$(PREFIX)/lib - @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 - @ldconfig + $Q echo "[Install Headers]" + $Q install -m 0755 -d $(DESTDIR)$(PREFIX)/include + $Q install -m 0644 $(HEADERS) $(DESTDIR)$(PREFIX)/include + $Q echo "[Install Dynamic Lib]" + $Q install -m 0755 -d $(DESTDIR)$(PREFIX)/lib + $Q install -m 0755 libwiringPi.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) + $Q ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so + $Q $(LDCONFIG) -.PHONEY: install-static +.PHONY: install-static install-static: $(STATIC) - @echo "[Install Static]" - @install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib + $Q echo "[Install Headers]" + $Q install -m 0755 -d $(DESTDIR)$(PREFIX)/include + $Q install -m 0644 $(HEADERS) $(DESTDIR)$(PREFIX)/include + $Q echo "[Install Static Lib]" + $Q install -m 0755 -d $(DESTDIR)$(PREFIX)/lib + $Q install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib -.PHONEY: uninstall +.PHONY: install-deb +install-deb: $(DYNAMIC) + $Q echo "[Install Headers: deb]" + $Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/include + $Q install -m 0644 $(HEADERS) ~/wiringPi/debian-template/wiringPi/usr/include + $Q echo "[Install Dynamic Lib: deb]" + install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/lib + install -m 0755 libwiringPi.so.$(VERSION) ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPi.so.$(VERSION) + ln -sf ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPi.so.$(VERSION) ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPi.so + +.PHONY: uninstall uninstall: - @echo "[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)/lib/libwiringPi.* - @ldconfig + $Q echo "[UnInstall]" + $Q cd $(DESTDIR)$(PREFIX)/include/ && rm -f $(HEADERS) + $Q cd $(DESTDIR)$(PREFIX)/lib/ && rm -f libwiringPi.* + $Q $(LDCONFIG) -.PHONEY: depend +.PHONY: depend depend: makedepend -Y $(SRC) $(SRC_I2C) # DO NOT DELETE -wiringPi.o: wiringPi.h -wiringPiFace.o: wiringPi.h +wiringPi.o: softPwm.h softTone.h 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 -softPwm.o: wiringPi.h softPwm.h -softServo.o: wiringPi.h softServo.h -softTone.o: wiringPi.h softTone.h +wiringPiSPI.o: wiringPi.h wiringPiSPI.h wiringPiI2C.o: wiringPi.h wiringPiI2C.h +softPwm.o: wiringPi.h softPwm.h +softTone.o: wiringPi.h softTone.h +mcp23008.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23008.h +mcp23016.o: wiringPi.h wiringPiI2C.h mcp23016.h mcp23016reg.h +mcp23017.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23017.h +mcp23s08.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s08.h +mcp23s17.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s17.h +sr595.o: wiringPi.h sr595.h +pcf8574.o: wiringPi.h wiringPiI2C.h pcf8574.h +pcf8591.o: wiringPi.h wiringPiI2C.h pcf8591.h +mcp3002.o: wiringPi.h wiringPiSPI.h mcp3002.h +mcp3004.o: wiringPi.h wiringPiSPI.h mcp3004.h +mcp4802.o: wiringPi.h wiringPiSPI.h mcp4802.h +mcp3422.o: wiringPi.h wiringPiI2C.h mcp3422.h +max31855.o: wiringPi.h wiringPiSPI.h max31855.h +max5322.o: wiringPi.h wiringPiSPI.h max5322.h +sn3218.o: wiringPi.h wiringPiI2C.h sn3218.h +drcSerial.o: wiringPi.h wiringSerial.h drcSerial.h +wpiExtensions.o: wiringPi.h mcp23008.h mcp23016.h mcp23017.h mcp23s08.h +wpiExtensions.o: mcp23s17.h sr595.h pcf8574.h pcf8591.h mcp3002.h mcp3004.h +wpiExtensions.o: mcp4802.h mcp3422.h max31855.h max5322.h sn3218.h +wpiExtensions.o: drcSerial.h wpiExtensions.h diff --git a/wiringPi/drcSerial.c b/wiringPi/drcSerial.c new file mode 100644 index 0000000..6491a98 --- /dev/null +++ b/wiringPi/drcSerial.c @@ -0,0 +1,201 @@ +/* + * drcSerial.c: + * Extend wiringPi with the DRC Serial protocol (e.g. to Arduino) + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include + +#include "wiringPi.h" +#include "wiringSerial.h" + +#include "drcSerial.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 - node->pinBase) ; + + /**/ if (mode == PUD_UP) + { + serialPutchar (node->fd, '1') ; + serialPutchar (node->fd, pin - node->pinBase) ; + } + else if (mode == PUD_OFF) + { + serialPutchar (node->fd, '0') ; + serialPutchar (node->fd, pin - node->pinBase) ; + } +} + + +/* + * myDigitalWrite: + ********************************************************************************* + */ + +static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + serialPutchar (node->fd, value == 0 ? '0' : '1') ; + serialPutchar (node->fd, pin - node->pinBase) ; +} + + +/* + * myPwmWrite: + ********************************************************************************* + */ + +static void myPwmWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + serialPutchar (node->fd, 'v') ; + serialPutchar (node->fd, pin - node->pinBase) ; + serialPutchar (node->fd, value & 0xFF) ; +} + + +/* + * myAnalogRead: + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + int vHi, vLo ; + + serialPutchar (node->fd, 'a') ; + serialPutchar (node->fd, pin - node->pinBase) ; + vHi = serialGetchar (node->fd) ; + vLo = serialGetchar (node->fd) ; + + return (vHi << 8) | vLo ; +} + + +/* + * myDigitalRead: + ********************************************************************************* + */ + +static int myDigitalRead (struct wiringPiNodeStruct *node, int pin) +{ + serialPutchar (node->fd, 'r') ; // Send read command + serialPutchar (node->fd, pin - node->pinBase) ; + return (serialGetchar (node->fd) == '0') ? 0 : 1 ; +} + + +/* + * drcSetup: + * Create a new instance of an DRC GPIO interface. + * Could be a variable nunber of pins here - we might not know in advance + * if it's an ATmega with 14 pins, or something with less or more! + ********************************************************************************* + */ + +int drcSetupSerial (const int pinBase, const int numPins, const char *device, const int baud) +{ + int fd ; + int ok, tries ; + time_t then ; + struct wiringPiNodeStruct *node ; + + if ((fd = serialOpen (device, baud)) < 0) + return 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) && (!ok) ; ++tries) + { + serialPutchar (fd, '@') ; // Ping + then = time (NULL) + 2 ; + while (time (NULL) < then) + if (serialDataAvail (fd)) + { + if (serialGetchar (fd) == '@') + { + ok = TRUE ; + break ; + } + } + } + + if (!ok) + { + serialClose (fd) ; + return wiringPiFailure (WPI_FATAL, "Unable to communicate with DRC serial 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/drcSerial.h b/wiringPi/drcSerial.h new file mode 100644 index 0000000..29e988e --- /dev/null +++ b/wiringPi/drcSerial.h @@ -0,0 +1,33 @@ +/* + * drcSerial.h: + * Extend wiringPi with the DRC Serial protocol (e.g. to Arduino) + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int drcSetupSerial (const int pinBase, const int numPins, const char *device, const int baud) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/max31855.c b/wiringPi/max31855.c new file mode 100644 index 0000000..ea184d8 --- /dev/null +++ b/wiringPi/max31855.c @@ -0,0 +1,99 @@ +/* + * max31855.c: + * Extend wiringPi with the max31855 SPI Analog to Digital convertor + * Copyright (c) 2012-2015 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include +#include + +#include "max31855.h" + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + uint32_t spiData ; + int temp ; + int chan = pin - node->pinBase ; + + wiringPiSPIDataRW (node->fd, (unsigned char *)&spiData, 4) ; + + spiData = __bswap_32(spiData) ; + + switch (chan) + { + case 0: // Existing read - return raw value * 4 + spiData >>= 18 ; + temp = spiData & 0x1FFF ; // Bottom 13 bits + if ((spiData & 0x2000) != 0) // Negative + temp = -temp ; + + return temp ; + + case 1: // Return error bits + return spiData & 0x7 ; + + case 2: // Return temp in C * 10 + spiData >>= 18 ; + temp = spiData & 0x1FFF ; // Bottom 13 bits + if ((spiData & 0x2000) != 0) // Negative + temp = -temp ; + + return (int)((((double)temp * 25) + 0.5) / 10.0) ; + + case 3: // Return temp in F * 10 + spiData >>= 18 ; + temp = spiData & 0x1FFF ; // Bottom 13 bits + if ((spiData & 0x2000) != 0) // Negative + temp = -temp ; + + return (int)((((((double)temp * 0.25 * 9.0 / 5.0) + 32.0) * 100.0) + 0.5) / 10.0) ; + + default: // Who knows... + return 0 ; + + } +} + + +/* + * max31855Setup: + * Create a new wiringPi device node for an max31855 on the Pi's + * SPI interface. + ********************************************************************************* + */ + +int max31855Setup (const int pinBase, int spiChannel) +{ + struct wiringPiNodeStruct *node ; + + if (wiringPiSPISetup (spiChannel, 5000000) < 0) // 5MHz - prob 4 on the Pi + return -1 ; + + node = wiringPiNewNode (pinBase, 4) ; + + node->fd = spiChannel ; + node->analogRead = myAnalogRead ; + + return 0 ; +} diff --git a/wiringPi/max31855.h b/wiringPi/max31855.h new file mode 100644 index 0000000..385c4bd --- /dev/null +++ b/wiringPi/max31855.h @@ -0,0 +1,33 @@ +/* + * max31855.c: + * Extend wiringPi with the MAX31855 SPI Thermocouple driver + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int max31855Setup (int pinBase, int spiChannel) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/max5322.c b/wiringPi/max5322.c new file mode 100644 index 0000000..b7cd6a9 --- /dev/null +++ b/wiringPi/max5322.c @@ -0,0 +1,84 @@ +/* + * max5322.c: + * Extend wiringPi with the MAX5322 SPI Digital to Analog convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "max5322.h" + +/* + * myAnalogWrite: + * Write analog value on the given pin + ********************************************************************************* + */ + +static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + unsigned char spiData [2] ; + unsigned char chanBits, dataBits ; + int chan = pin - node->pinBase ; + + if (chan == 0) + chanBits = 0b01000000 ; + else + chanBits = 0b01010000 ; + + chanBits |= ((value >> 12) & 0x0F) ; + dataBits = ((value ) & 0xFF) ; + + spiData [0] = chanBits ; + spiData [1] = dataBits ; + + wiringPiSPIDataRW (node->fd, spiData, 2) ; +} + +/* + * max5322Setup: + * Create a new wiringPi device node for an max5322 on the Pi's + * SPI interface. + ********************************************************************************* + */ + +int max5322Setup (const int pinBase, int spiChannel) +{ + struct wiringPiNodeStruct *node ; + unsigned char spiData [2] ; + + if (wiringPiSPISetup (spiChannel, 8000000) < 0) // 10MHz Max + return -1 ; + + node = wiringPiNewNode (pinBase, 2) ; + + node->fd = spiChannel ; + node->analogWrite = myAnalogWrite ; + +// Enable both DACs + + spiData [0] = 0b11100000 ; + spiData [1] = 0 ; + + wiringPiSPIDataRW (node->fd, spiData, 2) ; + + return 0 ; +} diff --git a/wiringPi/max5322.h b/wiringPi/max5322.h new file mode 100644 index 0000000..a217cf8 --- /dev/null +++ b/wiringPi/max5322.h @@ -0,0 +1,33 @@ +/* + * max5322.h: + * Extend wiringPi with the MAX5322 SPI Digital to Analog convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int max5322Setup (int pinBase, int spiChannel) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp23008.c b/wiringPi/mcp23008.c new file mode 100644 index 0000000..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/mcp23016.c b/wiringPi/mcp23016.c new file mode 100644 index 0000000..e5cc632 --- /dev/null +++ b/wiringPi/mcp23016.c @@ -0,0 +1,164 @@ +/* + * mcp23016.c: + * Extend wiringPi with the MCP 23016 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "wiringPi.h" +#include "wiringPiI2C.h" +#include "mcp23016.h" + +#include "mcp23016reg.h" + + +/* + * myPinMode: + ********************************************************************************* + */ + +static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode) +{ + int mask, old, reg ; + + pin -= node->pinBase ; + + if (pin < 8) // Bank A + reg = MCP23016_IODIR0 ; + else + { + reg = MCP23016_IODIR1 ; + pin &= 0x07 ; + } + + mask = 1 << pin ; + old = wiringPiI2CReadReg8 (node->fd, reg) ; + + if (mode == OUTPUT) + old &= (~mask) ; + else + old |= mask ; + + wiringPiI2CWriteReg8 (node->fd, reg, old) ; +} + + +/* + * myDigitalWrite: + ********************************************************************************* + */ + +static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + int bit, old ; + + pin -= node->pinBase ; // Pin now 0-15 + + bit = 1 << (pin & 7) ; + + if (pin < 8) // Bank A + { + old = node->data2 ; + + if (value == LOW) + old &= (~bit) ; + else + old |= bit ; + + wiringPiI2CWriteReg8 (node->fd, MCP23016_GP0, old) ; + node->data2 = old ; + } + else // Bank B + { + old = node->data3 ; + + if (value == LOW) + old &= (~bit) ; + else + old |= bit ; + + wiringPiI2CWriteReg8 (node->fd, MCP23016_GP1, old) ; + node->data3 = old ; + } +} + + +/* + * myDigitalRead: + ********************************************************************************* + */ + +static int myDigitalRead (struct wiringPiNodeStruct *node, int pin) +{ + int mask, value, gpio ; + + pin -= node->pinBase ; + + if (pin < 8) // Bank A + gpio = MCP23016_GP0 ; + else + { + gpio = MCP23016_GP1 ; + pin &= 0x07 ; + } + + mask = 1 << pin ; + value = wiringPiI2CReadReg8 (node->fd, gpio) ; + + if ((value & mask) == 0) + return LOW ; + else + return HIGH ; +} + + +/* + * mcp23016Setup: + * Create a new instance of an MCP23016 I2C GPIO interface. We know it + * has 16 pins, so all we need to know here is the I2C address and the + * user-defined pin base. + ********************************************************************************* + */ + +int mcp23016Setup (const int pinBase, const int i2cAddress) +{ + int fd ; + struct wiringPiNodeStruct *node ; + + if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) + return fd ; + + wiringPiI2CWriteReg8 (fd, MCP23016_IOCON0, IOCON_INIT) ; + wiringPiI2CWriteReg8 (fd, MCP23016_IOCON1, IOCON_INIT) ; + + node = wiringPiNewNode (pinBase, 16) ; + + node->fd = fd ; + node->pinMode = myPinMode ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->data2 = wiringPiI2CReadReg8 (fd, MCP23016_OLAT0) ; + node->data3 = wiringPiI2CReadReg8 (fd, MCP23016_OLAT1) ; + + return 0 ; +} diff --git a/wiringPi/mcp23016.h b/wiringPi/mcp23016.h new file mode 100644 index 0000000..f9b5cc5 --- /dev/null +++ b/wiringPi/mcp23016.h @@ -0,0 +1,33 @@ +/* + * mcp23016.h: + * Extend wiringPi with the MCP 23016 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp23016Setup (const int pinBase, const int i2cAddress) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp23016reg.h b/wiringPi/mcp23016reg.h new file mode 100644 index 0000000..9aea92d --- /dev/null +++ b/wiringPi/mcp23016reg.h @@ -0,0 +1,48 @@ +/* + * mcp23016: + * Copyright (c) 2012-2013 Gordon Henderson + * + * Header file for code using the MCP23016 GPIO expander + * chip. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +// MCP23016 Registers + +#define MCP23016_GP0 0x00 +#define MCP23016_GP1 0x01 +#define MCP23016_OLAT0 0x02 +#define MCP23016_OLAT1 0x03 +#define MCP23016_IPOL0 0x04 +#define MCP23016_IPOL1 0x05 +#define MCP23016_IODIR0 0x06 +#define MCP23016_IODIR1 0x07 +#define MCP23016_INTCAP0 0x08 +#define MCP23016_INTCAP1 0x09 +#define MCP23016_IOCON0 0x0A +#define MCP23016_IOCON1 0x0B + +// Bits in the IOCON register + +#define IOCON_IARES 0x01 + +// Default initialisation mode + +#define IOCON_INIT 0 diff --git a/wiringPi/mcp23017.c b/wiringPi/mcp23017.c new file mode 100644 index 0000000..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..5d44940 --- /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 mcp3002 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/mcp3004.c b/wiringPi/mcp3004.c new file mode 100644 index 0000000..82c73dd --- /dev/null +++ b/wiringPi/mcp3004.c @@ -0,0 +1,76 @@ +/* + * mcp3004.c: + * Extend wiringPi with the MCP3004 SPI Analog to Digital convertor + * Copyright (c) 2012-2013 Gordon Henderson + * + * Thanks also to "ShorTie" on IRC for some remote debugging help! + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "mcp3004.h" + +/* + * myAnalogRead: + * Return the analog value of the given pin + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + unsigned char spiData [3] ; + unsigned char chanBits ; + int chan = pin - node->pinBase ; + + chanBits = 0b10000000 | (chan << 4) ; + + spiData [0] = 1 ; // Start bit + spiData [1] = chanBits ; + spiData [2] = 0 ; + + wiringPiSPIDataRW (node->fd, spiData, 3) ; + + return ((spiData [1] << 8) | spiData [2]) & 0x3FF ; +} + + +/* + * mcp3004Setup: + * Create a new wiringPi device node for an mcp3004 on the Pi's + * SPI interface. + ********************************************************************************* + */ + +int mcp3004Setup (const int pinBase, int spiChannel) +{ + struct wiringPiNodeStruct *node ; + + if (wiringPiSPISetup (spiChannel, 1000000) < 0) + return -1 ; + + node = wiringPiNewNode (pinBase, 8) ; + + node->fd = spiChannel ; + node->analogRead = myAnalogRead ; + + return 0 ; +} diff --git a/wiringPi/mcp3004.h b/wiringPi/mcp3004.h new file mode 100644 index 0000000..a07c0bf --- /dev/null +++ b/wiringPi/mcp3004.h @@ -0,0 +1,33 @@ +/* + * mcp3004.c: + * Extend wiringPi with the MCP3004 SPI Analog to Digital convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp3004Setup (int pinBase, int spiChannel) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp3422.c b/wiringPi/mcp3422.c new file mode 100644 index 0000000..831aece --- /dev/null +++ b/wiringPi/mcp3422.c @@ -0,0 +1,110 @@ +/* + * mcp3422.c: + * Extend wiringPi with the MCP3422 I2C ADC chip + * Also works for the MCP3423 and MCP3224 (4 channel) chips + * 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 + +#include "mcp3422.h" + + +/* + * myAnalogRead: + * Read a channel from the device + ********************************************************************************* + */ + +int myAnalogRead (struct wiringPiNodeStruct *node, int chan) +{ + unsigned char config ; + unsigned char buffer [4] ; + 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) ; + read (node->fd, buffer, 4) ; + value = ((buffer [0] & 3) << 16) | (buffer [1] << 8) | buffer [0] ; + break ; + + case MCP3422_SR_15: // 16 bits + delay ( 70) ; + read (node->fd, buffer, 3) ; + value = (buffer [0] << 8) | buffer [1] ; + break ; + + case MCP3422_SR_60: // 14 bits + delay ( 17) ; + read (node->fd, buffer, 3) ; + value = ((buffer [0] & 0x3F) << 8) | buffer [1] ; + break ; + + case MCP3422_SR_240: // 12 bits + delay ( 5) ; + read (node->fd, buffer, 3) ; + value = ((buffer [0] & 0x0F) << 8) | buffer [0] ; + break ; + } + + return value ; +} + + +/* + * mcp3422Setup: + * Create a new wiringPi device node for the mcp3422 + ********************************************************************************* + */ + +int mcp3422Setup (int pinBase, int i2cAddress, int sampleRate, int gain) +{ + int fd ; + struct wiringPiNodeStruct *node ; + + if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) + return fd ; + + node = wiringPiNewNode (pinBase, 4) ; + + 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..bb4692d --- /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 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..c172d1c --- /dev/null +++ b/wiringPi/pcf8574.c @@ -0,0 +1,126 @@ +/* + * pcf8574.c: + * Extend wiringPi with the PCF8574 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "wiringPi.h" +#include "wiringPiI2C.h" + +#include "pcf8574.h" + + +/* + * myPinMode: + * The PCF8574 is an odd chip - the pins are effectively bi-directional, + * however the pins should be drven high when used as an input pin... + * So, we're effectively copying digitalWrite... + ********************************************************************************* + */ + +static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode) +{ + int bit, old ; + + bit = 1 << ((pin - node->pinBase) & 7) ; + + old = node->data2 ; + if (mode == OUTPUT) + old &= (~bit) ; // Write bit to 0 + else + old |= bit ; // Write bit to 1 + + wiringPiI2CWrite (node->fd, old) ; + node->data2 = old ; +} + + + +/* + * myDigitalWrite: + ********************************************************************************* + */ + +static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + int bit, old ; + + bit = 1 << ((pin - node->pinBase) & 7) ; + + old = node->data2 ; + if (value == LOW) + old &= (~bit) ; + else + old |= bit ; + + wiringPiI2CWrite (node->fd, old) ; + node->data2 = old ; +} + + +/* + * myDigitalRead: + ********************************************************************************* + */ + +static int myDigitalRead (struct wiringPiNodeStruct *node, int pin) +{ + int mask, value ; + + mask = 1 << ((pin - node->pinBase) & 7) ; + value = wiringPiI2CRead (node->fd) ; + + if ((value & mask) == 0) + return LOW ; + else + return HIGH ; +} + + +/* + * pcf8574Setup: + * Create a new instance of a PCF8574 I2C GPIO interface. We know it + * has 8 pins, so all we need to know here is the I2C address and the + * user-defined pin base. + ********************************************************************************* + */ + +int pcf8574Setup (const int pinBase, const int i2cAddress) +{ + int fd ; + struct wiringPiNodeStruct *node ; + + if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) + return 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..8e2d818 --- /dev/null +++ b/wiringPi/pcf8574.h @@ -0,0 +1,33 @@ +/* + * pcf8574.h: + * Extend wiringPi with the PCF8574 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int pcf8574Setup (const int pinBase, const int i2cAddress) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/pcf8591.c b/wiringPi/pcf8591.c new file mode 100644 index 0000000..0c86056 --- /dev/null +++ b/wiringPi/pcf8591.c @@ -0,0 +1,90 @@ +/* + * pcf8591.c: + * Extend wiringPi with the PCF8591 I2C GPIO Analog expander chip + * The chip has 1 8-bit DAC and 4 x 8-bit ADCs + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include + +#include "wiringPi.h" +#include "wiringPiI2C.h" + +#include "pcf8591.h" + + +/* + * myAnalogWrite: + ********************************************************************************* + */ + +static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + unsigned char b [2] ; + b [0] = 0x40 ; + b [1] = value & 0xFF ; + write (node->fd, b, 2) ; +} + + +/* + * myAnalogRead: + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + int x ; + + wiringPiI2CWrite (node->fd, 0x40 | ((pin - node->pinBase) & 3)) ; + + x = wiringPiI2CRead (node->fd) ; // Throw away the first read + x = wiringPiI2CRead (node->fd) ; + + return x ; +} + + +/* + * pcf8591Setup: + * Create a new instance of a PCF8591 I2C GPIO interface. We know it + * has 4 pins, (4 analog inputs and 1 analog output which we'll shadow + * input 0) so all we need to know here is the I2C address and the + * user-defined pin base. + ********************************************************************************* + */ + +int pcf8591Setup (const int pinBase, const int i2cAddress) +{ + int fd ; + struct wiringPiNodeStruct *node ; + + if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) + return fd ; + + node = wiringPiNewNode (pinBase, 4) ; + + node->fd = fd ; + node->analogRead = myAnalogRead ; + node->analogWrite = myAnalogWrite ; + + return 0 ; +} diff --git a/wiringPi/pcf8591.h b/wiringPi/pcf8591.h new file mode 100644 index 0000000..6b44ccf --- /dev/null +++ b/wiringPi/pcf8591.h @@ -0,0 +1,33 @@ +/* + * pcf8591.h: + * Extend wiringPi with the PCF8591 I2C GPIO Analog expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int pcf8591Setup (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/sn3218.c b/wiringPi/sn3218.c new file mode 100644 index 0000000..7ceb156 --- /dev/null +++ b/wiringPi/sn3218.c @@ -0,0 +1,75 @@ +/* + * sn3218.c: + * Extend wiringPi with the SN3218 I2C LEd Driver + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "sn3218.h" + +/* + * myAnalogWrite: + * Write analog value on the given pin + ********************************************************************************* + */ + +static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + int fd = node->fd ; + int chan = 0x01 + (pin - node->pinBase) ; + + wiringPiI2CWriteReg8 (fd, chan, value & 0xFF) ; // Value + wiringPiI2CWriteReg8 (fd, 0x16, 0x00) ; // Update +} + +/* + * sn3218Setup: + * Create a new wiringPi device node for an sn3218 on the Pi's + * SPI interface. + ********************************************************************************* + */ + +int sn3218Setup (const int pinBase) +{ + int fd ; + struct wiringPiNodeStruct *node ; + + if ((fd = wiringPiI2CSetup (0x54)) < 0) + return fd ; + +// Setup the chip - initialise all 18 LEDs to off + +//wiringPiI2CWriteReg8 (fd, 0x17, 0) ; // Reset + wiringPiI2CWriteReg8 (fd, 0x00, 1) ; // Not Shutdown + wiringPiI2CWriteReg8 (fd, 0x13, 0x3F) ; // Enable LEDs 0- 5 + wiringPiI2CWriteReg8 (fd, 0x14, 0x3F) ; // Enable LEDs 6-11 + wiringPiI2CWriteReg8 (fd, 0x15, 0x3F) ; // Enable LEDs 12-17 + wiringPiI2CWriteReg8 (fd, 0x16, 0x00) ; // Update + + node = wiringPiNewNode (pinBase, 18) ; + + node->fd = fd ; + node->analogWrite = myAnalogWrite ; + + return 0 ; +} diff --git a/wiringPi/sn3218.h b/wiringPi/sn3218.h new file mode 100644 index 0000000..580d5f9 --- /dev/null +++ b/wiringPi/sn3218.h @@ -0,0 +1,33 @@ +/* + * sn3218.c: + * Extend wiringPi with the SN3218 I2C LED driver board. + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int sn3218Setup (int pinBase) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/softPwm.c b/wiringPi/softPwm.c index b568dfb..98b408f 100644 --- a/wiringPi/softPwm.c +++ b/wiringPi/softPwm.c @@ -1,7 +1,7 @@ /* * softPwm.c: * Provide 2 channels of software driven PWM. - * Copyright (c) 2012 Gordon Henderson + * Copyright (c) 2012-2014 Gordon Henderson *********************************************************************** * This file is part of wiringPi: * https://projects.drogon.net/raspberry-pi/wiringpi/ @@ -28,17 +28,22 @@ #include "wiringPi.h" #include "softPwm.h" -#define MAX_PINS 64 +// MAX_PINS: +// This is more than the number of Pi pins because we can actually softPwm +// pins that are on GPIO expanders. It's not that efficient and more than 1 or +// 2 pins on e.g. (SPI) mcp23s17 won't really be that effective, however... + +#define MAX_PINS 1024 // The PWM Frequency is derived from the "pulse time" below. Essentially, // the frequency is a function of the range and this pulse time. -// The total period will be range * pulse time in uS, so a pulse time -// of 100 and a range of 100 gives a period of 100 * 100 = 10,000 uS +// The total period will be range * pulse time in µS, so a pulse time +// of 100 and a range of 100 gives a period of 100 * 100 = 10,000 µS // which is a frequency of 100Hz. // // It's possible to get a higher frequency by lowering the pulse time, // however CPU uage will skyrocket as wiringPi uses a hard-loop to time -// periods under 100uS - this is because the Linux timer calls are just +// periods under 100µS - this is because the Linux timer calls are just // accurate at all, and have an overhead. // // Another way to increase the frequency is to reduce the range - however @@ -46,10 +51,10 @@ #define PULSE_TIME 100 -static int marks [MAX_PINS] ; -static int range [MAX_PINS] ; - -int newPin = -1 ; +static volatile int marks [MAX_PINS] ; +static volatile int range [MAX_PINS] ; +static volatile pthread_t threads [MAX_PINS] ; +static volatile int newPin = -1 ; /* @@ -61,11 +66,15 @@ int newPin = -1 ; static PI_THREAD (softPwmThread) { int pin, mark, space ; + struct sched_param param ; + + param.sched_priority = sched_get_priority_max (SCHED_RR) ; + pthread_setschedparam (pthread_self (), SCHED_RR, ¶m) ; pin = newPin ; newPin = -1 ; - piHiPri (50) ; + piHiPri (90) ; for (;;) { @@ -93,7 +102,7 @@ static PI_THREAD (softPwmThread) void softPwmWrite (int pin, int value) { - pin &= 63 ; + pin &= (MAX_PINS - 1) ; /**/ if (value < 0) value = 0 ; @@ -106,13 +115,20 @@ void softPwmWrite (int pin, int value) /* * softPwmCreate: - * Create a new PWM thread. + * Create a new softPWM thread. ********************************************************************************* */ int softPwmCreate (int pin, int initialValue, int pwmRange) { int res ; + pthread_t myThread ; + + if (range [pin] != 0) // Already running on this pin + return -1 ; + + if (range <= 0) + return -1 ; pinMode (pin, OUTPUT) ; digitalWrite (pin, LOW) ; @@ -121,10 +137,30 @@ int softPwmCreate (int pin, int initialValue, int pwmRange) range [pin] = pwmRange ; newPin = pin ; - res = piThreadCreate (softPwmThread) ; + res = pthread_create (&myThread, NULL, softPwmThread, NULL) ; while (newPin != -1) delay (1) ; + threads [pin] = myThread ; + return res ; } + + +/* + * softPwmStop: + * Stop an existing softPWM thread + ********************************************************************************* + */ + +void softPwmStop (int pin) +{ + if (range [pin] != 0) + { + pthread_cancel (threads [pin]) ; + pthread_join (threads [pin], NULL) ; + range [pin] = 0 ; + digitalWrite (pin, LOW) ; + } +} diff --git a/wiringPi/softPwm.h b/wiringPi/softPwm.h index 28ad299..0351da5 100644 --- a/wiringPi/softPwm.h +++ b/wiringPi/softPwm.h @@ -28,6 +28,7 @@ extern "C" { extern int softPwmCreate (int pin, int value, int range) ; extern void softPwmWrite (int pin, int value) ; +extern void softPwmStop (int pin) ; #ifdef __cplusplus } diff --git a/wiringPi/softTone.c b/wiringPi/softTone.c index 8463627..e2fb737 100644 --- a/wiringPi/softTone.c +++ b/wiringPi/softTone.c @@ -36,7 +36,8 @@ #define PULSE_TIME 100 -static int frewqs [MAX_PINS] ; +static int freqs [MAX_PINS] ; +static pthread_t threads [MAX_PINS] ; static int newPin = -1 ; @@ -49,7 +50,11 @@ static int newPin = -1 ; static PI_THREAD (softToneThread) { - int pin, frewq, halfPeriod ; + int pin, freq, halfPeriod ; + struct sched_param param ; + + param.sched_priority = sched_get_priority_max (SCHED_RR) ; + pthread_setschedparam (pthread_self (), SCHED_RR, ¶m) ; pin = newPin ; newPin = -1 ; @@ -58,12 +63,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 +88,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 ; } @@ -105,17 +110,41 @@ void softToneWrite (int pin, int frewq) int softToneCreate (int pin) { int res ; + pthread_t myThread ; pinMode (pin, OUTPUT) ; digitalWrite (pin, LOW) ; - frewqs [pin] = 0 ; + if (threads [pin] != 0) + return -1 ; + + freqs [pin] = 0 ; newPin = pin ; - res = piThreadCreate (softToneThread) ; + res = pthread_create (&myThread, NULL, softToneThread, NULL) ; while (newPin != -1) delay (1) ; + threads [pin] = myThread ; + return res ; } + + +/* + * softToneStop: + * Stop an existing softTone thread + ********************************************************************************* + */ + +void softToneStop (int pin) +{ + if (threads [pin] != 0) + { + pthread_cancel (threads [pin]) ; + pthread_join (threads [pin], NULL) ; + threads [pin] = 0 ; + digitalWrite (pin, LOW) ; + } +} diff --git a/wiringPi/softTone.h b/wiringPi/softTone.h index 80c64fe..a93c5af 100644 --- a/wiringPi/softTone.h +++ b/wiringPi/softTone.h @@ -31,7 +31,8 @@ extern "C" { #endif extern int softToneCreate (int pin) ; -extern void softToneWrite (int pin, int frewq) ; +extern void softToneStop (int pin) ; +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..503151f 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -1,7 +1,7 @@ /* * wiringPi: - * Arduino compatable (ish) Wiring library for the Raspberry Pi - * Copyright (c) 2012 Gordon Henderson + * Arduino look-a-like Wiring library for the Raspberry Pi + * Copyright (c) 2012-2015 Gordon Henderson * Additional code for pwmSetClock by Chris Hall * * Thanks to code samples from Gert Jan van Loo and the @@ -53,6 +53,7 @@ #include +#include #include #include #include @@ -69,30 +70,30 @@ #include #include +#include "softPwm.h" +#include "softTone.h" + #include "wiringPi.h" -// Function stubs - -void (*pinMode) (int pin, int mode) ; -int (*getAlt) (int pin) ; -void (*pullUpDnControl) (int pin, int pud) ; -void (*digitalWrite) (int pin, int value) ; -void (*digitalWriteByte) (int value) ; -void (*pwmWrite) (int pin, int value) ; -void (*gpioClockSet) (int pin, int value) ; -void (*setPadDrive) (int group, int value) ; -int (*digitalRead) (int pin) ; -int (*waitForInterrupt) (int pin, int mS) ; -void (*pwmSetMode) (int mode) ; -void (*pwmSetRange) (unsigned int range) ; -void (*pwmSetClock) (int divisor) ; - - #ifndef TRUE #define TRUE (1==1) #define FALSE (1==2) #endif +// Environment Variables + +#define ENV_DEBUG "WIRINGPI_DEBUG" +#define ENV_CODES "WIRINGPI_CODES" +#define ENV_GPIOMEM "WIRINGPI_GPIOMEM" + + +// 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) + +struct wiringPiNodeStruct *wiringPiNodes = NULL ; + // BCM Magic #define BCM_PASSWORD 0x5A000000 @@ -121,7 +122,6 @@ void (*pwmSetClock) (int divisor) ; #define FSEL_INPT 0b000 #define FSEL_OUTP 0b001 #define FSEL_ALT0 0b100 -#define FSEL_ALT0 0b100 #define FSEL_ALT1 0b101 #define FSEL_ALT2 0b110 #define FSEL_ALT3 0b111 @@ -131,13 +131,16 @@ void (*pwmSetClock) (int divisor) ; // Access from ARM Running Linux // Taken from Gert/Doms code. Some of this is not in the manual // that I can find )-: +// +// Updates in September 2015 - all now static variables (and apologies for the caps) +// due to the Pi v2 and the new /dev/gpiomem interface -#define BCM2708_PERI_BASE 0x20000000 -#define GPIO_PADS (BCM2708_PERI_BASE + 0x00100000) -#define CLOCK_BASE (BCM2708_PERI_BASE + 0x00101000) -#define GPIO_BASE (BCM2708_PERI_BASE + 0x00200000) -#define GPIO_TIMER (BCM2708_PERI_BASE + 0x0000B000) -#define GPIO_PWM (BCM2708_PERI_BASE + 0x0020C000) +static volatile unsigned int RASPBERRY_PI_PERI_BASE ; +static volatile unsigned int GPIO_PADS ; +static volatile unsigned int GPIO_CLOCK_BASE ; +static volatile unsigned int GPIO_BASE ; +static volatile unsigned int GPIO_TIMER ; +static volatile unsigned int GPIO_PWM ; #define PAGE_SIZE (4*1024) #define BLOCK_SIZE (4*1024) @@ -192,8 +195,91 @@ 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 + + +// Data for use with the boardId functions. +// The order of entries here to correspond with the PI_MODEL_X +// and PI_VERSION_X defines in wiringPi.h +// Only intended for the gpio command - use at your own risk! + +static int piModel2 = FALSE ; + +const char *piModelNames [16] = +{ + "Model A", // 0 + "Model B", // 1 + "Model A+", // 2 + "Model B+", // 3 + "Pi 2", // 4 + "Alpha", // 5 + "CM", // 6 + "Unknown07", // 07 + "Unknown08", // 08 + "Pi Zero", // 09 + "Unknown10", // 10 + "Unknown11", // 11 + "Unknown12", // 12 + "Unknown13", // 13 + "Unknown14", // 14 + "Unknown15", // 15 +} ; + +const char *piRevisionNames [16] = +{ + "00", + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10", + "11", + "12", + "13", + "14", + "15", +} ; + +const char *piMakerNames [16] = +{ + "Sony", // 0 + "Egoman", // 1 + "Embest", // 2 + "Unknown", // 3 + "Embest", // 4 + "Unknown05", // 5 + "Unknown06", // 6 + "Unknown07", // 7 + "Unknown08", // 8 + "Unknown09", // 9 + "Unknown10", // 10 + "Unknown11", // 11 + "Unknown12", // 12 + "Unknown13", // 13 + "Unknown14", // 14 + "Unknown15", // 15 +} ; + +const int piMemorySize [8] = +{ + 256, // 0 + 512, // 1 + 1024, // 2 + 0, // 3 + 0, // 4 + 0, // 5 + 0, // 6 + 0, // 7 +} ; // Time for easy calculations @@ -202,15 +288,28 @@ 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 ; + +// Use /dev/gpiomem ? + +int wiringPiTryGpioMem = FALSE ; // sysFds: // Map a file descriptor from the /sys/class/gpio/gpioX/value -static int sysFds [64] ; +static int sysFds [64] = +{ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +} ; // ISR Data @@ -223,17 +322,19 @@ 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 3 different board revisions here. static int *pinToGpio ; +// Revision 1, 1.1: + 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 - SDA1, SCL1 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: @@ -242,6 +343,8 @@ static int pinToGpioR1 [64] = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 } ; +// Revision 2: + static int pinToGpioR2 [64] = { 17, 18, 27, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7 @@ -249,18 +352,93 @@ static int pinToGpioR2 [64] = 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 - 28, 29, 30, 31, // New GPIOs 8 though 11 wpi 17 - 20 + 28, 29, 30, 31, // Rev 2: New GPIOs 8 though 11 wpi 17 - 20 + 5, 6, 13, 19, 26, // B+ wpi 21, 22, 23, 24, 25 + 12, 16, 20, 21, // B+ wpi 26, 27, 28, 29 + 0, 1, // B+ wpi 30, 31 // Padding: - -1, -1, -1, -1, -1, -1, -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 } ; +// physToGpio: +// Take a physical pin (1 through 26) and re-map it to the BCM_GPIO pin +// Cope for 2 different board revisions here. +// Also add in the P5 connector, so the P5 pins are 3,4,5,6, so 53,54,55,56 + +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 + + -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 + +// B+ + + 0, 1, + 5, -1, + 6, 12, + 13, -1, + 19, 16, + 26, 20, + -1, 21, + +// the P5 connector on the Rev 2 boards: + + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + 28, 29, + 30, 31, + -1, -1, + -1, -1, + -1, -1, + -1, -1, +} ; + // 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 +473,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 @@ -327,7 +504,7 @@ static uint8_t gpioToEDS [] = } ; // gpioToREN -// (Word) offset to the Rising edgde ENable register +// (Word) offset to the Rising edge ENable register static uint8_t gpioToREN [] = { @@ -376,6 +553,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 +573,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,46 +627,52 @@ 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. + * This is not strictly the board revision but is used to check the + * layout of the GPIO connector - and there are 2 types that we are + * really interested in here. The very earliest Pi's and the + * ones that came after that which switched some pins .... * - * Much confusion here )-: - * Seems there are some boards with 0000 in them (mistake in manufacture) - * and some board with 0005 in them (another mistake in manufacture?) - * So the distinction between boards that I can see is: - * 0000 - Error - * 0001 - Not used - * 0002 - Rev 1 - * 0003 - Rev 1 - * 0004 - Rev 2 (Early reports? - * 0005 - Rev 2 (but error?) - * 0006 - Rev 2 - * 0008 - Rev 2 - Model A - * 000e - Rev 2 + 512MB - * 000f - Rev 2 + 512MB + * Revision 1 really means the early Model A and B's. + * Revision 2 is everything else - it covers the B, B+ and CM. + * ... and the Pi 2 - which is a B+ ++ ... + * ... and the Pi 0 - which is an A+ ... * - * A small thorn is the olde style overvolting - that will add in - * 1000000 + * The main difference between the revision 1 and 2 system that I use here + * is the mapping of the GPIO pins. From revision 2, the Pi Foundation changed + * 3 GPIO pins on the (original) 26-way header - BCM_GPIO 22 was dropped and + * replaced with 27, and 0 + 1 - I2C bus 0 was changed to 2 + 3; I2C bus 1. * ********************************************************************************* */ -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) ; @@ -501,7 +685,7 @@ int piBoardRev (void) { FILE *cpuFd ; char line [120] ; - char *c, lastChar ; + char *c ; static int boardRev = -1 ; if (boardRev != -1) // No point checking twice @@ -510,6 +694,190 @@ int piBoardRev (void) if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL) piBoardRevOops ("Unable to open /proc/cpuinfo") ; +// Start by looking for the Architecture to make sure we're really running +// on a Pi. I'm getting fed-up with people whinging at me because +// they can't get it to work on weirdFruitPi boards... + + while (fgets (line, 120, cpuFd) != NULL) + if (strncmp (line, "Hardware", 8) == 0) + break ; + + if (strncmp (line, "Hardware", 8) != 0) + piBoardRevOops ("No hardware line") ; + + if (wiringPiDebug) + printf ("piboardRev: Hardware: %s\n", line) ; + +// See if it's BCM2708 or BCM2709 + + if (strstr (line, "BCM2709") != NULL) // Pi v2 - no point doing anything more at this point + { + piModel2 = TRUE ; + fclose (cpuFd) ; + return boardRev = 2 ; + } + else if (strstr (line, "BCM2708") == NULL) + { + fprintf (stderr, "Unable to determine hardware version. I see: %s,\n", line) ; + fprintf (stderr, " - expecting BCM2708 or BCM2709.\n") ; + fprintf (stderr, "If this is a genuine Raspberry Pi then please report this\n") ; + fprintf (stderr, "to projects@drogon.net. If this is not a Raspberry Pi then you\n") ; + fprintf (stderr, "are on your own as wiringPi is designed to support the\n") ; + fprintf (stderr, "Raspberry Pi ONLY.\n") ; + exit (EXIT_FAILURE) ; + } + +// Now do the rest of it as before - we just need to see if it's an older +// Rev 1 as anything else is rev 2. + +// Isolate the Revision line + + rewind (cpuFd) ; + while (fgets (line, 120, cpuFd) != NULL) + if (strncmp (line, "Revision", 8) == 0) + break ; + + fclose (cpuFd) ; + + if (strncmp (line, "Revision", 8) != 0) + piBoardRevOops ("No \"Revision\" line") ; + +// Chomp trailing CR/NL + + for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c) + *c = 0 ; + + if (wiringPiDebug) + printf ("piboardRev: Revision string: %s\n", line) ; + +// Scan to the first character of the revision number + + for (c = line ; *c ; ++c) + if (*c == ':') + break ; + + if (*c != ':') + piBoardRevOops ("Bogus \"Revision\" line (no colon)") ; + +// Chomp spaces + + ++c ; + while (isspace (*c)) + ++c ; + + if (!isxdigit (*c)) + piBoardRevOops ("Bogus \"Revision\" line (no hex digit at start of revision)") ; + +// Make sure its long enough + + if (strlen (c) < 4) + piBoardRevOops ("Bogus revision line (too small)") ; + +// If you have overvolted the Pi, then it appears that the revision +// has 100000 added to it! +// The actual condition for it being set is: +// (force_turbo || current_limit_override || temp_limit>85) && over_voltage>0 + + +// This test is not correct for the new encoding scheme, so we'll remove it here as +// we don't really need it at this point. + +/******************** + if (wiringPiDebug) + if (strlen (c) != 4) + printf ("piboardRev: This Pi has/is (force_turbo || current_limit_override || temp_limit>85) && over_voltage>0\n") ; +*******************/ + +// Isolate last 4 characters: + + c = c + strlen (c) - 4 ; + + if (wiringPiDebug) + printf ("piboardRev: last4Chars are: \"%s\"\n", c) ; + + if ( (strcmp (c, "0002") == 0) || (strcmp (c, "0003") == 0)) + boardRev = 1 ; + else + boardRev = 2 ; // Covers everything else from the B revision 2 to the B+, the Pi v2 and CM's. + + if (wiringPiDebug) + printf ("piBoardRev: Returning revision: %d\n", boardRev) ; + + return boardRev ; +} + + +/* + * piBoardId: + * Return the real details of the board we have. + * + * This is undocumented and really only intended for the GPIO command. + * Use at your own risk! + * + * Seems there are some boards with 0000 in them (mistake in manufacture) + * So the distinction between boards that I can see is: + * + * 0000 - Error + * 0001 - Not used + * + * Original Pi boards: + * 0002 - Model B, Rev 1, 256MB, Egoman + * 0003 - Model B, Rev 1.1, 256MB, Egoman, Fuses/D14 removed. + * + * Newer Pi's with remapped GPIO: + * 0004 - Model B, Rev 2, 256MB, Sony + * 0005 - Model B, Rev 2, 256MB, Qisda + * 0006 - Model B, Rev 2, 256MB, Egoman + * 0007 - Model A, Rev 2, 256MB, Egoman + * 0008 - Model A, Rev 2, 256MB, Sony + * 0009 - Model A, Rev 2, 256MB, Qisda + * 000d - Model B, Rev 2, 512MB, Egoman (Red Pi, Blue Pi?) + * 000e - Model B, Rev 2, 512MB, Sony + * 000f - Model B, Rev 2, 512MB, Qisda + * 0010 - Model B+, Rev 1.2, 512MB, Sony + * 0011 - Pi CM, Rev 1.2, 512MB, Sony + * 0012 - Model A+ Rev 1.2, 256MB, Sony + * 0014 - Pi CM, Rev 1.1, 512MB, Sony (Actual Revision might be different) + * 0015 - Model A+ Rev 1.1, 256MB, Sony + * + * A small thorn is the olde style overvolting - that will add in + * 1000000 + * + * The Pi compute module has an revision of 0011 or 0014 - since we only + * check the last digit, then it's 1, therefore it'll default to not 2 or + * 3 for a Rev 1, so will appear as a Rev 2. This is fine for the most part, but + * we'll properly detect the Compute Module later and adjust accordingly. + * + * And then things changed with the introduction of the v2... + * + * For Pi v2 and subsequent models - e.g. the Zero: + * + * [USER:8] [NEW:1] [MEMSIZE:3] [MANUFACTURER:4] [PROCESSOR:4] [TYPE:8] [REV:4] + * NEW 23: will be 1 for the new scheme, 0 for the old scheme + * MEMSIZE 20: 0=256M 1=512M 2=1G + * MANUFACTURER 16: 0=SONY 1=EGOMAN 2=EMBEST + * PROCESSOR 12: 0=2835 1=2836 + * TYPE 04: 0=MODELA 1=MODELB 2=MODELA+ 3=MODELB+ 4=Pi2 MODEL B 5=ALPHA 6=CM + * REV 00: 0=REV0 1=REV1 2=REV2 + ********************************************************************************* + */ + +void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) +{ + FILE *cpuFd ; + char line [120] ; + char *c ; + unsigned int revision ; + int bRev, bType, bProc, bMfg, bMem, bWarranty ; + +// Will deal with the properly later on - for now, lets just get it going... +// unsigned int modelNum ; + + (void)piBoardRev () ; // Call this first to make sure all's OK. Don't care about the result. + + if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL) + piBoardRevOops ("Unable to open /proc/cpuinfo") ; + while (fgets (line, 120, cpuFd) != NULL) if (strncmp (line, "Revision", 8) == 0) break ; @@ -519,43 +887,161 @@ int piBoardRev (void) if (strncmp (line, "Revision", 8) != 0) piBoardRevOops ("No \"Revision\" line") ; +// Chomp trailing CR/NL + for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c) *c = 0 ; if (wiringPiDebug) - printf ("piboardRev: Revision string: %s\n", line) ; + printf ("piboardId: Revision string: %s\n", line) ; + +// Need to work out if it's using the new or old encoding scheme: + +// Scan to the first character of the revision number for (c = line ; *c ; ++c) - if (isdigit (*c)) + if (*c == ':') break ; - if (!isdigit (*c)) - piBoardRevOops ("No numeric revision string") ; + if (*c != ':') + piBoardRevOops ("Bogus \"Revision\" line (no colon)") ; -// If you have overvolted the Pi, then it appears that the revision -// has 100000 added to it! +// Chomp spaces - if (wiringPiDebug) - if (strlen (c) != 4) - printf ("piboardRev: This Pi has/is overvolted!\n") ; + ++c ; + while (isspace (*c)) + ++c ; - lastChar = line [strlen (line) - 1] ; + if (!isxdigit (*c)) + piBoardRevOops ("Bogus \"Revision\" line (no hex digit at start of revision)") ; - if (wiringPiDebug) - printf ("piboardRev: lastChar is: '%c' (%d, 0x%02X)\n", lastChar, lastChar, lastChar) ; + revision = (unsigned int)strtol (c, NULL, 16) ; // Hex number with no leading 0x - /**/ if ((lastChar == '2') || (lastChar == '3')) - boardRev = 1 ; - else - boardRev = 2 ; +// Check for new way: - if (wiringPiDebug) - printf ("piBoardRev: Returning revision: %d\n", boardRev) ; + if ((revision & (1 << 23)) != 0) // New way + { + if (wiringPiDebug) + printf ("piBoardId: New Way: revision is: 0x%08X\n", revision) ; - return boardRev ; + bRev = (revision & (0x0F << 0)) >> 0 ; + bType = (revision & (0xFF << 4)) >> 4 ; + bProc = (revision & (0x0F << 12)) >> 12 ; // Not used for now. + bMfg = (revision & (0x0F << 16)) >> 16 ; + bMem = (revision & (0x07 << 20)) >> 20 ; + bWarranty = (revision & (0x03 << 24)) != 0 ; + + *model = bType ; + *rev = bRev ; + *mem = bMem ; + *maker = bMfg ; + *warranty = bWarranty ; + + if (wiringPiDebug) + printf ("piboardId: rev: %d, type: %d, proc: %d, mfg: %d, mem: %d, warranty: %d\n", + bRev, bType, bProc, bMfg, bMem, bWarranty) ; + } + else // Old way + { + if (wiringPiDebug) + printf ("piBoardId: Old Way: revision is: %s\n", c) ; + + if (!isdigit (*c)) + piBoardRevOops ("Bogus \"Revision\" line (no digit at start of revision)") ; + +// Make sure its long enough + + if (strlen (c) < 4) + piBoardRevOops ("Bogus \"Revision\" line (not long enough)") ; + +// If longer than 4, we'll assume it's been overvolted + + *warranty = strlen (c) > 4 ; + +// Extract last 4 characters: + + c = c + strlen (c) - 4 ; + +// Fill out the replys as appropriate + + /**/ if (strcmp (c, "0002") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0003") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0004") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0005") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_UNKNOWN ; } + else if (strcmp (c, "0006") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0007") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0008") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; ; } + else if (strcmp (c, "0009") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_UNKNOWN ; } + else if (strcmp (c, "000d") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "000e") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "000f") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0010") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0011") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0012") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0013") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0014") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0015") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else { *model = 0 ; *rev = 0 ; *mem = 0 ; *maker = 0 ; } + } +} + + + +/* + * 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 (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; + + 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 +1050,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 +1071,72 @@ 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 ; -} - - -void pwmSetRangeWPi (unsigned int range) -{ - *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ; - *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ; -} - -void pwmSetRangeSys (unsigned int range) -{ - return ; -} /* - * pwmSetClockWPi: + * 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 pwmSetRange (unsigned int range) +{ + if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) + { + if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; + + *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ; + *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ; + } +} + + +/* + * 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 (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; - pwm_control = *(pwm + PWM_CONTROL) ; // preserve PWM_CONTROL + if (wiringPiDebug) + printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ; + + 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,24 +1144,128 @@ 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)) ; + if (wiringPiDebug) + printf ("Set to: %d. Now : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ; + } } -void pwmSetClockSys (int divisor) + +/* + * gpioClockSet: + * Set the freuency on a GPIO clock pin + ********************************************************************************* + */ + +void gpioClockSet (int pin, int freq) { - return ; + 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 ; + + if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; + + divi = 19200000 / freq ; + divr = 19200000 % freq ; + divf = (int)((double)divr * 4096.0 / 19200000.0) ; + + if (divi > 4095) + divi = 4095 ; + + *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | GPIO_CLOCK_SOURCE ; // Stop GPIO Clock + while ((*(clk + gpioToClkCon [pin]) & 0x80) != 0) // ... and wait + ; + + *(clk + gpioToClkDiv [pin]) = BCM_PASSWORD | (divi << 12) | divf ; // Set dividers + *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | 0x10 | GPIO_CLOCK_SOURCE ; // Start Clock +} + + +/* + * wiringPiFindNode: + * Locate our device node + ********************************************************************************* + */ + +struct wiringPiNodeStruct *wiringPiFindNode (int pin) +{ + struct wiringPiNodeStruct *node = wiringPiNodes ; + + while (node != NULL) + if ((pin >= node->pinBase) && (pin <= node->pinMax)) + return node ; + else + node = node->next ; + + return NULL ; +} + + +/* + * wiringPiNewNode: + * Create a new GPIO node into the wiringPi handling system + ********************************************************************************* + */ + +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) +{ + int pin ; + struct wiringPiNodeStruct *node ; + +// Minimum pin base is 64 + + if (pinBase < 64) + (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: pinBase of %d is < 64\n", pinBase) ; + +// Check all pins in-case there is overlap: + + for (pin = pinBase ; pin < (pinBase + numPins) ; ++pin) + if (wiringPiFindNode (pin) != NULL) + (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Pin %d overlaps with existing definition\n", pin) ; + + node = (struct wiringPiNodeStruct *)calloc (sizeof (struct wiringPiNodeStruct), 1) ; // calloc zeros + if (node == NULL) + (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Unable to allocate memory: %s\n", strerror (errno)) ; + + node->pinBase = pinBase ; + node->pinMax = pinBase + numPins - 1 ; + node->pinMode = pinModeDummy ; + node->pullUpDnControl = pullUpDnControlDummy ; + node->digitalRead = digitalReadDummy ; + node->digitalWrite = digitalWriteDummy ; + node->pwmWrite = pwmWriteDummy ; + node->analogRead = analogReadDummy ; + node->analogWrite = analogWriteDummy ; + node->next = wiringPiNodes ; + wiringPiNodes = node ; + + return node ; } @@ -686,230 +1285,122 @@ void pinEnableED01Pi (int pin) #endif - /* - * digitalWrite: - * Set an output bit + ********************************************************************************* + * Core Functions ********************************************************************************* */ -void digitalWriteWPi (int pin, int value) -{ - pin = pinToGpio [pin & 63] ; +/* + * pinModeAlt: + * This is an un-documented special to let you set any pin to any mode + ********************************************************************************* + */ - if (value == LOW) - *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ; +void pinModeAlt (int pin, int mode) +{ + int fSel, shift ; + + 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 ; + + fSel = gpioToGPFSEL [pin] ; + shift = gpioToShift [pin] ; + + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | ((mode & 0x7) << shift) ; + } +} + + +/* + * pinMode: + * Sets the mode of a pin to be input, output or PWM output + ********************************************************************************* + */ + +void pinMode (int pin, int mode) +{ + int fSel, shift, alt ; + struct wiringPiNodeStruct *node = wiringPiNodes ; + int origPin = pin ; + + 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 ; + + softPwmStop (origPin) ; + softToneStop (origPin) ; + + 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 == SOFT_PWM_OUTPUT) + softPwmCreate (origPin, 0, 100) ; + else if (mode == SOFT_TONE_OUTPUT) + softToneCreate (origPin) ; + else if (mode == PWM_TONE_OUTPUT) + { + if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; + + pinMode (origPin, PWM_OUTPUT) ; // Call myself to enable PWM mode + pwmSetMode (PWM_MODE_MS) ; + } + else if (mode == PWM_OUTPUT) + { + if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; + + if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin + return ; + +// Set pin to PWM mode + + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; + delayMicroseconds (110) ; // See comments in pwmSetClockWPi + + 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 (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; + + 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 - *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ; -} - -void digitalWriteGpio (int pin, int value) -{ - pin &= 63 ; - - if (value == LOW) - *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ; - else - *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ; -} - -void digitalWriteSys (int pin, int value) -{ - pin &= 63 ; - - if (sysFds [pin] != -1) { - if (value == LOW) - write (sysFds [pin], "0\n", 2) ; - else - write (sysFds [pin], "1\n", 2) ; - } -} - - -/* - * 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 - ********************************************************************************* - */ - -void digitalWriteByteGpio (int value) -{ - uint32_t pinSet = 0 ; - uint32_t pinClr = 0 ; - int mask = 1 ; - int pin ; - - for (pin = 0 ; pin < 8 ; ++pin) - { - if ((value & mask) == 0) - pinClr |= (1 << pinToGpio [pin]) ; - else - pinSet |= (1 << pinToGpio [pin]) ; - - mask <<= 1 ; - } - - *(gpio + gpioToGPCLR [0]) = pinClr ; - *(gpio + gpioToGPSET [0]) = pinSet ; -} - -void digitalWriteByteSys (int value) -{ - int mask = 1 ; - int pin ; - - for (pin = 0 ; pin < 8 ; ++pin) - { - digitalWriteSys (pinToGpio [pin], value & mask) ; - mask <<= 1 ; - } -} - - -/* - * pwmWrite: - * Set an output PWM value - ********************************************************************************* - */ - -void pwmWriteGpio (int pin, int value) -{ - int port ; - - pin = pin & 63 ; - port = gpioToPwmPort [pin] ; - - *(pwm + port) = value ; -} - -void pwmWriteWPi (int pin, int value) -{ - pwmWriteGpio (pinToGpio [pin & 63], value) ; -} - -void pwmWriteSys (int pin, int value) -{ - return ; -} - - -/* - * gpioClockSet: - * Set the freuency on a GPIO clock pin - ********************************************************************************* - */ - -void gpioClockSetGpio (int pin, int freq) -{ - int divi, divr, divf ; - - pin &= 63 ; - - divi = 19200000 / freq ; - divr = 19200000 % freq ; - divf = (int)((double)divr * 4096.0 / 19200000.0) ; - - if (divi > 4095) - divi = 4095 ; - - *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | GPIO_CLOCK_SOURCE ; // Stop GPIO Clock - while ((*(clk + gpioToClkCon [pin]) & 0x80) != 0) // ... and wait - ; - - *(clk + gpioToClkDiv [pin]) = BCM_PASSWORD | (divi << 12) | divf ; // Set dividers - *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | 0x10 | GPIO_CLOCK_SOURCE ; // Start Clock -} - -void gpioClockSetWPi (int pin, int freq) -{ - gpioClockSetGpio (pinToGpio [pin & 63], freq) ; -} - -void gpioClockSetSys (int pin, int freq) -{ - return ; -} - - -/* - * setPadDrive: - * Set the PAD driver value - ********************************************************************************* - */ - -void setPadDriveWPi (int group, int value) -{ - uint32_t wrVal ; - - if ((group < 0) || (group > 2)) + if ((node = wiringPiFindNode (pin)) != NULL) + node->pinMode (node, pin, mode) ; 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)) ; } } -void setPadDriveGpio (int group, int value) -{ - setPadDriveWPi (group, value) ; -} - -void setPadDriveSys (int group, int value) -{ - return ; -} - - -/* - * digitalRead: - * Read the value of a given Pin, returning HIGH or LOW - ********************************************************************************* - */ - -int digitalReadWPi (int pin) -{ - pin = pinToGpio [pin & 63] ; - - if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0) - return HIGH ; - else - return LOW ; -} - -int digitalReadGpio (int pin) -{ - pin &= 63 ; - - if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0) - return HIGH ; - else - return LOW ; -} - -int digitalReadSys (int pin) -{ - char c ; - - pin &= 63 ; - - if (sysFds [pin] == -1) - return 0 ; - - lseek (sysFds [pin], 0L, SEEK_SET) ; - read (sysFds [pin], &c, 1) ; - return (c == '0') ? 0 : 1 ; -} - /* * pullUpDownCtrl: @@ -920,90 +1411,264 @@ int digitalReadSys (int pin) ********************************************************************************* */ -void pullUpDnControlGpio (int pin, int pud) +void pullUpDnControl (int pin, int pud) { - 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) ; -} - -void pullUpDnControlSys (int pin, int pud) -{ - return ; + *(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 + { + if ((node = wiringPiFindNode (pin)) != NULL) + node->pullUpDnControl (node, pin, pud) ; + return ; + } } /* - * pinMode: - * Sets the mode of a pin to be input, output or PWM output + * digitalRead: + * Read the value of a given Pin, returning HIGH or LOW ********************************************************************************* */ -void pinModeGpio (int pin, int mode) +int digitalRead (int pin) { -// register int barrier ; + char c ; + struct wiringPiNodeStruct *node = wiringPiNodes ; - int fSel, shift, alt ; - - pin &= 63 ; - - 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 ((pin & PI_GPIO_MASK) == 0) // On-Board Pin { - if ((alt = gpioToPwmALT [pin]) == 0) // Not a PWM pin - return ; + /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode + { + if (sysFds [pin] == -1) + return LOW ; -// Set pin to PWM mode + 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 ; - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; - delayMicroseconds (110) ; // See comments in pwmSetClockWPi - - pwmSetModeWPi (PWM_MODE_BAL) ; // Pi default mode - pwmSetRangeWPi (1024) ; // Default range of 1024 - pwmSetClockWPi (32) ; // 19.2 / 32 = 600KHz - Also starts the PWM + if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0) + return HIGH ; + else + return LOW ; } - else if (mode == GPIO_CLOCK) + else { - 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) ; - gpioClockSetGpio (pin, 100000) ; + if ((node = wiringPiFindNode (pin)) == NULL) + return LOW ; + return node->digitalRead (node, pin) ; } } -void pinModeWPi (int pin, int mode) + +/* + * digitalWrite: + * Set an output bit + ********************************************************************************* + */ + +void digitalWrite (int pin, int value) { - pinModeGpio (pinToGpio [pin & 63], mode) ; + 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) + { + 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 ; + + 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) ; + } } -void pinModeSys (int pin, int mode) + +/* + * pwmWrite: + * Set an output PWM value + ********************************************************************************* + */ + +void pwmWrite (int pin, int value) { - return ; + struct wiringPiNodeStruct *node = wiringPiNodes ; + + if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin + { + if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; + + /**/ if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [pin] ; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio [pin] ; + else if (wiringPiMode != WPI_MODE_GPIO) + return ; + + *(pwm + gpioToPwmPort [pin]) = value ; + } + else + { + if ((node = wiringPiFindNode (pin)) != NULL) + node->pwmWrite (node, pin, value) ; + } +} + + +/* + * 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) +{ + struct wiringPiNodeStruct *node = wiringPiNodes ; + + if ((node = wiringPiFindNode (pin)) == NULL) + return 0 ; + else + return node->analogRead (node, pin) ; +} + + +/* + * 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 analogWrite (int pin, int value) +{ + struct wiringPiNodeStruct *node = wiringPiNodes ; + + if ((node = wiringPiFindNode (pin)) == NULL) + return ; + + node->analogWrite (node, pin, value) ; +} + + +/* + * pwmToneWrite: + * Pi Specific. + * Output the given frequency on the Pi's PWM pin + ********************************************************************************* + */ + +void pwmToneWrite (int pin, int freq) +{ + int range ; + + if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; + + if (freq == 0) + pwmWrite (pin, 0) ; // Off + else + { + range = 600000 / freq ; + pwmSetRange (range) ; + pwmWrite (pin, freq / 2) ; + } +} + + + +/* + * 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 + ********************************************************************************* + */ + +void digitalWriteByte (int value) +{ + uint32_t pinSet = 0 ; + uint32_t pinClr = 0 ; + int mask = 1 ; + int pin ; + + /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) + { + for (pin = 0 ; pin < 8 ; ++pin) + { + digitalWrite (pin, value & mask) ; + mask <<= 1 ; + } + return ; + } + else + { + for (pin = 0 ; pin < 8 ; ++pin) + { + if ((value & mask) == 0) + pinClr |= (1 << pinToGpio [pin]) ; + else + pinSet |= (1 << pinToGpio [pin]) ; + + mask <<= 1 ; + } + + *(gpio + gpioToGPCLR [0]) = pinClr ; + *(gpio + gpioToGPSET [0]) = pinSet ; + } } /* * 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 +1676,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 @@ -1031,22 +1701,14 @@ int waitForInterruptSys (int pin, int mS) // Do a dummy read to clear the interrupt // A one character read appars to be enough. +// Followed by a seek to reset it. (void)read (fd, &c, 1) ; + lseek (fd, 0, SEEK_SET) ; 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 +1720,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 +1737,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 +1746,25 @@ 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 ((pin < 0) || (pin > 63)) + return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-63 (%d)\n", pin) ; - 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,38 +1781,54 @@ 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 ; + return wiringPiFailure (WPI_FATAL, "wiringPiISR: fork failed: %s\n", strerror (errno)) ; if (pid == 0) // Child, exec { - execl ("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ; - return -1 ; // Failure ... + /**/ if (access ("/usr/local/bin/gpio", X_OK) == 0) + { + execl ("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ; + return wiringPiFailure (WPI_FATAL, "wiringPiISR: execl failed: %s\n", strerror (errno)) ; + } + else if (access ("/usr/bin/gpio", X_OK) == 0) + { + execl ("/usr/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ; + return wiringPiFailure (WPI_FATAL, "wiringPiISR: execl failed: %s\n", strerror (errno)) ; + } + else + return wiringPiFailure (WPI_FATAL, "wiringPiISR: Can't find gpio program\n") ; } else // Parent, wait wait (NULL) ; } -// Now pre-open the /sys/class node - it may already be open if -// we are in Sys mode, but this will do no harm. +// Now pre-open the /sys/class node - but it may already be open if +// we are in Sys mode... - sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; - if ((sysFds [pin] = open (fName, O_RDWR)) < 0) - return -1 ; + if (sysFds [bcmGpioPin] == -1) + { + sprintf (fName, "/sys/class/gpio/gpio%d/value", bcmGpioPin) ; + if ((sysFds [bcmGpioPin] = open (fName, O_RDWR)) < 0) + return wiringPiFailure (WPI_FATAL, "wiringPiISR: unable to open %s: %s\n", fName, strerror (errno)) ; + } // 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 +1837,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 +1850,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 ********************************************************************************* */ @@ -1216,6 +1902,8 @@ void delayMicrosecondsHard (unsigned int howLong) void delayMicroseconds (unsigned int howLong) { struct timespec sleeper ; + unsigned int uSecs = howLong % 1000000 ; + unsigned int wSecs = howLong / 1000000 ; /**/ if (howLong == 0) return ; @@ -1223,8 +1911,8 @@ void delayMicroseconds (unsigned int howLong) delayMicrosecondsHard (howLong) ; else { - sleeper.tv_sec = 0 ; - sleeper.tv_nsec = (long)(howLong * 1000) ; + sleeper.tv_sec = wSecs ; + sleeper.tv_nsec = (long)(uSecs * 1000L) ; nanosleep (&sleeper, NULL) ; } } @@ -1272,132 +1960,117 @@ unsigned int micros (void) * * Default setup: Initialises the system into wiringPi Pin mode and uses the * memory mapped hardware directly. + * + * Changed now to revert to "gpio" mode if we're running on a Compute Module. ********************************************************************************* */ int wiringPiSetup (void) { - int fd ; - int boardRev ; + int fd ; + int boardRev ; + int model, rev, mem, maker, overVolted ; - 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 (getenv (ENV_GPIOMEM) != NULL) + wiringPiTryGpioMem = TRUE ; 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 ; - else - pinToGpio = pinToGpioR2 ; - -// 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 ; + printf ("wiringPi: wiringPiSetup called\n") ; + if (wiringPiTryGpioMem) + printf ("wiringPi: Using /dev/gpiomem\n") ; } -// GPIO: + boardRev = piBoardRev () ; + + /**/ if (boardRev == 1) // A, B, Rev 1, 1.1 + { + pinToGpio = pinToGpioR1 ; + physToGpio = physToGpioR1 ; + } + else // A, B, Rev 2, B+, CM, Pi2 + { + pinToGpio = pinToGpioR2 ; + physToGpio = physToGpioR2 ; + } + + if (piModel2) + RASPBERRY_PI_PERI_BASE = 0x3F000000 ; + else + RASPBERRY_PI_PERI_BASE = 0x20000000 ; + +// Open the master /dev/ memory control device + +// See if /dev/gpiomem exists and we can open it... + + if (wiringPiTryGpioMem) + { + if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/gpiomem: %s\n", strerror (errno)) ; + RASPBERRY_PI_PERI_BASE = 0 ; + } + +// ... otherwise fall back to the original /dev/mem which requires root level access + + else + { + +// This check is here because people are too stupid to check for themselves or read +// error messages. + + if (geteuid () != 0) + (void)wiringPiFailure (WPI_FATAL, "wiringPiSetup: Must be root. (Did you forget sudo?)\n") ; + + if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ; + } + +// Set the offsets into the memory interface. + + GPIO_PADS = RASPBERRY_PI_PERI_BASE + 0x00100000 ; + GPIO_CLOCK_BASE = RASPBERRY_PI_PERI_BASE + 0x00101000 ; + GPIO_BASE = RASPBERRY_PI_PERI_BASE + 0x00200000 ; + GPIO_TIMER = RASPBERRY_PI_PERI_BASE + 0x0000B000 ; + GPIO_PWM = RASPBERRY_PI_PERI_BASE + 0x0020C000 ; + +// Map the individual hardware components + +// 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 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) +// Clock control (needed for PWM) - clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, CLOCK_BASE) ; + clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_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 +// 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)) ; -// The system timer +#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,10 +2079,17 @@ int wiringPiSetup (void) *(timer + TIMER_CONTROL) = 0x0000280 ; *(timer + TIMER_PRE_DIV) = 0x00000F9 ; timerIrqRaw = timer + TIMER_IRQ_RAW ; +#endif initialiseEpoch () ; - wiringPiMode = WPI_MODE_PINS ; +// If we're running on a compute module, then wiringPi pin numbers don't really many anything... + + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; + if (model == PI_MODEL_CM) + wiringPiMode = WPI_MODE_GPIO ; + else + wiringPiMode = WPI_MODE_PINS ; return 0 ; } @@ -1426,40 +2106,39 @@ int wiringPiSetup (void) int wiringPiSetupGpio (void) { - int x ; - - if (geteuid () != 0) - { - fprintf (stderr, "Must be root to call wiringPiSetupGpio(). (Did you forget sudo?)\n") ; - exit (EXIT_FAILURE) ; - } - - if ((x = wiringPiSetup ()) < 0) - return x ; + (void)wiringPiSetup () ; if (wiringPiDebug) printf ("wiringPi: wiringPiSetupGpio called\n") ; - pinMode = pinModeGpio ; - getAlt = getAltGpio ; - pullUpDnControl = pullUpDnControlGpio ; - digitalWrite = digitalWriteGpio ; - digitalWriteByte = digitalWriteByteGpio ; - gpioClockSet = gpioClockSetGpio ; - pwmWrite = pwmWriteGpio ; - setPadDrive = setPadDriveGpio ; - digitalRead = digitalReadGpio ; - waitForInterrupt = waitForInterruptGpio ; - pwmSetMode = pwmSetModeWPi ; - pwmSetRange = pwmSetRangeWPi ; - pwmSetClock = pwmSetClockWPi ; - wiringPiMode = WPI_MODE_GPIO ; return 0 ; } +/* + * wiringPiSetupPhys: + * Must be called once at the start of your program execution. + * + * Phys setup: Initialises the system into Physical Pin mode and uses the + * memory mapped hardware directly. + ********************************************************************************* + */ + +int wiringPiSetupPhys (void) +{ + (void)wiringPiSetup () ; + + if (wiringPiDebug) + printf ("wiringPi: wiringPiSetupPhys called\n") ; + + wiringPiMode = WPI_MODE_PHYS ; + + return 0 ; +} + + /* * wiringPiSetupSys: * Must be called once at the start of your program execution. @@ -1475,32 +2154,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..7b9605f 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -21,15 +21,18 @@ *********************************************************************** */ +#ifndef __WIRING_PI_H__ +#define __WIRING_PI_H__ + // Handy defines -// Deprecated -#define NUM_PINS 17 +// wiringPi modes #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 @@ -38,6 +41,9 @@ #define OUTPUT 1 #define PWM_OUTPUT 2 #define GPIO_CLOCK 3 +#define SOFT_PWM_OUTPUT 4 +#define SOFT_TONE_OUTPUT 5 +#define PWM_TONE_OUTPUT 6 #define LOW 0 #define HIGH 1 @@ -60,10 +66,80 @@ #define INT_EDGE_RISING 2 #define INT_EDGE_BOTH 3 +// Pi model types and version numbers +// Intended for the GPIO program Use at your own risk. + +#define PI_MODEL_A 0 +#define PI_MODEL_B 1 +#define PI_MODEL_AP 2 +#define PI_MODEL_BP 3 +#define PI_MODEL_2 4 +#define PI_ALPHA 5 +#define PI_MODEL_CM 6 +#define PI_MODEL_07 7 +#define PI_MODEL_08 8 +#define PI_MODEL_ZERO 9 + +#define PI_VERSION_1 0 +#define PI_VERSION_1_1 1 +#define PI_VERSION_1_2 2 +#define PI_VERSION_2 3 + +#define PI_MAKER_SONY 0 +#define PI_MAKER_EGOMAN 1 +#define PI_MAKER_MBEST 2 +#define PI_MAKER_UNKNOWN 3 + +extern const char *piModelNames [16] ; +extern const char *piRevisionNames [16] ; +extern const char *piMakerNames [16] ; +extern const int piMemorySize [ 8] ; + + +// Intended for the GPIO program Use at your own risk. + // Threads #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 ; +} ; + +extern struct wiringPiNodeStruct *wiringPiNodes ; + // Function prototypes // c++ wrappers thanks to a comment by Nick Lott @@ -73,46 +149,67 @@ extern "C" { #endif -// Basic wiringPi functions +// Data + +// Internal + +extern int wiringPiFailure (int fatal, const char *message, ...) ; + +// Core wiringPi functions + +extern struct wiringPiNodeStruct *wiringPiFindNode (int pin) ; +extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ; extern int wiringPiSetup (void) ; extern int wiringPiSetupSys (void) ; extern int wiringPiSetupGpio (void) ; +extern int wiringPiSetupPhys (void) ; + +extern void pinModeAlt (int pin, int mode) ; +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 piBoardRev (void) ; -extern int wpiPinToGpio (int wpiPin) ; - 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 void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted) ; +extern int wpiPinToGpio (int wpiPin) ; +extern int physPinToGpio (int physPin) ; +extern void setPadDrive (int group, int value) ; +extern int getAlt (int pin) ; +extern void pwmToneWrite (int pin, int freq) ; +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 @@ -124,3 +221,5 @@ extern unsigned int micros (void) ; #ifdef __cplusplus } #endif + +#endif diff --git a/wiringPi/wiringPiI2C.c b/wiringPi/wiringPiI2C.c index 93fe1d3..c787bce 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.word & 0xFFFF ; } @@ -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..453df31 100644 --- a/wiringPi/wiringPiSPI.c +++ b/wiringPi/wiringPiSPI.c @@ -1,7 +1,7 @@ /* * wiringPiSPI.c: * Simplified SPI access routines - * Copyright (c) 2012 Gordon Henderson + * Copyright (c) 2012-2015 Gordon Henderson *********************************************************************** * This file is part of wiringPi: * https://projects.drogon.net/raspberry-pi/wiringpi/ @@ -25,20 +25,23 @@ #include #include +#include +#include #include #include +#include "wiringPi.h" + #include "wiringPiSPI.h" // The SPI bus parameters // Variables as they need to be passed as pointers later on -static char *spiDev0 = "/dev/spidev0.0" ; -static char *spiDev1 = "/dev/spidev0.1" ; -static uint8_t spiMode = 0 ; -static uint8_t spiBPW = 8 ; -static uint16_t spiDelay = 0; +const static char *spiDev0 = "/dev/spidev0.0" ; +const static char *spiDev1 = "/dev/spidev0.1" ; +const static uint8_t spiBPW = 8 ; +const static uint16_t spiDelay = 0 ; static uint32_t spiSpeeds [2] ; static int spiFds [2] ; @@ -71,6 +74,11 @@ int wiringPiSPIDataRW (int channel, unsigned char *data, int len) channel &= 1 ; +// Mentioned in spidev.h but not used in the original kernel documentation +// test program )-: + + memset (&spi, 0, sizeof (spi)) ; + spi.tx_buf = (unsigned long)data ; spi.rx_buf = (unsigned long)data ; spi.len = len ; @@ -83,35 +91,46 @@ int wiringPiSPIDataRW (int channel, unsigned char *data, int len) /* - * wiringPiSPISetup: - * Open the SPI device, and set it up, etc. + * wiringPiSPISetupMode: + * Open the SPI device, and set it up, with the mode, etc. ********************************************************************************* */ -int wiringPiSPISetup (int channel, int speed) +int wiringPiSPISetupMode (int channel, int speed, int mode) { int fd ; - channel &= 1 ; + mode &= 3 ; // Mode is 0, 1, 2 or 3 + channel &= 1 ; // Channel is 0 or 1 if ((fd = open (channel == 0 ? spiDev0 : spiDev1, O_RDWR)) < 0) - return -1 ; + return wiringPiFailure (WPI_ALMOST, "Unable to open SPI device: %s\n", strerror (errno)) ; spiSpeeds [channel] = speed ; spiFds [channel] = fd ; // Set SPI parameters. -// Why are we reading it afterwriting it? I've no idea, but for now I'm blindly -// copying example code I've seen online... - if (ioctl (fd, SPI_IOC_WR_MODE, &spiMode) < 0) return -1 ; - if (ioctl (fd, SPI_IOC_RD_MODE, &spiMode) < 0) return -1 ; + if (ioctl (fd, SPI_IOC_WR_MODE, &mode) < 0) + return wiringPiFailure (WPI_ALMOST, "SPI Mode Change failure: %s\n", strerror (errno)) ; + + if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0) + return wiringPiFailure (WPI_ALMOST, "SPI BPW Change failure: %s\n", strerror (errno)) ; - if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0) return -1 ; - if (ioctl (fd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0) return -1 ; - - if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) return -1 ; - if (ioctl (fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) return -1 ; + if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) + return wiringPiFailure (WPI_ALMOST, "SPI Speed Change failure: %s\n", strerror (errno)) ; return fd ; } + + +/* + * wiringPiSPISetup: + * Open the SPI device, and set it up, etc. in the default MODE 0 + ********************************************************************************* + */ + +int wiringPiSPISetup (int channel, int speed) +{ + return wiringPiSPISetupMode (channel, speed, 0) ; +} diff --git a/wiringPi/wiringPiSPI.h b/wiringPi/wiringPiSPI.h index f53697d..3980321 100644 --- a/wiringPi/wiringPiSPI.h +++ b/wiringPi/wiringPiSPI.h @@ -1,7 +1,7 @@ /* * wiringPiSPI.h: * Simplified SPI access routines - * Copyright (c) 2012 Gordon Henderson + * Copyright (c) 2012-2015 Gordon Henderson *********************************************************************** * This file is part of wiringPi: * https://projects.drogon.net/raspberry-pi/wiringpi/ @@ -26,9 +26,10 @@ extern "C" { #endif -int wiringPiSPIGetFd (int channel) ; -int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ; -int wiringPiSPISetup (int channel, int speed) ; +int wiringPiSPIGetFd (int channel) ; +int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ; +int wiringPiSPISetupMode (int channel, int speed, int mode) ; +int wiringPiSPISetup (int channel, int speed) ; #ifdef __cplusplus } diff --git a/wiringPi/wiringSerial.c b/wiringPi/wiringSerial.c index 28ec598..ca976a9 100644 --- a/wiringPi/wiringSerial.c +++ b/wiringPi/wiringSerial.c @@ -41,7 +41,7 @@ ********************************************************************************* */ -int serialOpen (char *device, int baud) +int serialOpen (const char *device, const int baud) { struct termios options ; speed_t myBaud ; @@ -60,6 +60,7 @@ int serialOpen (char *device, int baud) case 1200: myBaud = B1200 ; break ; case 1800: myBaud = B1800 ; break ; case 2400: myBaud = B2400 ; break ; + case 4800: myBaud = B4800 ; break ; case 9600: myBaud = B9600 ; break ; case 19200: myBaud = B19200 ; break ; case 38400: myBaud = B38400 ; break ; @@ -116,7 +117,7 @@ int serialOpen (char *device, int baud) ********************************************************************************* */ -void serialFlush (int fd) +void serialFlush (const int fd) { tcflush (fd, TCIOFLUSH) ; } @@ -128,7 +129,7 @@ void serialFlush (int fd) ********************************************************************************* */ -void serialClose (int fd) +void serialClose (const int fd) { close (fd) ; } @@ -140,7 +141,7 @@ void serialClose (int fd) ********************************************************************************* */ -void serialPutchar (int fd, unsigned char c) +void serialPutchar (const int fd, const unsigned char c) { write (fd, &c, 1) ; } @@ -152,7 +153,7 @@ void serialPutchar (int fd, unsigned char c) ********************************************************************************* */ -void serialPuts (int fd, char *s) +void serialPuts (const int fd, const char *s) { write (fd, s, strlen (s)) ; } @@ -163,7 +164,7 @@ void serialPuts (int fd, char *s) ********************************************************************************* */ -void serialPrintf (int fd, char *message, ...) +void serialPrintf (const int fd, const char *message, ...) { va_list argp ; char buffer [1024] ; @@ -182,7 +183,7 @@ void serialPrintf (int fd, char *message, ...) ********************************************************************************* */ -int serialDataAvail (int fd) +int serialDataAvail (const int fd) { int result ; @@ -201,7 +202,7 @@ int serialDataAvail (int fd) ********************************************************************************* */ -int serialGetchar (int fd) +int serialGetchar (const int fd) { uint8_t x ; diff --git a/wiringPi/wiringSerial.h b/wiringPi/wiringSerial.h index 1a4198c..430dc73 100644 --- a/wiringPi/wiringSerial.h +++ b/wiringPi/wiringSerial.h @@ -24,14 +24,14 @@ extern "C" { #endif -extern int serialOpen (char *device, int baud) ; -extern void serialClose (int fd) ; -extern void serialFlush (int fd) ; -extern void serialPutchar (int fd, unsigned char c) ; -extern void serialPuts (int fd, char *s) ; -extern void serialPrintf (int fd, char *message, ...) ; -extern int serialDataAvail (int fd) ; -extern int serialGetchar (int fd) ; +extern int serialOpen (const char *device, const int baud) ; +extern void serialClose (const int fd) ; +extern void serialFlush (const int fd) ; +extern void serialPutchar (const int fd, const unsigned char c) ; +extern void serialPuts (const int fd, const char *s) ; +extern void serialPrintf (const int fd, const char *message, ...) ; +extern int serialDataAvail (const int fd) ; +extern int serialGetchar (const int fd) ; #ifdef __cplusplus } diff --git a/wiringPi/wiringShift.c b/wiringPi/wiringShift.c index b9b7a44..3df94e8 100644 --- a/wiringPi/wiringShift.c +++ b/wiringPi/wiringShift.c @@ -56,7 +56,6 @@ uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) return value; } - /* * shiftOut: * Shift data out to a clocked source diff --git a/wiringPi/wiringShift.h b/wiringPi/wiringShift.h index a3f4581..419ade4 100644 --- a/wiringPi/wiringShift.h +++ b/wiringPi/wiringShift.h @@ -33,8 +33,8 @@ extern "C" { #endif -extern uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) ; -extern void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ; +extern uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) ; +extern void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ; #ifdef __cplusplus } diff --git a/wiringPi/wpiExtensions.c b/wiringPi/wpiExtensions.c new file mode 100644 index 0000000..4cae9c4 --- /dev/null +++ b/wiringPi/wpiExtensions.c @@ -0,0 +1,731 @@ +/* + * extensions.c: + * Originally part of the GPIO program to test, peek, poke and otherwise + * noodle with the GPIO hardware on the Raspberry Pi. + * Now used as a general purpose library to allow systems to dynamically + * add in new devices into wiringPi at program run-time. + * Copyright (c) 2012-2015 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "mcp23008.h" +#include "mcp23016.h" +#include "mcp23017.h" +#include "mcp23s08.h" +#include "mcp23s17.h" +#include "sr595.h" +#include "pcf8574.h" +#include "pcf8591.h" +#include "mcp3002.h" +#include "mcp3004.h" +#include "mcp4802.h" +#include "mcp3422.h" +#include "max31855.h" +#include "max5322.h" +#include "sn3218.h" +#include "drcSerial.h" + +#include "wpiExtensions.h" + +extern int wiringPiDebug ; + +static int verbose ; +static char errorMessage [1024] ; + + +#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) ; +} ; + + +/* + * verbError: + * Convenient error handling + ********************************************************************************* + */ + +static void verbError (const char *message, ...) +{ + va_list argp ; + va_start (argp, message) ; + vsnprintf (errorMessage, 1023, message, argp) ; + va_end (argp) ; + + if (verbose) + fprintf (stderr, "%s\n", errorMessage) ; +} + + +/* + * extractInt: + * Check & return an integer at the given location (prefixed by a :) + ********************************************************************************* + */ + +static char *extractInt (char *progName, char *p, int *num) +{ + if (*p != ':') + { + verbError ("%s: colon expected", progName) ; + return NULL ; + } + + ++p ; + + if (!isdigit (*p)) + { + verbError ("%s: digit expected", progName) ; + return NULL ; + } + + *num = strtol (p, NULL, 0) ; + while (isdigit (*p)) + ++p ; + + return p ; +} + + +/* + * extractStr: + * Check & return a string at the given location (prefixed by a :) + ********************************************************************************* + */ + +static char *extractStr (char *progName, char *p, char **str) +{ + char *q, *r ; + + if (*p != ':') + { + verbError ("%s: colon expected", progName) ; + return NULL ; + } + + ++p ; + + if (!isprint (*p)) + { + verbError ("%s: character expected", progName) ; + return NULL ; + } + + q = p ; + while ((*q != 0) && (*q != ':')) + ++q ; + + *str = r = calloc (q - p + 2, 1) ; // Zeros it + + while (p != q) + *r++ = *p++ ; + + return p ; +} + + + +/* + * doExtensionMcp23008: + * MCP23008 - 8-bit I2C GPIO expansion chip + * mcp23002:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionMcp23008 (char *progName, int pinBase, char *params) +{ + int i2c ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x01) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + mcp23008Setup (pinBase, i2c) ; + + return TRUE ; +} + + +/* + * doExtensionMcp23016: + * MCP230016- 16-bit I2C GPIO expansion chip + * mcp23016:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionMcp23016 (char *progName, int pinBase, char *params) +{ + int i2c ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x03) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + mcp23016Setup (pinBase, i2c) ; + + return TRUE ; +} + + +/* + * doExtensionMcp23017: + * MCP230017- 16-bit I2C GPIO expansion chip + * mcp23017:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionMcp23017 (char *progName, int pinBase, char *params) +{ + int i2c ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x03) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + mcp23017Setup (pinBase, i2c) ; + + return TRUE ; +} + + +/* + * doExtensionMcp23s08: + * MCP23s08 - 8-bit SPI GPIO expansion chip + * mcp23s08:base:spi:port + ********************************************************************************* + */ + +static int doExtensionMcp23s08 (char *progName, int pinBase, char *params) +{ + int spi, port ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI address (%d) out of range", progName, spi) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &port)) == NULL) + return FALSE ; + + if ((port < 0) || (port > 7)) + { + verbError ("%s: port address (%d) out of range", progName, port) ; + return FALSE ; + } + + mcp23s08Setup (pinBase, spi, port) ; + + return TRUE ; +} + + +/* + * doExtensionMcp23s17: + * MCP23s17 - 16-bit SPI GPIO expansion chip + * mcp23s17:base:spi:port + ********************************************************************************* + */ + +static int doExtensionMcp23s17 (char *progName, int pinBase, char *params) +{ + int spi, port ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI address (%d) out of range", progName, spi) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &port)) == NULL) + return FALSE ; + + if ((port < 0) || (port > 7)) + { + verbError ("%s: port address (%d) out of range", progName, port) ; + return FALSE ; + } + + mcp23s17Setup (pinBase, spi, port) ; + + return TRUE ; +} + + +/* + * doExtensionSr595: + * Shift Register 74x595 + * sr595:base:pins:data:clock:latch + ********************************************************************************* + */ + +static int doExtensionSr595 (char *progName, int pinBase, char *params) +{ + int pins, data, clock, latch ; + +// Extract pins + + if ((params = extractInt (progName, params, &pins)) == NULL) + return FALSE ; + + if ((pins < 8) || (pins > 32)) + { + verbError ("%s: pin count (%d) out of range - 8-32 expected.", progName, pins) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &data)) == NULL) + return FALSE ; + + if ((params = extractInt (progName, params, &clock)) == NULL) + return FALSE ; + + if ((params = extractInt (progName, params, &latch)) == NULL) + return FALSE ; + + sr595Setup (pinBase, pins, data, clock, latch) ; + + return TRUE ; +} + + +/* + * doExtensionPcf8574: + * Digital IO (Crude!) + * pcf8574:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionPcf8574 (char *progName, int pinBase, char *params) +{ + int i2c ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x03) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + pcf8574Setup (pinBase, i2c) ; + + return TRUE ; +} + + +/* + * doExtensionPcf8591: + * Analog IO + * pcf8591:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionPcf8591 (char *progName, int pinBase, char *params) +{ + int i2c ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x03) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + pcf8591Setup (pinBase, i2c) ; + + return TRUE ; +} + + +/* + * doExtensionMax31855: + * Analog IO + * max31855:base:spiChan + ********************************************************************************* + */ + +static int doExtensionMax31855 (char *progName, int pinBase, char *params) +{ + int spi ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI channel (%d) out of range", progName, spi) ; + return FALSE ; + } + + max31855Setup (pinBase, spi) ; + + return TRUE ; +} + + +/* + * doExtensionMcp3002: + * Analog IO + * mcp3002:base:spiChan + ********************************************************************************* + */ + +static int doExtensionMcp3002 (char *progName, int pinBase, char *params) +{ + int spi ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI channel (%d) out of range", progName, spi) ; + return FALSE ; + } + + mcp3002Setup (pinBase, spi) ; + + return TRUE ; +} + + +/* + * doExtensionMcp3004: + * Analog IO + * mcp3004:base:spiChan + ********************************************************************************* + */ + +static int doExtensionMcp3004 (char *progName, int pinBase, char *params) +{ + int spi ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI channel (%d) out of range", progName, spi) ; + return FALSE ; + } + + mcp3004Setup (pinBase, spi) ; + + return TRUE ; +} + + +/* + * doExtensionMax5322: + * Analog O + * max5322:base:spiChan + ********************************************************************************* + */ + +static int doExtensionMax5322 (char *progName, int pinBase, char *params) +{ + int spi ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI channel (%d) out of range", progName, spi) ; + return FALSE ; + } + + max5322Setup (pinBase, spi) ; + + return TRUE ; +} + + +/* + * doExtensionMcp4802: + * Analog IO + * mcp4802:base:spiChan + ********************************************************************************* + */ + +static int doExtensionMcp4802 (char *progName, int pinBase, char *params) +{ + int spi ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI channel (%d) out of range", progName, spi) ; + return FALSE ; + } + + mcp4802Setup (pinBase, spi) ; + + return TRUE ; +} + + +/* + * doExtensionSn3218: + * Analog Output (LED Driver) + * sn3218:base + ********************************************************************************* + */ + +static int doExtensionSn3218 (char *progName, int pinBase, char *params) +{ + sn3218Setup (pinBase) ; + return TRUE ; +} + + +/* + * doExtensionMcp3422: + * Analog IO + * mcp3422:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionMcp3422 (char *progName, int pinBase, char *params) +{ + int i2c, sampleRate, gain ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x03) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &sampleRate)) == NULL) + return FALSE ; + + if ((sampleRate < 0) || (sampleRate > 3)) + { + verbError ("%s: sample rate (%d) out of range", progName, sampleRate) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &gain)) == NULL) + return FALSE ; + + if ((gain < 0) || (gain > 3)) + { + verbError ("%s: gain (%d) out of range", progName, gain) ; + return FALSE ; + } + + mcp3422Setup (pinBase, i2c, sampleRate, gain) ; + + return TRUE ; +} + + +/* + * doExtensionDrcS: + * Interface to a DRC Serial system + * drcs:base:pins:serialPort:baud + ********************************************************************************* + */ + +static int doExtensionDrcS (char *progName, int pinBase, char *params) +{ + char *port ; + int pins, baud ; + + if ((params = extractInt (progName, params, &pins)) == NULL) + return FALSE ; + + if ((pins < 1) || (pins > 100)) + { + verbError ("%s: pins (%d) out of range (2-100)", progName, pins) ; + return FALSE ; + } + + if ((params = extractStr (progName, params, &port)) == NULL) + return FALSE ; + + if (strlen (port) == 0) + { + verbError ("%s: serial port device name required", progName) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &baud)) == NULL) + return FALSE ; + + if ((baud < 1) || (baud > 4000000)) + { + verbError ("%s: baud rate (%d) out of range", progName, baud) ; + return FALSE ; + } + + drcSetupSerial (pinBase, pins, port, baud) ; + + return TRUE ; +} + + + +/* + * Function list + ********************************************************************************* + */ + +static struct extensionFunctionStruct extensionFunctions [] = +{ + { "mcp23008", &doExtensionMcp23008 }, + { "mcp23016", &doExtensionMcp23016 }, + { "mcp23017", &doExtensionMcp23017 }, + { "mcp23s08", &doExtensionMcp23s08 }, + { "mcp23s17", &doExtensionMcp23s17 }, + { "sr595", &doExtensionSr595 }, + { "pcf8574", &doExtensionPcf8574 }, + { "pcf8591", &doExtensionPcf8591 }, + { "mcp3002", &doExtensionMcp3002 }, + { "mcp3004", &doExtensionMcp3004 }, + { "mcp4802", &doExtensionMcp4802 }, + { "mcp3422", &doExtensionMcp3422 }, + { "max31855", &doExtensionMax31855 }, + { "max5322", &doExtensionMax5322 }, + { "sn3218", &doExtensionSn3218 }, + { "drcs", &doExtensionDrcS }, + { NULL, NULL }, +} ; + + +/* + * loadWPiExtension: + * Load in a wiringPi extension + * The extensionData always starts with the name, a colon then the pinBase + * number. Other parameters after that are decoded by the module in question. + ********************************************************************************* + */ + +int loadWPiExtension (char *progName, char *extensionData, int printErrors) +{ + char *p ; + char *extension = extensionData ; + struct extensionFunctionStruct *extensionFn ; + int pinBase = 0 ; + + verbose = printErrors ; + +// Get the extension name by finding the first colon + + p = extension ; + while (*p != ':') + { + if (!*p) // ran out of characters + { + verbError ("%s: extension name not terminated by a colon", progName) ; + return FALSE ; + } + ++p ; + } + *p++ = 0 ; + +// Simple ATOI code + + if (!isdigit (*p)) + { + verbError ("%s: pinBase number expected after extension name", progName) ; + return FALSE ; + } + + while (isdigit (*p)) + { + if (pinBase > 1000000000) // Lets be realistic here... + { + verbError ("%s: pinBase too large", progName) ; + return FALSE ; + } + + pinBase = pinBase * 10 + (*p - '0') ; + ++p ; + } + + if (pinBase < 64) + { + verbError ("%s: pinBase (%d) too small. Minimum is 64.", progName, pinBase) ; + return FALSE ; + } + +// Search for extensions: + + for (extensionFn = extensionFunctions ; extensionFn->name != NULL ; ++extensionFn) + { + if (strcmp (extensionFn->name, extension) == 0) + return extensionFn->function (progName, pinBase, p) ; + } + + verbError ("%s: extension %s not found", progName, extension) ; + return FALSE ; +} diff --git a/wiringPi/wpiExtensions.h b/wiringPi/wpiExtensions.h new file mode 100644 index 0000000..fcaec96 --- /dev/null +++ b/wiringPi/wpiExtensions.h @@ -0,0 +1,26 @@ +/* + * extensions.h: + * Part of the GPIO program to test, peek, poke and otherwise + * noodle with the GPIO hardware on the Raspberry Pi. + * Copyright (c) 2012-2015 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + + +extern int loadWPiExtension (char *progName, char *extensionData, int verbose) ;