commit 2fe3003e20162ccbc41197d0365e47ee51d6aad0 Author: liuls2002 Date: Fri Aug 11 15:53:17 2023 +0800 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e6ad4ba --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*.o +*.so +lib*.so.* +*~ +debian-template/wiringPi +debian-template/wiringpi-*.deb +gpio/gpio +examples/speed +examples/blink diff --git a/COPYING.LESSER b/COPYING.LESSER new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/COPYING.LESSER @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..4e1df2e --- /dev/null +++ b/INSTALL @@ -0,0 +1,29 @@ + +How to install wiringPi +======================= + +The easiest way is to use the supplied 'build' script: + + ./build + +that should do a complete install or upgrade of wiringPi for you. + +That will install a dynamic library. + +Some distributions do not have /usr/local/lib in the default LD_LIBRARY_PATH. To +fix this, you need to edit /etc/ld.so.conf and add in a single line: + + /usr/local/lib + +then run the ldconfig command. + + sudo ldconfig + +To un-install wiringPi: + + ./build uninstall + +Gordon Henderson + +projects@drogon.net +https://projects.drogon.net/ diff --git a/People b/People new file mode 100644 index 0000000..1123f9d --- /dev/null +++ b/People @@ -0,0 +1,37 @@ + +Just a quick note to some people who've provided help, suggestions, +bug-fixes, etc. along the way... + +Nick Lott: (And others) + Hints about making it work with C++ + +Philipp Stefan Neininger: + Minor bug in the Makefile to do with cross compiling + +Chris McSweeny + Hints and tips about the use of arithmetic in gettimeofday() + inside the dealyMicrosecondsHard() function. + And spotting a couple of schoolboy errors in the (experimental) + softServo code, prompting me to completely re-write it. + +Armin (Via projects website) + Some pointers about the i2c-dev.h files. + +Arno Wagner + Suggestions for the mmap calls in wiringPiSetup() + +CHARLES Thibaut: + A small issue in softTone + +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... + +Dolf Andringa + Support for multiple SpiDev devices/ports + Debian build support diff --git a/README.md b/README.md new file mode 100644 index 0000000..925a7fb --- /dev/null +++ b/README.md @@ -0,0 +1,390 @@ +## How to download wiringOP + +``` +# apt-get update +# apt-get install -y git +# git clone https://github.com/orangepi-xunlong/wiringOP.git +``` + +## How to build wiringOP + +``` +# cd wiringOP +# ./build clean +# ./build +``` + +--- +## The output of the gpio readall command + +## Allwinner H2+ + +### Orange Pi Zero/R1 + +``` + +------+-----+----------+------+---+ OPi H2 +---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | | | 3.3V | | | 1 || 2 | | | 5V | | | + | 12 | 0 | SDA.0 | ALT2 | 0 | 3 || 4 | | | 5V | | | + | 11 | 1 | SCL.0 | ALT2 | 0 | 5 || 6 | | | GND | | | + | 6 | 2 | PWM.1 | OFF | 0 | 7 || 8 | 0 | ALT2 | TXD.1 | 3 | 198 | + | | | GND | | | 9 || 10 | 0 | ALT2 | RXD.1 | 4 | 199 | + | 1 | 5 | RXD.2 | ALT2 | 0 | 11 || 12 | 0 | OFF | PA07 | 6 | 7 | + | 0 | 7 | TXD.2 | ALT2 | 0 | 13 || 14 | | | GND | | | + | 3 | 8 | CTS.2 | OFF | 0 | 15 || 16 | 0 | ALT3 | SDA.1 | 9 | 19 | + | | | 3.3V | | | 17 || 18 | 0 | ALT3 | SCK.1 | 10 | 18 | + | 15 | 11 | MOSI.1 | ALT2 | 1 | 19 || 20 | | | GND | | | + | 16 | 12 | MISO.1 | ALT2 | 0 | 21 || 22 | 0 | OFF | RTS.2 | 13 | 2 | + | 14 | 14 | SCLK.1 | ALT2 | 0 | 23 || 24 | 0 | ALT2 | CE.1 | 15 | 13 | + | | | GND | | | 25 || 26 | 0 | OFF | PA10 | 16 | 10 | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+ OPi H2 +---+------+----------+-----+------+ +``` + +## Allwinner H3 + +### Orange Pi Zero Plus 2 + +``` + +------+-----+----------+------+---+ZEROPLUS 2+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | | | 3.3V | | | 1 || 2 | | | 5V | | | + | 12 | 0 | SDA.0 | ALT2 | 0 | 3 || 4 | | | 5V | | | + | 11 | 1 | SCL.0 | ALT2 | 0 | 5 || 6 | | | GND | | | + | 6 | 2 | PA6 | OFF | 0 | 7 || 8 | 0 | ALT2 | TXD.2 | 3 | 0 | + | | | GND | | | 9 || 10 | 0 | ALT2 | RXD.2 | 4 | 1 | + | 352 | 5 | S-SCL | ALT2 | 0 | 11 || 12 | 0 | OFF | PD11 | 6 | 107 | + | 353 | 7 | S-SDA | ALT2 | 0 | 13 || 14 | | | GND | | | + | 3 | 8 | CTS.2 | OFF | 0 | 15 || 16 | 0 | ALT3 | SDA.1 | 9 | 19 | + | | | 3.3V | | | 17 || 18 | 0 | ALT3 | SCL.1 | 10 | 18 | + | 15 | 11 | MOSI.1 | ALT2 | 0 | 19 || 20 | | | GND | | | + | 16 | 12 | MISO.1 | ALT2 | 0 | 21 || 22 | 0 | OFF | RTS.2 | 13 | 2 | + | 14 | 14 | SCLK.1 | ALT2 | 0 | 23 || 24 | 0 | ALT2 | CE.1 | 15 | 13 | + | | | GND | | | 25 || 26 | 0 | OFF | PD14 | 16 | 110 | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+ZEROPLUS 2+---+------+----------+-----+------+ +``` + +### OrangePi One/Lite/Pc/Plus/PcPlus/Plus2e + +``` + +------+-----+----------+------+---+OrangePiH3+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | | | 3.3V | | | 1 || 2 | | | 5V | | | + | 12 | 0 | SDA.0 | OUT | 0 | 3 || 4 | | | 5V | | | + | 11 | 1 | SCL.0 | OUT | 0 | 5 || 6 | | | GND | | | + | 6 | 2 | PA6 | OUT | 0 | 7 || 8 | 0 | OUT | TXD.3 | 3 | 13 | + | | | GND | | | 9 || 10 | 0 | OUT | RXD.3 | 4 | 14 | + | 1 | 5 | RXD.2 | OUT | 0 | 11 || 12 | 0 | OUT | PD14 | 6 | 110 | + | 0 | 7 | TXD.2 | OUT | 0 | 13 || 14 | | | GND | | | + | 3 | 8 | CTS.2 | OUT | 0 | 15 || 16 | 0 | OUT | PC04 | 9 | 68 | + | | | 3.3V | | | 17 || 18 | 0 | OUT | PC07 | 10 | 71 | + | 64 | 11 | MOSI.0 | OUT | 0 | 19 || 20 | | | GND | | | + | 65 | 12 | MISO.0 | OUT | 0 | 21 || 22 | 0 | OUT | RTS.2 | 13 | 2 | + | 66 | 14 | SCLK.0 | OUT | 0 | 23 || 24 | 0 | OUT | CE.0 | 15 | 67 | + | | | GND | | | 25 || 26 | 0 | OUT | PA21 | 16 | 21 | + | 19 | 17 | SDA.1 | OUT | 0 | 27 || 28 | 0 | OUT | SCL.1 | 18 | 18 | + | 7 | 19 | PA07 | OUT | 0 | 29 || 30 | | | GND | | | + | 8 | 20 | PA08 | OUT | 0 | 31 || 32 | 0 | OUT | RTS.1 | 21 | 200 | + | 9 | 22 | PA09 | OUT | 0 | 33 || 34 | | | GND | | | + | 10 | 23 | PA10 | OUT | 0 | 35 || 36 | 0 | OUT | CTS.1 | 24 | 201 | + | 20 | 25 | PA20 | OUT | 0 | 37 || 38 | 0 | OUT | TXD.1 | 26 | 198 | + | | | GND | | | 39 || 40 | 0 | OUT | RXD.1 | 27 | 199 | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+OrangePiH3+---+------+----------+-----+------+ +``` + +## Allwinner H5 + +### Orange Pi Zero Plus + +``` + +------+-----+----------+------+---+ ZEROPLUS +---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | | | 3.3V | | | 1 || 2 | | | 5V | | | + | 12 | 0 | SDA.0 | ALT2 | 0 | 3 || 4 | | | 5V | | | + | 11 | 1 | SCL.0 | ALT2 | 0 | 5 || 6 | | | GND | | | + | 6 | 2 | PA6 | OFF | 0 | 7 || 8 | 0 | ALT2 | TXD.1 | 3 | 198 | + | | | GND | | | 9 || 10 | 0 | ALT2 | RXD.1 | 4 | 199 | + | 1 | 5 | RXD.2 | ALT2 | 0 | 11 || 12 | 0 | OFF | PA07 | 6 | 7 | + | 0 | 7 | TXD.2 | ALT2 | 0 | 13 || 14 | | | GND | | | + | 3 | 8 | CTS.2 | OFF | 0 | 15 || 16 | 0 | ALT3 | SDA.1 | 9 | 19 | + | | | 3.3V | | | 17 || 18 | 0 | ALT3 | SCL.1 | 10 | 18 | + | 15 | 11 | MOSI.1 | ALT2 | 0 | 19 || 20 | | | GND | | | + | 16 | 12 | MISO.1 | ALT2 | 0 | 21 || 22 | 0 | OFF | RTS.2 | 13 | 2 | + | 14 | 14 | SCLK.1 | ALT2 | 0 | 23 || 24 | 0 | ALT2 | CE.1 | 15 | 13 | + | | | GND | | | 25 || 26 | 0 | OFF | PA10 | 16 | 10 | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+ ZEROPLUS +---+------+----------+-----+------+ +``` + +### Orange Pi Zero Plus 2 + +``` + +------+-----+----------+------+---+ZEROPLUS 2+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | | | 3.3V | | | 1 || 2 | | | 5V | | | + | 12 | 0 | SDA.0 | ALT2 | 0 | 3 || 4 | | | 5V | | | + | 11 | 1 | SCL.0 | ALT2 | 0 | 5 || 6 | | | GND | | | + | 6 | 2 | PA6 | OFF | 0 | 7 || 8 | 0 | ALT2 | TXD.2 | 3 | 0 | + | | | GND | | | 9 || 10 | 0 | ALT2 | RXD.2 | 4 | 1 | + | 352 | 5 | S-SCL | ALT2 | 0 | 11 || 12 | 0 | OFF | PD11 | 6 | 107 | + | 353 | 7 | S-SDA | ALT2 | 0 | 13 || 14 | | | GND | | | + | 3 | 8 | CTS.2 | OFF | 0 | 15 || 16 | 0 | ALT3 | SDA.1 | 9 | 19 | + | | | 3.3V | | | 17 || 18 | 0 | ALT3 | SCL.1 | 10 | 18 | + | 15 | 11 | MOSI.1 | ALT2 | 0 | 19 || 20 | | | GND | | | + | 16 | 12 | MISO.1 | ALT2 | 0 | 21 || 22 | 0 | OFF | RTS.2 | 13 | 2 | + | 14 | 14 | SCLK.1 | ALT2 | 0 | 23 || 24 | 0 | ALT2 | CE.1 | 15 | 13 | + | | | GND | | | 25 || 26 | 0 | OFF | PD14 | 16 | 110 | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+ZEROPLUS 2+---+------+----------+-----+------+ +``` + +### Orange Pi Pc 2 + +``` + +------+-----+----------+------+---+ OPi PC2 +---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | | | 3.3V | | | 1 || 2 | | | 5V | | | + | 12 | 0 | SDA.0 | ALT2 | 0 | 3 || 4 | | | 5V | | | + | 11 | 1 | SCL.0 | ALT2 | 0 | 5 || 6 | | | GND | | | + | 6 | 2 | PWM.1 | OFF | 0 | 7 || 8 | 0 | OFF | PC05 | 3 | 69 | + | | | GND | | | 9 || 10 | 0 | OFF | PC06 | 4 | 70 | + | 1 | 5 | RXD.2 | ALT2 | 0 | 11 || 12 | 0 | OFF | PD14 | 6 | 110 | + | 0 | 7 | TXD.2 | ALT2 | 0 | 13 || 14 | | | GND | | | + | 3 | 8 | CTS.2 | ALT2 | 0 | 15 || 16 | 0 | OFF | PC04 | 9 | 68 | + | | | 3.3V | | | 17 || 18 | 0 | OFF | PC07 | 10 | 71 | + | 15 | 11 | MOSI.1 | ALT2 | 0 | 19 || 20 | | | GND | | | + | 16 | 12 | MISO.1 | ALT2 | 0 | 21 || 22 | 0 | ALT2 | RTS.2 | 13 | 2 | + | 14 | 14 | SCLK.1 | ALT2 | 0 | 23 || 24 | 0 | ALT2 | CE.1 | 15 | 13 | + | | | GND | | | 25 || 26 | 0 | OFF | PA21 | 16 | 21 | + | 19 | 17 | SDA.1 | ALT3 | 0 | 27 || 28 | 0 | ALT3 | SCL.1 | 18 | 18 | + | 7 | 19 | PA07 | OFF | 0 | 29 || 30 | | | GND | | | + | 8 | 20 | PA08 | OFF | 0 | 31 || 32 | 0 | ALT2 | RTS.1 | 21 | 200 | + | 9 | 22 | PA09 | OFF | 0 | 33 || 34 | | | GND | | | + | 10 | 23 | PA10 | OFF | 0 | 35 || 36 | 0 | ALT2 | CTS.1 | 24 | 201 | + | 107 | 25 | PD11 | OFF | 0 | 37 || 38 | 0 | ALT2 | TXD.1 | 26 | 198 | + | | | GND | | | 39 || 40 | 0 | ALT2 | RXD.1 | 27 | 199 | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+ OPi PC2 +---+------+----------+-----+------+ +``` + +### Orange Pi Prime + +``` + +------+-----+----------+------+---+ PRIME +---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | | | 3.3V | | | 1 || 2 | | | 5V | | | + | 12 | 0 | SDA.0 | ALT2 | 0 | 3 || 4 | | | 5V | | | + | 11 | 1 | SCL.0 | ALT2 | 0 | 5 || 6 | | | GND | | | + | 6 | 2 | PWM.1 | OFF | 0 | 7 || 8 | 0 | OFF | PC05 | 3 | 69 | + | | | GND | | | 9 || 10 | 0 | OFF | PC06 | 4 | 70 | + | 1 | 5 | RXD.2 | ALT2 | 0 | 11 || 12 | 0 | OFF | PD14 | 6 | 110 | + | 0 | 7 | TXD.2 | ALT2 | 0 | 13 || 14 | | | GND | | | + | 3 | 8 | CTS.2 | ALT2 | 0 | 15 || 16 | 0 | OFF | PC04 | 9 | 68 | + | | | 3.3V | | | 17 || 18 | 0 | OFF | PC07 | 10 | 71 | + | 15 | 11 | MOSI.1 | ALT2 | 0 | 19 || 20 | | | GND | | | + | 16 | 12 | MISO.1 | ALT2 | 0 | 21 || 22 | 0 | ALT2 | RTS.2 | 13 | 2 | + | 14 | 14 | SCLK.1 | ALT2 | 0 | 23 || 24 | 0 | ALT2 | CE.1 | 15 | 13 | + | | | GND | | | 25 || 26 | 0 | OFF | PC08 | 16 | 72 | + | 19 | 17 | SDA.1 | ALT3 | 0 | 27 || 28 | 0 | ALT3 | SCL.1 | 18 | 18 | + | 7 | 19 | PA07 | OFF | 0 | 29 || 30 | | | GND | | | + | 8 | 20 | PA08 | OFF | 0 | 31 || 32 | 0 | OFF | PC09 | 21 | 73 | + | 9 | 22 | PA09 | OFF | 0 | 33 || 34 | | | GND | | | + | 10 | 23 | PA10 | OFF | 0 | 35 || 36 | 0 | OFF | PC10 | 24 | 74 | + | 107 | 25 | PD11 | OFF | 0 | 37 || 38 | 0 | OFF | PC11 | 26 | 75 | + | | | GND | | | 39 || 40 | 0 | OFF | PC12 | 27 | 76 | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+ PRIME +---+------+----------+-----+------+ +``` + +## Allwinner A64 + +### Orange Pi Win/Winplus + +``` + +------+-----+----------+------+---+ OPi Win +---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | | | 3.3V | | | 1 || 2 | | | 5V | | | + | 227 | 0 | SDA.1 | ALT2 | 0 | 3 || 4 | | | 5V | | | + | 226 | 1 | SCL.1 | ALT2 | 0 | 5 || 6 | | | GND | | | + | 362 | 2 | PL10 | OFF | 0 | 7 || 8 | 0 | ALT2 | PL02 | 3 | 354 | + | | | GND | | | 9 || 10 | 0 | ALT2 | PL03 | 4 | 355 | + | 229 | 5 | RXD.3 | ALT2 | 0 | 11 || 12 | 0 | OFF | PD04 | 6 | 100 | + | 228 | 7 | TXD.3 | ALT2 | 0 | 13 || 14 | | | GND | | | + | 231 | 8 | CTS.3 | OUT | 0 | 15 || 16 | 0 | OFF | PL09 | 9 | 361 | + | | | 3.3V | | | 17 || 18 | 0 | OFF | PC04 | 10 | 68 | + | 98 | 11 | MOSI.1 | ALT4 | 0 | 19 || 20 | | | GND | | | + | 99 | 12 | MISO.1 | ALT4 | 0 | 21 || 22 | 0 | OFF | RTS.3 | 13 | 230 | + | 97 | 14 | SCLK.1 | ALT4 | 0 | 23 || 24 | 0 | ALT4 | CE.1 | 15 | 96 | + | | | GND | | | 25 || 26 | 0 | OFF | PD06 | 16 | 102 | + | 143 | 17 | SDA.2 | ALT3 | 0 | 27 || 28 | 0 | ALT3 | SCL.2 | 18 | 142 | + | 36 | 19 | PB04 | OFF | 0 | 29 || 30 | | | GND | | | + | 37 | 20 | PB05 | OFF | 0 | 31 || 32 | 0 | ALT2 | RTS.2 | 21 | 34 | + | 38 | 22 | PB06 | OFF | 0 | 33 || 34 | | | GND | | | + | 39 | 23 | PB07 | OFF | 0 | 35 || 36 | 0 | ALT2 | CTS.2 | 24 | 35 | + | 101 | 25 | PD05 | OFF | 0 | 37 || 38 | 0 | ALT2 | TXD.2 | 26 | 32 | + | | | GND | | | 39 || 40 | 0 | ALT2 | RXD.2 | 27 | 33 | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+ OPi Win +---+------+----------+-----+------+ +``` + +## Allwinner H6 + +### Orange Pi 3/3 LTS + +``` + +------+-----+----------+------+---+ OPi 3 +---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | | | 3.3V | | | 1 || 2 | | | 5V | | | + | 122 | 0 | SDA.0 | OFF | 0 | 3 || 4 | | | 5V | | | + | 121 | 1 | SCL.0 | OFF | 0 | 5 || 6 | | | GND | | | + | 118 | 2 | PWM.0 | OFF | 0 | 7 || 8 | 0 | OFF | PL02 | 3 | 354 | + | | | GND | | | 9 || 10 | 0 | OFF | PL03 | 4 | 355 | + | 120 | 5 | RXD.3 | ALT4 | 0 | 11 || 12 | 0 | OFF | PD18 | 6 | 114 | + | 119 | 7 | TXD.3 | ALT4 | 0 | 13 || 14 | | | GND | | | + | 362 | 8 | PL10 | OFF | 0 | 15 || 16 | 0 | OFF | PD15 | 9 | 111 | + | | | 3.3V | | | 17 || 18 | 0 | OFF | PD16 | 10 | 112 | + | 229 | 11 | MOSI.1 | ALT2 | 0 | 19 || 20 | | | GND | | | + | 230 | 12 | MISO.1 | ALT2 | 0 | 21 || 22 | 0 | OFF | PD21 | 13 | 117 | + | 228 | 14 | SCLK.1 | ALT2 | 0 | 23 || 24 | 0 | ALT2 | CE.1 | 15 | 227 | + | | | GND | | | 25 || 26 | 0 | OFF | PL08 | 16 | 360 | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+ OPi 3 +---+------+----------+-----+------+ +``` + +### Orange Pi Lite2/OnePlus + +``` + +------+-----+----------+------+---+ OPi H6 +---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | | | 3.3V | | | 1 || 2 | | | 5V | | | + | 230 | 0 | SDA.1 | OFF | 0 | 3 || 4 | | | 5V | | | + | 229 | 1 | SCL.1 | OFF | 0 | 5 || 6 | | | GND | | | + | 228 | 2 | PWM1 | OFF | 0 | 7 || 8 | 0 | OFF | PD21 | 3 | 117 | + | | | GND | | | 9 || 10 | 0 | OFF | PD22 | 4 | 118 | + | 120 | 5 | RXD.3 | ALT4 | 0 | 11 || 12 | 0 | OFF | PC09 | 6 | 73 | + | 119 | 7 | TXD.3 | ALT4 | 0 | 13 || 14 | | | GND | | | + | 122 | 8 | CTS.3 | OFF | 0 | 15 || 16 | 0 | OFF | PC08 | 9 | 72 | + | | | 3.3V | | | 17 || 18 | 0 | OFF | PC07 | 10 | 71 | + | 66 | 11 | MOSI.0 | ALT4 | 0 | 19 || 20 | | | GND | | | + | 67 | 12 | MISO.0 | ALT4 | 0 | 21 || 22 | 0 | OFF | RTS.3 | 13 | 121 | + | 64 | 14 | SCLK.0 | ALT4 | 0 | 23 || 24 | 0 | ALT4 | CE.0 | 15 | 69 | + | | | GND | | | 25 || 26 | 0 | OFF | PH03 | 16 | 227 | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+ OPi H6 +---+------+----------+-----+------+ +``` + +## Allwinner H616 + +### Orange Pi Zero2/Zero2 LTS/Zero2 B + +``` + +------+-----+----------+------+---+ Zero 2 +---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | | | 3.3V | | | 1 || 2 | | | 5V | | | + | 229 | 0 | SDA.3 | OFF | 0 | 3 || 4 | | | 5V | | | + | 228 | 1 | SCL.3 | OFF | 0 | 5 || 6 | | | GND | | | + | 73 | 2 | PC9 | OFF | 0 | 7 || 8 | 0 | ALT2 | TXD.5 | 3 | 226 | + | | | GND | | | 9 || 10 | 0 | ALT2 | RXD.5 | 4 | 227 | + | 70 | 5 | PC6 | ALT5 | 0 | 11 || 12 | 0 | OFF | PC11 | 6 | 75 | + | 69 | 7 | PC5 | ALT5 | 0 | 13 || 14 | | | GND | | | + | 72 | 8 | PC8 | OFF | 0 | 15 || 16 | 0 | OFF | PC15 | 9 | 79 | + | | | 3.3V | | | 17 || 18 | 0 | OFF | PC14 | 10 | 78 | + | 231 | 11 | MOSI.1 | ALT4 | 0 | 19 || 20 | | | GND | | | + | 232 | 12 | MISO.1 | ALT4 | 0 | 21 || 22 | 0 | OFF | PC7 | 13 | 71 | + | 230 | 14 | SCLK.1 | ALT4 | 0 | 23 || 24 | 0 | ALT4 | CE.1 | 15 | 233 | + | | | GND | | | 25 || 26 | 0 | OFF | PC10 | 16 | 74 | + | 65 | 17 | PC1 | OFF | 0 | 27 || 28 | | | | | | + | 272 | 18 | PI16 | OFF | 0 | 29 || 30 | | | | | | + | 262 | 19 | PI6 | OFF | 0 | 31 || 32 | | | | | | + | 234 | 20 | PH10 | ALT3 | 0 | 33 || 34 | | | | | | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+ Zero 2 +---+------+----------+-----+------+ +``` + +## RockChip RK3399 + +### Orange Pi RK3399 + +``` + +------+-----+----------+------+---+OPi RK3399+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | | | 3.3V | | | 1 || 2 | | | 5V | | | + | 43 | 0 | SDA.0 | ALT2 | 1 | 3 || 4 | | | 5V | | | + | 44 | 1 | SCL.0 | ALT2 | 1 | 5 || 6 | | | GND | | | + | 64 | 2 | GPIO4 | ALT3 | 0 | 7 || 8 | 0 | ALT2 | Tx | 3 | 148 | + | | | GND | | | 9 || 10 | 1 | ALT2 | Rx | 4 | 147 | + | 80 | 5 | GPIO17 | ALT2 | 0 | 11 || 12 | 0 | ALT3 | GPIO18 | 6 | 65 | + | 81 | 7 | GPIO27 | ALT2 | 0 | 13 || 14 | | | GND | | | + | 82 | 8 | GPIO22 | ALT2 | 0 | 15 || 16 | 0 | IN | GPIO23 | 9 | 66 | + | | | 3.3V | | | 17 || 18 | 0 | IN | GPIO24 | 10 | 67 | + | 39 | 11 | MOSI | ALT2 | 1 | 19 || 20 | | | GND | | | + | 40 | 12 | MISO | ALT2 | 1 | 21 || 22 | 0 | ALT2 | GPIO25 | 13 | 83 | + | 41 | 14 | SCLK | ALT3 | 1 | 23 || 24 | 1 | ALT3 | CS0 | 15 | 42 | + | | | GND | | | 25 || 26 | 0 | ALT2 | CS1 | 16 | 133 | + | 154 | 17 | DNP1 | IN | 0 | 27 || 28 | 1 | IN | DNP2 | 18 | 50 | + | 68 | 19 | GPIO5 | OUT | 1 | 29 || 30 | | | GND | | | + | 69 | 20 | GPIO6 | OUT | 1 | 31 || 32 | 1 | OUT | GPIO12 | 21 | 76 | + | 70 | 22 | GPIO13 | OUT | 1 | 33 || 34 | | | GND | | | + | 71 | 23 | GPIO19 | OUT | 1 | 35 || 36 | 1 | OUT | GPIO16 | 24 | 73 | + | 72 | 25 | GPIO26 | OUT | 1 | 37 || 38 | 0 | IN | GPIO20 | 26 | 74 | + | | | GND | | | 39 || 40 | 0 | ALT4 | GPIO21 | 27 | 75 | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+OPi RK3399+---+------+----------+-----+------+ + ``` + + ### Orange Pi 4/4B/4 LTS + + ``` + +------+-----+----------+------+---+OrangePi 4+---+---+--+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | | | 3.3V | | | 1 || 2 | | | 5V | | | + | 64 | 0 | I2C2_SDA | ALT3 | 0 | 3 || 4 | | | 5V | | | + | 65 | 1 | I2C2_SCL | ALT3 | 0 | 5 || 6 | | | GND | | | + | 150 | 2 | PWM1 | IN | 0 | 7 || 8 | 1 | ALT2 | I2C3_SCL | 3 | 145 | + | | | GND | | | 9 || 10 | 1 | ALT2 | I2C3_SDA | 4 | 144 | + | 33 | 5 | GPIO1_A1 | IN | 0 | 11 || 12 | 1 | IN | GPIO1_C2 | 6 | 50 | + | 35 | 7 | GPIO1_A3 | OUT | 0 | 13 || 14 | | | GND | | | + | 92 | 8 | GPIO2_D4 | OUT | 1 | 15 || 16 | 0 | IN | GPIO1_C6 | 9 | 54 | + | | | 3.3V | | | 17 || 18 | 0 | IN | GPIO1_C7 | 10 | 55 | + | 40 | 11 | SPI1_TXD | ALT2 | 1 | 19 || 20 | | | GND | | | + | 39 | 12 | SPI1_RXD | ALT2 | 1 | 21 || 22 | 0 | IN | GPIO1_D0 | 13 | 56 | + | 41 | 14 | SPI1_CLK | ALT3 | 1 | 23 || 24 | 1 | ALT3 | SPI1_CS | 15 | 42 | + | | | GND | | | 25 || 26 | 0 | IN | GPIO4_C5 | 16 | 149 | + | 64 | 17 | I2C2_SDA | ALT3 | 0 | 27 || 28 | 0 | ALT3 | I2C2_SCL | 18 | 65 | + | | | I2S0_RX | | | 29 || 30 | | | GND | | | + | | | I2S0_TX | | | 31 || 32 | | | I2S_CLK | | | + | | | I2S0_SCK | | | 33 || 34 | | | GND | | | + | | | I2S0_SI0 | | | 35 || 36 | | | I2S0_SO0 | | | + | | | I2S0_SI1 | | | 37 || 38 | | | I2S0_SI2 | | | + | | | GND | | | 39 || 40 | | | I2S0_SI3 | | | + +------+-----+----------+------+---+----++----+---+------+----------+-----+------+ + | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO | + +------+-----+----------+------+---+OrangePi 4+---+---+--+----------+-----+------+ +``` diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..e72716a --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +2.46 diff --git a/build b/build new file mode 100644 index 0000000..e32c86f --- /dev/null +++ b/build @@ -0,0 +1,300 @@ +#!/bin/bash -e + +# build +# Simple wiringPi build and install script +# +# Copyright (c) 2012-2015 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# A "wiring" library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# +# +# 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..." + echo "Please check the messages and fix any problems. If you're still stuck," + echo "then please email all the output and as many details as you can to" + echo " projects@drogon.net" + echo "" + exit 1 + fi +} + +select_boards() +{ + local cnt=0 + local choice + local call=${1} + + boards=("orangepir1" + "orangepizero" + "orangepizero-lts" + "orangepipc" + "orangepipch5" + "orangepipcplus" + "orangepiplus2e" + "orangepione" + "orangepioneh5" + "orangepilite" + "orangepiplus" + "orangepizeroplus2h3" + "orangepizeroplus" + "orangepipc2" + "orangepiprime" + "orangepizeroplus2h5" + "orangepiwin" + "orangepiwinplus" + "orangepi3" + "orangepi3-lts" + "orangepilite2" + "orangepioneplus" + "orangepi4" + "orangepi4-lts" + "orangepirk3399" + "orangepi800" + "orangepizero2" + "orangepizero2-lts" + "orangepizero2-b" + "orangepizero3" + "orangepir1plus-lts" + "orangepir1plus") + + if [[ -f /etc/orangepi-release ]]; then + + source /etc/orangepi-release + + elif [[ -f /etc/armbian-release ]]; then + + source /etc/armbian-release + [[ $BOARD == orangepi-r1 ]] && BOARD=orangepir1 + [[ $BOARD == orangepi-rk3399 ]] && BOARD=orangepirk3399 + [[ $BOARD == orangepizeroplus2-h3 ]] && BOARD=orangepizeroplus2h3 + [[ $BOARD == orangepizeroplus2-h5 ]] && BOARD=orangepizeroplus2h5 + + else + + printf "All available boards:\n" + for var in ${boards[@]} ; do + printf "%4d. %s\n" $cnt ${boards[$cnt]} + ((cnt+=1)) + done + + while true ; do + read -p "Choice: " choice + if [ -z "${choice}" ] ; then + continue + fi + if [ -z "${choice//[0-9]/}" ] ; then + if [ $choice -ge 0 -a $choice -lt $cnt ] ; then + export BOARD="${boards[$choice]}" + break + fi + fi + printf "Invalid input ...\n" + done + fi + + [[ $BOARD == orangepir1 ]] && BOARD=orangepir1-h2 + [[ $BOARD == orangepizero ]] && BOARD=orangepizero-h2 + [[ $BOARD == orangepizero-lts ]] && BOARD=orangepizero-h2 + [[ $BOARD == orangepipc ]] && BOARD=orangepipc-h3 + [[ $BOARD == orangepipch5 ]] && BOARD=orangepipc-h3 + [[ $BOARD == orangepipcplus ]] && BOARD=orangepipcplus-h3 + [[ $BOARD == orangepiplus2e ]] && BOARD=orangepiplus2e-h3 + [[ $BOARD == orangepione ]] && BOARD=orangepione-h3 + [[ $BOARD == orangepioneh5 ]] && BOARD=orangepione-h3 + [[ $BOARD == orangepilite ]] && BOARD=orangepilite-h3 + [[ $BOARD == orangepiplus ]] && BOARD=orangepiplus-h3 + [[ $BOARD == orangepizeroplus ]] && BOARD=orangepizeroplus-h5 + [[ $BOARD == orangepipc2 ]] && BOARD=orangepipc2-h5 + [[ $BOARD == orangepiprime ]] && BOARD=orangepiprime-h5 + [[ $BOARD == orangepiwin ]] && BOARD=orangepiwin-a64 + [[ $BOARD == orangepiwinplus ]] && BOARD=orangepiwinplus-a64 + [[ $BOARD == orangepi3 ]] && BOARD=orangepi3-h6 + [[ $BOARD == orangepi3-lts ]] && BOARD=orangepi3-h6 + [[ $BOARD == orangepilite2 ]] && BOARD=orangepilite2-h6 + [[ $BOARD == orangepioneplus ]] && BOARD=orangepioneplus-h6 + [[ $BOARD == orangepizero2 ]] && BOARD=orangepizero2-h616 + [[ $BOARD == orangepizero2-lts ]] && BOARD=orangepizero2-h616 + [[ $BOARD == orangepizero2-b ]] && BOARD=orangepizero2-h616 + [[ $BOARD == orangepizero3 ]] && BOARD=orangepizero2-h616 + [[ $BOARD == orangepir1plus ]] && BOARD=orangepir1plus-rk3328 + [[ $BOARD == orangepir1plus-lts ]] && BOARD=orangepir1plus-rk3328 + + export BOARD="${BOARD}" +} + +sudo=${WIRINGPI_SUDO-sudo} + +if [ x$1 = "xclean" ]; then + cd wiringPi + echo -n "wiringPi: " ; make clean + cd ../devLib + echo -n "DevLib: " ; make clean + cd ../gpio + echo -n "gpio: " ; make clean + cd ../examples + echo -n "Examples: " ; make clean + cd Gertboard + echo -n "Gertboard: " ; make clean + cd ../PiFace + echo -n "PiFace: " ; make clean + cd ../q2w + echo -n "Quick2Wire: " ; make clean + cd ../PiGlow + echo -n "PiGlow: " ; make clean + cd ../scrollPhat + echo -n "scrollPhat: " ; make clean + cd ../.. + echo -n "Deb: " ; rm -f debian-template/wiringpi*.deb + echo + exit +fi + +if [ x$1 = "xuninstall" ]; then + cd wiringPi + echo -n "wiringPi: " ; $sudo make uninstall + cd ../devLib + echo -n "DevLib: " ; $sudo make uninstall + cd ../gpio + echo -n "gpio: " ; $sudo make uninstall + exit +fi + +# Only if you know what you're doing! + +if [ x$1 = "xdebian" ]; then + here=`pwd` + echo "removing old libs" + cd debian-template/wiringPi + rm -rf usr + echo "building wiringPi" + cd $here/wiringPi + make install-deb + echo "building devLib" + cd $here/devLib + make install-deb INCLUDE='-I. -I../wiringPi' + echo "building gpio" + cd $here/gpio + make install-deb INCLUDE='-I../wiringPi -I../devLib' LDFLAGS=-L../debian-template/wiringPi/usr/lib + echo "Building deb package" + 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 + + select_boards + + echo "wiringPi Build script" + echo "=====================" + echo + + 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 + + + echo + echo "WiringPi Library" + cd wiringPi + $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 -j5 + check_make_ok + $sudo make install + check_make_ok + +# echo +# echo "wiringPi Daemon" +# cd ../wiringPiD +# make -j5 +# check_make_ok +# $sudo make install +# check_make_ok + +# echo +# echo "Examples" +# cd ../examples +# make +# cd .. + +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/.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..7f313dc --- /dev/null +++ b/devLib/Makefile @@ -0,0 +1,140 @@ +# +# Makefile: +# wiringPi device - A "wiring" library for the Raspberry Pi +# +# Copyright (c) 2012-2016 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# https://projects.drogon.net/raspberry-pi/wiringpi/ +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + +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 \ + scrollPhat.c \ + piGlow.c + +OBJ = $(SRC:.c=.o) + +HEADERS = ds1302.h gertboard.h lcd128x64.h lcd.h maxdetect.h piFace.h piGlow.h piNes.h\ + scrollPhat.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 $(CURDIR)/../debian-template/wiringPi/usr/include + $Q install -m 0644 $(HEADERS) $(CURDIR)/../debian-template/wiringPi/usr/include + $Q echo "[Install Dynamic Lib: deb]" + install -m 0755 -d $(CURDIR)/../debian-template/wiringPi/usr/lib + install -m 0755 libwiringPiDev.so.$(VERSION) $(CURDIR)/../debian-template/wiringPi/usr/lib/libwiringPiDev.so.$(VERSION) + ln -sf $(CURDIR)/../debian-template/wiringPi/usr/lib/libwiringPiDev.so.$(VERSION) $(CURDIR)/../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 +scrollPhat.o: scrollPhatFont.h scrollPhat.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..6a84415 --- /dev/null +++ b/devLib/gertboard.c @@ -0,0 +1,164 @@ +/* + * gertboard.c: + * Access routines for the SPI devices on the Gertboard + * Copyright (c) 2012 Gordon Henderson + * + * The Gertboard has: + * + * An MCP3002 dual-channel A to D convertor connected + * to the SPI bus, selected by chip-select A, and: + * + * An MCP4802 dual-channel D to A convertor connected + * to the SPI bus, selected via chip-select B. + * + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + + +#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] << 8) | (spiData [1] >> 1)) & 0x3FF ; +} + + +/* + * gertboardSPISetup: + * Initialise the SPI bus, etc. + ********************************************************************************* + */ + +int gertboardSPISetup (void) +{ + if (wiringPiSPISetup (SPI_A2D, SPI_ADC_SPEED) < 0) + return -1 ; + + if (wiringPiSPISetup (SPI_D2A, SPI_DAC_SPEED) < 0) + return -1 ; + + return 0 ; +} + + +/* + * New wiringPi node extension methods. + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, const int chan) +{ + return gertboardAnalogRead (chan - node->pinBase) ; +} + +static void myAnalogWrite (struct wiringPiNodeStruct *node, const int chan, const int value) +{ + gertboardAnalogWrite (chan - node->pinBase, value) ; +} + + +/* + * gertboardAnalogSetup: + * Create a new wiringPi device node for the analog devices on the + * Gertboard. We create one node with 2 pins - each pin being read + * and write - although the operations actually go to different + * hardware devices. + ********************************************************************************* + */ + +int gertboardAnalogSetup (const int pinBase) +{ + struct wiringPiNodeStruct *node ; + int x ; + + if (( x = gertboardSPISetup ()) != 0) + return x; + + node = wiringPiNewNode (pinBase, 2) ; + node->analogRead = myAnalogRead ; + node->analogWrite = myAnalogWrite ; + + return 0 ; +} diff --git a/devLib/gertboard.h b/devLib/gertboard.h new file mode 100644 index 0000000..3fa1919 --- /dev/null +++ b/devLib/gertboard.h @@ -0,0 +1,45 @@ +/* + * gertboard.h: + * Access routines for the SPI devices on the Gertboard + * Copyright (c) 2012 Gordon Henderson + * + * The Gertboard has an MCP4802 dual-channel D to A convertor + * connected to the SPI bus, selected via chip-select B. + * + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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..74ff70e --- /dev/null +++ b/devLib/maxdetect.c @@ -0,0 +1,238 @@ +/* + * maxdetect.c: + * Driver for the MaxDetect series sensors + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +//#include +//#include + +#include + +#include "maxdetect.h" + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==2) +#endif + + +/* + * maxDetectLowHighWait: + * Wait for a transition from low to high on the bus + ********************************************************************************* + */ + +static int maxDetectLowHighWait (const int pin) +{ + struct timeval now, timeOut, timeUp ; + +// If already high then wait for pin to go low + + gettimeofday (&now, NULL) ; + timerclear (&timeOut) ; + timeOut.tv_usec = 1000 ; + timeradd (&now, &timeOut, &timeUp) ; + + while (digitalRead (pin) == HIGH) + { + gettimeofday (&now, NULL) ; + if (timercmp (&now, &timeUp, >)) + return FALSE ; + } + +// Wait for it to go HIGH + + gettimeofday (&now, NULL) ; + timerclear (&timeOut) ; + timeOut.tv_usec = 1000 ; + timeradd (&now, &timeOut, &timeUp) ; + + while (digitalRead (pin) == LOW) + { + gettimeofday (&now, NULL) ; + if (timercmp (&now, &timeUp, >)) + return FALSE ; + } + + return TRUE ; +} + + +/* + * maxDetectClockByte: + * Read in a single byte from the MaxDetect bus + ********************************************************************************* + */ + +static unsigned int maxDetectClockByte (const int pin) +{ + unsigned int byte = 0 ; + int bit ; + + for (bit = 0 ; bit < 8 ; ++bit) + { + if (!maxDetectLowHighWait (pin)) + return 0 ; + +// bit starting now - we need to time it. + + delayMicroseconds (30) ; + byte <<= 1 ; + if (digitalRead (pin) == HIGH) // It's a 1 + byte |= 1 ; + } + + return byte ; +} + + +/* + * maxDetectRead: + * Read in and return the 4 data bytes from the MaxDetect sensor. + * Return TRUE/FALSE depending on the checksum validity + ********************************************************************************* + */ + +int maxDetectRead (const int pin, unsigned char buffer [4]) +{ + int i ; + unsigned int checksum ; + unsigned char localBuf [5] ; + struct timeval now, then, took ; + +// See how long we took + + gettimeofday (&then, NULL) ; + +// Wake up the RHT03 by pulling the data line low, then high +// Low for 10mS, high for 40uS. + + pinMode (pin, OUTPUT) ; + digitalWrite (pin, 0) ; delay (10) ; + digitalWrite (pin, 1) ; delayMicroseconds (40) ; + pinMode (pin, INPUT) ; + +// Now wait for sensor to pull pin low + + if (!maxDetectLowHighWait (pin)) + return FALSE ; + +// and read in 5 bytes (40 bits) + + for (i = 0 ; i < 5 ; ++i) + localBuf [i] = maxDetectClockByte (pin) ; + + checksum = 0 ; + for (i = 0 ; i < 4 ; ++i) + { + buffer [i] = localBuf [i] ; + checksum += localBuf [i] ; + } + checksum &= 0xFF ; + +// See how long we took + + gettimeofday (&now, NULL) ; + timersub (&now, &then, &took) ; + +// Total time to do this should be: +// 10mS + 40µS - reset +// + 80µS + 80µS - sensor doing its low -> high thing +// + 40 * (50µS + 27µS (0) or 70µS (1) ) +// = 15010µS +// so if we take more than that, we've had a scheduling interruption and the +// reading is probably bogus. + + if ((took.tv_sec != 0) || (took.tv_usec > 16000)) + return FALSE ; + + return checksum == localBuf [4] ; +} + + +/* + * readRHT03: + * Read the Temperature & Humidity from an RHT03 sensor + * Values returned are *10, so 123 is 12.3. + ********************************************************************************* + */ + +int readRHT03 (const int pin, int *temp, int *rh) +{ + static struct timeval then ; // will initialise to zero + static int lastTemp = 0 ; + static int lastRh = 0 ; + + int result ; + struct timeval now, timeOut ; + unsigned char buffer [4] ; + +// The data sheets say to not read more than once every 2 seconds, so you +// get the last good reading + + gettimeofday (&now, NULL) ; + if (timercmp (&now, &then, <)) + { + *rh = lastRh ; + *temp = lastTemp ; + return TRUE ; + } + +// Set timeout for next read + + gettimeofday (&now, NULL) ; + timerclear (&timeOut) ; + timeOut.tv_sec = 2 ; + timeradd (&now, &timeOut, &then) ; + +// Read ... + + result = maxDetectRead (pin, buffer) ; + + if (!result) // Try again, but just once + result = maxDetectRead (pin, buffer) ; + + if (!result) + return FALSE ; + + *rh = (buffer [0] * 256 + buffer [1]) ; + *temp = (buffer [2] * 256 + buffer [3]) ; + + if ((*temp & 0x8000) != 0) // Negative + { + *temp &= 0x7FFF ; + *temp = -*temp ; + } + +// Discard obviously bogus readings - the checksum can't detect a 2-bit error +// (which does seem to happen - no realtime here) + + if ((*rh > 999) || (*temp > 800) || (*temp < -400)) + return FALSE ; + + lastRh = *rh ; + lastTemp = *temp ; + + return TRUE ; +} diff --git a/devLib/maxdetect.h b/devLib/maxdetect.h new file mode 100644 index 0000000..a1fd742 --- /dev/null +++ b/devLib/maxdetect.h @@ -0,0 +1,40 @@ +/* + * maxdetect.h: + * Driver for the MaxDetect series sensors + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + + +#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..cadbfe8 --- /dev/null +++ b/devLib/piFaceOld.c @@ -0,0 +1,177 @@ +/* + * piFace.: + * Copyright (c) 2012-2016 Gordon Henderson + * + * This file to interface with the PiFace peripheral device which + * has an MCP23S17 GPIO device connected via the SPI bus. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + + +#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/devLib/scrollPhat.c b/devLib/scrollPhat.c new file mode 100644 index 0000000..c1a6f11 --- /dev/null +++ b/devLib/scrollPhat.c @@ -0,0 +1,430 @@ +/* + * scrollPhat.c: + * Simple driver for the Pimoroni Scroll Phat device + * + * Copyright (c) 2015 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include +#include + +#include + +#include "scrollPhatFont.h" +#include "scrollPhat.h" + +// Size + +#define SP_WIDTH 11 +#define SP_HEIGHT 5 + +// I2C + +#define PHAT_I2C_ADDR 0x60 + +// Software copy of the framebuffer +// it's 8-bit deep although the display itself is only 1-bit deep. + +static unsigned char frameBuffer [SP_WIDTH * SP_HEIGHT] ; + +static int lastX, lastY ; +static int printDelayFactor ; +static int scrollPhatFd ; + +static int putcharX ; + +#undef DEBUG + + +/* + * delay: + * Wait for some number of milliseconds. + * This taken from wiringPi as there is no-need to include the whole of + * wiringPi just for the delay function. + ********************************************************************************* + */ + +static void delay (unsigned int howLong) +{ + struct timespec sleeper, dummy ; + + sleeper.tv_sec = (time_t)(howLong / 1000) ; + sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ; + + nanosleep (&sleeper, &dummy) ; +} + + + +/* + * scrollPhatUpdate: + * Copy our software version to the real display + ********************************************************************************* + */ + +void scrollPhatUpdate (void) +{ + register int x, y ; + register unsigned char data, pixel ; + unsigned char pixels [SP_WIDTH] ; + +#ifdef DEBUG + printf ("+-----------+\n") ; + for (y = 0 ; y < SP_HEIGHT ; ++y) + { + putchar ('|') ; + for (x = 0 ; x < SP_WIDTH ; ++x) + { + pixel = frameBuffer [x + y * SP_WIDTH] ; + putchar (pixel == 0 ? ' ' : '*') ; + } + printf ("|\n") ; + } + printf ("+-----------+\n") ; +#endif + + for (x = 0 ; x < SP_WIDTH ; ++x) + { + data = 0 ; + for (y = 0 ; y < SP_HEIGHT ; ++y) + { + pixel = frameBuffer [x + y * SP_WIDTH] ; + data = (data << 1) | ((pixel == 0) ? 0 : 1) ; + } + pixels [x] = data ; + } + + for (x = 0 ; x < SP_WIDTH ; ++x) + wiringPiI2CWriteReg8 (scrollPhatFd, 1 + x, pixels [x]) ; + + wiringPiI2CWriteReg8 (scrollPhatFd, 0x0C, 0) ; +} + + +/* + ********************************************************************************* + * Standard Graphical Functions + ********************************************************************************* + */ + + +/* + * scrollPhatPoint: + * Plot a pixel. Crude clipping - speed is not the essence here. + ********************************************************************************* + */ + +void scrollPhatPoint (int x, int y, int colour) +{ + lastX = x ; + lastY = y ; + + if ((x < 0) || (x >= SP_WIDTH) || (y < 0) || (y >= SP_HEIGHT)) + return ; + + frameBuffer [x + y * SP_WIDTH] = colour ; +} + + +/* + * scrollPhatLine: scrollPhatLineTo: + * Classic Bressenham Line code - rely on the point function to do the + * clipping for us here. + ********************************************************************************* + */ + +void scrollPhatLine (int x0, int y0, int x1, int y1, int colour) +{ + int dx, dy ; + int sx, sy ; + int err, e2 ; + + lastX = x1 ; + lastY = y1 ; + + dx = abs (x1 - x0) ; + dy = abs (y1 - y0) ; + + sx = (x0 < x1) ? 1 : -1 ; + sy = (y0 < y1) ? 1 : -1 ; + + err = dx - dy ; + + for (;;) + { + scrollPhatPoint (x0, y0, colour) ; + + if ((x0 == x1) && (y0 == y1)) + break ; + + e2 = 2 * err ; + + if (e2 > -dy) + { + err -= dy ; + x0 += sx ; + } + + if (e2 < dx) + { + err += dx ; + y0 += sy ; + } + } + +} + +void scrollPhatLineTo (int x, int y, int colour) +{ + scrollPhatLine (lastX, lastY, x, y, colour) ; +} + + +/* + * scrollPhatRectangle: + * A rectangle is a spoilt days fishing + ********************************************************************************* + */ + +void scrollPhatRectangle (int x1, int y1, int x2, int y2, int colour, int filled) +{ + register int x ; + + if (filled) + { + /**/ if (x1 == x2) + scrollPhatLine (x1, y1, x2, y2, colour) ; + else if (x1 < x2) + for (x = x1 ; x <= x2 ; ++x) + scrollPhatLine (x, y1, x, y2, colour) ; + else + for (x = x2 ; x <= x1 ; ++x) + scrollPhatLine (x, y1, x, y2, colour) ; + } + else + { + scrollPhatLine (x1, y1, x2, y1, colour) ; + scrollPhatLineTo (x2, y2, colour) ; + scrollPhatLineTo (x1, y2, colour) ; + scrollPhatLineTo (x1, y1, colour) ; + } +} + + +/* + * scrollPhatPutchar: + * Print a single character to the screen then advance the pointer by an + * appropriate ammount (variable width font). + * We rely on the clipping done by the pixel plot function to keep us + * out of trouble. + * Return the width + space + ********************************************************************************* + */ + +int scrollPhatPutchar (int c) +{ + register int x, y ; + + unsigned char line ; + unsigned char *fontPtr ; + unsigned char *p2 ; + int lineWidth, width, mask ; + +// The font is printable characters, uppercase only... +// and somewhat varaible width... + + c &= 0x7F ; + if (c > 0x60) + c -= 64 ; + else + c -= 32 ; + + fontPtr = scrollPhatFont + c * fontHeight ; + +// Work out width of this character +// There probably is a more efficient way to do this, but... + + p2 = fontPtr ; + width = 0 ; + for (y = 0 ; y < fontHeight ; ++y) + { + mask = 0x80 ; + for (lineWidth = 8 ; lineWidth > 0 ; --lineWidth) + { + if ((*p2 & mask) != 0) + break ; + mask >>= 1 ; + } + if (lineWidth > width) + width = lineWidth ; + + ++p2 ; + } + + if (width == 0) // Likely to be a blank or space character + width = 3 ; + + for (y = fontHeight - 1 ; y >= 0 ; --y) + { + x = 0 ; + line = *fontPtr++ ; + for (mask = 1 << (width - 1) ; mask != 0 ; mask >>= 1) + { + scrollPhatPoint (putcharX + x, y, (line & mask)) ; + ++x ; + } + } + +// make a line of space + + for (y = fontHeight - 1 ; y >= 0 ; --y) + scrollPhatPoint (putcharX + width, y, 0) ; + + putcharX = putcharX + width + 1 ; + + return width + 1 ; +} + + +/* + * scrollPhatPuts: + * Send a string to the display - and scroll it across. + * This is somewhat of a hack in that we print the entire string to the + * display and let the point clipping take care of what's off-screen... + ********************************************************************************* + */ + +void scrollPhatPuts (const char *str) +{ + int i ; + int movingX = 0 ; + const char *s ; + int pixelLen ; + +// Print it once, then we know the width in pixels... + + putcharX = 0 ; + s = str ; + while (*s) + scrollPhatPutchar (*s++) ; + + pixelLen = putcharX ; + +// Now scroll it by printing it and moving left one pixel + + movingX = 0 ; + for (i = 0 ; i < pixelLen ; ++i) + { + putcharX = movingX ; + s = str ; + while (*s) + scrollPhatPutchar (*s++) ; + --movingX ; + scrollPhatUpdate () ; + delay (printDelayFactor) ; + } +} + + +/* + * scrollPhatPrintf: + * Does what it says + ********************************************************************************* + */ + +void scrollPhatPrintf (const char *message, ...) +{ + va_list argp ; + char buffer [1024] ; + + va_start (argp, message) ; + vsnprintf (buffer, 1023, message, argp) ; + va_end (argp) ; + + scrollPhatPuts (buffer) ; +} + + +/* + * scrollPhatPrintSpeed: + * Change the print speed - mS per shift by 1 pixel + ********************************************************************************* + */ + +void scrollPhatPrintSpeed (const int pps) +{ + if (pps < 0) + printDelayFactor = 0 ; + else + printDelayFactor = pps ; +} + + +/* + * scrollPhatClear: + * Clear the display + ********************************************************************************* + */ + +void scrollPhatClear (void) +{ + register int i ; + register unsigned char *ptr = frameBuffer ; + + for (i = 0 ; i < (SP_WIDTH * SP_HEIGHT) ; ++i) + *ptr++ = 0 ; + + scrollPhatUpdate () ; +} + + +/* + * scrollPhatIntensity: + * Set the display brightness - percentage + ********************************************************************************* + */ + +void scrollPhatIntensity (const int percent) +{ + wiringPiI2CWriteReg8 (scrollPhatFd, 0x19, (127 * percent) / 100) ; +} + + +/* + * scrollPhatSetup: + * Initialise the Scroll Phat display + ********************************************************************************* + */ + +int scrollPhatSetup (void) +{ + if ((scrollPhatFd = wiringPiI2CSetup (PHAT_I2C_ADDR)) < 0) + return scrollPhatFd ; + + wiringPiI2CWriteReg8 (scrollPhatFd, 0x00, 0x03) ; // Enable display, set to 5x11 mode + scrollPhatIntensity (10) ; + scrollPhatClear () ; + scrollPhatPrintSpeed (100) ; + + return 0 ; +} diff --git a/devLib/scrollPhat.h b/devLib/scrollPhat.h new file mode 100644 index 0000000..0e762b1 --- /dev/null +++ b/devLib/scrollPhat.h @@ -0,0 +1,39 @@ +/* + * scrollPhat.h: + * Simple driver for the Pimoroni Scroll Phat device + * + * Copyright (c) 2015 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +extern void scrollPhatPoint (int x, int y, int colour) ; +extern void scrollPhatLine (int x0, int y0, int x1, int y1, int colour) ; +extern void scrollPhatLineTo (int x, int y, int colour) ; +extern void scrollPhatRectangle (int x1, int y1, int x2, int y2, int colour, int filled) ; +extern void scrollPhatUpdate (void) ; +extern void scrollPhatClear (void) ; + +extern int scrollPhatPutchar (int c) ; +//extern void scrollPhatPutchar (int c) ; +extern void scrollPhatPuts (const char *str) ; +extern void scrollPhatPrintf (const char *message, ...) ; +extern void scrollPhatPrintSpeed (const int cps10) ; + +extern void scrollPhatIntensity (const int percent) ; +extern int scrollPhatSetup (void) ; diff --git a/devLib/scrollPhatFont.h b/devLib/scrollPhatFont.h new file mode 100644 index 0000000..92f623a --- /dev/null +++ b/devLib/scrollPhatFont.h @@ -0,0 +1,544 @@ +/* + * scrollPhatFont.h: + * Simple font for the Pimoroni Scroll Phat. + * Note: this is a very much reduced font - 5 pixels high and + * mostly 4 pixels wide - sometimes 5. Also only + * printable characters from space to _ uppercase only. + * + * Copyright (c) 2015-2016 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +static const int fontHeight = 5 ; + +static unsigned char scrollPhatFont [] = +{ + +// 0x20, Space. Handeled as a special case in the code. + + 0x0, // .... + 0x0, // .... + 0x0, // .... + 0x0, // .... + 0x0, // .... + +// 0x21, ! + + 0x1, // * + 0x1, // * + 0x1, // * + 0x0, // . + 0x1, // * + +// 0x22, " + + 0x5, // *..* + 0x5, // *..* + 0x0, // .... + 0x0, // .... + 0x0, // .... + +// 0x23, # + + 0x9, // *..* + 0xF, // **** + 0x9, // *..* + 0xF, // **** + 0x9, // *..* + +// 0x24, $ + + 0x1, // ..*. + 0x7, // .*** + 0x2, // ..*. + 0xE, // ***. + 0x8, // ..*. + +// 0x25, % + + 0x9, // *..* + 0x1, // ...* + 0x6, // .**. + 0x8, // *... + 0x9, // *..* + +// 0x26, & + + 0x6, // .**. + 0x8, // *... + 0x4, // .*.. + 0xA, // *.*. + 0x5, // .*.* + +// 0x27, ' + + 0x1, // .* + 0x2, // *. + 0x0, // .. + 0x0, // .. + 0x0, // .. + +// 0x28, ( + + 0x3, // ..** + 0x4, // .*.. + 0x8, // *... + 0x4, // .*.. + 0x3, // ..** + +// 0x29, ) + + 0xC, // **.. + 0x2, // ..*. + 0x1, // ...* + 0x2, // ..*. + 0xC, // **.. + +// 0x2A, * + + 0x9, // *..* + 0x6, // .**. + 0xF, // **** + 0x6, // .**. + 0x9, // *..* + +// 0x2B, + + + 0x6, // .**. + 0x6, // .**. + 0xF, // **** + 0x6, // .**. + 0x6, // .**. + +// 0x2C, , + + 0x0, // .. + 0x0, // .. + 0x0, // .. + 0x1, // .* + 0x2, // *. + +// 0x2D, - + + 0x0, // .... + 0x0, // .... + 0xF, // **** + 0x0, // .... + 0x0, // .... + +// 0x2E, . + + 0x0, // . + 0x0, // . + 0x0, // . + 0x0, // . + 0x1, // * + +// 0x2F, / + + 0x1, // ...* + 0x3, // ..** + 0x4, // ..*. + 0xC, // **.. + 0x8, // *... + +// 0x30, 0 + + 0x6, // .**. + 0x9, // *..* + 0x9, // *..* + 0x9, // *..* + 0x6, // .**. + +// 0x31, 1 + + 0x2, // ..*. + 0x6, // .**. + 0x2, // ..*. + 0x2, // ..*. + 0x7, // .*** + +// 0x32, 2 + + 0x6, // .**. + 0x1, // ...* + 0x6, // .**. + 0x8, // *... + 0xF, // **** + +// 0x33, 3 + + 0xE, // ***. + 0x1, // ...* + 0xE, // ***. + 0x1, // ...* + 0xE, // ***. + +// 0x34, 4 + + 0x6, // .**. + 0xA, // *.*. + 0xF, // **** + 0x2, // ..*. + 0x2, // ..*. + +// 0x35, 5 + + 0xF, // **** + 0x8, // *... + 0xF, // **** + 0x1, // ...* + 0xE, // ***. + +// 0x36, 6 + + 0x2, // ..*. + 0x4, // .*.. + 0xA, // *.*. + 0x9, // *..* + 0x6, // .**. + +// 0x37, 7 + + 0xF, // **** + 0x1, // ...* + 0x2, // ..*. + 0x4, // .*.. + 0x8, // *... + +// 0x38, 8 + + 0x6, // .**. + 0x9, // *..* + 0x6, // .**. + 0x9, // *..* + 0x6, // .**. + +// 0x39, 9 + + 0x6, // .**. + 0x9, // *..* + 0x7, // .*.* + 0x1, // ..*. + 0x2, // .*.. + +// 0x3A, : + + 0x0, // . + 0x1, // * + 0x0, // . + 0x1, // * + 0x0, // . + +// 0x3B, ; + + 0x0, // .. + 0x1, // .* + 0x0, // .. + 0x1, // .* + 0x2, // *. + +// 0x3C, < + + 0x2, // ..*. + 0x4, // .*.. + 0x8, // *... + 0x4, // .*.. + 0x2, // ..*. + +// 0x3D, = + + 0x0, // .... + 0xF, // **** + 0x0, // .... + 0xF, // **** + 0x0, // .... + +// 0x3E, > + + 0x0, // .*.. + 0x0, // ..*. + 0x0, // ...* + 0x0, // ..*. + 0x0, // .*.. + +// 0x3F, ? + + 0x6, // .**. + 0x1, // ...* + 0x2, // ..*. + 0x0, // .... + 0x2, // ..*. + +// 0x40, @ + + 0x6, // .**. + 0xD, // **.* + 0x8, // *... + 0x4, // .*.. + 0x3, // ..** + +// 0x41, A + + 0x6, // .**. + 0x9, // *..* + 0xF, // **** + 0x9, // *..* + 0x9, // *..* + +// 0x42, B + + 0xE, // ***. + 0x9, // *..* + 0xE, // ***. + 0x9, // *..* + 0xE, // ***. + +// 0x43, C + + 0x6, // .**. + 0x9, // *..* + 0x8, // *... + 0x9, // *..* + 0x6, // .**. + +// 0x44, D + + 0xE, // ***. + 0x9, // *..* + 0x9, // *..* + 0x9, // *..* + 0xE, // ***. + +// 0x45, E + + 0xF, // **** + 0x8, // *... + 0xE, // ***. + 0x8, // *... + 0xF, // **** + +// 0x46, F + + 0xF, // **** + 0x8, // *... + 0xE, // ***. + 0x8, // *... + 0x8, // *... + +// 0x47, G + + 0x6, // .**. + 0x9, // *..* + 0x8, // *... + 0xB, // *.** + 0x6, // .**. + +// 0x48, H + + 0x9, // *..* + 0x9, // *..* + 0xF, // **** + 0x9, // *..* + 0x9, // *..* + +// 0x49, I + + 0x7, // *** + 0x2, // .*. + 0x2, // .*. + 0x2, // .*. + 0x7, // *** + +// 0x4A, J + + 0x7, // .*** + 0x2, // ..*. + 0x2, // ..*. + 0xA, // *.*. + 0x4, // .*.. + +// 0x4B, K + + 0x9, // *..* + 0xA, // *.*. + 0xC, // **.. + 0xA, // *.*. + 0x9, // *..* + +// 0x4C, L + + 0x4, // *.. + 0x4, // *.. + 0x4, // *.. + 0x4, // *.. + 0x7, // *** + +// 0x4D, M + + 0x11, // *...* + 0x1B, // **.** + 0x15, // *.*.* + 0x11, // *...* + 0x11, // *...* + +// 0x4E, N + + 0x9, // *..* + 0xD, // **.* + 0xB, // *.** + 0x9, // *..* + 0x9, // *..* + +// 0x4F, O + + 0x6, // .**. + 0x9, // *..* + 0x9, // *..* + 0x9, // *..* + 0x6, // .**. + +// 0x50, P + + 0xE, // ***. + 0x9, // *..* + 0xE, // ***. + 0x8, // *... + 0x8, // *... + +// 0x51, Q + + 0x6, // .**. + 0x9, // *..* + 0x9, // *..* + 0xA, // *.*. + 0x5, // .*.* + +// 0x52, R + + 0xE, // ***. + 0x9, // *..* + 0xF, // ***. + 0xA, // *.*. + 0x9, // *..* + +// 0x53, S + + 0x6, // .**. + 0x8, // *... + 0x6, // .**. + 0x1, // ...* + 0x6, // .**. + +// 0x54, T + + 0x7, // .*** + 0x2, // ..*. + 0x2, // ..*. + 0x2, // ..*. + 0x2, // ..*. + +// 0x55, U + + 0x9, // *..* + 0x9, // *..* + 0x9, // *..* + 0x9, // *..* + 0x6, // .**. + +// 0x56, V + + 0x11, // *...* + 0x11, // *...* + 0x11, // *...* + 0x0A, // .*.*. + 0x04, // ..*.. + +// 0x57, W + + 0x11, // *...* + 0x11, // *...* + 0x11, // *...* + 0x15, // *.*.* + 0x1B, // **.** + +// 0x58, X + + 0x9, // *..* + 0x9, // *..* + 0x6, // .**. + 0x9, // *..* + 0x9, // *..* + +// 0x59, Y + + 0x11, // *...* + 0x0A, // .*.*. + 0x04, // ..*.. + 0x04, // ..*.. + 0x04, // ..*.. + +// 0x5A, Z + + 0xF, // **** + 0x1, // ...* + 0x6, // .**. + 0x8, // *... + 0xF, // **** + +// 0x5B, [ + + 0xE, // ***. + 0x8, // *... + 0x8, // *... + 0x8, // *... + 0xE, // ***. + +// 0x5C, Backslash + + 0x8, // *... + 0xC, // **.. + 0x6, // .**. + 0x3, // ..** + 0x1, // ...* + +// 0x5D, ] + + 0x7, // .*** + 0x1, // ...* + 0x1, // ...* + 0x1, // ...* + 0x7, // .*** + +// 0x5E, ^ + + 0x6, // .**. + 0x9, // *..* + 0x0, // .... + 0x0, // .... + 0x0, // .... + +// 0x5F, _ + + 0x0, // .... + 0x0, // .... + 0x0, // .... + 0x0, // .... + 0xF, // **** +} ; diff --git a/examples/COPYING.LESSER b/examples/COPYING.LESSER new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/examples/COPYING.LESSER @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. 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 new file mode 100644 index 0000000..2dbdd72 --- /dev/null +++ b/examples/Makefile @@ -0,0 +1,197 @@ +# +# Makefile: +# wiringPi - A "wiring" library for the Raspberry Pi +# https://projects.drogon.net/wiring-pi +# +# Copyright (c) 2012-2015 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# 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 -lcrypt -lrt + +# Should not alter anything below this line +############################################################################### + +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 \ + w25q64_test.c oled_demo.c spiSpeed.c \ + watchdog.c spidev_test.c spidev_test_linux3_4.c + +OBJ = $(SRC:.c=.o) + +BINS = $(SRC:.c=) + +all: + $Q cat README.TXT + $Q echo " $(BINS)" | fmt + $Q echo "" + +really-all: $(BINS) + +blink: blink.o + $Q echo [link] + $Q $(CC) -o $@ blink.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 + $Q echo [link] + $Q $(CC) -o $@ speed.o $(LDFLAGS) $(LDLIBS) + +lcd: lcd.o + $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 + $Q echo [link] + $Q $(CC) -o $@ wfi.o $(LDFLAGS) $(LDLIBS) + +isr: isr.o + $Q echo [link] + $Q $(CC) -o $@ isr.o $(LDFLAGS) $(LDLIBS) + +isr-osc: isr-osc.o + $Q echo [link] + $Q $(CC) -o $@ isr-osc.o $(LDFLAGS) $(LDLIBS) + +nes: nes.o + $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 + $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 + $Q echo [link] + $Q $(CC) -o $@ delayTest.o $(LDFLAGS) $(LDLIBS) + +serialRead: serialRead.o + $Q echo [link] + $Q $(CC) -o $@ serialRead.o $(LDFLAGS) $(LDLIBS) + +serialTest: serialTest.o + $Q echo [link] + $Q $(CC) -o $@ serialTest.o $(LDFLAGS) $(LDLIBS) + +okLed: okLed.o + $Q echo [link] + $Q $(CC) -o $@ okLed.o $(LDFLAGS) $(LDLIBS) + +tone: tone.o + $Q echo [link] + $Q $(CC) -o $@ tone.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) + +w25q64_test: w25q64_test.o + $Q echo [link] + $Q $(CC) -o $@ w25q64_test.o $(LDFLAGS) $(LDLIBS) + +watchdog: watchdog.o + $Q echo [link] + $Q $(CC) -o $@ watchdog.o $(LDFLAGS) $(LDLIBS) + +spidev_test: spidev_test.o + $Q echo [link] + $Q $(CC) -o $@ spidev_test.o $(LDFLAGS) $(LDLIBS) + +spidev_test_linux3_4: spidev_test_linux3_4.o + $Q echo [link] + $Q $(CC) -o $@ spidev_test_linux3_4.o $(LDFLAGS) $(LDLIBS) + +oled_demo: oled_demo.o + $Q echo [link] + $Q $(CC) -o $@ oled_demo.o $(LDFLAGS) $(LDLIBS) + +spiSpeed: spiSpeed.o + $Q echo [link] + $Q $(CC) -o $@ spiSpeed.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/Makefile b/examples/PiFace/Makefile new file mode 100644 index 0000000..f937c14 --- /dev/null +++ b/examples/PiFace/Makefile @@ -0,0 +1,88 @@ +# +# Makefile: +# wiringPi - A "wiring" library for the Raspberry Pi +# https://projects.drogon.net/wiring-pi +# +# Copyright (c) 2012 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# A "wiring" library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + +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..f182db7 --- /dev/null +++ b/examples/PiGlow/Makefile @@ -0,0 +1,82 @@ +# +# Makefile: +# wiringPi - A "wiring" library for the Raspberry Pi +# https://projects.drogon.net/wiring-pi +# +# Copyright (c) 2012-2015 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# A "wiring" library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + +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/README.TXT b/examples/README.TXT new file mode 100644 index 0000000..33263b1 --- /dev/null +++ b/examples/README.TXT @@ -0,0 +1,18 @@ + +wiringPi Examples +================= + +There are now too many examples to compile them all in a sensible time, +and you probably don't want to compile or run them all anyway, so they +have been separated out. + +To compile an individual example, just type + + make exampleName + +To really compile everything: + + make really-all + +The individual tests are: + diff --git a/examples/blink-thread.c b/examples/blink-thread.c new file mode 100644 index 0000000..a53fbf3 --- /dev/null +++ b/examples/blink-thread.c @@ -0,0 +1,61 @@ +/* + * blink-thread.c: + * Standard "blink" program in wiringPi. Blinks an LED connected + * to the first GPIO pin. + * + * 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 + +// LED Pin - wiringPi pin 0 is BCM_GPIO 17. + +#define LED 0 + +PI_THREAD (blinky) +{ + for (;;) + { + digitalWrite (LED, HIGH) ; // On + delay (500) ; // mS + digitalWrite (LED, LOW) ; // Off + delay (500) ; + } +} + + +int main (void) +{ + printf ("Raspberry Pi blink\n") ; + + wiringPiSetup () ; + pinMode (LED, OUTPUT) ; + + piThreadCreate (blinky) ; + + for (;;) + { + printf ("Hello, world\n") ; + delay (600) ; + } + + return 0 ; +} diff --git a/examples/blink.c b/examples/blink.c new file mode 100644 index 0000000..7181295 --- /dev/null +++ b/examples/blink.c @@ -0,0 +1,31 @@ +#include +#include + +#define NUM 17 //26pin +//#define NUM 18 //26pin +//#define NUM 20 //for Orange Pi Zero 2 +//#define NUM 19 //for Orange Pi 4 +//#define NUM 28 //40pin + +int main (void) +{ + int i = 0; + + wiringPiSetup () ; + + for (i = 0; i < NUM; i++) + pinMode (i, OUTPUT) ; + + for ( ;; ) + { + for (i = 0; i < NUM; i++) + digitalWrite (i, HIGH) ; // On + delay (2000) ; // mS + + for (i = 0; i < NUM; i++) + digitalWrite (i, LOW) ; // Off + delay (2000) ; + } + + return 0; +} diff --git a/examples/blink.rtb b/examples/blink.rtb new file mode 100644 index 0000000..eb7d26c --- /dev/null +++ b/examples/blink.rtb @@ -0,0 +1,30 @@ +// blink.rtb: +// Blink program in Return to Basic +// +// 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 . + *********************************************************************** +// +PinMode (0, 1) // Output +CYCLE + DigitalWrite (0, 1) // Pin 0 ON + WAIT (0.5) // 0.5 seconds + DigitalWrite (0, 0) + WAIT (0.5) +REPEAT +END diff --git a/examples/blink.sh b/examples/blink.sh new file mode 100644 index 0000000..3975bb7 --- /dev/null +++ b/examples/blink.sh @@ -0,0 +1,37 @@ +#!/bin/sh -e +# +# blink.sh: +# Standard "blink" program in wiringPi. Blinks an LED connected +# to the first GPIO pin. +# +# 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 0 is BCM_GPIO 17. + +PIN=0 + +gpio mode $PIN out + +while true; do + gpio write $PIN 1 + sleep 0.5 + gpio write $PIN 0 + sleep 0.5 +done 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-drcn.c b/examples/blink8-drcn.c new file mode 100644 index 0000000..96c775b --- /dev/null +++ b/examples/blink8-drcn.c @@ -0,0 +1,61 @@ +/* + * blink8-drcn.c: + * Simple sequence over the first 8 GPIO pins - LEDs + * Aimed at the Ladder board, but it's fairly generic. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General 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 (void) +{ + int i, led ; + + printf ("Raspberry Pi - 8-LED Sequencer\n") ; + printf ("==============================\n") ; + printf ("\n") ; + printf ("Connect LEDs to the first 8 GPIO pins and watch ...\n") ; + + int pinBase = 100 ; + +// wiringPiSetup () ; + drcSetupNet (pinBase, 100, "192.168.254.21", "6124", "123456") ; + + for (i = 0 ; i < 8 ; ++i) + pinMode (i + pinBase, OUTPUT) ; + + for (;;) + { + for (led = 0 ; led < 8 ; ++led) + { + digitalWrite (led + pinBase, 1) ; + delay (10) ; + } + + for (led = 0 ; led < 8 ; ++led) + { + digitalWrite (led + pinBase, 0) ; + delay (10) ; + } + } +} diff --git a/examples/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/delayTest.c b/examples/delayTest.c new file mode 100644 index 0000000..d772cf9 --- /dev/null +++ b/examples/delayTest.c @@ -0,0 +1,102 @@ +/* + * delayTest.c: + * Just a little test program I'm using to experiment with + * various timings and latency, etc. + * + * 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 CYCLES 1000 + +int main() +{ + int x ; + struct timeval t1, t2, t3 ; + int t ; + int max, min ; + int del ; + int underRuns, overRuns, exactRuns, bogusRuns, total ; + int descheds ; + + +// Baseline test + + gettimeofday (&t1, NULL) ; + gettimeofday (&t2, NULL) ; + + t = t2.tv_usec - t1.tv_usec ; + printf ("Baseline test: %d\n", t); + + for (del = 1 ; del < 200 ; ++del) + { + underRuns = overRuns = exactRuns = total = 0 ; + descheds = 0 ; + max = 0 ; + min = 999 ; + + for (x = 0 ; x < CYCLES ; ++x) + { + for (;;) // Repeat this if we get a delay over 999uS + { // -> High probability Linux has deschedulled us + gettimeofday (&t1, NULL) ; + usleep (del) ; +// delayMicroseconds (del) ; + gettimeofday (&t2, NULL) ; + + timersub (&t2, &t1, &t3) ; + + t = t3.tv_usec ; + + if (t > 999) + { + ++descheds ; + continue ; + } + else + break ; + } + + if (t == del) + ++exactRuns ; + else if (t < del) + ++underRuns ; + else if (t > del) + ++overRuns ; + + if (t > max) + max = t ; + else if (t < min) + min = t ; + + total += t ; + } + printf ("Delay: %3d. Min: %3d, Max: %3d, Unders: %3d, Overs: %3d, Exacts: %3d, Average: %3d, Descheds: %2d\n", + del, min, max, underRuns, overRuns, exactRuns, total / CYCLES, descheds) ; + fflush (stdout) ; + usleep (1000) ; + } + + 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/header.h b/examples/header.h new file mode 100644 index 0000000..82f723d --- /dev/null +++ b/examples/header.h @@ -0,0 +1,23 @@ +/* + * file.c: + * + * 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 . + *********************************************************************** + */ + diff --git a/examples/isr-osc.c b/examples/isr-osc.c new file mode 100644 index 0000000..a872ee3 --- /dev/null +++ b/examples/isr-osc.c @@ -0,0 +1,118 @@ +/* + * isr-osc.c: + * Wait for Interrupt test program - ISR method - interrupt oscillator + * + * How to test: + * + * IMPORTANT: To run this test we connect 2 GPIO pins together, but + * before we do that YOU must make sure that they are both setup + * the right way. If they are set to outputs and one is high and one low, + * then you connect the wire, you'll create a short and that won't be good. + * + * Before making the connection, type: + * gpio mode 0 output + * gpio write 0 0 + * gpio mode 1 input + * then you can connect them together. + * + * Run the program, then: + * gpio write 0 1 + * gpio write 0 0 + * + * at which point it will trigger an interrupt and the program will + * then do the up/down toggling for itself and run at full speed, and + * it will report the number of interrupts recieved every second. + * + * Copyright (c) 2013 Gordon Henderson. projects@drogon.net + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include +#include + + +// What GPIO input are we using? +// This is a wiringPi pin number + +#define OUT_PIN 0 +#define IN_PIN 1 + +// globalCounter: +// Global variable to count interrupts +// Should be declared volatile to make sure the compiler doesn't cache it. + +static volatile int globalCounter = 0 ; + +/* + * myInterrupt: + ********************************************************************************* + */ + +void myInterrupt (void) +{ + digitalWrite (OUT_PIN, 1) ; + ++globalCounter ; + digitalWrite (OUT_PIN, 0) ; +} + + +/* + ********************************************************************************* + * main + ********************************************************************************* + */ + +int main (void) +{ + int myCounter = 0 ; + int lastCounter = 0 ; + + if (wiringPiSetup () < 0) + { + fprintf (stderr, "Unable to setup wiringPi: %s\n", strerror (errno)) ; + return 1 ; + } + + pinMode (OUT_PIN, OUTPUT) ; + pinMode (IN_PIN, INPUT) ; + + if (wiringPiISR (IN_PIN, INT_EDGE_FALLING, &myInterrupt) < 0) + { + fprintf (stderr, "Unable to setup ISR: %s\n", strerror (errno)) ; + return 1 ; + } + + for (;;) + { + printf ("Waiting ... ") ; fflush (stdout) ; + + while (myCounter == globalCounter) + delay (1000) ; + + printf (" Done. counter: %6d: %6d\n", + globalCounter, myCounter - lastCounter) ; + lastCounter = myCounter ; + myCounter = globalCounter ; + } + + return 0 ; +} diff --git a/examples/isr.c b/examples/isr.c new file mode 100644 index 0000000..abc6aec --- /dev/null +++ b/examples/isr.c @@ -0,0 +1,110 @@ +/* + * isr.c: + * Wait for Interrupt test program - ISR method + * + * How to test: + * Use the SoC's pull-up and pull down resistors that are avalable + * on input pins. So compile & run this program (via sudo), then + * in another terminal: + * gpio mode 0 up + * gpio mode 0 down + * at which point it should trigger an interrupt. Toggle the pin + * up/down to generate more interrupts to test. + * + * 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 + + +// globalCounter: +// Global variable to count interrupts +// Should be declared volatile to make sure the compiler doesn't cache it. + +static volatile int globalCounter [8] ; + + +/* + * myInterrupt: + ********************************************************************************* + */ + +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] ; } + + +/* + ********************************************************************************* + * main + ********************************************************************************* + */ + +int main (void) +{ + int gotOne, pin ; + int myCounter [8] ; + + for (pin = 0 ; pin < 8 ; ++pin) + globalCounter [pin] = myCounter [pin] = 0 ; + + 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) ; + + 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 new file mode 100644 index 0000000..510f562 --- /dev/null +++ b/examples/lcd.c @@ -0,0 +1,286 @@ +/* + * lcd.c: + * Text-based LCD driver. + * This is designed to drive the parallel interface LCD drivers + * based in the Hitachi HD44780U controller and compatables. + * + * 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/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General 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 + +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 ; + + char buf [32] ; + + if (argc != 4) + return usage (argv [0]) ; + + printf ("Raspberry Pi LCD test\n") ; + printf ("=====================\n") ; + + bits = atoi (argv [1]) ; + cols = atoi (argv [2]) ; + rows = atoi (argv [3]) ; + + if (!((rows == 1) || (rows == 2) || (rows == 4))) + { + fprintf (stderr, "%s: rows must be 1, 2 or 4\n", argv [0]) ; + return EXIT_FAILURE ; + } + + if (!((cols == 16) || (cols == 20))) + { + fprintf (stderr, "%s: cols must be 16 or 20\n", argv [0]) ; + return EXIT_FAILURE ; + } + + wiringPiSetup () ; + + 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) ; + + if (lcdHandle < 0) + { + fprintf (stderr, "%s: lcdInit failed\n", argv [0]) ; + return -1 ; + } + + lcdPosition (lcdHandle, 0, 0) ; lcdPuts (lcdHandle, "Gordon Henderson") ; + lcdPosition (lcdHandle, 0, 1) ; lcdPuts (lcdHandle, " wiringpi.com ") ; + + 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 (;;) + { + scrollMessage (0, cols) ; + + if (rows == 1) + continue ; + + tim = time (NULL) ; + t = localtime (&tim) ; + + sprintf (buf, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ; + + lcdPosition (lcdHandle, (cols - 8) / 2, 1) ; + lcdPuts (lcdHandle, buf) ; + + if (rows == 2) + continue ; + + 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/nes.c b/examples/nes.c new file mode 100644 index 0000000..31908e8 --- /dev/null +++ b/examples/nes.c @@ -0,0 +1,67 @@ +/* + * nes.c: + * Test program for an old NES controller connected to the Pi. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General 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 BLANK "| " + +int main () +{ + int joystick ; + unsigned int buttons ; + + if (wiringPiSetup () == -1) + { + fprintf (stdout, "oops: %s\n", strerror (errno)) ; + return 1 ; + } + + if ((joystick = setupNesJoystick (2, 1, 0)) == -1) + { + fprintf (stdout, "Unable to setup joystick\n") ; + return 1 ; + } + + for (;;) + { + buttons = readNesJoystick (joystick) ; + + if ((buttons & NES_UP) != 0) printf ("| UP " ) ; else printf (BLANK) ; + if ((buttons & NES_DOWN) != 0) printf ("| DOWN " ) ; else printf (BLANK) ; + if ((buttons & NES_LEFT) != 0) printf ("| LEFT " ) ; else printf (BLANK) ; + if ((buttons & NES_RIGHT) != 0) printf ("|RIGHT " ) ; else printf (BLANK) ; + if ((buttons & NES_SELECT) != 0) printf ("|SELECT" ) ; else printf (BLANK) ; + if ((buttons & NES_START) != 0) printf ("|START " ) ; else printf (BLANK) ; + if ((buttons & NES_A) != 0) printf ("| A " ) ; else printf (BLANK) ; + if ((buttons & NES_B) != 0) printf ("| B " ) ; else printf (BLANK) ; + printf ("|\n") ; + } + + return 0 ; +} diff --git a/examples/okLed.c b/examples/okLed.c new file mode 100644 index 0000000..930f266 --- /dev/null +++ b/examples/okLed.c @@ -0,0 +1,82 @@ +/* + * okLed.c: + * Make the OK LED on the Pi Pulsate... + * + * Originally posted to the Raspberry Pi forums: + * http://www.raspberrypi.org/phpBB3/viewtopic.php?p=162581#p162581 + * + * Compile this and store it somewhere, then kick it off at boot time + * e.g. by putting it in /etc/rc.local and running it in the + * background & + * + * 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 + +// 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) ; + + softPwmCreate (OK_LED, 0, 100) ; + + for (;;) + { + for (i = 0 ; i <= 100 ; ++i) + { + softPwmWrite (OK_LED, i) ; + delay (10) ; + } + delay (50) ; + + for (i = 100 ; i >= 0 ; --i) + { + softPwmWrite (OK_LED, i) ; + delay (10) ; + } + delay (10) ; + } + + return 0 ; +} diff --git a/examples/oled_demo.c b/examples/oled_demo.c new file mode 100644 index 0000000..93c1e30 --- /dev/null +++ b/examples/oled_demo.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2015, Vladimir Komendantskiy + * MIT License + * + * SSD1306 demo of block and font drawing. + */ + +// +// fixed for OrangePiZero by HypHop +// + +#include +#include +#include +#include +#include +#include + +#include "oled.h" +#include "font.h" + +int oled_demo(struct display_info *disp) { + int i; + char buf[100]; + + //putstrto(disp, 0, 0, "Spnd spd 2468 rpm"); + // oled_putstrto(disp, 0, 9+1, "Spnd cur 0.46 A"); + oled_putstrto(disp, 0, 9+1, "Welcome to"); + disp->font = font1; + // oled_putstrto(disp, 0, 18+2, "Spnd tmp 53 C"); + oled_putstrto(disp, 0, 18+2, "----OrangePi----"); + disp->font = font2; + // oled_putstrto(disp, 0, 27+3, "DrvX tmp 64 C"); + oled_putstrto(disp, 0, 27+3, "This is 0.96OLED"); + oled_putstrto(disp, 0, 36+4, ""); + oled_putstrto(disp, 0, 45+5, ""); + disp->font = font1; + // oled_putstrto(disp, 0, 54, "Total cur 2.36 A"); + oled_putstrto(disp, 0, 54, "*****************"); + oled_send_buffer(disp); + + disp->font = font3; + for (i=0; i<100; i++) { + sprintf(buf, "Spnd spd %d rpm", i); + oled_putstrto(disp, 0, 0, buf); + oled_putstrto(disp, 135-i, 36+4, "==="); + oled_putstrto(disp, 100, 0+i/2, "."); + oled_send_buffer(disp); + } + //oled_putpixel(disp, 60, 45); + //oled_putstr(disp, 1, "hello"); + +return 0; +} + +void show_error(int err, int add) { + //const gchar* errmsg; + //errmsg = g_strerror(errno); + printf("\nERROR: %i, %i\n\n", err, add); + //printf("\nERROR\n"); +} + +void show_usage(char *progname) { + printf("\nUsage:\n%s \n", progname); +} + +int main(int argc, char **argv) { + int e; + char filename[32]; + struct display_info disp; + + if (argc < 2) { + show_usage(argv[0]); + + return -1; + } + + memset(&disp, 0, sizeof(disp)); + sprintf(filename, "%s", argv[1]); + disp.address = OLED_I2C_ADDR; + disp.font = font2; + + e = oled_open(&disp, filename); + + if (e < 0) { + show_error(1, e); + } else { + e = oled_init(&disp); + if (e < 0) { + show_error(2, e); + } else { + printf("---------start--------\n"); + if (oled_demo(&disp) < 0) + show_error(3, 777); + printf("----------end---------\n"); + } + } + + return 0; +} diff --git a/examples/pwm.c b/examples/pwm.c new file mode 100644 index 0000000..06483b9 --- /dev/null +++ b/examples/pwm.c @@ -0,0 +1,44 @@ +/* + * pwm.c: + * This tests the hardware PWM channel. + * + * 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 + +#define PWM_PIN 29 + +int main (void) +{ + printf ("OrangePi Pi wiringPi PWM test program\n") ; + + if (wiringPiSetup () == -1) + exit (1) ; + + pinMode (PWM_PIN, PWM_OUTPUT) ; + pwmWrite (PWM_PIN, 500) ; + + return 0 ; +} diff --git a/examples/q2w/Makefile b/examples/q2w/Makefile new file mode 100644 index 0000000..8f773bf --- /dev/null +++ b/examples/q2w/Makefile @@ -0,0 +1,84 @@ +# +# Makefile: +# wiringPi - A "wiring" library for the Raspberry Pi +# https://projects.drogon.net/wiring-pi +# +# Copyright (c) 2012-2013 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# A "wiring" library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + +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..854f837 --- /dev/null +++ b/examples/rht03.c @@ -0,0 +1,86 @@ +/* + * rht03.c: + * Driver for the MaxDetect series sensors + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General 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 7 + +/* + *********************************************************************** + * The main program + *********************************************************************** + */ + +int main (void) +{ + int result, temp, rh ; + int minT, maxT, minRH, maxRH ; + + int numGood, numBad ; + + wiringPiSetup () ; + piHiPri (55) ; + + minT = 1000 ; + maxT = -1000 ; + + minRH = 1000 ; + maxRH = -1000 ; + + numGood = numBad = 0 ; + + for (;;) + { + delay (100) ; + + result = readRHT03 (RHT03_PIN, &temp, &rh) ; + + if (!result) + { + printf (".") ; + fflush (stdout) ; + ++numBad ; + continue ; + } + + ++numGood ; + + if (temp < minT) minT = temp ; + if (temp > maxT) maxT = temp ; + if (rh < minRH) minRH = rh ; + if (rh > maxRH) maxRH = rh ; + + printf ("\r%6d, %6d: ", numGood, numBad) ; + printf ("Temp: %5.1f, RH: %5.1f%%", temp / 10.0, rh / 10.0) ; + printf (" Max/Min Temp: %5.1f:%5.1f", maxT / 10.0, minT / 10.0) ; + printf (" Max/Min RH: %5.1f:%5.1f", maxRH / 10.0, minRH / 10.0) ; + + printf ("\n") ; + } + + return 0 ; +} diff --git a/examples/scrollPhat/Makefile b/examples/scrollPhat/Makefile new file mode 100644 index 0000000..2471f69 --- /dev/null +++ b/examples/scrollPhat/Makefile @@ -0,0 +1,79 @@ +# +# Makefile: +# wiringPi - A "wiring" library for the Raspberry Pi +# https://projects.drogon.net/wiring-pi +# +# Copyright (c) 2012-2015 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# A "wiring" library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + +ifneq ($V,1) +Q ?= @ +endif + +#DEBUG = -g -O0 +DEBUG = -O3 +CC = gcc +INCLUDE = -I/usr/local/include +CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe + +LDFLAGS = -L/usr/local/lib +LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm + +# Should not alter anything below this line +############################################################################### + +SRC = scphat.c test.c + +OBJ = $(SRC:.c=.o) + +BINS = $(SRC:.c=) + +all: $(BINS) + +test: test.o + $Q echo [link] + $Q $(CC) -o $@ test.o $(LDFLAGS) $(LDLIBS) + +scphat: scphat.o + $Q echo [link] + $Q $(CC) -o $@ scphat.o $(LDFLAGS) $(LDLIBS) + + +.c.o: + $Q echo [CC] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ + +clean: + $Q echo "[Clean]" + $Q rm -f $(OBJ) *~ core tags $(BINS) + +tags: $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) + +install: scphat + $Q echo Installing scphat into /usr/local/bin + $Q cp -a scphat /usr/local/bin/scphat + $Q chmod 755 /usr/local/bin/scphat + $Q echo Done. Remember to load the I2C drivers if needed. + +depend: + makedepend -Y $(SRC) + +# DO NOT DELETE diff --git a/examples/scrollPhat/scphat.c b/examples/scrollPhat/scphat.c new file mode 100644 index 0000000..8f90bad --- /dev/null +++ b/examples/scrollPhat/scphat.c @@ -0,0 +1,230 @@ +/* + * scphat.c: + * Little program to allow use of the Pimoroni Sctoll Phat + * from the command-line. + * + * Copyright (c) 2015-2016 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General 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 + +static char *progName ; + + +/* + * checkArgs: + * Count the arguments for each little function + ********************************************************************************* + */ + +static void checkArgs (char *command, int num, int arg, int argc) +{ + if ((arg + num) < argc) + return ; + + fprintf (stderr, "%s: Not enough data for %s command.\n", progName, command) ; + exit (EXIT_FAILURE) ; +} + + +/* + * doClear: + * Clear the display + ********************************************************************************* + */ + +static int doClear (void) +{ + scrollPhatClear () ; + return 1 ; +} + + +/* + * doBright + ********************************************************************************* + */ + +static int doBright (int arg, int argc, char *argv []) +{ + checkArgs ("bright", 1, arg, argc) ; + scrollPhatIntensity (atoi (argv [arg+1])) ; + return 2 ; +} + + + +/* + * doPlot + ********************************************************************************* + */ + +static int doPlot (int arg, int argc, char *argv []) +{ + checkArgs ("plot", 2, arg, argc) ; + scrollPhatPoint (atoi (argv [arg+1]), atoi (argv [arg+2]), 1) ; + scrollPhatUpdate () ; + return 3 ; +} + + +/* + * doLine + ********************************************************************************* + */ + +static int doLine (int arg, int argc, char *argv []) +{ + checkArgs ("line", 4, arg, argc) ; + scrollPhatLine (atoi (argv [arg+1]), atoi (argv [arg+2]), + atoi (argv [arg+3]), atoi (argv [arg+4]), 1) ; + scrollPhatUpdate () ; + return 5 ; +} + + +/* + * doLineTo + ********************************************************************************* + */ + +static int doLineTo (int arg, int argc, char *argv []) +{ + checkArgs ("lineto", 2, arg, argc) ; + scrollPhatLineTo (atoi (argv [arg+1]), atoi (argv [arg+2]), 1) ; + scrollPhatUpdate () ; + return 3 ; +} + + +/* + * doWait + ********************************************************************************* + */ + +static int doWait (int arg, int argc, char *argv []) +{ + checkArgs ("wait", 1, arg, argc) ; + delay (atoi (argv [arg+1]) * 100) ; + scrollPhatUpdate () ; + return 2 ; +} + + +/* + * doSpeed + ********************************************************************************* + */ + +static int doSpeed (int arg, int argc, char *argv []) +{ + checkArgs ("speed", 1, arg, argc) ; + scrollPhatPrintSpeed (atoi (argv [arg+1])) ; + return 2 ; +} + + +/* + * doScroll + ********************************************************************************* + */ + +static int doScroll (int arg, int argc, char *argv []) +{ + checkArgs ("scroll", 1, arg, argc) ; + scrollPhatPuts (argv [arg+1]) ; + return 2 ; +} + + +static void failUsage (void) +{ + fprintf (stderr, "Usage: %s command [paremters] ...\n", progName) ; + fprintf (stderr, " commands:\n") ; + fprintf (stderr, " clear/cls - Clear the display\n") ; + fprintf (stderr, " bright N - Set display brightness; 1-100\n") ; + fprintf (stderr, " plot X Y - Set a single pixel at location X Y; 0-10, 0-4\n") ; + fprintf (stderr, " line X1 Y1 X2 Y2 - Draw a line from the 2 points\n") ; + fprintf (stderr, " lineto X2 Y2 - Draw a line from the last point to the new one\n") ; + fprintf (stderr, " wait/delay N - Wait for N 10ths seconds\n") ; + fprintf (stderr, " speed N - Set scrolling speed (cps)\n") ; + fprintf (stderr, " scroll S - Scroll the given string\n") ; + fprintf (stderr, "\n") ; + fprintf (stderr, " Example: %s plot 0 0 wait 50 scroll \" Hello \"\n", progName) ; + exit (EXIT_FAILURE) ; +} + + +/* + * the works + ********************************************************************************* + */ + +int main (int argc, char *argv []) +{ + int arg = 1 ; + char *command ; + + progName = argv [0] ; + + wiringPiSetupSys () ; + + if (scrollPhatSetup () != 0) + { + fprintf (stderr, "%s: Unable to initialise the scrollPhat: %s\n", progName, strerror (errno)) ; + exit (EXIT_FAILURE) ; + } + + progName = argv [0] ; + + if (argc < 2) + { + fprintf (stderr, "%s: Nothing to do...\n", argv [0]) ; + failUsage () ; + } + + while (arg != argc) + { + command = argv [arg] ; + /**/ if (strcasecmp (command, "clear") == 0) arg += doClear () ; + else if (strcasecmp (command, "cls") == 0) arg += doClear () ; + else if (strcasecmp (command, "bright") == 0) arg += doBright (arg, argc, argv) ; + else if (strcasecmp (command, "plot") == 0) arg += doPlot (arg, argc, argv) ; + else if (strcasecmp (command, "line") == 0) arg += doLine (arg, argc, argv) ; + else if (strcasecmp (command, "lineto") == 0) arg += doLineTo (arg, argc, argv) ; + else if (strcasecmp (command, "wait") == 0) arg += doWait (arg, argc, argv) ; + else if (strcasecmp (command, "delay") == 0) arg += doWait (arg, argc, argv) ; + else if (strcasecmp (command, "speed") == 0) arg += doSpeed (arg, argc, argv) ; + else if (strcasecmp (command, "scroll") == 0) arg += doScroll (arg, argc, argv) ; + else + { + fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [arg]) ; + failUsage () ; + } + } + + return 0 ; +} diff --git a/examples/scrollPhat/test.c b/examples/scrollPhat/test.c new file mode 100644 index 0000000..e4d8021 --- /dev/null +++ b/examples/scrollPhat/test.c @@ -0,0 +1,115 @@ +/* + * test.c: + * Little test program forthe Pimoroni Scroll Phat. + * + * Copyright (c) 2015-2016 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General 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 + + +/* + * prompt: + * Simple prompt & wait + ********************************************************************************* + */ + +static void prompt (const char *p) +{ + printf (" %s. Press ENTER: ", p) ; + (void)getchar () ; +} + + +/* + * the works + ********************************************************************************* + */ + +int main (void) +{ + int x, y ; + + printf ("\n") ; + printf ("Scroll Phat Test program\n") ; + printf ("========================\n") ; + + if (scrollPhatSetup () != 0) + { + printf ("Unable to initialise the scrollPhat: %s\n", strerror (errno)) ; + exit (1) ; + } + + printf ("-> Scroll Phat initialised OK\n") ; + printf ("... Basic display tests.\n\n") ; + + prompt ("Display ought to be blank") ; + +// Light all pixels using one point at a time + + for (y = 0 ; y < 5 ; ++y) + for (x = 0 ; x < 12 ; ++x) + scrollPhatPoint (x, y, 1) ; + scrollPhatUpdate () ; + + prompt ("Display ought to be all lit-up") ; + +// Big rectangle + + scrollPhatClear () ; + scrollPhatRectangle (0,0, 10, 4, 1, 0) ; + scrollPhatUpdate () ; + + prompt ("There should now be a rectangle round the outside") ; + + scrollPhatLine (0,0, 10,4, 1) ; + scrollPhatLine (0,4, 10,0, 1) ; + scrollPhatUpdate () ; + + prompt ("Diagonal lines") ; + + scrollPhatIntensity (1) ; + + prompt ("Minimum brightness") ; + + scrollPhatIntensity (100) ; + + prompt ("Maximum brightness") ; + + scrollPhatIntensity (10) ; + + prompt ("Default brightness") ; + + scrollPhatClear () ; + + printf (" Message Test...Press Ctrl-C to exit: ") ; + fflush (stdout) ; + + scrollPhatPrintSpeed (75) ; + for (;;) + scrollPhatPuts (" Welcome to the scroll phat from Pimoroni ") ; + + return 0 ; +} diff --git a/examples/serialRead.c b/examples/serialRead.c new file mode 100644 index 0000000..aaceed9 --- /dev/null +++ b/examples/serialRead.c @@ -0,0 +1,48 @@ +/* + * serial.c: + * Example program to read bytes from the Serial line + * + * 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 + +int main () +{ + int fd ; + + if ((fd = serialOpen ("/dev/ttyS2", 115200)) < 0) + { + fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ; + return 1 ; + } + +// Loop, getting and printing characters + + for (;;) + { + putchar (serialGetchar (fd)) ; + fflush (stdout) ; + } +} diff --git a/examples/serialTest.c b/examples/serialTest.c new file mode 100644 index 0000000..d50b1bc --- /dev/null +++ b/examples/serialTest.c @@ -0,0 +1,75 @@ +/* + * serialTest.c: + * Very simple program to test the serial port. Expects + * the port to be looped back to itself + * + * 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 main () +{ + int fd ; + int count ; + unsigned int nextTime ; + + if ((fd = serialOpen ("/dev/ttyS2", 115200)) < 0) + { + fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ; + return 1 ; + } + + if (wiringPiSetup () == -1) + { + fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ; + return 1 ; + } + + nextTime = millis () + 300 ; + + for (count = 0 ; count < 256 ; ) + { + if (millis () > nextTime) + { + printf ("\nOut: %3d: ", count) ; + fflush (stdout) ; + serialPutchar (fd, count) ; + nextTime += 300 ; + ++count ; + } + + delay (3) ; + + while (serialDataAvail (fd)) + { + printf (" -> %3d", serialGetchar (fd)) ; + fflush (stdout) ; + } + } + + printf ("\n") ; + return 0 ; +} diff --git a/examples/servo.c b/examples/servo.c new file mode 100644 index 0000000..aa1ab05 --- /dev/null +++ b/examples/servo.c @@ -0,0 +1,57 @@ +/* + * servo.c: + * Test of the softServo code. + * Do not use this code - use the servoBlaster kernel module instead + * + * 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 main () +{ + if (wiringPiSetup () == -1) + { + fprintf (stdout, "oops: %s\n", strerror (errno)) ; + return 1 ; + } + + softServoSetup (0, 1, 2, 3, 4, 5, 6, 7) ; + + softServoWrite (0, 0) ; +/* + softServoWrite (1, 1000) ; + softServoWrite (2, 1100) ; + softServoWrite (3, 1200) ; + softServoWrite (4, 1300) ; + softServoWrite (5, 1400) ; + softServoWrite (6, 1500) ; + softServoWrite (7, 2200) ; +*/ + + for (;;) + delay (10) ; + +} 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 new file mode 100644 index 0000000..aa31e15 --- /dev/null +++ b/examples/speed.c @@ -0,0 +1,95 @@ +/* + * speed.c: + * Simple program to measure the speed of the various GPIO + * access mechanisms. + * + * 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 + +#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) +{ + printf ("OrangePi Pi wiringPi GPIO speed test program\n") ; + printf ("=============================================\n") ; + +// Start the standard way + + printf ("\nNative wiringPi method: (%8d iterations)\n", FAST_COUNT) ; + wiringPiSetup () ; + pinMode (0, OUTPUT) ; + speedTest (0, FAST_COUNT) ; + +// GPIO + +/* printf ("\nNative GPIO method: (%8d iterations)\n", FAST_COUNT) ; + wiringPiSetupGpio () ; + pinMode (17, OUTPUT) ; + speedTest (17, FAST_COUNT) ;*/ + +// Phys + + printf ("\nPhysical pin GPIO method: (%8d iterations)\n", FAST_COUNT) ; + wiringPiSetupPhys () ; + pinMode (11, OUTPUT) ; + speedTest (11, FAST_COUNT) ; + +// Switch to SYS mode: + + 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/examples/spidev_test.c b/examples/spidev_test.c new file mode 100644 index 0000000..3559e76 --- /dev/null +++ b/examples/spidev_test.c @@ -0,0 +1,480 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * SPI testing utility (using spidev driver) + * + * Copyright (c) 2007 MontaVista Software, Inc. + * Copyright (c) 2007 Anton Vorontsov + * + * Cross-compile with cross-gcc -I/path/to/cross-kernel/include + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +static void pabort(const char *s) +{ + perror(s); + abort(); +} + +static const char *device = "/dev/spidev1.1"; +static uint32_t mode; +static uint8_t bits = 8; +static char *input_file; +static char *output_file; +static uint32_t speed = 500000; +static uint16_t delay; +static int verbose; +static int transfer_size; +static int iterations; +static int interval = 5; /* interval in seconds for showing transfer rate */ + +uint8_t default_tx[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x95, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x0D, +}; + +uint8_t default_rx[ARRAY_SIZE(default_tx)] = {0, }; +char *input_tx; + +static void hex_dump(const void *src, size_t length, size_t line_size, + char *prefix) +{ + int i = 0; + const unsigned char *address = src; + const unsigned char *line = address; + unsigned char c; + + printf("%s | ", prefix); + while (length-- > 0) { + printf("%02X ", *address++); + if (!(++i % line_size) || (length == 0 && i % line_size)) { + if (length == 0) { + while (i++ % line_size) + printf("__ "); + } + printf(" |"); + while (line < address) { + c = *line++; + printf("%c", (c < 32 || c > 126) ? '.' : c); + } + printf("|\n"); + if (length > 0) + printf("%s | ", prefix); + } + } +} + +/* + * Unescape - process hexadecimal escape character + * converts shell input "\x23" -> 0x23 + */ +static int unescape(char *_dst, char *_src, size_t len) +{ + int ret = 0; + int match; + char *src = _src; + char *dst = _dst; + unsigned int ch; + + while (*src) { + if (*src == '\\' && *(src+1) == 'x') { + match = sscanf(src + 2, "%2x", &ch); + if (!match) + pabort("malformed input string"); + + src += 4; + *dst++ = (unsigned char)ch; + } else { + *dst++ = *src++; + } + ret++; + } + return ret; +} + +static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len) +{ + int ret; + int out_fd; + struct spi_ioc_transfer tr = { + .tx_buf = (unsigned long)tx, + .rx_buf = (unsigned long)rx, + .len = len, + .delay_usecs = delay, + .speed_hz = speed, + .bits_per_word = bits, + }; + + if (mode & SPI_TX_QUAD) + tr.tx_nbits = 4; + else if (mode & SPI_TX_DUAL) + tr.tx_nbits = 2; + if (mode & SPI_RX_QUAD) + tr.rx_nbits = 4; + else if (mode & SPI_RX_DUAL) + tr.rx_nbits = 2; + if (!(mode & SPI_LOOP)) { + if (mode & (SPI_TX_QUAD | SPI_TX_DUAL)) + tr.rx_buf = 0; + else if (mode & (SPI_RX_QUAD | SPI_RX_DUAL)) + tr.tx_buf = 0; + } + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + if (verbose) + hex_dump(tx, len, 32, "TX"); + + if (output_file) { + out_fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (out_fd < 0) + pabort("could not open output file"); + + ret = write(out_fd, rx, len); + if (ret != len) + pabort("not all bytes written to output file"); + + close(out_fd); + } + + if (verbose) + hex_dump(rx, len, 32, "RX"); +} + +static void print_usage(const char *prog) +{ + printf("Usage: %s [-DsbdlHOLC3vpNR24SI]\n", prog); + puts(" -D --device device to use (default /dev/spidev1.1)\n" + " -s --speed max speed (Hz)\n" + " -d --delay delay (usec)\n" + " -b --bpw bits per word\n" + " -i --input input data from a file (e.g. \"test.bin\")\n" + " -o --output output data to a file (e.g. \"results.bin\")\n" + " -l --loop loopback\n" + " -H --cpha clock phase\n" + " -O --cpol clock polarity\n" + " -L --lsb least significant bit first\n" + " -C --cs-high chip select active high\n" + " -3 --3wire SI/SO signals shared\n" + " -v --verbose Verbose (show tx buffer)\n" + " -p Send data (e.g. \"1234\\xde\\xad\")\n" + " -N --no-cs no chip select\n" + " -R --ready slave pulls low to pause\n" + " -2 --dual dual transfer\n" + " -4 --quad quad transfer\n" + " -S --size transfer size\n" + " -I --iter iterations\n"); + exit(1); +} + +static void parse_opts(int argc, char *argv[]) +{ + while (1) { + static const struct option lopts[] = { + { "device", 1, 0, 'D' }, + { "speed", 1, 0, 's' }, + { "delay", 1, 0, 'd' }, + { "bpw", 1, 0, 'b' }, + { "input", 1, 0, 'i' }, + { "output", 1, 0, 'o' }, + { "loop", 0, 0, 'l' }, + { "cpha", 0, 0, 'H' }, + { "cpol", 0, 0, 'O' }, + { "lsb", 0, 0, 'L' }, + { "cs-high", 0, 0, 'C' }, + { "3wire", 0, 0, '3' }, + { "no-cs", 0, 0, 'N' }, + { "ready", 0, 0, 'R' }, + { "dual", 0, 0, '2' }, + { "verbose", 0, 0, 'v' }, + { "quad", 0, 0, '4' }, + { "size", 1, 0, 'S' }, + { "iter", 1, 0, 'I' }, + { NULL, 0, 0, 0 }, + }; + int c; + + c = getopt_long(argc, argv, "D:s:d:b:i:o:lHOLC3NR24p:vS:I:", + lopts, NULL); + + if (c == -1) + break; + + switch (c) { + case 'D': + device = optarg; + break; + case 's': + speed = atoi(optarg); + break; + case 'd': + delay = atoi(optarg); + break; + case 'b': + bits = atoi(optarg); + break; + case 'i': + input_file = optarg; + break; + case 'o': + output_file = optarg; + break; + case 'l': + mode |= SPI_LOOP; + break; + case 'H': + mode |= SPI_CPHA; + break; + case 'O': + mode |= SPI_CPOL; + break; + case 'L': + mode |= SPI_LSB_FIRST; + break; + case 'C': + mode |= SPI_CS_HIGH; + break; + case '3': + mode |= SPI_3WIRE; + break; + case 'N': + mode |= SPI_NO_CS; + break; + case 'v': + verbose = 1; + break; + case 'R': + mode |= SPI_READY; + break; + case 'p': + input_tx = optarg; + break; + case '2': + mode |= SPI_TX_DUAL; + break; + case '4': + mode |= SPI_TX_QUAD; + break; + case 'S': + transfer_size = atoi(optarg); + break; + case 'I': + iterations = atoi(optarg); + break; + default: + print_usage(argv[0]); + break; + } + } + if (mode & SPI_LOOP) { + if (mode & SPI_TX_DUAL) + mode |= SPI_RX_DUAL; + if (mode & SPI_TX_QUAD) + mode |= SPI_RX_QUAD; + } +} + +static void transfer_escaped_string(int fd, char *str) +{ + size_t size = strlen(str); + uint8_t *tx; + uint8_t *rx; + + tx = malloc(size); + if (!tx) + pabort("can't allocate tx buffer"); + + rx = malloc(size); + if (!rx) + pabort("can't allocate rx buffer"); + + size = unescape((char *)tx, str, size); + transfer(fd, tx, rx, size); + free(rx); + free(tx); +} + +static void transfer_file(int fd, char *filename) +{ + ssize_t bytes; + struct stat sb; + int tx_fd; + uint8_t *tx; + uint8_t *rx; + + if (stat(filename, &sb) == -1) + pabort("can't stat input file"); + + tx_fd = open(filename, O_RDONLY); + if (tx_fd < 0) + pabort("can't open input file"); + + tx = malloc(sb.st_size); + if (!tx) + pabort("can't allocate tx buffer"); + + rx = malloc(sb.st_size); + if (!rx) + pabort("can't allocate rx buffer"); + + bytes = read(tx_fd, tx, sb.st_size); + if (bytes != sb.st_size) + pabort("failed to read input file"); + + transfer(fd, tx, rx, sb.st_size); + free(rx); + free(tx); + close(tx_fd); +} + +static uint64_t _read_count; +static uint64_t _write_count; + +static void show_transfer_rate(void) +{ + static uint64_t prev_read_count, prev_write_count; + double rx_rate, tx_rate; + + rx_rate = ((_read_count - prev_read_count) * 8) / (interval*1000.0); + tx_rate = ((_write_count - prev_write_count) * 8) / (interval*1000.0); + + printf("rate: tx %.1fkbps, rx %.1fkbps\n", rx_rate, tx_rate); + + prev_read_count = _read_count; + prev_write_count = _write_count; +} + +static void transfer_buf(int fd, int len) +{ + uint8_t *tx; + uint8_t *rx; + int i; + + tx = malloc(len); + if (!tx) + pabort("can't allocate tx buffer"); + for (i = 0; i < len; i++) + tx[i] = random(); + + rx = malloc(len); + if (!rx) + pabort("can't allocate rx buffer"); + + transfer(fd, tx, rx, len); + + _write_count += len; + _read_count += len; + + if (mode & SPI_LOOP) { + if (memcmp(tx, rx, len)) { + fprintf(stderr, "transfer error !\n"); + hex_dump(tx, len, 32, "TX"); + hex_dump(rx, len, 32, "RX"); + exit(1); + } + } + + free(rx); + free(tx); +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + int fd; + + parse_opts(argc, argv); + + fd = open(device, O_RDWR); + if (fd < 0) + pabort("can't open device"); + + /* + * spi mode + */ + ret = ioctl(fd, SPI_IOC_WR_MODE32, &mode); + if (ret == -1) + pabort("can't set spi mode"); + + ret = ioctl(fd, SPI_IOC_RD_MODE32, &mode); + if (ret == -1) + pabort("can't get spi mode"); + + /* + * bits per word + */ + ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); + if (ret == -1) + pabort("can't set bits per word"); + + ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits); + if (ret == -1) + pabort("can't get bits per word"); + + /* + * max speed hz + */ + ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); + if (ret == -1) + pabort("can't set max speed hz"); + + ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); + if (ret == -1) + pabort("can't get max speed hz"); + + printf("spi mode: 0x%x\n", mode); + printf("bits per word: %d\n", bits); + printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); + + if (input_tx && input_file) + pabort("only one of -p and --input may be selected"); + + if (input_tx) + transfer_escaped_string(fd, input_tx); + else if (input_file) + transfer_file(fd, input_file); + else if (transfer_size) { + struct timespec last_stat; + + clock_gettime(CLOCK_MONOTONIC, &last_stat); + + while (iterations-- > 0) { + struct timespec current; + + transfer_buf(fd, transfer_size); + + clock_gettime(CLOCK_MONOTONIC, ¤t); + if (current.tv_sec - last_stat.tv_sec > interval) { + show_transfer_rate(); + last_stat = current; + } + } + printf("total: tx %.1fKB, rx %.1fKB\n", + _write_count/1024.0, _read_count/1024.0); + } else + transfer(fd, default_tx, default_rx, sizeof(default_tx)); + + close(fd); + + return ret; +} diff --git a/examples/spidev_test_linux3_4.c b/examples/spidev_test_linux3_4.c new file mode 100644 index 0000000..16feda9 --- /dev/null +++ b/examples/spidev_test_linux3_4.c @@ -0,0 +1,210 @@ +/* + * SPI testing utility (using spidev driver) + * + * Copyright (c) 2007 MontaVista Software, Inc. + * Copyright (c) 2007 Anton Vorontsov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + * Cross-compile with cross-gcc -I/path/to/cross-kernel/include + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +static void pabort(const char *s) +{ + perror(s); + abort(); +} + +static const char *device = "/dev/spidev1.1"; +static uint8_t mode; +static uint8_t bits = 8; +static uint32_t speed = 500000; +static uint16_t delay; + +static void transfer(int fd) +{ + int ret; + uint8_t tx[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x95, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, + 0xF0, 0x0D, + }; + uint8_t rx[ARRAY_SIZE(tx)] = {0, }; + struct spi_ioc_transfer tr = { + .tx_buf = (unsigned long)tx, + .rx_buf = (unsigned long)rx, + .len = ARRAY_SIZE(tx), + .delay_usecs = delay, + .speed_hz = speed, + .bits_per_word = bits, + }; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + if (ret < 1) + pabort("can't send spi message"); + + for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { + if (!(ret % 6)) + puts(""); + printf("%.2X ", rx[ret]); + } + puts(""); +} + +static void print_usage(const char *prog) +{ + printf("Usage: %s [-DsbdlHOLC3]\n", prog); + puts(" -D --device device to use (default /dev/spidev1.1)\n" + " -s --speed max speed (Hz)\n" + " -d --delay delay (usec)\n" + " -b --bpw bits per word \n" + " -l --loop loopback\n" + " -H --cpha clock phase\n" + " -O --cpol clock polarity\n" + " -L --lsb least significant bit first\n" + " -C --cs-high chip select active high\n" + " -3 --3wire SI/SO signals shared\n"); + exit(1); +} + +static void parse_opts(int argc, char *argv[]) +{ + while (1) { + static const struct option lopts[] = { + { "device", 1, 0, 'D' }, + { "speed", 1, 0, 's' }, + { "delay", 1, 0, 'd' }, + { "bpw", 1, 0, 'b' }, + { "loop", 0, 0, 'l' }, + { "cpha", 0, 0, 'H' }, + { "cpol", 0, 0, 'O' }, + { "lsb", 0, 0, 'L' }, + { "cs-high", 0, 0, 'C' }, + { "3wire", 0, 0, '3' }, + { "no-cs", 0, 0, 'N' }, + { "ready", 0, 0, 'R' }, + { NULL, 0, 0, 0 }, + }; + int c; + + c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL); + + if (c == -1) + break; + + switch (c) { + case 'D': + device = optarg; + break; + case 's': + speed = atoi(optarg); + break; + case 'd': + delay = atoi(optarg); + break; + case 'b': + bits = atoi(optarg); + break; + case 'l': + mode |= SPI_LOOP; + break; + case 'H': + mode |= SPI_CPHA; + break; + case 'O': + mode |= SPI_CPOL; + break; + case 'L': + mode |= SPI_LSB_FIRST; + break; + case 'C': + mode |= SPI_CS_HIGH; + break; + case '3': + mode |= SPI_3WIRE; + break; + case 'N': + mode |= SPI_NO_CS; + break; + case 'R': + mode |= SPI_READY; + break; + default: + print_usage(argv[0]); + break; + } + } +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + int fd; + + parse_opts(argc, argv); + + fd = open(device, O_RDWR); + if (fd < 0) + pabort("can't open device"); + + /* + * spi mode + */ + ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); + if (ret == -1) + pabort("can't set spi mode"); + + ret = ioctl(fd, SPI_IOC_RD_MODE, &mode); + if (ret == -1) + pabort("can't get spi mode"); + + /* + * bits per word + */ + ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); + if (ret == -1) + pabort("can't set bits per word"); + + ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits); + if (ret == -1) + pabort("can't get bits per word"); + + /* + * max speed hz + */ + ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); + if (ret == -1) + pabort("can't set max speed hz"); + + ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); + if (ret == -1) + pabort("can't get max speed hz"); + + printf("spi mode: %d\n", mode); + printf("bits per word: %d\n", bits); + printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); + + transfer(fd); + + close(fd); + + return ret; +} diff --git a/examples/w25q64_test.c b/examples/w25q64_test.c new file mode 100644 index 0000000..5a16d95 --- /dev/null +++ b/examples/w25q64_test.c @@ -0,0 +1,139 @@ +#include +#include +#include +#include +#include "w25q64.h" + +#define SPI_CHANNEL 0 // /dev/spidevX.0 +//#define SPI_CHANNEL 1 // /dev/spidevX.0 + +#define SPI_PORT 0 +//#define SPI_PORT 1 + +void dump(uint8_t *dt, uint32_t n) { + uint32_t sz; + char buf[64]; + uint16_t clm = 0; + uint8_t data; + uint8_t sum; + uint8_t vsum[16]; + uint8_t total =0; + uint32_t saddr =0; + uint32_t eaddr =n-1; + sz = eaddr -saddr; + + printf("----------------------------------------------------------\n"); + uint16_t i; + for (i=0;i<16;i++) vsum[i]=0; + uint32_t addr; + for (addr = saddr; addr <= eaddr; addr++) { + data = dt[addr]; + if (clm == 0) { + sum =0; + printf("%05x: ",addr); + } + + sum+=data; + vsum[addr % 16]+=data; + + printf("%02x ",data); + clm++; + if (clm == 16) { + printf("|%02x \n",sum); + clm = 0; + } + } + printf("----------------------------------------------------------\n"); + printf(" "); + for (i=0; i<16;i++) { + total+=vsum[i]; + printf("%02x ",vsum[i]); + } + printf("|%02x \n\n",total); +} + +void main() { + uint8_t buf[256]; + uint8_t wdata[16]; + uint8_t i; + uint16_t n; + + // Start SPI channel 0 with 2MHz + + //if (wiringPiSPISetup(SPI_CHANNEL, 2000000) < 0) { + if (wiringPiSPISetupMode(SPI_CHANNEL, SPI_PORT, 2000000, 0) < 0) { + printf("SPISetup failed:\n"); + } + + // Start Flush Memory + W25Q64_begin(SPI_CHANNEL); + + // JEDEC ID Get + W25Q64_readManufacturer(buf); + printf("JEDEC ID : "); + for (i=0; i< 3; i++) { + printf("%x ",buf[i]); + } + printf("\n"); + + // Unique ID Get + W25Q64_readUniqieID(buf); + printf("Unique ID : "); + for (i=0; i< 7; i++) { + printf("%x ",buf[i]); + } + printf("\n"); + + // Read 256 byte data from Address=0 + memset(buf,0,256); + n = W25Q64_read(0, buf, 256); + printf("Read Data: n=%d\n",n); + dump(buf,256); + + // First read 256 byte data from Address=0 + memset(buf,0,256); + n = W25Q64_fastread(0, buf, 256); + printf("Fast Read Data: n=%d\n",n); + dump(buf,256); + + // Erase data by Sector + n = W25Q64_eraseSector(0,true); + printf("Erase Sector(0): n=%d\n",n); + memset(buf,0,256); + n = W25Q64_read (0, buf, 256); + dump(buf,256); + + // Write data to Sector=0 Address=10 + for (i=0; i < 26;i++) { + wdata[i]='A'+i; // A-Z + } + n = W25Q64_pageWrite(0, 10, wdata, 26); + printf("page_write(0,10,d,26): n=%d\n",n); + + // Read 256 byte data from Address=0 + memset(buf,0,256); + n = W25Q64_read(0, buf, 256); + printf("Read Data: n=%d\n",n); + dump(buf,256); + + // Write data to Sector=0 Address=0 + for (i=0; i < 10;i++) { + wdata[i]='0'+i; // 0-9 + } + n = W25Q64_pageWrite(0, 0, wdata, 10); + printf("page_write(0,0,d,10): n=%d\n",n); + + // First read 256 byte data from Address=0 + memset(buf,0,256); + n = W25Q64_fastread(0,buf, 256); + printf("Fast Read Data: n=%d\n",n); + dump(buf,256); + + // Get fron Status Register1 + buf[0] = W25Q64_readStatusReg1(); + printf("Status Register-1: %x\n",buf[0]); + + // Get fron Status Register2 + buf[0] = W25Q64_readStatusReg2(); + printf("Status Register-2: %x\n",buf[0]); +} diff --git a/examples/watchdog.c b/examples/watchdog.c new file mode 100644 index 0000000..c8e4a2a --- /dev/null +++ b/examples/watchdog.c @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct watchdog_info{ + unsigned int options; //options the card/driver supprots 19 + unsigned int firmware_version; //firmcard version of the card + unsigned char identity[32]; //identity of the board 21 + }; + +#define WATCHDOG_IOCTL_BASE 'W' +#define WDIOC_GETSUPPORT _IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info) +#define WDIOC_SETTIMEOUT _IOWR(WATCHDOG_IOCTL_BASE, 6, int) +#define WDIOC_GETTIMEOUT _IOR(WATCHDOG_IOCTL_BASE, 7, int) //27 +#define WDIOS_DISABLECARD 0x0001 +#define WDIOS_ENABLECARD 0x0002 +#define WDIOC_SETOPTIONS _IOR(WATCHDOG_IOCTL_BASE, 4, int) +#define WDIOC_KEEPALIVE _IOR(WATCHDOG_IOCTL_BASE, 5, int) + +int Getch (void) //无回显的从å±å¹•è¾“入字符,æ¥è¾¾åˆ°å–‚狗的目的 + +{ + + int ch; + struct termios oldt, newt; //终端设备结构体 + tcgetattr(STDIN_FILENO, &oldt); //获得终端属性 + newt = oldt; + newt.c_lflag &= ~(ECHO|ICANON); //设置无回显属性 + tcsetattr(STDIN_FILENO, TCSANOW, &newt); //设置新的终端属性 + ch = getchar(); //ä»Žé”®ç›˜è¾“å…¥ä¸€ä¸ªæ•°æ® + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); //æ¢å¤ç»ˆç«¯è®¾å¤‡åˆå§‹è®¾ç½® + return ch; + +} + //suspend some seconds +int zsleep(int millisecond) + +{ + unsigned long usec; + usec=1000*millisecond; + usleep(usec); //usleep(1)ç¡çœ ä¸€å¾®ç§’(10E-6),这里也就是0.1s +} +int Init() +{ + int fd; + //open device file + fd = open("/dev/watchdog",O_RDWR); //打开看门狗设备 + if(fd < 0) + { + printf("device open fail\n"); + return -1; + } + printf("open success\n"); + return fd; +} + +int main(int argc,char **argv) +{ + int fd,ch; + int i,j; + char c; + struct watchdog_info wi; + if(argc != 2){ + printf("Usage : ./watchdog 10\n"); + return -1; + } + fd=Init(); //打开终端看门狗设备 + ioctl(fd, WDIOC_SETOPTIONS, WDIOS_ENABLECARD); + //读æ¿å¡ä¿¡æ¯ï¼Œä½†ä¸å¸¸ç”¨ + ioctl(fd,WDIOC_GETSUPPORT,&wi); + printf("options is %d,identity is %s\n",wi.options,wi.identity); + //读看门狗溢出时间 + + printf("put_usr return,if 0,success:%d\n",ioctl(fd,WDIOC_GETTIMEOUT,&i)); + + printf("The old reset time is: %d\n", i); + //关闭 + i=WDIOS_DISABLECARD;//WDIOC_SETOPTIONS=0X0001 + printf("return ENOTTY,if -1,success:%d\n",ioctl(fd,WDIOC_SETOPTIONS,&i)); + //打开 + i=WDIOS_ENABLECARD;//WDIOS_ENABLECARD 0x0002 + printf("return ENOTTY,if -1,success:%d\n",ioctl(fd,WDIOC_SETOPTIONS,&i)); + i=atoi(argv[1]); + printf("put_user return,if 0,success:%d\n",ioctl(fd,WDIOC_SETTIMEOUT,&i)); + //读新的设置时间 + + printf("put_usr return,if 0,success:%d\n",ioctl(fd,WDIOC_GETTIMEOUT,&i)); + + + while(1) + { + zsleep(100); + if((c=Getch())!=27){ + //输入如果ä¸æ˜¯ESC,就喂狗,å¦åˆ™ä¸å–‚狗,到时间åŽç³»ç»Ÿé‡å¯ + printf("keep alive \n"); + ioctl(fd,WDIOC_KEEPALIVE,NULL); + //write(fd,NULL,1); //åŒæ ·æ˜¯å–‚ç‹— + + } + } + close(fd); //关闭设备 + return 0; +} diff --git a/examples/wfi.c b/examples/wfi.c new file mode 100644 index 0000000..6bb6892 --- /dev/null +++ b/examples/wfi.c @@ -0,0 +1,161 @@ +/* + * wfi.c: + * Wait for Interrupt test program + * + * This program demonstrates the use of the waitForInterrupt() + * function in wiringPi. It listens to a button input on + * BCM_GPIO pin 17 (wiringPi pin 0) + * + * The biggest issue with this method is that it really only works + * well in Sys mode. + * + * Jan 2013: This way of doing things is sort of deprecated now, see + * the wiringPiISR() function instead and the isr.c test program here. + * + * 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 + +// A 'key' which we can lock and unlock - values are 0 through 3 +// This is interpreted internally as a pthread_mutex by wiringPi +// which is hiding some of that to make life simple. + +#define COUNT_KEY 0 + +// What BCM_GPIO input are we using? + +#define BUTTON_PIN 17 + +// Debounce time in mS + +#define DEBOUNCE_TIME 100 + + +// globalCounter: +// Global variable to count interrupts +// Should be declared volatile to make sure the compiler doesn't cache it. + +static volatile int globalCounter = 0 ; + + +/* + * waitForIt: + * This is a thread created using the wiringPi simplified threading + * mechanism. It will wait on an interrupt on the button and increment + * a counter. + ********************************************************************************* + */ + +PI_THREAD (waitForIt) +{ + int state = 0 ; + int debounceTime = 0 ; + + (void)piHiPri (10) ; // Set this thread to be high priority + + for (;;) + { + if (waitForInterrupt (BUTTON_PIN, -1) > 0) // Got it + { +// Bouncing? + + if (millis () < debounceTime) + { + debounceTime = millis () + DEBOUNCE_TIME ; + continue ; + } + +// We have a valid one + + state ^= 1 ; + + piLock (COUNT_KEY) ; + ++globalCounter ; + piUnlock (COUNT_KEY) ; + +// Wait for key to be released + + while (digitalRead (BUTTON_PIN) == LOW) + delay (1) ; + + debounceTime = millis () + DEBOUNCE_TIME ; + } + } +} + + +/* + * setup: + * Demo a crude but effective way to initialise the hardware + ********************************************************************************* + */ + +void setup (void) +{ + +// Use the gpio program to initialise the hardware +// (This is the crude, but effective) + + system ("gpio edge 17 falling") ; + +// Setup wiringPi + + wiringPiSetupSys () ; + +// Fire off our interrupt handler + + piThreadCreate (waitForIt) ; + +} + + +/* + * main + ********************************************************************************* + */ + +int main (void) +{ + int lastCounter = 0 ; + int myCounter = 0 ; + + setup () ; + + for (;;) + { + printf ("Waiting ... ") ; fflush (stdout) ; + + while (myCounter == lastCounter) + { + piLock (COUNT_KEY) ; + myCounter = globalCounter ; + piUnlock (COUNT_KEY) ; + delay (500) ; + } + + printf (" Done. myCounter: %5d\n", myCounter) ; + lastCounter = myCounter ; + } + + return 0 ; +} diff --git a/gpio/COPYING.LESSER b/gpio/COPYING.LESSER new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/gpio/COPYING.LESSER @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/gpio/Makefile b/gpio/Makefile new file mode 100644 index 0000000..2ac4070 --- /dev/null +++ b/gpio/Makefile @@ -0,0 +1,177 @@ +# +# Makefile: +# The gpio command: +# A swiss-army knige of GPIO shenanigans. +# https://projects.drogon.net/wiring-pi +# +# Copyright (c) 2012-2016 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# A "wiring" library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + +DESTDIR?=/usr +PREFIX?=/local + +ifneq ($V,1) +Q ?= @ +endif + +#DEBUG = -g -O0 +DEBUG = -O2 +CC = gcc +INCLUDE = -I$(DESTDIR)$(PREFIX)/include +CFLAGS = $(DEBUG) -Wall -Wextra $(INCLUDE) -Winline -pipe + +LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib +LIBS = -lwiringPi -lwiringPiDev -lpthread -lrt -lm -lcrypt + +ifeq ($(BOARD),) + BOARD = orangepioneplus-h6 +endif + +ifeq ($(BOARD), orangepi2giot) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_2G_IOT +endif + +ifneq ($(findstring $(BOARD), "orangepione-h3" "orangepilite-h3" "orangepipc-h3" "orangepiplus-h3" "orangepipcplus-h3" "orangepiplus2e-h3"),) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_H3 +endif + +ifeq ($(BOARD), orangepipc2-h5) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_PC2 +endif + +ifeq ($(BOARD), orangepiprime-h5) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_PRIME +endif + +ifeq ($(BOARD), orangepizeroplus-h5) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_ZEROPLUS +endif + +ifneq ($(findstring $(BOARD), "orangepiwin-a64" "orangepiwinplus-a64"),) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_WIN +endif + +ifneq ($(findstring $(BOARD), "orangepizero-h2" "orangepir1-h2"),) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_ZERO +endif + +ifneq ($(findstring $(BOARD), "orangepioneplus-h6" "orangepilite2-h6"),) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_LITE2 +endif + +ifeq ($(BOARD), orangepi3-h6) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_3 +endif + +ifeq ($(BOARD), orangepizero2-h616) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_ZERO2 +endif + +ifeq ($(BOARD), orangepizeroplus2h3) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_ZEROPLUS2_H3 +endif + +ifeq ($(BOARD), orangepizeroplus2h5) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_ZEROPLUS2_H5 +endif + +ifeq ($(BOARD), orangepirk3399) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_RK3399 +endif + +ifeq ($(BOARD), orangepi4) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_4 +endif + +ifeq ($(BOARD), orangepi4-lts) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_4_LTS +endif + +ifeq ($(BOARD), orangepi800) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_800 +endif + +ifeq ($(BOARD), orangepir1plus-rk3328) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_R1PLUS +endif + +EXTRA_CFLAGS += -DCONFIG_ORANGEPI + +# May not need to alter anything below this line +############################################################################### + +SRC = gpio.c readall.c OrangePi.c + +OBJ = $(SRC:.c=.o) + +all: gpio + +version.h: ../VERSION + $Q echo Need to run newVersion above. + +gpio: $(OBJ) + $Q echo [Link] + $Q $(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS) + +.c.o: + $Q echo [Compile] $< + $Q $(CC) -c $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ + +.PHONY: clean +clean: + $Q echo "[Clean]" + $Q rm -f $(OBJ) gpio *~ core tags *.bak + +.PHONY: tags +tags: $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) + +.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)/share/man/man1 + $Q cp gpio.1 $(DESTDIR)$(PREFIX)/share/man/man1/ + +.PHONY: install-deb +install-deb: gpio + $Q echo "[Install: deb]" + $Q install -m 0755 -d $(CURDIR)/../debian-template/wiringPi/usr/bin + $Q install -m 0755 gpio $(CURDIR)/../debian-template/wiringPi/usr/bin + $Q install -m 0755 -d $(CURDIR)/../debian-template/wiringPi/usr/share/man/man1 + $Q install -m 0644 gpio.1 $(CURDIR)/../debian-template/wiringPi/usr/share/man/man1 + +.PHONY: uninstall +uninstall: + $Q echo "[UnInstall]" + $Q rm -f $(DESTDIR)$(PREFIX)/bin/gpio + $Q rm -f $(DESTDIR)$(PREFIX)/share/man/man1/gpio.1 + +.PHONY: depend +depend: + makedepend -Y $(SRC) + +# DO NOT DELETE + +gpio.o: ../version.h diff --git a/gpio/OrangePi.c b/gpio/OrangePi.c new file mode 100644 index 0000000..7498f3d --- /dev/null +++ b/gpio/OrangePi.c @@ -0,0 +1,1373 @@ +#include +#include +#include +#include "OrangePi.h" +#include + +#ifdef CONFIG_ORANGEPI_PC2 +int physToWpi[64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, //3, 4 + 1, -1, //5, 6 + 2, 3, //7, 8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23, 24 + -1, 16, // 25, 26 + 17, 18, //27, 28 + 19, -1, //29, 30 + 20, 21, //31, 32 + 22, -1, //33, 34 + 23, 24, //35, 36 + 25, 26, //37, 38 + -1, 27, //39, 40 + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //41-> 55 + -1, -1, -1, -1, -1, -1, -1, -1 // 56-> 63 +}; + +char *physNames[64] = +{ + NULL, + + " 3.3V", "5V ", + " SDA.0", "5V ", + " SCL.0", "GND ", + " PWM.1", "PC05 ", + " GND", "PC06 ", + " RXD.2", "PD14 ", + " TXD.2", "GND ", + " CTS.2", "PC04 ", + " 3.3V", "PC07 ", + " MOSI.1", "GND ", + " MISO.1", "RTS.2 ", + " SCLK.1", "CE.1 ", + " GND", "PA21 ", + " SDA.1", "SCL.1 ", + " PA07", "GND ", + " PA08", "RTS.1 ", + " PA09", "GND ", + " PA10", "CTS.1 ", + " PD11", "TXD.1 ", + " GND", "RXD.1 ", + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +}; +#endif /* PC2 */ + +#ifdef CONFIG_ORANGEPI_PRIME +int physToWpi[64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, //3, 4 + 1, -1, //5, 6 + 2, 3, //7, 8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23, 24 + -1, 16, // 25, 26 + 17, 18, //27, 28 + 19, -1, //29, 30 + 20, 21, //31, 32 + 22, -1, //33, 34 + 23, 24, //35, 36 + 25, 26, //37, 38 + -1, 27, //39, 40 + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //41-> 55 + -1, -1, -1, -1, -1, -1, -1, -1 // 56-> 63 +}; + +char *physNames[64] = +{ + NULL, + + " 3.3V", "5V ", + " SDA.0", "5V ", + " SCL.0", "GND ", + " PWM.1", "PC05 ", + " GND", "PC06 ", + " RXD.2", "PD14 ", + " TXD.2", "GND ", + " CTS.2", "PC04 ", + " 3.3V", "PC07 ", + " MOSI.1", "GND ", + " MISO.1", "RTS.2 ", + " SCLK.1", "CE.1 ", + " GND", "PC08 ", + " SDA.1", "SCL.1 ", + " PA07", "GND ", + " PA08", "PC09 ", + " PA09", "GND ", + " PA10", "PC10 ", + " PD11", "PC11 ", + " GND", "PC12 ", + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +}; +#endif /* PRIME */ + +#ifdef CONFIG_ORANGEPI_ZEROPLUS +int physToWpi [64] = //return wiringPI pin +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, //3, 4 + 1, -1, //5, 6 + 2, 3, //7, 8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23, 24 + -1, 16, // 25, 26 + + -1, -1, //27, 28 + -1, -1, //29, 30 + -1, -1, //31, 32 + -1, -1, //33, 34 + -1, -1, //35, 36 + -1, -1, //37, 38 + -1, -1, //39, 40 + -1, -1, //41, 42 +// Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +char *physNames[64] = +{ + NULL, + + " 3.3V", "5V ", + " SDA.0", "5V ", + " SCL.0", "GND ", + " PA6", "TXD.1 ", + " GND", "RXD.1 ", + " RXD.2", "PA07 ", + " TXD.2", "GND ", + " CTS.2", "SDA.1 ", + " 3.3V", "SCL.1 ", + " MOSI.1", "GND ", + " MISO.1", "RTS.2 ", + " SCLK.1", "CE.1 ", + " GND", "PA10 ", + + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, +}; +#endif /* ZEROPLUS */ + +#ifdef CONFIG_ORANGEPI_2G_IOT +char *physNames[64] = +{ + NULL, + + " 3.3V", "5V ", + " SDA.0", "5V ", + " SCL.0", "GND ", + " GPIO.7", "TXD.2 ", + " GND", "RXD.2 ", + " RXD.1", "GPIO.1 ", + " TXD.1", "GND ", + " CTS.1", "GPIO.4 ", + " 3.3V", "GPIO.5 ", + " SDI.2", "GND ", + " SDIO.2", "RTS1 ", + " SCLK.2", "CE.0 ", + " GND", "CE.1 ", + " SDA.1", "SCL.1 ", + " GPIO.21", "GND ", + " GPIO.22", "RTS.2 ", + " GPIO.23", "GND ", + " GPIO.24", "CTS.2 ", + " GPIO.25", "SCL.2 ", + " GND", "SDA.2 ", + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +}; + +int physToWpi[64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 8, -1, // 3, 4 + 9, -1, // 5, 6 + 7, 15, // 7, 8 + -1, 16, // 9, 10 + 0, 1, //11, 12 + 2, -1, //13, 14 + 3, 4, //15, 16 + -1, 5, //17, 18 + 12, -1, //19, 20 + 13, 6, //21, 22 + 14, 10, //23, 24 + -1, 11, //25, 26 + 30, 31, //27, 28 + 21, -1, //29, 30 + 22, 26, //31, 32 + 23, -1, //33, 34 + 24, 27, //35, 36 + 25, 28, //37, 38 + -1, 29, //39, 40 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //41-> 55 + -1, -1, -1, -1, -1, -1, -1, -1 // 56-> 63 +}; +#endif + +#ifdef CONFIG_ORANGEPI_WIN +char *physNames [64] = +{ + NULL, + + " 3.3V", "5V ", + " SDA.1", "5V ", + " SCL.1", "GND ", + " PL10", "PL02 ", + " GND", "PL03 ", + " RXD.3", "PD04 ", + " TXD.3", "GND ", + " CTS.3", "PL09 ", + " 3.3V", "PC04 ", + " MOSI.1", "GND ", + " MISO.1", "RTS.3 ", + " SCLK.1", "CE.1 ", + " GND", "PD06 ", + " SDA.2", "SCL.2 ", + " PB04", "GND ", + " PB05", "RTS.2 ", + " PB06", "GND ", + " PB07", "CTS.2 ", + " PD05", "TXD.2 ", + " GND", "RXD.2 ", + + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +}; + +int physToWpi [64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, // 3, 4 + 1, -1, // 5, 6 + 2, 3, // 7, 8 + -1, 4, // 9, 10 + 5, 6, //11, 12 + 7, -1, //13, 14 + 8, 9, //15, 16 + -1, 10, //17, 18 + 11, -1, //19, 20 + 12, 13, //21, 22 + 14, 15, //23, 24 + -1, 16, //25, 26 + 17, 18, //27, 28 + 19, -1, //29, 30 + 20, 21, //31, 32 + 22, -1, //33, 34 + 23, 24, //35, 36 + 25, 26, //37, 38 + -1, 27, //39, 40 + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //41-> 55 + -1, -1, -1, -1, -1, -1, -1, -1 // 56-> 63 +}; +#endif + +#ifdef CONFIG_ORANGEPI_H3 +int physToWpi[64] = +{ + -1, //0 + -1, -1, // 1, 2 + 0, -1, // 3, 4 + 1, -1, // 5, 6 + 2, 3, // 7, 8 + -1, 4, // 9, 10 + 5, 6, //11, 12 + 7, -1, //13, 14 + 8, 9, //15, 16 + -1, 10, //17, 18 + 11, -1, //19, 20 + 12, 13, //21, 22 + 14, 15, //23, 24 + -1, 16, //25, 26 + 17, 18, //27, 28 + 19, -1, //29, 30 + 20, 21, //31, 32 + 22, -1, //33, 34 + 23, 24, //35, 36 + 25, 26, //37, 38 + -1, 27, //39, 40 + 28, 29, //41, 42 + + // Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +char *physNames[64] = +{ + NULL, + + " 3.3V", "5V ", + " SDA.0", "5V ", + " SCL.0", "GND ", + " PA6", "TXD.3 ", + " GND", "RXD.3 ", + " RXD.2", "PD14 ", + " TXD.2", "GND ", + " CTS.2", "PC04 ", + " 3.3V", "PC07 ", + " MOSI.0", "GND ", + " MISO.0", "RTS.2 ", + " SCLK.0", "CE.0 ", + " GND", "PA21 ", + " SDA.1", "SCL.1 ", + " PA07", "GND ", + " PA08", "RTS.1 ", + " PA09", "GND ", + " PA10", "CTS.1 ", + " PA20", "TXD.1 ", + " GND", "RXD.1 ", + " PA04", "PA05 ", + + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, +}; +#endif /* H3 */ + +#if CONFIG_ORANGEPI_ZEROPLUS2_H3 || CONFIG_ORANGEPI_ZEROPLUS2_H5 +int physToWpi [64] = //return wiringPI pin +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, //3, 4 + 1, -1, //5, 6 + 2, 3, //7, 8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23, 24 + -1, 16, // 25, 26 + + -1, -1, //27, 28 + -1, -1, //29, 30 + -1, -1, //31, 32 + -1, -1, //33, 34 + -1, -1, //35, 36 + -1, -1, //37, 38 + -1, -1, //39, 40 + -1, -1, //41, 42 +// Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +char *physNames[64] = +{ + NULL, + + " 3.3V", "5V ", + " SDA.0", "5V ", + " SCL.0", "GND ", + " PA6", "TXD.2 ", + " GND", "RXD.2 ", + " S-SCL", "PD11 ", + " S-SDA", "GND ", + " CTS.2", "SDA.1 ", + " 3.3V", "SCL.1 ", + " MOSI.1", "GND ", + " MISO.1", "RTS.2 ", + " SCLK.1", "CE.1 ", + " GND", "PD14 ", + + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, +}; +#endif /* ZERO_PLUS2 */ + + +#ifdef CONFIG_ORANGEPI_ZERO +int physToWpi [64] = +{ + -1, // 0 + + -1, -1, // 1, 2 + 0, -1, // 3, 4 + 1, -1, // 5, 6 + 2, 3, // 7, 8 + -1, 4, // 9, 10 + 5, 6, //11, 12 + 7, -1, //13, 14 + 8, 9, //15, 16 + -1, 10, //17, 18 + 11, -1, //19, 20 + 12, 13, //21, 22 + 14, 15, //23, 24 + -1, 16, //25, 26 + + -1, -1, //27, 28 + -1, -1, //29, 30 + -1, -1, //31, 32 + -1, -1, //33, 34 + -1, -1, //35, 36 + -1, -1, //37, 38 + -1, -1, //39, 40 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //41-> 55 + -1, -1, -1, -1, -1, -1, -1, -1 // 56-> 63 +}; + +char *physNames[64] = +{ + NULL, + + " 3.3V", "5V ", + " SDA.0", "5V ", + " SCL.0", "GND ", + " PA6", "TXD.1 ", + " GND", "RXD.1 ", + " RXD.2", "PA07 ", + " TXD.2", "GND ", + " CTS.2", "SDA.1 ", + " 3.3V", "SCK.1 ", + " MOSI.1", "GND ", + " MISO.1", "RTS.2 ", + " SCLK.1", "CE.1 ", + " GND", "PA10 ", + + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, +}; +#endif + +#ifdef CONFIG_ORANGEPI_LITE2 +int physToWpi [64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, + 1, -1, + 2, 3, //7, 8 + -1, 4, + 5, 6, //11, 12 + 7, -1, + 8, 9, //15, 16 + -1, 10, + 11, -1, //19, 20 + 12, 13, + 14, 15, //23, 24 + -1, 16, // 25, 26 + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 + +}; + +char *physNames [64] = +{ + NULL, + + " 3.3V", "5V ", + " SDA.1", "5V ", + " SCL.1", "GND ", + " PH4", "PD21 ", + " GND", "PD22 ", + " RXD.3", "PC9 ", + " TXD.3", "GND ", + " CTS.3", "PC8 ", + " 3.3V", "PC7 ", + " MOSI.0", "GND ", + " MISO.0", "RTS.3 ", + " SCLK.0", "CE.0 ", + " GND", "PH3 ", + + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, +}; +#endif + +#ifdef CONFIG_ORANGEPI_3 +int physToWpi [64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, + 1, -1, + 2, 3, //7, 8 + -1, 4, + 5, 6, //11, 12 + 7, -1, + 8, 9, //15, 16 + -1, 10, + 11, -1, //19, 20 + 12, 13, + 14, 15, //23, 24 + -1, 16, // 25, 26 + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 + +}; + +char *physNames [64] = +{ + NULL, + + " 3.3V", "5V ", + " SDA.0", "5V ", + " SCL.0", "GND ", + " PWM.0", "PL02 ", + " GND", "PL03 ", + " RXD.3", "PD18 ", + " TXD.3", "GND ", + " PL10", "PD15 ", + " 3.3V", "PD16 ", + " MOSI.1", "GND ", + " MISO.1", "PD21 ", + " SCLK.1", "CE.1 ", + " GND", "PL08 ", + + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, +}; +#endif + +// #ifdef CONFIG_ORANGEPI_ZERO2 +// int physToWpi [64] = +// { +// -1, // 0 +// -1, -1, // 1, 2 +// 0, -1, +// 1, -1, +// 2, 3, //7, 8 +// -1, 4, +// 5, 6, //11, 12 +// 7, -1, +// 8, 9, //15, 16 +// -1, 10, +// 11, -1, //19, 20 +// 12, 13, +// 14, 15, //23, 24 +// -1, 16, // 25, 26 +// 17, -1, +// 18, -1, +// 19, -1, +// 20, -1, + +// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 +// -1, // ... 63 + +// }; + +// char *physNames [64] = +// { +// NULL, + +// " 3.3V", "5V ", +// " SDA.3", "5V ", +// " SCL.3", "GND ", +// " PC9", "TXD.5 ", +// " GND", "RXD.5 ", +// " PC6", "PC11 ", +// " PC5", "GND ", +// " PC8", "PC15 ", +// " 3.3V", "PC14 ", +// " MOSI.1", "GND ", +// " MISO.1", "PC7 ", +// " SCLK.1", "CE.1 ", +// " GND", "PC10 ", +// " PC1", " ", +// " PI16", " ", +// " PI6", " ", +// " PH10", " ", + + +// NULL, NULL, +// NULL, NULL, +// NULL, NULL, +// NULL, NULL, +// NULL, NULL, +// NULL, NULL, +// NULL, NULL, +// NULL, NULL, +// NULL, NULL, +// NULL, NULL, +// NULL, NULL, +// NULL, NULL, +// NULL, NULL, +// NULL, NULL, +// NULL, NULL, +// NULL, NULL, +// NULL, NULL, +// NULL, +// }; +// #endif + +#ifdef CONFIG_ORANGEPI_ZERO2 +// phys = pins +int pinToGpioOrangePi [64] = +{ + -1, // 0 + -1 , -1 , + 264 , -1 , + 263 , -1 , + 256 , 224 , + -1 , 225 , + 226 , 257 , + 227 , -1 , + 269 , 270 , + -1 , 228 , + 231 , -1 , + 232 , 262 , + 230 , 229 , + -1 , 233 , + 266 , 265 , + 267 , -1 , + 268 , 261 , + 271 , -1 , + 258 , 234 , + 272 , 260 , + -1 , 259 , // 40 + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, // 63 +}; +int physToWpi[64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 3, -1, //3, 4 + 5, -1, //5, 6 + 7, 8, //7, 8 + -1, 10, //9,10 + 11, 12, //11,12 + 13, -1, //13,14 + 15, 16, //15,16 + -1, 18, //17,18 + 19, -1, //19,20 + 21, 22, //21,22 + 23, 24, //23, 24 + -1, 26, // 25, 26 + 27, 28, //27, 28 + 29, -1, //29, 30 + 31, 32, //31, 32 + 33, -1, //33, 34 + 35, 36, //35, 36 + 37, 38, //37, 38 + -1, 40, //39, 40 + // Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +char *physNames[64] = +{ + NULL, + " 3.3V", "5V ", + " TWI1_SDA", "5V ", + " TWI1_SCL", "GND ", + "I2S0_MCLK", "TX0", + " GND", "RX0", + " TX5", "I2S_CLK", + " RX5", "GND ", + " TX4/PWM3", "RX4/PWM4", + " 3.3V", "PH4", + "SPI1_MOSI", "GND ", + "SPI1_MISO", "RX2", + " SPI1_CLK", "SPI1_CS0 ", + " GND", "SPI1_CS1", + " TWI2_SDA", "TWI2_SCL", + " PI11", "GND ", + " PI12", "LEDC/TX2", + " PI15", "GND ", + "I2S0_LRCK", "PH10", + " PI16", "I2S0_DOUT", + " GND", "I2S0_DIN", + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +}; +#endif + +#ifdef CONFIG_ORANGEPI_RK3399 +int pinToGpioOrangePi [64] = +{ + 43, 44, // 0, 1 + 64, 148, // 2, 3 + 147, 80, // 4 5 + 65, 81, // 6, 7 + 82, 66, // 8, 9 + 67, 39, //10,11 + 40, 83, //12,13 + 41, 42, //14,15 + 133, 154, //16,17 + 50, 68, //18,19 + 69, 76, //20,21 + 70, 71, //22,23 + 73, 72, //24,25 + 74, 75, //26,27 + + -1, -1, //28,29 + -1, -1, //30,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 +}; + +int physToWpi[64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, //3, 4 + 1, -1, //5, 6 + 2, 3, //7, 8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23, 24 + -1, 16, // 25, 26 + + 17, 18, //27, 28 + 19, -1, //29, 30 + 20, 21, //31, 32 + 22, -1, //33, 34 + 23, 24, //35, 36 + 25, 26, //37, 38 + -1, 27, //39, 40 + // Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +char *physNames[64] = +{ + NULL, + " 3.3V", "5V ", + " SDA.0", "5V ", + " SCL.0", "GND ", + " GPIO4", "Tx ", + " GND", "Rx ", + " GPIO17", "GPIO18 ", + " GPIO27", "GND ", + " GPIO22", "GPIO23 ", + " 3.3V", "GPIO24 ", + " MOSI", "GND ", + " MISO", "GPIO25 ", + " SCLK", "CS0 ", + " GND", "CS1 ", + " DNP1", "DNP2 ", + " GPIO5", "GND ", + " GPIO6", "GPIO12 ", + " GPIO13", "GND ", + " GPIO19", "GPIO16 ", + " GPIO26", "GPIO20 ", + " GND", "GPIO21 ", + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +}; +#endif + + +#ifdef CONFIG_ORANGEPI_800 +int pinToGpioOrangePi [64] = +{ + 43, 44, //0,1 + 150, 39, //2,3 + 40, 148, //4,5 + 152, 147, //6,7 + 149, 64, //8,9 + 65, 74, //10,11 + 73, 153, //12,13 + 75, 76, //14,15 + 154, -1, //16,17 + -1, -1, //18,19 + -1, -1, //20,21 + -1, -1, //22,23 + -1, -1, //24,25 + -1, -1, //26,27 + -1, -1, //28,29 + -1, -1, //30,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 +}; + +int physToWpi[64] = +{ + -1, //0 + -1, -1, //1,2 + 0, -1, //3,4 + 1, -1, //5,6 + 2, 3, //7,8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23,24 + -1, 16, //25,26 + -1, -1, //27,28 + -1, -1, //29,30 + -1, -1, //31,32 + -1, -1, //33,34 + -1, -1, //35,36 + -1, -1, //37,38 + -1, -1, //39,40 + // Padding: + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +char *physNames[64] = +{ + NULL, + " 3.3V", "5V ", + " SDA.4", "5V ", + " SCL.4", "GND ", + " PWM1", "RXD.4 ", + " GND", "TXD.4 ", + " TXD.2", "GPIO4_D0", + " RXD.2", "GND ", + "GPIO4_C5", "SDA.2 ", + " 3.3V", "SCL.2 ", + "SPI2_TXD", "GND ", + "SPI2_RXD", "GPIO4_D1", + "SPI2_CLK", "SPI2_CS ", + " GND", "GPIO4_D2", + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +}; +#endif + +#ifdef CONFIG_ORANGEPI_4 +int pinToGpioOrangePi [64] = +{ + 64, 65, // 0, 1 + 150, 145, // 2, 3 + 144, 33, // 4 5 + 50, 35, // 6, 7 + 92, 54, // 8, 9 + 55, 40, //10,11 + + 39, 56, //12,13 + + 41, 42, //14,15 + 149, 64, //16,17 + 65, -1, //18,19 + -1, -1, //20,21 + -1, -1, //22,23 + -1, -1, //24,25 + + + -1, -1, //26,27 + + -1, -1, //28,29 + -1, -1, //30,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 +}; +int physToWpi[64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, //3, 4 + 1, -1, //5, 6 + 2, 3, //7, 8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23, 24 + -1, 16, // 25, 26 + + 17, 18, //27, 28 + -1, -1, //29, 30 + -1, -1, //31, 32 + -1, -1, //33, 34 + -1, -1, //35, 36 + -1, -1, //37, 38 + -1, -1, //39, 40 + // Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +char *physNames[64] = +{ + NULL, + " 3.3V", "5V ", + "I2C2_SDA", "5V ", + "I2C2_SCL", "GND ", + " PWM1", "I2C3_SCL", + " GND", "I2C3_SDA", + "GPIO1_A1", "GPIO1_C2", + "GPIO1_A3", "GND ", + "GPIO2_D4", "GPIO1_C6", + " 3.3V", "GPIO1_C7", + "SPI1_TXD", "GND ", + "SPI1_RXD", "GPIO1_D0", + "SPI1_CLK", "SPI1_CS ", + " GND", "GPIO4_C5", + "I2C2_SDA", "I2C2_SCL", + " I2S0_RX", "GND ", + " I2S0_TX", "I2S_CLK ", + "I2S0_SCK", "GND ", + "I2S0_SI0", "I2S0_SO0", + "I2S0_SI1", "I2S0_SI2", + " GND", "I2S0_SI3", + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +}; +#endif + +#ifdef CONFIG_ORANGEPI_4_LTS +int pinToGpioOrangePi [64] = +{ + 52, 53, // 0, 1 + 150, 145, // 2, 3 + 144, 33, // 4 5 + 50, 35, // 6, 7 + 92, 54, // 8, 9 + 55, 40, //10,11 + 39, 56, //12,13 + 41, 42, //14,15 + 149, 64, //16,17 + 65, -1, //18,19 + -1, -1, //20,21 + -1, -1, //22,23 + -1, -1, //24,25 + -1, -1, //26,27 + -1, -1, //28,29 + -1, -1, //30,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 +}; +int physToWpi[64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, //3, 4 + 1, -1, //5, 6 + 2, 3, //7, 8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23, 24 + -1, 16, // 25, 26 + + -1, -1, //27, 28 + -1, -1, //29, 30 + -1, -1, //31, 32 + -1, -1, //33, 34 + -1, -1, //35, 36 + -1, -1, //37, 38 + -1, -1, //39, 40 + // Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +char *physNames[64] = +{ + NULL, + " 3.3V", "5V ", + "I2C8_SDA", "5V ", + "I2C8_SCL", "GND ", + " PWM1", "I2C3_SCL", + " GND", "I2C3_SDA", + "GPIO1_A1", "GPIO1_C2", + "GPIO1_A3", "GND ", + "GPIO2_D4", "GPIO1_C6", + " 3.3V", "GPIO1_C7", + "SPI1_TXD", "GND ", + "SPI1_RXD", "GPIO1_D0", + "SPI1_CLK", "SPI1_CS ", + " GND", "GPIO4_C5", + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +}; +#endif + +#ifdef CONFIG_ORANGEPI_R1PLUS +int physToWpi[64] = +{ + -1, //0 + -1, -1, //1, 2 + 0, 1, //3, 4 + 2, 3, //5, 6 + -1, -1, //7, 8 + -1, 4, //9, 10 + 5, 6, //11, 12 + 7, -1, //13, 14 + + -1, -1, //15,16 + -1, -1, //17,18 + -1, -1, //19,20 + -1, -1, //21,22 + -1, -1, //23,24 + -1, -1, //25,26 + -1, -1, //27,28 + -1, -1, //29,30 + -1, -1, //31,32 + -1, -1, //33,34 + -1, -1, //35,36 + -1, -1, //37,38 + -1, -1, //39,40 + // Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +char *physNames[64] = +{ + NULL, + + "5V ", "GND ", + "SDA.0 ", "SCK.0 ", + "TXD.1 ", "RXD.1 ", + " ", " ", + " ", "GPIO3_C0", + "CTS.1 ", "RTS.1 ", + "GPIO2_A2", " ", + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL,NULL,NULL,NULL,NULL, +}; +#endif + + + + +/* + * ReadAll + */ +void OrangePiReadAll(void) +{ + int pin; + int tmp = wiringPiDebug; + wiringPiDebug = FALSE; + +#ifdef CONFIG_ORANGEPI_PC2 + printf (" +------+-----+----------+------+---+ OPi PC2 +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_PRIME + printf (" +------+-----+----------+------+---+ PRIME +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_ZEROPLUS + printf (" +------+-----+----------+------+---+ ZEROPLUS +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_ZEROPLUS2_H5 + printf (" +------+-----+----------+------+---+ZEROPLUS 2+---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_2G_IOT + printf (" +------+-----+----------+------+---+ 2G-IOT +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_H3 + printf (" +------+-----+----------+------+---+OrangePiH3+---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_ZEROPLUS2_H3 + printf (" +------+-----+----------+------+---+ZEROPLUS 2+---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_ZERO + printf (" +------+-----+----------+------+---+ OPi H2 +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_WIN + printf (" +------+-----+----------+------+---+ OPi Win +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_LITE2 + printf (" +------+-----+----------+------+---+ OPi H6 +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_3 + printf (" +------+-----+----------+------+---+ OPi 3 +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_ZERO2 + printf (" +------+-----+----------+------+---+ H616 +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_RK3399 + printf (" +------+-----+----------+------+---+OPi RK3399+---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_4 + printf (" +------+-----+----------+------+---+OrangePi 4+---+---+--+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_4_LTS + printf (" +------+-----+----------+------+---+OPi 4 LTS +---+---+--+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_800 + printf (" +------+-----+----------+------+---+ 800 +---+---+--+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_R1PLUS + printf (" +------+-----+----------+------+---+ R1 Plus +---+---+--+----------+-----+------+\n"); +#endif + + printf (" | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO |\n"); + printf (" +------+-----+----------+------+---+----++----+---+------+----------+-----+------+\n"); + +#if defined CONFIG_ORANGEPI_H3 || defined CONFIG_ORANGEPI_RK3399 || CONFIG_ORANGEPI_4 || CONFIG_ORANGEPI_PC2 || CONFIG_ORANGEPI_PRIME || CONFIG_ORANGEPI_WIN + for (pin = 1 ; pin <= 40; pin += 2) + +#elif CONFIG_ORANGEPI_LITE2 || CONFIG_ORANGEPI_ZEROPLUS2_H3 || CONFIG_ORANGEPI_3 || CONFIG_ORANGEPI_ZERO || CONFIG_ORANGEPI_ZEROPLUS || CONFIG_ORANGEPI_R1 || CONFIG_ORANGEPI_ZEROPLUS2_H5 || CONFIG_ORANGEPI_800 || CONFIG_ORANGEPI_4_LTS + for (pin = 1 ; pin <= 26; pin += 2) + +#elif CONFIG_ORANGEPI_R1PLUS + for (pin = 1 ; pin <= 13; pin += 2) + +#elif CONFIG_ORANGEPI_ZERO2 + for (pin = 1 ; pin <= 34; pin += 2) +#endif + readallPhys(pin); + + printf (" +------+-----+----------+------+---+----++----+---+------+----------+-----+------+\n"); + printf (" | GPIO | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | GPIO |\n"); + +#ifdef CONFIG_ORANGEPI_PC2 + printf (" +------+-----+----------+------+---+ OPi PC2 +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_PRIME + printf (" +------+-----+----------+------+---+ PRIME +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_ZEROPLUS + printf (" +------+-----+----------+------+---+ ZEROPLUS +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_ZEROPLUS2_H5 + printf (" +------+-----+----------+------+---+ZEROPLUS 2+---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_2G_IOT + printf (" +------+-----+----------+------+---+ 2G-IOT +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_H3 + printf (" +------+-----+----------+------+---+OrangePiH3+---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_ZEROPLUS2_H3 + printf (" +------+-----+----------+------+---+ZEROPLUS 2+---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_ZERO + printf (" +------+-----+----------+------+---+ OPi H2 +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_WIN + printf (" +------+-----+----------+------+---+ OPi Win +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_LITE2 + printf (" +------+-----+----------+------+---+ OPi H6 +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_3 + printf (" +------+-----+----------+------+---+ OPi 3 +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_ZERO2 + printf (" +------+-----+----------+------+---+ H616 +---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_RK3399 + printf (" +------+-----+----------+------+---+OPi RK3399+---+------+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_4 + printf (" +------+-----+----------+------+---+OrangePi 4+---+---+--+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_4_LTS + printf (" +------+-----+----------+------+---+OPi 4 LTS +---+---+--+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_800 + printf (" +------+-----+----------+------+---+ 800 +---+---+--+----------+-----+------+\n"); +#elif CONFIG_ORANGEPI_R1PLUS + printf (" +------+-----+----------+------+---+ R1 Plus +---+---+--+----------+-----+------+\n"); +#endif + + wiringPiDebug = tmp; +} diff --git a/gpio/OrangePi.h b/gpio/OrangePi.h new file mode 100644 index 0000000..113842f --- /dev/null +++ b/gpio/OrangePi.h @@ -0,0 +1,11 @@ +#ifndef _ORANGEPI_H_ +#define _ORANGEPI_H_ + +extern char *physNames[64]; +extern int physToWpi[64]; +extern int pinToGpioOrangePi[64]; + +extern void OrangePiReadAll(void); +extern void readallPhys(int physPin); + +#endif diff --git a/gpio/gpio.1 b/gpio/gpio.1 new file mode 100644 index 0000000..a71aaae --- /dev/null +++ b/gpio/gpio.1 @@ -0,0 +1,351 @@ +.TH GPIO 1 "March 2018" wiringPi "Command-Line access to Raspberry Pi's GPIO" + +.SH NAME +gpio \- Command-line access to Raspberry Pi's GPIO + +.SH SYNOPSIS +.B gpio +.B \-v +.PP +.B gpio +.B [ \-g | \-1 ] +.B mode/read/write/aread/awrite/wb/pwm/pwnTone/clock/toggle/blink ... +.PP +.B gpio +.B [ \-x extension:params ] +.B mode/read/write/aread/awrite/pwm/toggle/blink ... +.PP +.B gpio +.B [ \-p ] +.B read/write/toggle/blink +.B ... +.PP +.B gpio +.B [ \-p ] +.B pwnTone pin frequency +.B ... +.PP +.B gpio +.B readall +.PP +.B gpio +.B unexportall/exports +.PP +.B gpio +.B export/edge/unexport +.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 +.B pwmr +range +.PP +.B gpio +.B load \ i2c/spi ... +.PP +.B gpio +.B gbr +channel +.PP +.B gpio +.B gbw +channel value + +.SH DESCRIPTION + +.B GPIO +is a swiss army knife of a command line tool to allow the user easy +access to the GPIO pins on the Raspberry Pi and the SPI A/D and D/A +converters on the Gertboard. It's designed for simple testing and +diagnostic purposes, but can be used in shell scripts for general if +somewhat slow control of the GPIO pins. + +It can also control the IO's on the PiFace IO board and load the SPI and I2C +kernel modules if required. + +Additionally, it can be used to set the exports in the \fI/sys/class/gpio\fR +system directory to allow subsequent programs to use the \fR/sys/class/gpio\fR +interface without needing to be run as root. + +.SH OPTIONS + +.TP +.B \-v +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 +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. 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 +Read the digital value of the given pin and print 0 or 1 to represent the +respective logic levels. + +.TP +.B write +Write the given value (0 or 1) to the pin. You need to set the pin +to output mode first. + +.TP +.B toggle +Changes the state of a GPIO pin; 0 to 1, or 1 to 0. + +Note unlike the blink command, the pin must be in output mode first. + +.TP +.B blink +Blinks the given pin on/off. Press Control-C to exit. + +Note: This command explicitly sets the pin to output mode. + +.TP +.B aread +Read the analog value of the given pin. This needs to be used in +conjunction with a -x flag to add in an extension that handles analog +inputs. + +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. + +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 +to specify a hexadecimal number. You need to set pins to output mode +first. + +.TP +.B readall +Output a table of all GPIO pins values. The values represent the actual values read +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 +into PWM mode first. + +.TP +.B clock +Set the output frequency on the given pin. The pin needs to be put into +clock mode first. + +.TP +.B mode +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. + +.TP +.B exports +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, \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 +later kernels, the \fI/sys/class/gpio/gpioX/edge\fR pseudo files to +that of the user running the \fBgpio\fR program. This means that you +can have a small script of gpio exports to setup the gpio pins as your +program requires without the need to run anything as root, or with the +sudo command. + +.TP +.B edge +This exports a GPIO pin in the \fI/sys/class/gpio\fR directory, set +the direction to input and set the edge interrupt method to \fInone\fR, +\fIrising\fR, \fIfalling\fR or \fIboth\fR. Use like the export command +above and note that \fBBCM_GPIO\fR pin number is used not not wiringPi pin +numbering. + +Like the export commands above, ownership is set to that of the +calling user, allowing subsequent access from user programs without +requiring root/sudo. + +.TP +.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 + +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+ and the Model B, v2. + +.TP +.B pwm-bal/pwm-ms +Change the PWM mode to balanced (the default) or mark:space ratio (traditional) + +.TP +.B pwmr +Change the PWM range register. The default is 1024. + +.TP +.B gbr +channel + +This reads the analog to digital converter on the Gertboard on the given +channel. The board jumpers need to be in-place to do this operation. + +.TP +.B gbw +channel value + +This writes the supplied value to the output channel on the Gertboards +SPI digital to analogue converter. +The board jumpers need to be in-place to do this operation. + + +.SH "WiringPi vs. BCM_GPIO Pin numbering vs. Physical pin numbering" + +.PP +The quickest way to get a list of the pin differences is to run the command +.TP +gpio readall + +.SH FILES + +.TP 2.2i +.I gpio +executable + +.SH EXAMPLES +.TP 2.2i +gpio mode 4 output # Set pin 4 to output +.PP +gpio -g mode 23 output # Set GPIO pin 23 to output (same as WiringPi pin 4) +.PP +gpio mode 1 pwm # Set pin 1 to PWM mode +.PP +gpio pwm 1 512 # Set pin 1 to PWM value 512 - half brightness +.PP +gpio export 17 out # Set GPIO Pin 17 to output +.PP +gpio export 0 in # Set GPIO Pin 0 (SDA0) to input. +.PP +gpio -g read 0 # Read GPIO Pin 0 (SDA0) + +.SH "NOTES" + +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 +http://wiringpi.com/ + +.SH AUTHOR + +Gordon Henderson + +.SH "REPORTING BUGS" + +Please report bugs to + +.SH COPYRIGHT + +Copyright (c) 2012-2018 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. + +.SH TRADEMARKS AND ACKNOWLEDGEMENTS + +Raspberry Pi is a trademark of the Raspberry Pi Foundation. See +http://raspberrypi.org/ for full details. diff --git a/gpio/gpio.c b/gpio/gpio.c new file mode 100644 index 0000000..26b1c9b --- /dev/null +++ b/gpio/gpio.c @@ -0,0 +1,1679 @@ +/* + * gpio.c: + * Swiss-Army-Knife, Set-UID command-line interface to the Raspberry + * Pi's GPIO. + * Copyright (c) 2012-2018 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "../version.h" + +#ifdef CONFIG_ORANGEPI +#include "OrangePi.h" +#include +#endif + +extern int wiringPiDebug ; + +// External functions I can't be bothered creating a separate .h file for: + +extern void doReadall (void) ; +extern void doAllReadall (void) ; +extern void doQmode (int argc, char *argv []) ; + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==2) +#endif + +#define PI_USB_POWER_CONTROL 38 +#define I2CDETECT "i2cdetect" +#define MODPROBE "modprobe" +#define RMMOD "rmmod" + +int wpMode ; + +#ifdef CONFIG_ORANGEPI +const char *piModelNames[6] = +{ + "Unknown", + "Model A", + "Model B", + "Model B+", + "Compute Module", +#ifdef CONFIG_ORANGEPI_2G_IOT + "OrangePi 2G-IOT", +#elif CONFIG_ORANGEPI_PC2 || CONFIG_ORANGEPI_ZEROPLUS2_H5 || CONFIG_ORANGEPI_ZEROPLUS || CONFIG_ORANGEPI_PRIME + "OrangePi PC2", +#elif CONFIG_ORANGEPI_A64 + "OrangePi Win/Winplus", +#elif CONFIG_ORANGEPI_H3 || CONFIG_ORANGEPI_ZEROPLUS2_H3 + "OrangePi H3 family", +#elif CONFIG_ORANGEPI_ZERO + "OrangePi Zero", +#endif +}; +#endif + +char *usage = "Usage: gpio -v\n" + " gpio -h\n" + " gpio [-g|-1] ...\n" + // " gpio [-d] ...\n" + // " [-x extension:params] [[ -x ...]] ...\n" + // " gpio [-p] ...\n" + " gpio ...\n" + // " gpio ...\n" + " gpio \n" + " gpio readall\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 port\n" + " gpio serial port\n" + " gpio rbx/rbd\n" + " gpio wb \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 + + +/* + * findExecutable: + * Code to locate the path to the given executable. We have a fixed list + * of locations to try which completely overrides any $PATH environment. + * This may be detrimental, however it avoids the reliance on $PATH + * which may be a security issue when this program is run a set-uid-root. + ********************************************************************************* + */ + +static const char *searchPath [] = +{ + "/sbin", + "/usr/sbin", + "/bin", + "/usr/bin", + NULL, +} ; + +static char *findExecutable (const char *progName) +{ + static char *path = NULL ; + int len = strlen (progName) ; + int i = 0 ; + struct stat statBuf ; + + for (i = 0 ; searchPath [i] != NULL ; ++i) + { + path = malloc (strlen (searchPath [i]) + len + 2) ; + sprintf (path, "%s/%s", searchPath [i], progName) ; + + if (stat (path, &statBuf) == 0) + return path ; + free (path) ; + } + + return NULL ; +} + + +/* + * changeOwner: + * Change the ownership of the file to the real userId of the calling + * program so we can access it. + ********************************************************************************* + */ + +static void changeOwner (char *cmd, char *file) +{ + uid_t uid = getuid () ; + uid_t gid = getgid () ; + + if (chown (file, uid, gid) != 0) + { + +// Removed (ignoring) the check for not existing as I'm fed-up with morons telling me that +// the warning message is an error. + + if (errno != ENOENT) + fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ; + } +} + + +/* + * moduleLoaded: + * Return true/false if the supplied module is loaded + ********************************************************************************* + */ + +static int moduleLoaded (char *modName) +{ + int len = strlen (modName) ; + int found = FALSE ; + FILE *fd = fopen ("/proc/modules", "r") ; + char line [80] ; + + if (fd == NULL) + { + fprintf (stderr, "gpio: Unable to check /proc/modules: %s\n", strerror (errno)) ; + exit (1) ; + } + + while (fgets (line, 80, fd) != NULL) + { + if (strncmp (line, modName, len) != 0) + continue ; + + found = TRUE ; + break ; + } + + fclose (fd) ; + + return found ; +} + + +/* + * doLoad: + * Load either the spi or i2c modules and change device ownerships, etc. + ********************************************************************************* + */ + +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", argv [0]) ; + exit (1) ; + } +} + +static void _doLoadUsage (char *argv []) +{ + fprintf (stderr, "Usage: %s load [I2C baudrate in Kb/sec]\n", argv [0]) ; + exit (1) ; +} + +static void doLoad (int argc, char *argv []) +{ + char *module1, *module2 ; + char cmd [80] ; + char *file1, *file2 ; + char args1 [32], args2 [32] ; + + checkDevTree (argv) ; + + if (argc < 3) + _doLoadUsage (argv) ; + + args1 [0] = args2 [0] = 0 ; + + /**/ if (strcasecmp (argv [2], "spi") == 0) + { + module1 = "spidev"; + module2 = "spi_bcm2708"; + file1 = "/dev/spidev0.0"; + file2 = "/dev/spidev0.1"; + if (argc == 4) + { + 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) ; + } + else if (strcasecmp (argv [2], "i2c") == 0) + { + module1 = "i2c_dev" ; + module2 = "i2c_bcm2708" ; + file1 = "/dev/i2c-0" ; + file2 = "/dev/i2c-1" ; + if (argc == 4) + sprintf (args2, " baudrate=%d", atoi (argv [3]) * 1000) ; + else if (argc > 4) + _doLoadUsage (argv) ; + } + else + _doLoadUsage (argv) ; + + if (findExecutable ("modprobe") == NULL) + printf ("No found\n") ; + + if (!moduleLoaded (module1)) + { + sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module1, args1) ; + if ( system (cmd) ){;} + } + + if (!moduleLoaded (module2)) + { + sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module2, args2) ; + if ( system (cmd) ){;} + } + + if (!moduleLoaded (module2)) + { + fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ; + exit (1) ; + } + + sleep (1) ; // To let things get settled + + changeOwner (argv [0], file1) ; + changeOwner (argv [0], file2) ; +} + + +/* + * doUnLoad: + * Un-Load either the spi or i2c modules and change device ownerships, etc. + ********************************************************************************* + */ + +static void _doUnLoadUsage (char *argv []) +{ + fprintf (stderr, "Usage: %s unload \n", argv [0]) ; + exit (1) ; +} + +static void doUnLoad (int argc, char *argv []) +{ + char *module1, *module2 ; + char cmd [80] ; + + checkDevTree (argv) ; + + if (argc != 3) + _doUnLoadUsage (argv) ; + + /**/ if (strcasecmp (argv [2], "spi") == 0) + { + module1 = "spidev" ; + module2 = "spi_bcm2708" ; + } + else if (strcasecmp (argv [2], "i2c") == 0) + { + module1 = "i2c_dev" ; + module2 = "i2c_bcm2708" ; + } + else + _doUnLoadUsage (argv) ; + + if (moduleLoaded (module1)) + { + sprintf (cmd, "%s %s", findExecutable (RMMOD), module1) ; + if ( system (cmd) ){;} + } + + if (moduleLoaded (module2)) + { + sprintf (cmd, "%s %s", findExecutable (RMMOD), module2) ; + if ( system (cmd) ){;} + } +} + + +/* + * doI2Cdetect: + * Run the i2cdetect command with the right runes for this Pi revision + ********************************************************************************* + */ + +static void doI2Cdetect (UNU int argc, char *argv []) +{ +// int port = piGpioLayout () == 1 ? 0 : 1 ; + int port = 0; + char *c, *command ; + + if (argc != 3) + { + fprintf (stderr, "Usage: %s i2cd/i2cdetect port\n", argv [0]) ; + exit (1) ; + } + + port = atoi (argv [2]); + + if ((c = findExecutable (I2CDETECT)) == NULL) + { + fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ; + return ; + } + +#ifndef CONFIG_ORANGEPI + if (!moduleLoaded ("i2c_dev")) + { + fprintf (stderr, "%s: The I2C kernel module(s) are not loaded.\n", argv [0]) ; + return ; + } +#endif + + command = malloc (strlen (c) + 16) ; + sprintf (command, "%s -y %d", c, port) ; + if (system (command) < 0) + fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ; + +} + + +/* + * doSerialTest: + * Very simple program to test the serial port. Expects + * the port to be looped back to itself + ********************************************************************************* + */ + +static void doSerialTest (UNU int argc, char *argv []) +{ + int fd ; + int count ; + unsigned int nextTime; + char * port; + + port = argv [2]; + + if (argc != 3) { + fprintf (stderr, "Usage: %s serial port(/dev/ttySX)\n", argv [0]) ; + exit (1) ; + } + + if ((fd = serialOpen (port, 115200)) < 0) { + fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ; + return; + } + + if (wiringPiSetup () == -1) { + fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ; + return; + } + + nextTime = millis () + 300 ; + + for (count = 0 ; count < 256 ; ) { + if (millis () > nextTime) { + printf ("\nOut: %3d: ", count) ; + fflush (stdout) ; + serialPutchar (fd, count) ; + nextTime += 300 ; + ++count ; + } + + delay (3) ; + + while (serialDataAvail (fd)) { + printf (" -> %3d", serialGetchar (fd)) ; + fflush (stdout) ; + } + } + + printf ("\n") ; + return; +} + + +/* + * doExports: + * List all GPIO exports + ********************************************************************************* + */ + +static void doExports (UNU int argc, UNU char *argv []) +{ + int fd ; + int i, j, l, first ; + char fName [128] ; + char buf [16] ; + +#ifdef CONFIG_ORANGEPI + for (first = 0, j = 0 ; j < 64 ; ++j) // Crude, but effective +#else + for (first = 0, i = 0 ; i < 64 ; ++i) // Crude, but effective +#endif + { + +// Try to read the direction +#ifdef CONFIG_ORANGEPI + i = pinToGpioOrangePi[j]; +#ifdef CONFIG_ORANGEPI_RK3399 + i += 1000; +#endif + +#endif + + sprintf (fName, "/sys/class/gpio/gpio%d/direction", i) ; + if ((fd = open (fName, O_RDONLY)) == -1) + continue ; + + if (first == 0) + { + ++first ; + printf ("GPIO Pins exported:\n") ; + } + + printf ("%4d(%d): ", j, i) ; + + if ((l = read (fd, buf, 16)) == 0) + sprintf (buf, "%s", "?") ; + + buf [l] = 0 ; + if ((buf [strlen (buf) - 1]) == '\n') + buf [strlen (buf) - 1] = 0 ; + + printf ("%-3s", buf) ; + + close (fd) ; + +// Try to Read the value + + sprintf (fName, "/sys/class/gpio/gpio%d/value", i) ; + if ((fd = open (fName, O_RDONLY)) == -1) + { + printf ("No Value file (huh?)\n") ; + continue ; + } + + if ((l = read (fd, buf, 16)) == 0) + sprintf (buf, "%s", "?") ; + + buf [l] = 0 ; + if ((buf [strlen (buf) - 1]) == '\n') + buf [strlen (buf) - 1] = 0 ; + + printf (" %s", buf) ; + +// Read any edge trigger file + + sprintf (fName, "/sys/class/gpio/gpio%d/edge", i) ; + if ((fd = open (fName, O_RDONLY)) == -1) + { + printf ("\n") ; + continue ; + } + + if ((l = read (fd, buf, 16)) == 0) + sprintf (buf, "%s", "?") ; + + buf [l] = 0 ; + if ((buf [strlen (buf) - 1]) == '\n') + buf [strlen (buf) - 1] = 0 ; + + printf (" %-8s\n", buf) ; + + close (fd) ; + } +} + + +/* + * doExport: + * gpio export pin mode + * This uses the /sys/class/gpio device interface. + ********************************************************************************* + */ + +void doExport (int argc, char *argv []) +{ + FILE *fd ; + int pin ; + char *mode ; + char fName [128] ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; +#ifdef CONFIG_ORANGEPI + pin = pinToGpioOrangePi[pin]; +#ifdef CONFIG_ORANGEPI_RK3399 + pin += 1000; +#endif + +#endif + + mode = argv [3] ; + + if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL) + { + fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ; + exit (1) ; + } + + fprintf (fd, "%d\n", pin) ; + fclose (fd) ; + + sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ; + if ((fd = fopen (fName, "w")) == NULL) + { + fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ; + exit (1) ; + } + + /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0)) + fprintf (fd, "in\n") ; + 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, out, high or low\n", argv [1], mode) ; + exit (1) ; + } + + fclose (fd) ; + +// Change ownership so the current user can actually use it + + sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; + changeOwner (argv [0], fName) ; + + sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ; + changeOwner (argv [0], fName) ; + +} + + +/* + * doWfi: + * gpio wfi pin mode + * Wait for Interrupt on a given pin. + * Slight cheat here - it's easier to actually use ISR now (which calls + * gpio to set the pin modes!) then we simply sleep, and expect the thread + * to exit the program. Crude but effective. + ********************************************************************************* + */ + +static void wfi (void) + { exit (0) ; } + +void doWfi (int argc, char *argv []) +{ + int pin, mode ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s wfi pin mode\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + + /**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ; + else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ; + else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ; + else + { + fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ; + exit (1) ; + } + + if (wiringPiISR (pin, mode, &wfi) < 0) + { + fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ; + exit (1) ; + } + + for (;;) + delay (9999) ; +} + + + +/* + * doEdge: + * gpio edge pin mode + * Easy access to changing the edge trigger on a GPIO pin + * This uses the /sys/class/gpio device interface. + ********************************************************************************* + */ + +void doEdge (int argc, char *argv []) +{ + FILE *fd ; + int pin ; + char *mode ; + char fName [128] ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; +#ifdef CONFIG_ORANGEPI + pin = pinToGpioOrangePi[pin]; +#ifdef CONFIG_ORANGEPI_RK3399 + pin += 1000; +#endif + +#endif + mode = argv [3] ; + +// Export the pin and set direction to input + + if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL) + { + fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ; + exit (1) ; + } + + fprintf (fd, "%d\n", pin) ; + fclose (fd) ; + + sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ; + if ((fd = fopen (fName, "w")) == NULL) + { + fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ; + exit (1) ; + } + + fprintf (fd, "in\n") ; + fclose (fd) ; + + sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ; + if ((fd = fopen (fName, "w")) == NULL) + { + fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ; + exit (1) ; + } + + /**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ; + else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ; + else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ; + else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ; + else + { + fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ; + exit (1) ; + } + +// Change ownership of the value and edge files, so the current user can actually use it! + + sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; + changeOwner (argv [0], fName) ; + + sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ; + changeOwner (argv [0], fName) ; + + fclose (fd) ; +} + + +/* + * doUnexport: + * gpio unexport pin + * This uses the /sys/class/gpio device interface. + ********************************************************************************* + */ + +void doUnexport (int argc, char *argv []) +{ + FILE *fd ; + int pin ; + + if (argc != 3) + { + fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; +#ifdef CONFIG_ORANGEPI + pin = pinToGpioOrangePi[pin]; +#ifdef CONFIG_ORANGEPI_RK3399 + pin += 1000; +#endif + +#endif + + if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL) + { + fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ; + exit (1) ; + } + + fprintf (fd, "%d\n", pin) ; + fclose (fd) ; +} + + +/* + * doUnexportAll: + * gpio unexportall + * Un-Export all the GPIO pins. + * This uses the /sys/class/gpio device interface. + ********************************************************************************* + */ + +void doUnexportall (char *progName) +{ + FILE *fd ; + int pin ; + int i; + + for (pin = 0 ; pin < 63 ; ++pin) + { +#ifdef CONFIG_ORANGEPI + i = pinToGpioOrangePi[pin]; +#ifdef CONFIG_ORANGEPI_RK3399 + i += 1000; +#endif + +#endif + if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL) + { + fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ; + exit (1) ; + } + fprintf (fd, "%d\n", i) ; + fclose (fd) ; + } +} + + +/* + * doReset: + * Reset the GPIO pins - as much as we can do + ********************************************************************************* + */ + +static void doReset (UNU 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 ... + ********************************************************************************* + */ + +void doMode (int argc, char *argv []) +{ + int pin ; + char *mode ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + + mode = argv [3] ; + + /**/ 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, "alt2") == 0) pinModeAlt (pin, 0b010) ; + else if (strcasecmp (mode, "alt3") == 0) pinModeAlt (pin, 0b011) ; + else if (strcasecmp (mode, "alt4") == 0) pinModeAlt (pin, 0b100) ; + else if (strcasecmp (mode, "alt5") == 0) pinModeAlt (pin, 0b101) ; + else if (strcasecmp (mode, "alt6") == 0) pinModeAlt (pin, 0b110) ; + else if (strcasecmp (mode, "alt7") == 0) pinModeAlt (pin, 0b111) ; + else + { + fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/clock/up/down/tri\n", argv [1], mode) ; + exit (1) ; + } +} + + +/* + * doPadDrive: + * gpio drive group value + ********************************************************************************* + */ + +static void doPadDrive (int argc, char *argv []) +{ + int group, val ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ; + exit (1) ; + } + + group = atoi (argv [2]) ; + val = atoi (argv [3]) ; + + if ((group < 0) || (group > 2)) + { + fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ; + exit (1) ; + } + + if ((val < 0) || (val > 7)) + { + fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ; + exit (1) ; + } + + setPadDrive (group, val) ; +} + + +/* + * 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) || (model == PI_MODEL_2))) + { + fprintf (stderr, "USB power contol is applicable to B+ and v2 boards only.\n") ; + exit (1) ; + } + +// Make sure we start in 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 + * Gertboard Write - To the Analog output + ********************************************************************************* + */ + +static void doGbw (int argc, char *argv []) +{ + int channel, value ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s gbw \n", argv [0]) ; + exit (1) ; + } + + channel = atoi (argv [2]) ; + value = atoi (argv [3]) ; + + if ((channel < 0) || (channel > 1)) + { + fprintf (stderr, "%s: gbw: Channel number must be 0 or 1\n", argv [0]) ; + exit (1) ; + } + + if ((value < 0) || (value > 255)) + { + fprintf (stderr, "%s: gbw: Value must be from 0 to 255\n", argv [0]) ; + exit (1) ; + } + + if (gertboardAnalogSetup (64) < 0) + { + fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ; + exit (1) ; + } + + analogWrite (64 + channel, value) ; +} + + +/* + * doGbr: + * gpio gbr channel + * From the analog input + ********************************************************************************* + */ + +static void doGbr (int argc, char *argv []) +{ + int channel ; + + if (argc != 3) + { + fprintf (stderr, "Usage: %s gbr \n", argv [0]) ; + exit (1) ; + } + + channel = atoi (argv [2]) ; + + if ((channel < 0) || (channel > 1)) + { + fprintf (stderr, "%s: gbr: Channel number must be 0 or 1\n", argv [0]) ; + exit (1) ; + } + + if (gertboardAnalogSetup (64) < 0) + { + fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ; + exit (1) ; + } + + printf ("%d\n", analogRead (64 + channel)) ; +} + + +/* + * doWrite: + * gpio write pin value + ********************************************************************************* + */ + +static void doWrite (int argc, char *argv []) +{ + int pin, val ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + + /**/ 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)) + val = 0 ; + else + val = atoi (argv [3]) ; + + /**/ if (val == 0) + digitalWrite (pin, LOW) ; + else + 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 wb value + ********************************************************************************* + */ + +static void doWriteByte (int argc, char *argv []) +{ + int val ; + + if (argc != 3) + { + fprintf (stderr, "Usage: %s wb value\n", argv [0]) ; + exit (1) ; + } + + val = (int)strtol (argv [2], NULL, 0) ; + + digitalWriteByte (val) ; +} + + +/* + * doReadByte: + * gpio rbx|rbd value + ********************************************************************************* + */ + +static void doReadByte (int argc, char *argv [], int printHex) +{ + int val ; + + if (argc != 2) + { + fprintf (stderr, "Usage: %s rbx|rbd\n", argv [0]) ; + exit (1) ; + } + + val = digitalReadByte () ; + if (printHex) + printf ("%02X\n", val) ; + else + printf ("%d\n", val) ; +} + + +/* + * doRead: + * Read a pin and return the value + ********************************************************************************* + */ + +void doRead (int argc, char *argv []) +{ + int pin, val ; + + if (argc != 3) + { + fprintf (stderr, "Usage: %s read pin\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + val = digitalRead (pin) ; + + printf ("%s\n", val == 0 ? "0" : "1") ; +} + + +/* + * doAread: + * Read an analog pin and return the value + ********************************************************************************* + */ + +void doAread (int argc, char *argv []) +{ + 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)) ; +} + + +/* + * doBlink: + * Blink an IO pin + ********************************************************************************* + */ + +void doBlink (int argc, char *argv []) +{ + int pin ; + + if (argc != 3) + { + fprintf (stderr, "Usage: %s blink pin\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + + pinMode (pin, OUTPUT) ; + for (;;) + { + digitalWrite (pin, !digitalRead (pin)) ; + delay (500) ; + } + +} + + +/* + * 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 + ********************************************************************************* + */ + +void doClock (int argc, char *argv []) +{ + int pin, freq ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s clock \n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + + freq = atoi (argv [3]) ; + + gpioClockSet (pin, freq) ; +} + + +/* + * doPwm: + * Output a PWM value on a pin + ********************************************************************************* + */ + +/* + * doPwm: + * Output a PWM value on a pin + ********************************************************************************* + */ + +void doPwm (int argc, char *argv []) +{ + int pin, val ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s pwm \n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + val = atoi (argv [3]) ; + + pinMode (pin, PWM_OUTPUT); + pwmWrite (pin, val) ; +} + + +/* + * doPwmMode: doPwmRange: doPwmClock: + * Change the PWM mode, range and clock divider values + ********************************************************************************* + */ + +static void doPwmMode (int mode) +{ + pwmSetMode (mode) ; +} + +static void doPwmRange (int argc, char *argv []) +{ + unsigned int range ; + + if (argc != 3) + { + fprintf (stderr, "Usage: %s pwmr \n", argv [0]) ; + exit (1) ; + } + + range = (unsigned int)strtoul (argv [2], NULL, 10) ; + + if (range == 0) + { + fprintf (stderr, "%s: range must be > 0\n", argv [0]) ; + exit (1) ; + } + + pwmSetRange (range) ; +} + +static void doPwmClock (int argc, char *argv []) +{ + unsigned int clock ; + + if (argc != 3) + { + fprintf (stderr, "Usage: %s pwmc \n", argv [0]) ; + exit (1) ; + } + + clock = (unsigned int)strtoul (argv [2], NULL, 10) ; + + if ((clock < 1) || (clock > 4095)) + { + fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ; + exit (1) ; + } + + pwmSetClock (clock) ; +} + + + +/* + * doVersion: + * Handle the ever more complicated version command and print out + * some usefull information. + ********************************************************************************* + */ + +static void doVersion (char *argv []) +{ + struct stat statBuf ; + char name [80] ; + FILE *fd ; + + int vMaj, vMin ; + + wiringPiVersion (&vMaj, &vMin) ; + printf ("gpio version: %d.%d\n", vMaj, vMin) ; + printf ("Copyright (c) 2012-2018 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) ; + +// 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 ("/proc/device-tree/model", &statBuf) == 0) // Output Kernel idea of board type + { + if ((fd = fopen ("/proc/device-tree/model", "r")) != NULL) + { + if ( fgets (name, 80, fd) ){;} + fclose (fd) ; + printf (" *--> %s\n", name) ; + } + } + +// if (stat ("/dev/gpiomem", &statBuf) == 0) // User level GPIO is GO +// printf (" * This Raspberry Pi supports user-level GPIO access.\n") ; +// else +// printf (" * Root or sudo required for GPIO access.\n") ; +} + + +/* + * main: + * Start here + ********************************************************************************* + */ +int main (int argc, char *argv []) +{ + int i ; + + if (getenv ("WIRINGPI_DEBUG") != NULL) + { + printf ("gpio: wiringPi debug mode enabled\n") ; + wiringPiDebug = TRUE ; + } + + if (argc == 1) + { + fprintf (stderr, +"%s: At your service!\n" +" Type: gpio -h for full details and\n" +" gpio readall for a quick printout of your connector details\n", argv [0]) ; + exit (EXIT_FAILURE) ; + } + +// Help + + if (strcasecmp (argv [1], "-h") == 0) + { + printf ("%s: %s\n", argv [0], usage) ; + exit (EXIT_SUCCESS) ; + } + +// 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 ("%d\n", piGpioLayout ()) ; + exit (EXIT_SUCCESS) ; + } + +// Version and information + + if (strcmp (argv [1], "-v") == 0) + { + doVersion (argv) ; + exit (EXIT_SUCCESS) ; + } + + if (strcasecmp (argv [1], "-warranty") == 0) + { + printf ("gpio version: %s\n", VERSION) ; + printf ("Copyright (c) 2012-2018 Gordon Henderson\n") ; + printf ("\n") ; + printf (" This program is free software; you can redistribute it and/or modify\n") ; + printf (" it under the terms of the GNU Leser General Public License as published\n") ; + printf (" by the Free Software Foundation, either version 3 of the License, or\n") ; + printf (" (at your option) any later version.\n") ; + printf ("\n") ; + printf (" This program is distributed in the hope that it will be useful,\n") ; + printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ; + printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ; + printf (" GNU Lesser General Public License for more details.\n") ; + printf ("\n") ; + printf (" You should have received a copy of the GNU Lesser General Public License\n") ; + printf (" along with this program. If not, see .\n") ; + printf ("\n") ; + exit (EXIT_SUCCESS) ; + } + + if (geteuid () != 0) + { + fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ; + exit (EXIT_FAILURE) ; + } + +// Initial test for /sys/class/gpio operations: + + /**/ 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], "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], "unload" ) == 0) { doUnLoad (argc, argv) ; return 0 ; } + +// Check for usb power command + + if (strcasecmp (argv [1], "usbp" ) == 0) { doUsbP (argc, argv) ; return 0 ; } + +// Gertboard commands + + if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; } + if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; } + +// Check for allreadall command, force Gpio mode + + if (strcasecmp (argv [1], "allreadall") == 0) + { + wiringPiSetupGpio () ; + doAllReadall () ; + return 0 ; + } + +// Check for -g argument + + /**/ if (strcasecmp (argv [1], "-g") == 0) + { + wiringPiSetupGpio () ; + + for (i = 2 ; i < argc ; ++i) + argv [i - 1] = argv [i] ; + --argc ; + 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) + { + piFaceSetup (200) ; + + for (i = 2 ; i < argc ; ++i) + argv [i - 1] = argv [i] ; + --argc ; + wpMode = WPI_MODE_PIFACE ; + } + +// Check for -z argument so we don't actually initialise wiringPi + + else if (strcasecmp (argv [1], "-z") == 0) + { + for (i = 2 ; i < argc ; ++i) + argv [i - 1] = argv [i] ; + --argc ; + wpMode = WPI_MODE_UNINITIALISED ; + } + +// Default to wiringPi mode + + else + { + wiringPiSetup () ; + wpMode = WPI_MODE_PINS ; + } + +// Check for -x argument to load in a new extension +// -x extension:base:args +// Can load many modules, but unless daemon mode we can only send one +// command at a time. + + while (strcasecmp (argv [1], "-x") == 0) + { + if (argc < 3) + { + fprintf (stderr, "%s: -x missing extension command.\n", argv [0]) ; + exit (EXIT_FAILURE) ; + } + + if (!loadWPiExtension (argv [0], argv [2], TRUE)) + { + fprintf (stderr, "%s: Extension load failed: %s\n", argv [0], strerror (errno)) ; + exit (EXIT_FAILURE) ; + } + +// Shift args down by 2 + + for (i = 3 ; i < argc ; ++i) + argv [i - 2] = argv [i] ; + argc -= 2 ; + } + + if (argc <= 1) + { + fprintf (stderr, "%s: no command given\n", argv [0]) ; + exit (EXIT_FAILURE) ; + } + +// 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) ; + else if (strcasecmp (argv [1], "blink" ) == 0) doBlink (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], "readall" ) == 0) doReadall () ; + else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ; + else if (strcasecmp (argv [1], "pins" ) == 0) doReadall () ; + else if (strcasecmp (argv [1], "qmode" ) == 0) doQmode (argc, argv) ; + 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], "serial" ) == 0) doSerialTest (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], "rbx" ) == 0) doReadByte (argc, argv, TRUE) ; + else if (strcasecmp (argv [1], "rbd" ) == 0) doReadByte (argc, argv, FALSE) ; + 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 (EXIT_FAILURE) ; + } + + return 0 ; +} diff --git a/gpio/pintest b/gpio/pintest new file mode 100644 index 0000000..b574361 --- /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: +# A "wiring" library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + + +# 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 + +#ifdef CONFIG_ORANGEPI +#include "OrangePi.h" +#endif + +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", "ALT2", "ALT3", "ALT4", "ALT5", "ALT6", "OFF" +} ; + +#ifndef CONFIG_ORANGEPI +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, +} ; +#endif + +/* + * 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 | + ********************************************************************************* + */ +void readallPhys (int physPin) +{ + int pin ; + + if (physPinToGpio (physPin) == -1) + printf (" | | ") ; + else + printf (" | %4d | %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 | %-4d", physToWpi [physPin], physPinToGpio (physPin)) ; + + printf (" |\n") ; +} + + +/* + * allReadall: + * Read all the pins regardless of the model. Primarily of use for + * the compute module, but handy for other fiddling... + ********************************************************************************* + */ + +static void allReadall (void) +{ + int pin ; + + printf ("+-----+------+-------+ +-----+------+-------+\n") ; + printf ("| Pin | Mode | Value | | Pin | Mode | Value |\n") ; + printf ("+-----+------+-------+ +-----+------+-------+\n") ; + + for (pin = 0 ; pin < 14 ; ++pin) + { + printf ("| %3d ", pin) ; + printf ("| %-4s ", alts [getAlt (pin)]) ; + printf ("| %s ", digitalRead (pin) == HIGH ? "High" : "Low ") ; + printf ("| ") ; + printf ("| %3d ", pin + 14) ; + printf ("| %-4s ", alts [getAlt (pin + 14)]) ; + printf ("| %s ", digitalRead (pin + 14) == 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+ or actually, all 40-pin Pi's + ********************************************************************************* + */ + +static void plus2header (int model) +{ + /**/ if (model == PI_MODEL_AP) + printf (" +-----+-----+---------+------+---+---Pi A+--+---+------+---------+-----+-----+\n") ; + else if (model == PI_MODEL_BP) + printf (" +-----+-----+---------+------+---+---Pi B+--+---+------+---------+-----+-----+\n") ; + else if (model == PI_MODEL_ZERO) + printf (" +-----+-----+---------+------+---+-Pi Zero--+---+------+---------+-----+-----+\n") ; + else if (model == PI_MODEL_ZERO_W) + printf (" +-----+-----+---------+------+---+-Pi ZeroW-+---+------+---------+-----+-----+\n") ; + else if (model == PI_MODEL_2) + printf (" +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+\n") ; + else if (model == PI_MODEL_3) + printf (" +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+\n") ; + else if (model == PI_MODEL_3P) + printf (" +-----+-----+---------+------+---+---Pi 3+--+---+------+---------+-----+-----+\n") ; + else + printf (" +-----+-----+---------+------+---+---Pi ?---+---+------+---------+-----+-----+\n") ; +} + + +static 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) ; +} + + +/* + * doReadall: + * Generic read all pins called from main program. Works out the Pi type + * and calls the appropriate function. + ********************************************************************************* + */ + +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_3) || (model == PI_MODEL_3P) || + (model == PI_MODEL_ZERO) || (model == PI_MODEL_ZERO_W)) + piPlusReadall (model) ; + else if ((model == PI_MODEL_CM) || (model == PI_MODEL_CM3)) + allReadall () ; + else if ( model == PI_MODEL_ORANGEPI) + OrangePiReadAll(); + else + printf ("Oops - unable to determine board type... model: %d\n", model) ; +} + + +/* + * doAllReadall: + * Force reading of all pins regardless of Pi model + ********************************************************************************* + */ + +void doAllReadall (void) +{ + allReadall () ; +} + + +/* + * doQmode: + * Query mode on a pin + ********************************************************************************* + */ + +void doQmode (int argc, char *argv []) +{ + int pin ; + + if (argc != 3) + { + fprintf (stderr, "Usage: %s qmode pin\n", argv [0]) ; + exit (EXIT_FAILURE) ; + } + + pin = atoi (argv [2]) ; + printf ("%s\n", alts [getAlt (pin)]) ; +} diff --git a/gpio/test.sh b/gpio/test.sh new file mode 100644 index 0000000..708f1d3 --- /dev/null +++ b/gpio/test.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# +# test.sh: +# Simple test: Assumes LEDs on Pins 0-7 and lights them +# in-turn. +################################################################################# +# This file is part of wiringPi: +# A "wiring" library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + +# Simple test - assumes LEDs on Pins 0-7. + +for i in `seq 0 7`; +do + gpio mode $i out +done + +while true; +do + for i in `seq 0 7`; + do + gpio write $i 1 + sleep 0.1 + done + + for i in `seq 0 7`; + do + gpio write $i 0 + sleep 0.1 + done +done diff --git a/newVersion b/newVersion new file mode 100644 index 0000000..ed4b438 --- /dev/null +++ b/newVersion @@ -0,0 +1,47 @@ +#!/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: +# A "wiring" library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + +echo Updating to version: `cat VERSION` + +rm -f version.h +vMaj=`cut -d. -f1 VERSION` +vMin=`cut -d. -f2 VERSION` +echo "#define VERSION \"`cat VERSION`\"" > version.h +echo "#define VERSION_MAJOR $vMaj" >> version.h +echo "#define VERSION_MINOR $vMin" >> 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++ + and BASIC 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 0000000..bd9629d Binary files /dev/null and b/pins/pins.pdf differ diff --git a/pins/pins.tex b/pins/pins.tex new file mode 100644 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/update b/update new file mode 100644 index 0000000..0f72243 --- /dev/null +++ b/update @@ -0,0 +1,5 @@ +#!/bin/sh + +# update - update source files from master on yakko + +rsync -aHx --exclude='*.o' --exclude='*~' -v --delete gordon@yakko:rpi/git/wiringPi/ . diff --git a/version.h b/version.h new file mode 100644 index 0000000..242c62b --- /dev/null +++ b/version.h @@ -0,0 +1,3 @@ +#define VERSION "2.46" +#define VERSION_MAJOR 2 +#define VERSION_MINOR 46 diff --git a/wiringPi/COPYING.LESSER b/wiringPi/COPYING.LESSER new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/wiringPi/COPYING.LESSER @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/wiringPi/Makefile b/wiringPi/Makefile new file mode 100644 index 0000000..71c38df --- /dev/null +++ b/wiringPi/Makefile @@ -0,0 +1,244 @@ +# +# Makefile: +# wiringPi - 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=libwiringPi.a +DYNAMIC=libwiringPi.so.$(VERSION) + +#DEBUG = -g -O0 +DEBUG = -O2 +CC = gcc +INCLUDE = -I. +DEFS = -D_GNU_SOURCE +CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wextra -Winline $(INCLUDE) -pipe -fPIC +#CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Wextra -Wconversion -Winline $(INCLUDE) -pipe -fPIC + +LIBS = -lm -lpthread -lrt -lcrypt + +ifeq ($(BOARD),) + BOARD = orangepioneplus-h6 +endif + +ifeq ($(BOARD), orangepi2giot) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_2G_IOT +endif + +ifeq ($(BOARD), orangepipc2-h5) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_PC2 +endif + +ifeq ($(BOARD), orangepiprime-h5) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_PRIME +endif + +ifeq ($(BOARD), orangepizeroplus-h5) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_ZEROPLUS +endif + +ifneq ($(findstring $(BOARD), "orangepiwin-a64" "orangepiwinplus-a64"),) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_WIN +endif + +ifneq ($(findstring $(BOARD), "orangepione-h3" "orangepilite-h3" "orangepipc-h3" "orangepiplus-h3" "orangepipcplus-h3" "orangepiplus2e-h3"),) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_H3 +endif + +ifneq ($(findstring $(BOARD), "orangepizero-h2" "orangepir1-h2"),) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_ZERO +endif + +ifneq ($(findstring $(BOARD), "orangepioneplus-h6" "orangepilite2-h6"),) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_LITE2 +endif + +ifeq ($(BOARD), orangepi3-h6) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_3 +endif + +ifeq ($(BOARD), orangepizero2-h616) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_ZERO2 +endif + +ifeq ($(BOARD), orangepizeroplus2h3) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_ZEROPLUS2_H3 +endif + +ifeq ($(BOARD), orangepizeroplus2h5) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_ZEROPLUS2_H5 +endif + +ifeq ($(BOARD), orangepirk3399) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_RK3399 +endif + +ifeq ($(BOARD), orangepi4) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_4 +endif + +ifeq ($(BOARD), orangepi4-lts) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_4_LTS +endif + +ifeq ($(BOARD), orangepi800) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_800 +endif + +ifeq ($(BOARD), orangepir1plus-rk3328) +EXTRA_CFLAGS = -DCONFIG_ORANGEPI_R1PLUS +endif + +EXTRA_CFLAGS += -DCONFIG_ORANGEPI + +############################################################################### + +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 ads1115.c \ + sn3218.c \ + bmp180.c htu21d.c ds18b20.c rht03.c \ + drcSerial.c drcNet.c \ + pseudoPins.c \ + wpiExtensions.c \ + w25q64.c \ + oled.c OrangePi.c + +HEADERS = $(shell ls *.h) + +OBJ = $(SRC:.c=.o) + +all: $(DYNAMIC) + + +.PHONY: static +static: + $Q cat noMoreStatic + +$(DYNAMIC): $(OBJ) + $Q echo "[Link (Dynamic)]" + $Q $(CC) -shared -Wl,-soname,libwiringPi.so$(WIRINGPI_SONAME_SUFFIX) -o libwiringPi.so.$(VERSION) $(OBJ) $(LIBS) + +.c.o: + $Q echo [Compile] $< + $Q $(CC) -c $(EXTRA_CFLAGS) $(CFLAGS) $< -o $@ + + +.PHONY: clean +clean: + $Q echo "[Clean]" + $Q rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPi.* + +.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 libwiringPi.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) + $Q ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so + $Q $(LDCONFIG) + +.PHONY: install-deb +install-deb: $(DYNAMIC) + $Q echo "[Install Headers: deb]" + $Q install -m 0755 -d $(CURDIR)/../debian-template/wiringPi/usr/include + $Q install -m 0644 $(HEADERS) $(CURDIR)/../debian-template/wiringPi/usr/include + $Q echo "[Install Dynamic Lib: deb]" + install -m 0755 -d $(CURDIR)/../debian-template/wiringPi/usr/lib + install -m 0755 libwiringPi.so.$(VERSION) $(CURDIR)/../debian-template/wiringPi/usr/lib/libwiringPi.so.$(VERSION) + ln -sf $(CURDIR)/../debian-template/wiringPi/usr/lib/libwiringPi.so.$(VERSION) $(CURDIR)/../debian-template/wiringPi/usr/lib/libwiringPi.so + +.PHONY: uninstall +uninstall: + $Q echo "[UnInstall]" + $Q cd $(DESTDIR)$(PREFIX)/include/ && rm -f $(HEADERS) + $Q cd $(DESTDIR)$(PREFIX)/lib/ && rm -f libwiringPi.* + $Q $(LDCONFIG) + + +.PHONY: depend +depend: + makedepend -Y $(SRC) $(SRC_I2C) + +# DO NOT DELETE + +wiringPi.o: softPwm.h softTone.h wiringPi.h ../version.h +wiringSerial.o: wiringSerial.h +wiringShift.o: wiringPi.h wiringShift.h +piHiPri.o: wiringPi.h +piThread.o: wiringPi.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 +w25q64.o: wiringPi.h wiringPiSPI.h w25q64.h +oled.o: wiringPi.h wiringPiSPI.h oled.h font.h +max5322.o: wiringPi.h wiringPiSPI.h max5322.h +ads1115.o: wiringPi.h wiringPiI2C.h ads1115.h +sn3218.o: wiringPi.h wiringPiI2C.h sn3218.h +bmp180.o: wiringPi.h wiringPiI2C.h bmp180.h +htu21d.o: wiringPi.h wiringPiI2C.h htu21d.h +ds18b20.o: wiringPi.h ds18b20.h +drcSerial.o: wiringPi.h wiringSerial.h drcSerial.h +pseudoPins.o: wiringPi.h pseudoPins.h +wpiExtensions.o: wiringPi.h mcp23008.h mcp23016.h mcp23017.h mcp23s08.h +wpiExtensions.o: mcp23s17.h sr595.h pcf8574.h pcf8591.h mcp3002.h mcp3004.h +wpiExtensions.o: mcp4802.h mcp3422.h max31855.h max5322.h ads1115.h sn3218.h +wpiExtensions.o: drcSerial.h pseudoPins.h bmp180.h htu21d.h ds18b20.h +wpiExtensions.o: wpiExtensions.h diff --git a/wiringPi/OrangePi.c b/wiringPi/OrangePi.c new file mode 100644 index 0000000..8f674f9 --- /dev/null +++ b/wiringPi/OrangePi.c @@ -0,0 +1,2733 @@ +#include "wiringPi.h" +#include +#include +#include +#include +#include +#include "OrangePi.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "softPwm.h" +#include "softTone.h" + +#ifdef CONFIG_ORANGEPI + +#ifdef CONFIG_ORANGEPI_2G_IOT +int pinToGpioOrangePi[64] = +{ + 70, 37, // 0, 1 + 14, 15, // 2, 3 + 69, 89, // 4 5 + 16, 56, // 6, 7 + 62, 63, // 8, 9 + 5, 6, //10,11 + 4, 3, //12,13 + 2, 72, //14,15 + 71, -1, //16,17 + -1, -1, //18,19 + -1, 90, //20,21 + 91, 92, //22,23 + 93, 94, //24,25 + 41, 40, //26,27 + 38, 39, //28,29 + 1, 0, //30,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 +}; + +int physToGpioOrangePi[64] =//head num map to OrangePi +{ + -1, // 0 + -1, -1, // 1, 2 + 62, -1, // 3, 4 + 63, -1, // 5, 6 + 56, 72, // 7, 8 + -1, 71, // 9, 10 + 70, 37, // 11, 12 + 14, -1, // 13, 14 + 15, 69, // 15, 16 + -1, 89, // 17, 18 + 4, -1, // 19, 20 + 3, 16, // 21, 22 + 2, 5, // 23, 24 + -1, 6, // 25, 26 + 1, 0, // 27, 28 + 90, -1, // 29, 30 + 91, 41, // 31, 32 + 92, -1, // 33, 34 + 93, 40, // 35, 36 + 94, 38, // 37, 38 + -1, 39, // 39, 40 +// Padding: + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int physToPinOrangePi[64] = //return wiringPI pin +{ + -1, // 0 + -1, -1, // 1, 2 + 8, -1, //3, 4 + 9, -1, //5, 6 + 7, 15, //7, 8 + -1, 16, //9,10 + 0, 1, //11,12 + 2, -1, //13,14 + 3, 4, //15,16 + -1, 5, //17,18 + 12, -1, //19,20 + 13, 6, //21,22 + 14, 10, //23, 24 + -1, 11, // 25, 26 + + 30, 31, //27, 28 + 21, -1, //29, 30 + 22, 26, //31, 32 + 23, -1, //33, 34 + 24, 27, //35, 36 + 25, 28, //37, 38 + -1, 29, //39, 40 +// Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int ORANGEPI_PIN_MASK[4][32] = //[BANK] [INDEX] +{ + { 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,},//PA + { 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,},//PB + { 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,},//PC + { 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,},//PD +}; + +#endif /* CONFIG_ORANGEPI_2G_IOT */ + +#ifdef CONFIG_ORANGEPI_PRIME +int pinToGpioOrangePi[64] = +{ + 12, 11, // 0, 1 + 6, 69, // 2, 3 + 70, 1, // 4 5 + 110,0, // 6, 7 + 3, 68, // 8, 9 + 71, 15, //10,11 + 16, 2, //12,13 + 14, 13, //14,15 + 72, 19, //16,17 + 18, 7, //18,19 + 8, 73, //20,21 + 9, 10, //22,23 + 74,107, //24,25 + 75, 76, //26,27 + + -1, -1, //28, 29 + -1, -1, //30,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 +}; + +int physToGpioOrangePi[64] =//head num map to OrangePi +{ + -1, // 0 + -1, -1, // 1, 2 + 12, -1, // 3, 4 + 11, -1, // 5, 6 + 6, 69, // 7, 8 + -1, 70, // 9, 10 + 1, 110, //11, 12 + 0, -1, //13, 14 + 3, 68, //15, 16 + -1, 71, //17, 18 + 15, -1, //19, 20 + 16, 2, //21, 22 + 14, 13, //23, 24 + -1, 72, //25, 26 + 19, 18, //27, 28 + 7, -1, //29, 30 + 8, 73, //31, 32 + 9, -1, //33, 34 + 10, 74, //35, 36 + 107, 75, //37, 38 + -1, 76, //39, 40 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //41-> 55 + -1, -1, -1, -1, -1, -1, -1, -1 // 56-> 63 +}; + +int physToPinOrangePi[64] = //return wiringPI pin +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, //3, 4 + 1, -1, //5, 6 + 2, 3, //7, 8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23, 24 + -1, 16, // 25, 26 + 17, 18, //27, 28 + 19, -1, //29, 30 + 20, 21, //31, 32 + 22, -1, //33, 34 + 23, 24, //35, 36 + 25, 26, //37, 38 + -1, 27, //39, 40 +// Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int ORANGEPI_PIN_MASK[9][32] = //[BANK] [INDEX] +{ + { 0, 1, 2, 3,-1,-1, 6, 7, 8, 9,10,11,12,13,14,15,16,-1,18,19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA + {-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,},//PB + {-1,-1,-1,-1, 4, 5, 6, 7, 8, 9,10,11,12,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,-1,-1,14,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PD + {-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,},//PE + {-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,},//PF + {-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,},//PG + {-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,},//PH + {-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,},//PI +}; +#endif /* PRIME */ + +#ifdef CONFIG_ORANGEPI_PC2 +int pinToGpioOrangePi[64] = +{ + 12, 11, // 0, 1 + 6, 69, // 2, 3 + 70, 1, // 4 5 + 110,0, // 6, 7 + 3, 68, // 8, 9 + 71, 15, //10,11 + 16, 2, //12,13 + 14, 13, //14,15 + 21, 19, //16,17 + 18, 7, //18,19 + 8, 200, //20,21 + 9, 10, //22,23 + 201,107, //24,25 + 198, 199, //26,27 + + -1, -1, //28, 29 + -1, -1, //30,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 +}; + +int physToGpioOrangePi[64] =//head num map to OrangePi +{ + -1, // 0 + -1, -1, // 1, 2 + 12, -1, // 3, 4 + 11, -1, // 5, 6 + 6, 69, // 7, 8 + -1, 70, // 9, 10 + 1, 110, //11, 12 + 0, -1, //13, 14 + 3, 68, //15, 16 + -1, 71, //17, 18 + 15, -1, //19, 20 + 16, 2, //21, 22 + 14, 13, //23, 24 + -1, 21, //25, 26 + 19, 18, //27, 28 + 7, -1, //29, 30 + 8, 200, //31, 32 + 9, -1, //33, 34 + 10, 201, //35, 36 + 107, 198, //37, 38 + -1, 199, //39, 40 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //41-> 55 + -1, -1, -1, -1, -1, -1, -1, -1 // 56-> 63 +}; + +int physToPinOrangePi[64] = //return wiringPI pin +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, //3, 4 + 1, -1, //5, 6 + 2, 3, //7, 8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23, 24 + -1, 16, // 25, 26 + 17, 18, //27, 28 + 19, -1, //29, 30 + 20, 21, //31, 32 + 22, -1, //33, 34 + 23, 24, //35, 36 + 25, 26, //37, 38 + -1, 27, //39, 40 +// Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int ORANGEPI_PIN_MASK[9][32] = //[BANK] [INDEX] +{ + { 0, 1, 2, 3,-1,-1, 6, 7, 8, 9,10,11,12,13,14,15,16,-1,18,19,-1,21,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA + {-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,},//PB + {-1,-1,-1,-1, 4, 5, 6, 7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,-1,-1,14,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PD + {-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,},//PE + {-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,},//PF + {-1,-1,-1,-1,-1,-1, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG + {-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,},//PH + {-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,},//PI +}; +#endif /* PC2 */ + + +#ifdef CONFIG_ORANGEPI_ZEROPLUS +int pinToGpioOrangePi [64] = +{ + 12, 11, 6, 198, 199, 1, 7, 0, 3, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7 + 19, 18, // I2C - SDA0, SCL0 wpi 8 - 9 + 15, 16, // SPI - CE1, CE0 wpi 10 - 11 + 2, 14, 13, // SPI - MOSI, MISO, SCLK wpi 12 - 14 + 10, -1, // UART - Tx, Rx wpi 15 - 16 + -1, -1, -1, -1, // Rev 2: New GPIOs 8 though 11 wpi 17 - 20 + -1, -1, -1, -1, -1, // B+ wpi 21, 22, 23, 24, 25 + -1, -1, // wpi 26, 27 + -1, -1, //PA4, PA5(PWM0) wpi 28, 29 + + -1, -1, // B+ wpi 30, 31 + +// Padding: + + -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 +}; + +int physToGpioOrangePi [64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 12, -1, + 11, -1, + 6, 198, + -1, 199, + 1, 7, + 0, -1, + 3, 19, + -1, 18, + 15, -1, + 16, 2, + 14, 13, + -1, 10, // 25, 26 + + -1, -1, //27, 28 + -1, -1, //29, 30 + -1, -1, //31, 32 + -1, -1, //33, 34 + -1, -1, //35, 36 + -1, -1, //37, 38 + -1, -1, //39, 40 + -1, -1, //41, 42 +// Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int physToPinOrangePi [64] = //return wiringPI pin +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, //3, 4 + 1, -1, //5, 6 + 2, 3, //7, 8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23, 24 + -1, 16, // 25, 26 + + -1, -1, //27, 28 + -1, -1, //29, 30 + -1, -1, //31, 32 + -1, -1, //33, 34 + -1, -1, //35, 36 + -1, -1, //37, 38 + -1, -1, //39, 40 + -1, -1, //41, 42 +// Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int ORANGEPI_PIN_MASK[12][32] = //[BANK] [INDEX] +{ + { 0, 1, 2, 3,-1,-1, 6, 7,-1,-1,10,11,12,13,14,15,16,-1,18,19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA + {-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,},//PB + {-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,},//PC + {-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,},//PD + {-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,},//PE + {-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,},//PF + {-1,-1,-1,-1,-1,-1, 6, 7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG + {-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,},//PH + {-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,},//PI + {-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,},//PJ + {-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,},//PK + {-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,},//PL +}; +#endif /* ZEROPLUS */ + +#ifdef CONFIG_ORANGEPI_WIN +int pinToGpioOrangePi [64] = +{ + 227, 226, // 0, 1 + 362, 354, // 2, 3 + 355, 229, // 4 5 + 100, 228, // 6, 7 + 231, 361, // 8, 9 + 68, 98, //10,11 + 99, 230, //12,13 + 97, 96, //14,15 + 102, 143, //16,17 + 142, 36, //18,19 + 37, 34, //20,21 + 38, 39, //22,23 + 35, 101, //24,25 + 32, 33, //26,27 + + -1, -1, //28,29 + -1, -1, //30,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 +}; + +int physToGpioOrangePi[64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 227, -1, // 3, 4 + 226, -1, // 5, 6 + 362, 354, // 7, 8 + -1, 355, // 9, 10 + 229, 100, //11, 12 + 228, -1, //13, 14 + 231, 361, //15, 16 + -1, 68, //17, 18 + 98, -1, //19, 20 + 99, 230, //21, 22 + 97, 96, //23, 24 + -1, 102, //25, 26 + 143, 142, //27, 28 + 36, -1, //29, 30 + 37, 34, //31, 32 + 38, -1, //33, 34 + 39, 35, //35, 36 + 101, 32, //37, 38 + -1, 33, //39, 40 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //41-> 55 + -1, -1, -1, -1, -1, -1, -1, -1 // 56-> 63 +}; + +int physToPinOrangePi [64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, // 3, 4 + 1, -1, // 5, 6 + 2, 3, // 7, 8 + -1, 4, // 9, 10 + 5, 6, //11, 12 + 7, -1, //13, 14 + 8, 9, //15, 16 + -1, 10, //17, 18 + 11, -1, //19, 20 + 12, 13, //21, 22 + 14, 15, //23, 24 + -1, 16, //25, 26 + 17, 18, //27, 28 + 19, -1, //29, 30 + 20, 21, //31, 32 + 22, -1, //33, 34 + 23, 24, //35, 36 + 25, 26, //37, 38 + -1, 27, //39, 40 + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //41-> 55 + -1, -1, -1, -1, -1, -1, -1, -1 // 56-> 63 +}; + +int ORANGEPI_PIN_MASK[12][32] = //[BANK] [INDEX] +{ + { 0, 1, 2, 3,-1,-1, 6, 7, 8, 9,10,11,12,13,14,15,16,-1,18,19,20,21,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA + { 0, 1, 2, 3, 4, 5, 6, 7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PB + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC + { 0, 1, 2, 3, 4, 5, 6,-1,-1,-1,-1,11,-1,-1,14,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PD + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PE + {-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,},//PF + {-1,-1,-1,-1,-1,-1, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG + {-1,-1, 2, 3, 4, 5, 6, 7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PH + {-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,},//PI + {-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,},//PJ + {-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,},//PK + {-1,-1, 2, 3,-1,-1,-1,-1,-1, 9,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PL +}; +#endif + +#ifdef CONFIG_ORANGEPI_H3 +int pinToGpioOrangePi [64] = +{ + 12, 11, 6, 13, 14, 1, 110, 0, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7 + 3, 68, // I2C - SDA0, SCL0 wpi 8 - 9 + 71, 64, // SPI - CE1, CE0 wpi 10 - 11 + 65, 2, 66, // SPI - MOSI, MISO, SCLK wpi 12 - 14 + 67, 21, // UART - Tx, Rx wpi 15 - 16 + 19, 18, 7, 8, // Rev 2: New GPIOs 8 though 11 wpi 17 - 20 + 200, 9, 10, 201, 20, // B+ wpi 21, 22, 23, 24, 25 + 198, 199, // wpi 26, 27 + -1, -1, //PA4, PA5(PWM0) wpi 28, 29 + + -1, -1, // B+ wpi 30, 31 + +// Padding: + + -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 +}; + +int physToGpioOrangePi [64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 12, -1, + 11, -1, + 6, 13, + -1, 14, + 1, 110, + 0, -1, + 3, 68, + -1, 71, + 64, -1, + 65, 2, + 66, 67, + -1, 21, // 25, 26 + + 19, 18, //27, 28 + 7, -1, //29, 30 + 8, 200, //31, 32 + 9, -1, //33, 34 + 10, 201, //35, 36 + 20, 198, //37, 38 + -1, 199, //39, 40 + 4, 5, //41, 42 +// Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int physToPinOrangePi [64] = //return wiringPI pin +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, //3, 4 + 1, -1, //5, 6 + 2, 3, //7, 8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23, 24 + -1, 16, // 25, 26 + + 17, 18, //27, 28 + 19, -1, //29, 30 + 20, 21, //31, 32 + 22, -1, //33, 34 + 23, 24, //35, 36 + 25, 26, //37, 38 + -1, 27, //39, 40 + 28, 29, //41, 42 +// Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int ORANGEPI_PIN_MASK[9][32] = //[BANK] [INDEX] +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,-1,-1,-1,18,19,20,21,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA + {-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,},//PB + { 0, 1, 2, 3, 4,-1,-1, 7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,14,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PD + {-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,},//PE + {-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,},//PF + {-1,-1,-1,-1,-1,-1, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG + {-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,},//PH + {-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,},//PI +}; +#endif + +#if CONFIG_ORANGEPI_ZEROPLUS2_H3 || CONFIG_ORANGEPI_ZEROPLUS2_H5 +int pinToGpioOrangePi [64] = +{ + 12, 11, 6, 0, 1, 352, 107, 353, 3, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7 + 19, 18, // I2C - SDA0, SCL0 wpi 8 - 9 + 15, 16, // SPI - CE1, CE0 wpi 10 - 11 + 2, 14, 13, // SPI - MOSI, MISO, SCLK wpi 12 - 14 + 110, -1, // UART - Tx, Rx wpi 15 - 16 + -1, -1, -1, -1, // Rev 2: New GPIOs 8 though 11 wpi 17 - 20 + -1, -1, -1, -1, -1, // B+ wpi 21, 22, 23, 24, 25 + -1, -1, // wpi 26, 27 + -1, -1, //PA4, PA5(PWM0) wpi 28, 29 + +// Padding: + + -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 +}; + +int physToGpioOrangePi [64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 12, -1, + 11, -1, + 6, 0, + -1, 1, + 352, 107, + 353, -1, + 3, 19, + -1, 18, + 15, -1, + 16, 2, + 14, 13, + -1, 110, // 25, 26 + + -1, -1, //27, 28 + -1, -1, //29, 30 + -1, -1, //31, 32 + -1, -1, //33, 34 + -1, -1, //35, 36 + -1, -1, //37, 38 + -1, -1, //39, 40 + -1, -1, //41, 42 +// Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int physToPinOrangePi [64] = //return wiringPI pin +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, //3, 4 + 1, -1, //5, 6 + 2, 3, //7, 8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23, 24 + -1, 16, // 25, 26 + + -1, -1, //27, 28 + -1, -1, //29, 30 + -1, -1, //31, 32 + -1, -1, //33, 34 + -1, -1, //35, 36 + -1, -1, //37, 38 + -1, -1, //39, 40 + -1, -1, //41, 42 +// Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int ORANGEPI_PIN_MASK[12][32] = //[BANK] [INDEX] +{ + { 0, 1, 2, 3,-1,-1, 6,-1,-1,-1,-1,11,12,13,14,15,16,-1,18,19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA + {-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,},//PB + {-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,},//PC + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,-1,-1,14,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PD + {-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,},//PE + {-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,},//PF + {-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,},//PG + {-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,},//PH + {-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,},//PI + {-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,},//PJ + {-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,},//PK + { 0, 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,},//PL +}; +#endif + +#ifdef CONFIG_ORANGEPI_ZERO +int pinToGpioOrangePi[64] = +{ + 12, 11, 6, 198, 199, 1, 7, 0, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7 + 3, 19, // I2C - SDA0, SCL0 wpi 8 - 9 + 18, 15, // SPI - CE1, CE0 wpi 10 - 11 + 16, 2, 14, // SPI - MOSI, MISO, SCLK wpi 12 - 14 + 13, 10, // UART - Tx, Rx wpi 15 - 16 + -1, -1, -1, -1, // Rev 2: New GPIOs 8 though 11 wpi 17 - 20 + -1, -1, -1, -1, -1, // B+ wpi 21, 22, 23, 24, 25 + -1, -1, -1, -1, // B+ wpi 26, 27, 28, 29 + -1, 1, // B+ wpi 30, 31 + +// Padding: + + -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 +}; + +int physToGpioOrangePi[64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 12, -1, + 11, -1, + 6,198, + -1,199, + 1, 7, + 0, -1, + 3, 19, + -1, 18, + 15, -1, + 16, 2, + 14, 13, + -1, 10, // 25, 26 + + -1, -1, //27, 28 + -1, -1, //29, 30 + -1, -1, //31, 32 + -1, -1, //33, 34 + -1, -1, //35, 36 + -1, -1, //37, 38 + -1, -1, //39, 40 +// Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int physToPinOrangePi[64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, //3, 4 + 1, -1, //5, 6 + 2, 3, //7, 8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23, 24 + -1, 16, // 25, 26 + + -1, -1, //27, 28 + -1, -1, //29, 30 + -1, -1, //31, 32 + -1, -1, //33, 34 + -1, -1, //35, 36 + -1, -1, //37, 38 + -1, -1, //39, 40 +// Padding: +// + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int ORANGEPI_PIN_MASK[12][32] = //[BANK] [INDEX] +{ + { 0, 1, 2, 3,-1,-1, 6, 7,-1,-1,10,11,12,13,14,15,16,-1,18,19,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PA + {-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,},//PB + {-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,},//PC + {-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,},//PD + {-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,},//PE + {-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,},//PF + {-1,-1,-1,-1,-1,-1, 6, 7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG + {-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,},//PH + {-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,},//PI + {-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,},//PJ + {-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,},//PK + {-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,},//PL +}; +#endif + +#ifdef CONFIG_ORANGEPI_LITE2 + +//pinToGpioR3 is for OrangePi H6 Lite2/OnePlus +int pinToGpioOrangePi [64] = +{ + 230, 229, + 228, 117, 118, + 120, 73, 119, 122, 72, 71, + 66, 67, 121, 64, 69, 227, + +// 71, 72, 73, 117, 118, 227, //GPIO 0 through 6: wpi 0 - 5 +// 229, 230, // I2C1 - SCL1, SDA1 wpi 6 - 7 +// 228, // PWM1 wpi 8 +// 119, 120, 121, 122, // UART3 - Tx3, Rx3, RTS3, CTS3 wpi 9 - 12 +// 64, 66, 67, 69, // SPI0 - SCLK, MOSI, MISO, CS wpi 13 - 16 + + // Padding: + + -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 +}; + +//physToGpioR3 is for OrangePi H6 Lite2/OnePlus +int physToGpioOrangePi [64] = +{ + -1, // 0 + + -1, -1, // 1, 2 + 230, -1, + 229, -1, + 228, 117, + -1, 118, + 120, 73, + 119, -1, + 122, 72, + -1, 71, + 66, -1, + 67, 121, + 64, 69, + -1, 227, // 25, 26 + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int physToPinOrangePi [64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, + 1, -1, + 2, 3, //7, 8 + -1, 4, + 5, 6, //11, 12 + 7, -1, + 8, 9, //15, 16 + -1, 10, + 11, -1, //19, 20 + 12, 13, + 14, 15, //23, 24 + -1, 16, // 25, 26 + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int ORANGEPI_PIN_MASK[12][32] = //[BANK] [INDEX] +{ + {-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,},//PA + {-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,},//PB + { 0,-1, 2, 3,-1, 5,-1, 7, 8, 9,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,21,22,23,24,25,26,-1,-1,-1,-1,-1,},//PD + {-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,},//PE + {-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,},//PF + {-1,-1,-1,-1,-1,-1, 6, 7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PG + {-1,-1,-1, 3, 4, 5, 6,-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,},//PH +}; +#endif + +#ifdef CONFIG_ORANGEPI_3 + +//pinToGpioR3 is for OrangePi H6 Pi 3 +int pinToGpioOrangePi [64] = +{ + 122, 121, + 118, 354, 355, + 120, 114, 119, 362, 111, 112, + 229, 230, 117, 228, 227, 360, + +// 71, 72, 73, 117, 118, 227, //GPIO 0 through 6: wpi 0 - 5 +// 229, 230, // I2C1 - SCL1, SDA1 wpi 6 - 7 +// 228, // PWM1 wpi 8 +// 119, 120, 121, 122, // UART3 - Tx3, Rx3, RTS3, CTS3 wpi 9 - 12 +// 64, 66, 67, 69, // SPI0 - SCLK, MOSI, MISO, CS wpi 13 - 16 + + // Padding: + + -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 +}; + +//physToGpioR3 is for OrangePi H6 Lite2/OnePlus +int physToGpioOrangePi [64] = +{ + -1, // 0 + + -1, -1, // 1, 2 + 122, -1, + 121, -1, + 118, 354, + -1, 355, + 120, 114, + 119, -1, + 362, 111, + -1, 112, + 229, -1, + 230, 117, + 228, 227, + -1, 360, // 25, 26 + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +} ; + +int physToPinOrangePi [64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, + 1, -1, + 2, 3, //7, 8 + -1, 4, + 5, 6, //11, 12 + 7, -1, + 8, 9, //15, 16 + -1, 10, + 11, -1, //19, 20 + 12, 13, + 14, 15, //23, 24 + -1, 16, // 25, 26 + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int ORANGEPI_PIN_MASK[12][32] = //[BANK] [INDEX] +{ + {-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,},//PA + {-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,},//PB + {-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,},//PC + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,15,16,-1,18,-1,-1,21,22,23,24,25,26,-1,-1,-1,-1,-1,},//PD + {-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,},//PE + {-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,},//PF + {-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,},//PG + {-1,-1,-1, 3, 4, 5, 6,-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,},//PH + {-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,},//PI + {-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,},//PJ + {-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,},//PK + {-1,-1, 2, 3,-1,-1,-1,-1, 8,-1,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PL +}; + +#endif + +#ifdef CONFIG_ORANGEPI_ZERO2 +int pinToGpioOrangePi [64] = +{ +// 229, 228, 73, 226, 227, 70, +// 75, 69, 72, 79, 78, 231, 232, +// 71, 230, 233, 74, 65, 272, 262,234, + +// // Padding: + +// -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, // ... 63 + + -1, // 0 + -1 , -1 , + 264 , -1 , + 263 , -1 , + 256 , 224 , + -1 , 225 , + 226 , 257 , + 227 , -1 , + 269 , 270 , + -1 , 228 , + 231 , -1 , + 232 , 262 , + 230 , 229 , + -1 , 233 , + 266 , 265 , + 267 , -1 , + 268 , 261 , + 271 , -1 , + 258 , 234 , + 272 , 260 , + -1 , 259 , // 40 + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, // 63 +}; + +int physToGpioOrangePi [64] = +{ +// -1, // 0 + +// -1, -1, // 1, 2 +// 229, -1, +// 228, -1, +// 73, 226, +// -1, 227, +// 70, 75, +// 69, -1, +// 72, 79, +// -1, 78, +// 231, -1, +// 232, 71, +// 230, 233, +// -1, 74, // 25, 26 +// 65, -1, +// 272, -1, +// 262, -1, +// 234, -1, + +// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 +// -1, -1, -1, -1, // ... 63 + + -1, // 0 + -1 , -1 , + 264 , -1 , + 263 , -1 , + 256 , 224 , + -1 , 225 , + 226 , 257 , + 227 , -1 , + 269 , 270 , + -1 , 228 , + 231 , -1 , + 232 , 262 , + 230 , 229 , + -1 , 233 , + 266 , 265 , + 267 , -1 , + 268 , 261 , + 271 , -1 , + 258 , 234 , + 272 , 260 , + -1 , 259 , // 40 + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, // 63 +} ; + +int physToPinOrangePi [64] = +{ + +// -1, // 0 +// -1, -1, // 1, 2 +// 0, -1, +// 1, -1, +// 2, 3, //7, 8 +// -1, 4, +// 5, 6, //11, 12 +// 7, -1, +// 8, 9, //15, 16 +// -1, 10, +// 11, -1, //19, 20 +// 12, 13, +// 14, 15, //23, 24 +// -1, 16, // 25, 26 +// 17, -1, +// 18, -1, +// 19, -1, +// 20, -1, + +// -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 +// -1, // ... 63 + + -1, // 0 + -1, -1, // 1, 2 + 3, -1, //3, 4 + 5, -1, //5, 6 + 7, 8, //7, 8 + -1, 10, //9,10 + 11, 12, //11,12 + 13, -1, //13,14 + 15, 16, //15,16 + -1, 18, //17,18 + 19, -1, //19,20 + 21, 22, //21,22 + 23, 24, //23, 24 + -1, 26, // 25, 26 + 27, 28, //27, 28 + 29, -1, //29, 30 + 31, 32, //31, 32 + 33, -1, //33, 34 + 35, 36, //35, 36 + 37, 38, //37, 38 + -1, 40, //39, 40 + // Padding: + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int ORANGEPI_PIN_MASK[12][32] = //[BANK] [INDEX] +{ + // {-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,},//PA + // {-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,},//PB + // {-1, 1,-1,-1,-1, 5, 6, 7, 8, 9,10,11,-1,-1,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PC + // {-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,},//PD + // {-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,},//PE + // {-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,},//PF + // {-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,},//PG + // {-1,-1, 2, 3, 4, 5, 6, 7, 8, 9,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PH + // {-1,-1,-1,-1,-1,-1, 6,-1,-1,-1,-1,-1,-1,-1,-1,-1,16,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PI + // {-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,},//PJ + // {-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,},//PK + // {-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,},//PE + + {-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,},//PA + {-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,},//PB + {-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,},//PC + {-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,},//PD + {-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,},//PE + {-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,},//PF + {-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,},//PG + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PH + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14,15,16,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,},//PI + {-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,},//PJ + {-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,},//PK + {-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,},//PE +}; +#endif + +#ifdef CONFIG_ORANGEPI_RK3399 +int pinToGpioOrangePi[64] = +{ + 43, 44, // 0, 1 + 64, 148, // 2, 3 + 147, 80, // 4 5 + 65, 81, // 6, 7 + 82, 66, // 8, 9 + 67, 39, //10,11 + 40, 83, //12,13 + 41, 42, //14,15 + 133, 154, //16,17 + 50, 68, //18,19 + 69, 76, //20,21 + 70, 71, //22,23 + 73, 72, //24,25 + 74, 75, //26,27 + + -1, -1, //28,29 + -1, -1, //30,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 +}; + +int physToGpioOrangePi[64] =//head num map to OrangePi +{ + -1, // 0 + -1, -1, // 1, 2 + 43, -1, // 3, 4 + 44, -1, // 5, 6 + 64, 148, // 7, 8 + -1, 147, // 9, 10 + 80, 65, // 11, 12 + 81, -1, // 13, 14 + 82, 66, // 15, 16 + -1, 67, // 17, 18 + 39, -1, // 19, 20 + 40, 83, // 21, 22 + 41, 42, // 23, 24 + -1, 133, // 25, 26 + 154, 50, // 27, 28 + 68, -1, // 29, 30 + 69, 76, // 31, 32 + 70, -1, // 33, 34 + 71, 73, // 35, 36 + 72, 74, // 37, 38 + -1, 75, // 39, 40 +// Padding: + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int physToPinOrangePi[64] = //return wiringPI pin +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, //3, 4 + 1, -1, //5, 6 + 2, 3, //7, 8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23, 24 + -1, 16, // 25, 26 + + 17, 18, //27, 28 + 19, -1, //29, 30 + 20, 21, //31, 32 + 22, -1, //33, 34 + 23, 24, //35, 36 + 25, 26, //37, 38 + -1, 27, //39, 40 +// Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + int ORANGEPI_PIN_MASK[5][32] = //[BANK] [INDEX] + { + { 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,},//PA + { 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,},//PB + { 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,},//PC + { 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,},//PD + { 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,},//PD + }; + +volatile uint32_t *gpio2_base; +volatile uint32_t *cru_base; +volatile uint32_t *grf_base; +volatile uint32_t *pmugrf_base; +volatile uint32_t *pmucru_base; +volatile uint32_t *gpio1_base; +volatile uint32_t *gpio4_base; +#endif /* CONFIG_ORANGEPI_RK3399 */ +// add 2019.1.8 + +#ifdef CONFIG_ORANGEPI_800 +int pinToGpioOrangePi [64] = +{ + 43, 44, //0,1 + 150, 39, //2,3 + 40, 148, //4,5 + 152, 147, //6,7 + 149, 64, //8,9 + 65, 74, //10,11 + 73, 153, //12,13 + 75, 76, //14,15 + 154, -1, //16,17 + -1, -1, //18,19 + -1, -1, //20,21 + -1, -1, //22,23 + -1, -1, //24,25 + -1, -1, //26,27 + -1, -1, //28,29 + -1, -1, //30,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 +}; + +int physToGpioOrangePi[64] =//head num map to OrangePi +{ + -1, // 0 + -1, -1, // 1, 2 + 43, -1, // 3, 4 + 44, -1, // 5, 6 + 150, 39, // 7, 8 + -1, 40, // 9, 10 + 148, 152, // 11, 12 + 147, -1, // 13, 14 + 149, 64, // 15, 16 + -1, 65, // 17, 18 + 74, -1, // 19, 20 + 73, 153, // 21, 22 + 75, 76, // 23, 24 + -1, 154, // 25, 26 + -1, -1, // 27, 28 + -1, -1, // 29, 30 + -1, -1, // 31, 32 + -1, -1, // 33, 34 + -1, -1, // 35, 36 + -1, -1, // 37, 38 + -1, 75, // 39, 40 + +// Padding: + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int physToPinOrangePi[64] = //return wiringPI pin +{ + -1, //0 + -1, -1, //1,2 + 0, -1, //3,4 + 1, -1, //5,6 + 2, 3, //7,8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23,24 + -1, 16, //25,26 + -1, -1, //27,28 + -1, -1, //29,30 + -1, -1, //31,32 + -1, -1, //33,34 + -1, -1, //35,36 + -1, -1, //37,38 + -1, -1, //39,40 + // Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int ORANGEPI_PIN_MASK[5][32] = //[BANK] [INDEX] +{ + { 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,}, + { 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,}, + { 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,}, +}; + +volatile uint32_t *gpio2_base; +volatile uint32_t *cru_base; +volatile uint32_t *grf_base; +volatile uint32_t *pmugrf_base; +volatile uint32_t *pmucru_base; +volatile uint32_t *gpio1_base; +volatile uint32_t *gpio4_base; +#endif /* CONFIG_ORANGEPI_800 */ + +#ifdef CONFIG_ORANGEPI_4 +int pinToGpioOrangePi [64] = +{ + 64, 65, // 0, 1 + 150, 145, // 2, 3 + 144, 33, // 4 5 + 50, 35, // 6, 7 + 92, 54, // 8, 9 + 55, 40, //10,11 + + 39, 56, //12,13 + + 41, 42, //14,15 + 149, 64, //16,17 + 65, -1, //18,19 + -1, -1, //20,21 + -1, -1, //22,23 + -1, -1, //24,25 + + + -1, -1, //26,27 + + -1, -1, //28,29 + -1, -1, //30,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 + +}; + +int physToGpioOrangePi[64] =//head num map to OrangePi +{ + -1, // 0 + -1, -1, // 1, 2 + 64, -1, // 3, 4 + 65, -1, // 5, 6 + 150, 145, // 7, 8 + -1, 144, // 9, 10 + 33, 50, // 11, 12 + 35, -1, // 13, 14 + 92, 54, // 15, 16 + -1, 55, // 17, 18 + 40, -1, // 19, 20 + 39, 56, // 21, 22 + 41, 42, // 23, 24 + -1, 149, // 25, 26 + 64, 65, // 27, 28 + -1, -1, // 29, 30 + -1, 76, // 31, 32 + -1, -1, // 33, 34 + -1, 73, // 35, 36 + -1, 74, // 37, 38 + -1, 75, // 39, 40 +// Padding: + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int physToPinOrangePi[64] = //return wiringPI pin +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, //3, 4 + 1, -1, //5, 6 + 2, 3, //7, 8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23, 24 + -1, 16, // 25, 26 + + 17, 18, //27, 28 + -1, -1, //29, 30 + -1, -1, //31, 32 + -1, -1, //33, 34 + -1, -1, //35, 36 + -1, -1, //37, 38 + -1, -1, //39, 40 + // Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 + +}; + int ORANGEPI_PIN_MASK[5][32] = //[BANK] [INDEX] + { + { 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,},//PA + { 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,},//PB + { 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,},//PC + { 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,},//PD + { 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,},//PD + }; + +volatile uint32_t *gpio2_base; +volatile uint32_t *cru_base; +volatile uint32_t *grf_base; +volatile uint32_t *pmugrf_base; +volatile uint32_t *pmucru_base; +volatile uint32_t *gpio1_base; +volatile uint32_t *gpio4_base; +#endif /* CONFIG_ORANGEPI_4 */ +// add 2019.1.8 + +#ifdef CONFIG_ORANGEPI_4_LTS +int pinToGpioOrangePi [64] = +{ + 52, 53, // 0, 1 + 150, 145, // 2, 3 + 144, 33, // 4 5 + 50, 35, // 6, 7 + 92, 54, // 8, 9 + 55, 40, //10,11 + 39, 56, //12,13 + 41, 42, //14,15 + 149, 64, //16,17 + 65, -1, //18,19 + -1, -1, //20,21 + -1, -1, //22,23 + -1, -1, //24,25 + -1, -1, //26,27 + -1, -1, //28,29 + -1, -1, //30,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 + +}; + +int physToGpioOrangePi[64] =//head num map to OrangePi +{ + -1, // 0 + -1, -1, // 1, 2 + 64, -1, // 3, 4 + 65, -1, // 5, 6 + 150, 145, // 7, 8 + -1, 144, // 9, 10 + 33, 50, // 11, 12 + 35, -1, // 13, 14 + 92, 54, // 15, 16 + -1, 55, // 17, 18 + 40, -1, // 19, 20 + 39, 56, // 21, 22 + 41, 42, // 23, 24 + -1, 149, // 25, 26 + -1, -1, // 27, 28 + -1, -1, // 29, 30 + -1, -1, // 31, 32 + -1, -1, // 33, 34 + -1, -1, // 35, 36 + -1, -1, // 37, 38 + -1, -1, // 39, 40 +//Padding: + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int physToPinOrangePi[64] = //return wiringPI pin +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, //3, 4 + 1, -1, //5, 6 + 2, 3, //7, 8 + -1, 4, //9,10 + 5, 6, //11,12 + 7, -1, //13,14 + 8, 9, //15,16 + -1, 10, //17,18 + 11, -1, //19,20 + 12, 13, //21,22 + 14, 15, //23, 24 + -1, 16, // 25, 26 + + -1, -1, //27, 28 + -1, -1, //29, 30 + -1, -1, //31, 32 + -1, -1, //33, 34 + -1, -1, //35, 36 + -1, -1, //37, 38 + -1, -1, //39, 40 + // Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 + +}; + int ORANGEPI_PIN_MASK[5][32] = //[BANK] [INDEX] + { + { 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,},//PA + { 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,},//PB + { 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,},//PC + { 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,},//PD + { 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,},//PD + }; + +volatile uint32_t *gpio2_base; +volatile uint32_t *cru_base; +volatile uint32_t *grf_base; +volatile uint32_t *pmugrf_base; +volatile uint32_t *pmucru_base; +volatile uint32_t *gpio1_base; +volatile uint32_t *gpio4_base; +#endif /* CONFIG_ORANGEPI_4_LTS */ + +#ifdef CONFIG_ORANGEPI_R1PLUS +int pinToGpioOrangePi [64] = +{ + 89, 88, // 0, 1 + 100, 102, // 2, 3 + 112, 103, // 4 5 + 101, 66, // 6, 7 + -1, -1, // 8, 9 + -1, -1, //10,11 + -1, -1, //12,13 + -1, -1, //14,15 + -1, -1, //16,17 + -1, -1, //18,19 + -1, -1, //20,21 + -1, -1, //22,23 + -1, -1, //24,25 + -1, -1, //26,27 + -1, -1, //28,29 + -1, -1, //30,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 + +}; + +int physToGpioOrangePi[64] =//head num map to OrangePi +{ + -1, // 0 + -1, -1, // 1, 2 + 89, 88, // 3, 4 + 100, 102, // 5, 6 + -1, -1, // 7, 8 + -1, 112, // 9, 10 + 103,101, // 11, 12 + 66, -1, // 13, 14 + -1, -1, // 15, 16 + -1, -1, // 17, 18 + -1, -1, // 19, 20 + -1, -1, // 21, 22 + -1, -1, // 23, 24 + -1, -1, // 25, 26 + -1, -1, // 27, 28 + -1, -1, // 29, 30 + -1, -1, // 31, 32 + -1, -1, // 33, 34 + -1, -1, // 35, 36 + -1, -1, // 37, 38 + -1, -1, // 39, 40 +// Padding: + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int physToPinOrangePi[64] = //return wiringPI pin +{ + -1, //0 + -1, -1, //1, 2 + 0, 1, //3, 4 + 2, 3, //5, 6 + -1, -1, //7, 8 + -1, 4, //9, 10 + 5, 6, //11, 12 + 7, -1, //13, 14 + + -1, -1, //15, 16 + -1, -1, //17, 18 + -1, -1, //19, 20 + -1, -1, //21, 22 + -1, -1, //23, 24 + -1, -1, //25, 26 + -1, -1, //27, 28 + -1, -1, //29, 30 + -1, -1, //31, 32 + -1, -1, //33, 34 + -1, -1, //35, 36 + -1, -1, //37, 38 + -1, -1, //39, 40 + // Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 56 + -1, -1, -1, -1, -1, -1, -1, // ... 63 +}; + +int ORANGEPI_PIN_MASK[5][32] = //[BANK] [INDEX] +{ + { 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,},//PA + { 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,},//PB + { 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,},//PC + { 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,},//PD + { 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,},//PD +}; + +volatile uint32_t *gpio2_base; +volatile uint32_t *gpio3_base; +volatile uint32_t *cru_base; +volatile uint32_t *grf_base; + + +#endif /* CONFIG_ORANGEPI_R1PLUS */ +// add 2020.11.26 + + + +/* + * 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! + */ + +const char *piModelNames[6] = +{ + "Unknown", + "Model A", + "Model B", + "Model B+", + "Compute Module", +#ifdef CONFIG_ORANGEPI_2G_IOT + "OrangePi 2G-IOT", +#elif CONFIG_ORANGEPI_PC2 || CONFIG_ORANGEPI_ZEROPLUS || CONFIG_ORANGEPI_ZEROPLUS2_H5 || CONFIG_ORANGEPI_PRIME + "OrangePi H5 family", +#elif CONFIG_ORANGEPI_WIN + "OrangePi Win/Winplus", +#elif CONFIG_ORANGEPI_H3 || CONFIG_ORANGEPI_ZEROPLUS2_H3 + "OrangePi H3 family", +#elif CONFIG_ORANGEPI_ZERO || CONFIG_ORANGEPI_R1 + "OrangePi H2+ family", +#endif +}; + +volatile uint32_t *OrangePi_gpio; +volatile uint32_t *OrangePi_gpioC; +int pwmmode = 1; + +const char * int2bin(uint32_t param) { + int bits = sizeof(uint32_t)*CHAR_BIT; + static char buffer[sizeof(uint32_t)*CHAR_BIT + 1]; + char chars[2] = {'0', '1'}; + int i,j,offset; + for (i = 0; i < bits; i++) { + j = bits - i - 1; + offset = (param & (1 << j)) >> j; + buffer[i] = chars[offset]; + } + buffer[bits] = '\0'; + return buffer; +} + +/* + * Read register value helper + */ +unsigned int readR(unsigned int addr) +{ +#ifdef CONFIG_ORANGEPI_2G_IOT + unsigned int val = 0; + unsigned int mmap_base = (addr & ~MAP_MASK); + unsigned int mmap_seek = (addr - mmap_base); + + if (mmap_base == 0x11a08000) /* Group C */ + val = *((char *)OrangePi_gpioC + mmap_seek); + else /* Group A, B and D */ + val = *((char *)OrangePi_gpio + mmap_seek); + return val; +#elif (defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800 ) + unsigned int val = 0; + unsigned int mmap_base = (addr & ~MAP_MASK); + unsigned int mmap_seek = (addr - mmap_base); + if(mmap_base == CRU_BASE) + val = *((unsigned int *)((unsigned char *)cru_base + mmap_seek)); + else if(mmap_base == GRF_BASE) + val = *((unsigned int *)((unsigned char *)grf_base + mmap_seek)); + else if(mmap_base == GPIO2_BASE) + val = *((unsigned int *)((unsigned char *)gpio2_base + mmap_seek)); + else if(mmap_base == GPIO1_BASE) + val = *((unsigned int *)((unsigned char *)gpio1_base + mmap_seek)); + else if(mmap_base == PMUCRU_BASE) + val = *((unsigned int *)((unsigned char *)pmucru_base + mmap_seek)); + else if(mmap_base == PMUGRF_BASE) + val = *((unsigned int *)((unsigned char *)pmugrf_base + mmap_seek)); + else if(mmap_base == GPIO4_BASE) + val = *((unsigned int *)((unsigned char *)gpio4_base + mmap_seek)); + else ; + + return val; +#elif (defined CONFIG_ORANGEPI_R1PLUS) + unsigned int val = 0; + unsigned int mmap_base = (addr & ~MAP_MASK); + unsigned int mmap_seek = (addr - mmap_base); + if(mmap_base == CRU_BASE) + val = *((unsigned int *)((unsigned char *)cru_base + mmap_seek)); + else if(mmap_base == GRF_BASE) + val = *((unsigned int *)((unsigned char *)grf_base + mmap_seek)); + else if(mmap_base == GPIO2_BASE) + val = *((unsigned int *)((unsigned char *)gpio2_base + mmap_seek)); + else if(mmap_base == GPIO3_BASE) + val = *((unsigned int *)((unsigned char *)gpio3_base + mmap_seek)); + else ; + return val; +#else + uint32_t val = 0; + uint32_t mmap_base = (addr & ~MAP_MASK); + uint32_t mmap_seek = ((addr - mmap_base) >> 2); + + if (addr >= GPIOL_BASE) { + val = *(OrangePi_gpioC + mmap_seek); + } else + val = *(OrangePi_gpio + mmap_seek); + return val; +#endif +} + +/* + * Wirte value to register helper + */ +void writeR(unsigned int val, unsigned int addr) +{ +#ifdef CONFIG_ORANGEPI_2G_IOT + unsigned int mmap_base = (addr & ~MAP_MASK); + unsigned int mmap_seek = (addr - mmap_base); + + if (mmap_base == 0x11a08000) + *((char *)OrangePi_gpioC + mmap_seek) = val; + else + *((char *)OrangePi_gpio + mmap_seek) = val; + +#elif (defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800) + unsigned int mmap_base = (addr & ~MAP_MASK); + unsigned int mmap_seek = (addr - mmap_base); + if(mmap_base == CRU_BASE) + *((unsigned int *)((unsigned char *)cru_base + mmap_seek)) = val; + else if(mmap_base == GRF_BASE) + *((unsigned int *)((unsigned char *)grf_base + mmap_seek)) = val; + else if(mmap_base == GPIO2_BASE) + *((unsigned int *)((unsigned char *)gpio2_base + mmap_seek)) = val; + else if(mmap_base == GPIO1_BASE) + *((unsigned int *)((unsigned char *)gpio1_base + mmap_seek)) = val; + else if(mmap_base == PMUCRU_BASE) + *((unsigned int *)((unsigned char *)pmucru_base + mmap_seek)) = val; + else if(mmap_base == PMUGRF_BASE) + *((unsigned int *)((unsigned char *)pmugrf_base + mmap_seek)) = val; + else if(mmap_base == GPIO4_BASE) + *((unsigned int *)((unsigned char *)gpio4_base + mmap_seek)) = val; + else ; + +#elif (defined CONFIG_ORANGEPI_R1PLUS) + unsigned int mmap_base = (addr & ~MAP_MASK); + unsigned int mmap_seek = (addr - mmap_base); + if(mmap_base == CRU_BASE) + *((unsigned int *)((unsigned char *)cru_base + mmap_seek)) = val; + else if(mmap_base == GRF_BASE) + *((unsigned int *)((unsigned char *)grf_base + mmap_seek)) = val; + else if(mmap_base == GPIO2_BASE) + *((unsigned int *)((unsigned char *)gpio2_base + mmap_seek)) = val; + else if(mmap_base == GPIO3_BASE) + *((unsigned int *)((unsigned char *)gpio3_base + mmap_seek)) = val; + else ; +#else + unsigned int mmap_base = (addr & ~MAP_MASK); + unsigned int mmap_seek = ((addr - mmap_base) >> 2); + + if (addr >= GPIOL_BASE) { + *(OrangePi_gpioC + mmap_seek) = val; + } else + *(OrangePi_gpio + mmap_seek) = val; +#endif +} + +void print_pwm_reg() { + uint32_t val = readR(SUNXI_PWM_CTRL_REG); + uint32_t val2 = readR(SUNXI_PWM_CH0_PERIOD); + if (wiringPiDebug) { + printf("SUNXI_PWM_CTRL_REG: %s\n", int2bin(val)); + printf("SUNXI_PWM_CH0_PERIOD: %s\n", int2bin(val2)); + } +} + +void sunxi_pwm_set_enable(int en) { + int val = 0; + val = readR(SUNXI_PWM_CTRL_REG); + if (en) { + val |= (SUNXI_PWM_CH0_EN | SUNXI_PWM_SCLK_CH0_GATING); + } + else { + val &= ~(SUNXI_PWM_CH0_EN | SUNXI_PWM_SCLK_CH0_GATING); + } + if (wiringPiDebug) + printf(">>function%s,no:%d,enable? :0x%x\n", __func__, __LINE__, val); + writeR(val, SUNXI_PWM_CTRL_REG); + delay(1); + print_pwm_reg(); +} + +void sunxi_pwm_set_mode(int mode) { + int val = 0; + val = readR(SUNXI_PWM_CTRL_REG); + mode &= 1; //cover the mode to 0 or 1 + if (mode) { //pulse mode + val |= (SUNXI_PWM_CH0_MS_MODE | SUNXI_PWM_CH0_PUL_START); + pwmmode = 1; + } else { //cycle mode + val &= ~(SUNXI_PWM_CH0_MS_MODE); + pwmmode = 0; + } + val |= (SUNXI_PWM_CH0_ACT_STA); + if (wiringPiDebug) + printf(">>function%s,no:%d,mode? :0x%x\n", __func__, __LINE__, val); + writeR(val, SUNXI_PWM_CTRL_REG); + delay(1); + print_pwm_reg(); +} + +void sunxi_pwm_set_clk(int clk) { + int val = 0; + if (wiringPiDebug) + printf(">>function%s,no:%d\n", __func__, __LINE__); + // sunxi_pwm_set_enable(0); + val = readR(SUNXI_PWM_CTRL_REG); + if (wiringPiDebug) + printf("read reg val: 0x%x\n", val); + //clear clk to 0 + val &= 0xf801f0; + val |= ((clk & 0xf) << 15); //todo check wether clk is invalid or not + writeR(val, SUNXI_PWM_CTRL_REG); + sunxi_pwm_set_enable(1); + if (wiringPiDebug) + printf(">>function%s,no:%d,clk? :0x%x\n", __func__, __LINE__, val); + delay(1); + print_pwm_reg(); +} + +/** + * ch0 and ch1 set the same,16 bit period and 16 bit act + */ +int sunxi_pwm_get_period(void) { + uint32_t period_cys = 0; + period_cys = readR(SUNXI_PWM_CH0_PERIOD); //get ch1 period_cys + if (wiringPiDebug) { + printf("periodcys: %d\n", period_cys); + } + period_cys &= 0xffff0000; //get period_cys + period_cys = period_cys >> 16; + if (wiringPiDebug) + printf(">>func:%s,no:%d,period/range:%d", __func__, __LINE__, period_cys); + delay(1); + return period_cys; +} + +int sunxi_pwm_get_act(void) { + uint32_t period_act = 0; + period_act = readR(SUNXI_PWM_CH0_PERIOD); //get ch1 period_cys + period_act &= 0xffff; //get period_act + if (wiringPiDebug) + printf(">>func:%s,no:%d,period/range:%d", __func__, __LINE__, period_act); + delay(1); + return period_act; +} + +void sunxi_pwm_set_period(int period_cys) { + uint32_t val = 0; + //all clear to 0 + if (wiringPiDebug) + printf(">>func:%s no:%d\n", __func__, __LINE__); + period_cys &= 0xffff; //set max period to 2^16 + period_cys = period_cys << 16; + val = readR(SUNXI_PWM_CH0_PERIOD); + if (wiringPiDebug) + printf("read reg val: 0x%x\n", val); + val &= 0x0000ffff; + period_cys |= val; + if (wiringPiDebug) + printf("write reg val: 0x%x\n", period_cys); + writeR(period_cys, SUNXI_PWM_CH0_PERIOD); + delay(1); + val = readR(SUNXI_PWM_CH0_PERIOD); + if (wiringPiDebug) + printf("readback reg val: 0x%x\n", val); + print_pwm_reg(); +} + +void sunxi_pwm_set_act(int act_cys) { + uint32_t per0 = 0; + //keep period the same, clear act_cys to 0 first + if (wiringPiDebug) + printf(">>func:%s no:%d\n", __func__, __LINE__); + per0 = readR(SUNXI_PWM_CH0_PERIOD); + if (wiringPiDebug) + printf("read reg val: 0x%x\n", per0); + per0 &= 0xffff0000; + act_cys &= 0xffff; + act_cys |= per0; + if (wiringPiDebug) + printf("write reg val: 0x%x\n", act_cys); + writeR(act_cys, SUNXI_PWM_CH0_PERIOD); + delay(1); + print_pwm_reg(); +} + + +int OrangePi_get_gpio_mode(int pin) +{ + unsigned int regval = 0; + unsigned int bank = pin >> 5; + unsigned int index = pin - (bank << 5); + unsigned int phyaddr = 0; + unsigned char mode = -1; + +#if (defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800) + unsigned int grf_phyaddr = 0, ddr_phyaddr = 0; + int offset = ((index - ((index >> 3) << 3))); + if(bank == 1){ + grf_phyaddr = PMUGRF_BASE + ((index >> 3) << 2) + 0x10; + ddr_phyaddr = GPIO1_BASE + GPIO_SWPORTA_DDR_OFFSET; + } + else if(bank == 2){ + grf_phyaddr = GRF_BASE + ((index >> 3) << 2); + ddr_phyaddr = GPIO2_BASE + GPIO_SWPORTA_DDR_OFFSET; + } + else if(bank == 4){ + grf_phyaddr = GRF_BASE + ((index >> 3) << 2) +0x20; + ddr_phyaddr = GPIO4_BASE + GPIO_SWPORTA_DDR_OFFSET; + } + else ; + if (ORANGEPI_PIN_MASK[bank-1][index] != -1) { + regval = readR(grf_phyaddr); + mode = (regval >> (offset << 1)) & 0x3;//获å–控制模å¼çš„那两ä½çš„值 + if(mode == 0){ //如果是gpioæ¨¡å¼ + regval = readR(ddr_phyaddr);//获å–gpioæ–¹å‘寄存器的值 + return (regval >> index) & 1;//index对应的gpioçš„æ–¹å‘值,0为in,1为out + } + return mode + 1;//如果ä¸æ˜¯gpio模å¼ï¼Œè¿”回的alt,从2开始,0å’Œ1是inå’Œout + } + +#elif CONFIG_ORANGEPI_R1PLUS + unsigned int grf_phyaddr = 0, ddr_phyaddr = 0; + int offset = ((index - ((index >> 3) << 3))); + if(bank == 2){ //gpio2 + //ddr_phyaddr = GPIO2_BASE + GPIO_SWPORTA_DDR_OFFSET; + ddr_phyaddr = 0xff230004; + //grf_phyaddr = GRF_BASE + ((index >> 3) << 2) + 0x10; + if(0 == (index >> 3))//gpio2_ax + { + grf_phyaddr = GRF_BASE + 0x20; + } + else if(3 == (index >> 3))//gpio2_dx + { + grf_phyaddr = GRF_BASE + 0x34; + } + } + else if(bank == 3){ + //grf_phyaddr = GRF_BASE + ((index >> 3) << 2) +0x20; + ddr_phyaddr = GPIO3_BASE + GPIO_SWPORTA_DDR_OFFSET; + if (0 == (index >> 3)) + { + if(4 == offset)//gpio3_a4 + { + grf_phyaddr = GRF_BASE + 0x38; + } + else//gpio3_a567 + { + grf_phyaddr = GRF_BASE + 0x3c; + } + } + else if(2 == (index >> 3)) //gpio3_c + { + grf_phyaddr = GRF_BASE + 0x48; + } + } + else; + if (ORANGEPI_PIN_MASK[bank-1][index] != -1) { + regval = readR(grf_phyaddr); + writeR(0xffff9877, 0xff440240); + + if(3 == bank && (0 == (index >> 3))) //gpio3_ax需è¦å†™3ä½ + { + mode = (regval >> ((offset % 5) * 3)) & 0x7; + } + else + { + mode = (regval >> (offset << 1)) & 0x3; + } + if(mode == 0){ + regval = readR(ddr_phyaddr); + return (regval >> index) & 1; + } + return mode + 1; + } + +#else + int offset = ((index - ((index >> 3) << 3)) << 2); + + if (bank == 11) { + phyaddr = GPIOL_BASE + ((index >> 3) << 2); + } + else + phyaddr = GPIO_BASE_MAP + (bank * 36) + ((index >> 3) << 2); + + /* Ignore unused gpio */ + if (ORANGEPI_PIN_MASK[bank][index] != -1) { + regval = readR(phyaddr); + mode = (regval >> offset) & 7; + } + + return mode; + +#endif +} + +/* + * Set GPIO Mode + */ +int OrangePi_set_gpio_mode(int pin, int mode) +{ + unsigned int regval = 0; + unsigned int bank = pin >> 5; + unsigned int index = pin - (bank << 5); + unsigned int phyaddr = 0; +#ifdef CONFIG_ORANGEPI_2G_IOT + unsigned int base_address = 0; +#elif (defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800 || defined CONFIG_ORANGEPI_R1PLUS) + int offset = ((index - ((index >> 3) << 3))); + unsigned int cru_phyaddr, grf_phyaddr, gpio_phyaddr; +#else + int offset = ((index - ((index >> 3) << 3)) << 2); + + if (bank == 11) { + phyaddr = GPIOL_BASE + ((index >> 3) << 2); + } + else + phyaddr = GPIO_BASE_MAP + (bank * 36) + ((index >> 3) << 2); +#endif + +#ifdef CONFIG_ORANGEPI_2G_IOT + /* Offset of register */ + if (bank == 0) /* group A */ + base_address = GPIOA_BASE; + else if (bank == 1) /* group B */ + base_address = GPIOB_BASE; + else if (bank == 2) /* group C */ + base_address = GPIOC_BASE; + else if (bank == 3) /* group D */ + base_address = GPIOD_BASE; + else + printf("Bad pin number\n"); + + if (mode == INPUT) + phyaddr = base_address + SET_IN_REGISTER; + else if (mode == OUTPUT) + phyaddr = base_address + OEN_SET_OUT_REGISTER; + else + printf("Invalid mode\n"); +#elif (defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800) + if(bank == 1){ + cru_phyaddr = PMUCRU_BASE + PMUCRU_CLKGATE_CON1_OFFSET; + grf_phyaddr = PMUGRF_BASE + ((index >> 3) << 2) + 0x10; + gpio_phyaddr = GPIO1_BASE + GPIO_SWPORTA_DDR_OFFSET; + } + + else if(bank == 2){ + cru_phyaddr = CRU_BASE + CRU_CLKGATE_CON31_OFFSET; + grf_phyaddr = GRF_BASE + ((index >> 3) << 2); + gpio_phyaddr = GPIO2_BASE + GPIO_SWPORTA_DDR_OFFSET; + } + else if(bank == 4){ + cru_phyaddr = CRU_BASE + CRU_CLKGATE_CON31_OFFSET; + grf_phyaddr = GRF_BASE + ((index >> 3) << 2) +0x20; + gpio_phyaddr = GPIO4_BASE + GPIO_SWPORTA_DDR_OFFSET; + } + else; + +#elif (defined CONFIG_ORANGEPI_R1PLUS) + if(bank == 2){ //gpio2 + cru_phyaddr = CRU_BASE + CRU_CLKGATE_CON16_OFFSET; + //grf_phyaddr = GRF_BASE + ((index >> 3) << 2) + 0x10; + gpio_phyaddr = GPIO2_BASE + GPIO_SWPORTA_DDR_OFFSET; + if(0 == (index >> 3))//gpio2_ax + { + grf_phyaddr = GRF_BASE + 0x20; + } + else if(3 == (index >> 3))//gpio2_dx + { + grf_phyaddr = GRF_BASE + 0x34; + } + } + else if(bank == 3){ + cru_phyaddr = CRU_BASE + CRU_CLKGATE_CON16_OFFSET; + //grf_phyaddr = GRF_BASE + ((index >> 3) << 2) +0x20; + gpio_phyaddr = GPIO3_BASE + GPIO_SWPORTA_DDR_OFFSET; + if (0 == (index >> 3)) + { + if(4 == offset)//gpio3_a4 + { + grf_phyaddr = GRF_BASE + 0x38; + } + else//gpio3_a567 + { + grf_phyaddr = GRF_BASE + 0x3c; + } + } + else if(2 == (index >> 3)) //gpio3_c + { + grf_phyaddr = GRF_BASE + 0x48; + } + } + else; +#endif + + /* Ignore unused gpio */ + if (ORANGEPI_PIN_MASK[bank][index] != -1) { +#if ! (defined CONFIG_ORANGEPI_2G_IOT || defined CONFIG_ORANGEPI_RK3399 || CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800 || CONFIG_ORANGEPI_R1PLUS) + regval = readR(phyaddr); + if (wiringPiDebug) + printf("Before read reg val: 0x%x offset:%d\n",regval,offset); +#endif + if (wiringPiDebug) + printf("Register[%#x]: %#x index:%d\n", phyaddr, regval, index); + + /* Set Input */ + if(INPUT == mode) { +#ifdef CONFIG_ORANGEPI_2G_IOT + writeR(GPIO_BIT(index), phyaddr); + +#elif (defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800) + writeR(0xffff0180, cru_phyaddr); + regval = readR(grf_phyaddr); + regval |= 0x3 << ((offset << 1) | 0x10); + regval &= ~(0x3 << (offset << 1)); + writeR(regval, grf_phyaddr); + regval = readR(gpio_phyaddr); + regval &= ~(1 << index); + writeR(regval, gpio_phyaddr); + if (wiringPiDebug){ + regval = readR(gpio_phyaddr); + printf("Input mode set over reg val: %#x\n",regval); + } + +#elif (defined CONFIG_ORANGEPI_R1PLUS) + writeR(0xffff9877, cru_phyaddr); + + regval = readR(grf_phyaddr); + if(3 == bank && (0 == (index >> 3))) //gpio3_a iomux需è¦å†™3ä½ + { + regval |= 0xffff0000; + regval &= ~(0x7 << ((offset % 5) * 3)); + } + else //å…¶ä»–çš„å†™ä¸¤ä½ + { + regval |= 0xffff0000; + regval &= ~(0x3 << (offset << 1)); + } + writeR(regval, grf_phyaddr); + + regval = readR(gpio_phyaddr); + regval &= ~(1 << index); + writeR(regval, gpio_phyaddr); + if (wiringPiDebug){ + regval = readR(gpio_phyaddr); + printf("Input mode set over reg val: %#x\n",regval); + } +#else + regval &= ~(7 << offset); + writeR(regval, phyaddr); + regval = readR(phyaddr); + if (wiringPiDebug) + printf("Input mode set over reg val: %#x\n",regval); +#endif + } else if(OUTPUT == mode) { /* Set Output */ +#ifdef CONFIG_ORANGEPI_2G_IOT + writeR(GPIO_BIT(index), phyaddr); + /* Set default value as 0 */ + writeR(GPIO_BIT(index), base_address + CLR_REGISTER); +#elif (defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800) + writeR(0xffff0180, cru_phyaddr); + regval = readR(grf_phyaddr); + regval |= 0x3 << ((offset << 1) | 0x10); + regval &= ~(0x3 << (offset << 1)); + writeR(regval, grf_phyaddr); + regval = readR(gpio_phyaddr); + regval |= 1 << index; + writeR(regval, gpio_phyaddr); + if (wiringPiDebug){ + regval = readR(gpio_phyaddr); + printf("Out mode get value: 0x%x\n",regval); + } + +#elif (defined CONFIG_ORANGEPI_R1PLUS) + writeR(0xffff9877, cru_phyaddr); + + regval = readR(grf_phyaddr); + if(3 == bank && (0 == (index >> 3))) //gpio3_a iomux需è¦å†™3ä½ + { + regval |= 0xffff0000; + regval &= ~(0x7 << ((offset % 5) * 3)); + } + else //å…¶ä»–çš„å†™ä¸¤ä½ + { + regval |= 0xffff0000; + regval &= ~(0x3 << (offset << 1)); + } + writeR(regval, grf_phyaddr); + + regval = readR(gpio_phyaddr); + regval |= 1 << index; + writeR(regval, gpio_phyaddr); + if (wiringPiDebug){ + regval = readR(gpio_phyaddr); + printf("Out mode get value: 0x%x\n",regval); + } + +#else + regval &= ~(7 << offset); + regval |= (1 << offset); + if (wiringPiDebug) + printf("Out mode ready set val: 0x%x\n",regval); + writeR(regval, phyaddr); + regval = readR(phyaddr); + if (wiringPiDebug) + printf("Out mode get value: 0x%x\n",regval); +#endif + }else if (PWM_OUTPUT == mode) { + // set pin PWMx to pwm mode + regval &= ~(7 << offset); + regval |= (0x3 << offset); + if (wiringPiDebug) + printf(">>>>>line:%d PWM mode ready to set val: 0x%x\n", __LINE__, regval); + writeR(regval, phyaddr); + delayMicroseconds(200); + regval = readR(phyaddr); + if (wiringPiDebug) + printf("<<<<> 5; + unsigned int index = pin - (bank << 5); + unsigned int phyaddr = 0; + unsigned int bit_value = -1, bit_enable = 0; + unsigned int offset; + +#if (defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800) + /* */if ( bank > 1) + phyaddr = GRF_BASE + RK3399_GRF_GPIO2_3_4_P_OFFSET + (((pin - 64) >> 3) << 2); + else if ( bank == 1 || pin < 16) + phyaddr = PMUGRF_BASE + RK3399_PMUGRF_GPIO0_1_P_OFFSET + (((pin - 0) >> 3) << 2); + else { + printf("gpio0 Group c,d does not support PU/PD control\n"); + return ; + } + + //offset = index - ((index >> 3) << 3); + offset = (index % 8) << 1; + bit_enable = 3 << ( 16 + offset); + + /* */if (PUD_UP == pud) { + if ( pin < 8 || (bank == 2 && index > 15)) /* gpio0a, gpio2c, gpio2d */ + bit_value = 3; + else + bit_value = 1; + } + else if (PUD_DOWN == pud) { + if ( pin < 8 || (bank == 2 && index > 15)) /* gpio0a, gpio2c, gpio2d */ + bit_value = 1; + else + bit_value = 2; + } + else if (PUD_OFF == pud) { + bit_value = 0; + } +#else + unsigned int pullOffset = 0x1C; + switch (pud) + { + case PUD_OFF: + bit_value = SUNXI_PUD_OFF; + break; + case PUD_UP: + bit_value = SUNXI_PUD_UP; + break; + case PUD_DOWN: + bit_value = SUNXI_PUD_DOWN; + break; + default: + printf("Unknow pull mode\n"); + return 0; + } + offset = ((index - ((index >> 4) << 4)) << 1); + pullOffset = 0x1C; + + if (bank == 11) + { + phyaddr = pullOffset + GPIOL_BASE + ((index >> 4) << 2); + } + else + phyaddr = pullOffset + GPIO_BASE_MAP + (bank * 36) + ((index >> 4) << 2); +#endif + /* Ignore unused gpio */ + if (ORANGEPI_PIN_MASK[bank][index] != -1) + { + if (wiringPiDebug) + printf("bank: %d, index: %d\n", bank, index); + + regval = readR(phyaddr); + if (wiringPiDebug) + printf("read val(%#x) from register[%#x]\n", regval, phyaddr); + + /* clear bit */ + regval &= ~(3 << offset); + + /* bit write enable*/ + regval |= bit_enable; + + /* set bit */ + regval |= (bit_value & 3) << offset; + + if (wiringPiDebug) + printf("write val(%#x) to register[%#x]\n", regval, phyaddr); + + writeR(regval, phyaddr); + regval = readR(phyaddr); + + if (wiringPiDebug) + printf("over reg val: %#x\n", regval); + } + else + printf("Pin pull control failed!\n"); + + return 0; +} + +#if !(defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800 || defined CONFIG_ORANGEPI_R1PLUS || CONFIG_ORANGEPI_2G_IOT) +int OrangePi_set_gpio_alt(int pin, int mode) +{ + unsigned int regval = 0; + unsigned int bank = pin >> 5; + unsigned int index = pin - (bank << 5); + unsigned int phyaddr = 0; + int offset = ((index - ((index >> 3) << 3)) << 2); + + if (bank == 11) { + phyaddr = GPIOL_BASE + ((index >> 3) << 2); + }else + phyaddr = GPIO_BASE_MAP + (bank * 36) + ((index >> 3) << 2); + + /* Ignore unused gpio */ + if (ORANGEPI_PIN_MASK[bank][index] != -1) { + if (wiringPiDebug) + printf("Register[%#x]: %#x index:%d\n", phyaddr, regval, index); + + regval = readR(phyaddr); + regval &= ~(7 << offset); + regval |= (mode << offset); + writeR(regval, phyaddr); + } else + printf("Pin alt mode failed!\n"); + + return 0; +} +#endif + +/* + * OrangePi Digital write + */ +int OrangePi_digitalWrite(int pin, int value) +{ + unsigned int bank = pin >> 5; + unsigned int index = pin - (bank << 5); + unsigned int phyaddr = 0; +#ifdef CONFIG_ORANGEPI_2G_IOT + unsigned int base_address = 0; + +#elif (defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800 || defined CONFIG_ORANGEPI_R1PLUS ) + unsigned int regval = 0; + unsigned int cru_phyaddr = 0; + +#else + unsigned int regval = 0; + + if (bank == 11) { + phyaddr = GPIOL_BASE + 0x10; + } + else + phyaddr = GPIO_BASE_MAP + (bank * 36) + 0x10; +#endif + +#ifdef CONFIG_ORANGEPI_2G_IOT + /* version 0.1 only support GPIOC output on OrangePi 2G-IOT */ + if (bank == 2) { /* group C */ + int fd; + char buf[20]; + + if (value == 1) + fd = open("/sys/bus/platform/drivers/rda-gpioc/rda-gpioc/gpo_set", O_RDWR); + else + fd = open("/sys/bus/platform/drivers/rda-gpioc/rda-gpioc/gpo_clear", O_RDWR); + if (fd < 0) { + printf("ERROR: can't operate GPIOC-%d\n", index); + return -1; + } + sprintf(buf, "%d", index); + + write(fd, buf, strlen(buf)); + + close(fd); + return 0; + } + +#endif + +#ifdef CONFIG_ORANGEPI_2G_IOT + /* Offset of register */ + if (bank == 0) /* group A */ + base_address = GPIOA_BASE; + else if (bank == 1) /* group B */ + base_address = GPIOB_BASE; + else if (bank == 2) /* group C */ + base_address = GPIOC_BASE; + else if (bank == 3) /* group D */ + base_address = GPIOD_BASE; + else + printf("Bad pin number\n"); + + if (value == 0) + phyaddr = base_address + CLR_REGISTER; + else if (value == 1) + phyaddr = base_address + SET_REGISTER; + else + printf("Invalid value\n"); + +#elif (defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800) + if(bank == 1){ + phyaddr = GPIO1_BASE + GPIO_SWPORTA_DR_OFFSET; + cru_phyaddr = PMUCRU_BASE + PMUCRU_CLKGATE_CON1_OFFSET; + } + else if(bank == 2){ + phyaddr = GPIO2_BASE + GPIO_SWPORTA_DR_OFFSET; + cru_phyaddr = CRU_BASE + CRU_CLKGATE_CON31_OFFSET; + } + else if(bank == 4){ + phyaddr = GPIO4_BASE + GPIO_SWPORTA_DR_OFFSET; + cru_phyaddr = CRU_BASE + CRU_CLKGATE_CON31_OFFSET; + } + else; + +#elif (defined CONFIG_ORANGEPI_R1PLUS) + if(bank == 2){ + phyaddr = GPIO2_BASE + GPIO_SWPORTA_DR_OFFSET; + cru_phyaddr = CRU_BASE + CRU_CLKGATE_CON16_OFFSET; + } + else if(bank == 3){ + phyaddr = GPIO3_BASE + GPIO_SWPORTA_DR_OFFSET; + cru_phyaddr = CRU_BASE + CRU_CLKGATE_CON16_OFFSET; + } + else; + +#endif + /* Ignore unused gpio */ + if (ORANGEPI_PIN_MASK[bank][index] != -1) { +#ifdef CONFIG_ORANGEPI_2G_IOT + writeR(GPIO_BIT(index), phyaddr); + +#else + #if (defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800) + writeR(0xffff0180, cru_phyaddr); + #elif (defined CONFIG_ORANGEPI_R1PLUS) + writeR(0xffff9877, cru_phyaddr); + #endif + regval = readR(phyaddr); + if (wiringPiDebug) + printf("befor write reg val: 0x%x,index:%d\n", regval, index); + if(0 == value) { + regval &= ~(1 << index); + writeR(regval, phyaddr); + regval = readR(phyaddr); + if (wiringPiDebug) + printf("LOW val set over reg val: 0x%x\n", regval); + } else { + regval |= (1 << index); + writeR(regval, phyaddr); + regval = readR(phyaddr); + if (wiringPiDebug) + printf("HIGH val set over reg val: 0x%x\n", regval); + } +#endif + } else + printf("Pin mode failed!\n"); + + return 0; +} + +/* + * OrangePi Digital Read + */ +int OrangePi_digitalRead(int pin) +{ + int bank = pin >> 5; + int index = pin - (bank << 5); + int val; +#if ! (defined CONFIG_ORANGEPI_2G_IOT || defined CONFIG_ORANGEPI_RK3399 || CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800 || defined CONFIG_ORANGEPI_R1PLUS) + + unsigned int phyaddr; + + if (bank == 11) { + phyaddr = GPIOL_BASE + 0x10; + } + else + phyaddr = GPIO_BASE_MAP + (bank * 36) + 0x10; +#endif + +#ifdef CONFIG_ORANGEPI_2G_IOT + unsigned int base_address = 0; + unsigned int phys_OEN_R; + unsigned int phys_SET_R; + unsigned int phys_VAL_R; + + /* version 0.1 not support GPIOC input function */ + if (bank == 2) + return -1; + + /* Offset of register */ + if (bank == 0) /* group A */ + base_address = GPIOA_BASE; + else if (bank == 1) /* group B */ + base_address = GPIOB_BASE; + else if (bank == 2) /* group C */ + base_address = GPIOC_BASE; + else if (bank == 3) /* group D */ + base_address = GPIOD_BASE; + else + printf("Bad pin number\n"); + + phys_OEN_R = base_address + OEN_VAL_REGISTER; + phys_SET_R = base_address + SET_REGISTER; + phys_VAL_R = base_address + VAL_REGISTER; + +#elif (defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800) + unsigned int phyaddr; + if(bank == 1) + phyaddr = GPIO1_BASE + GPIO_EXT_PORTA_OFFSET; + else if(bank == 2) + phyaddr = GPIO2_BASE + GPIO_EXT_PORTA_OFFSET; + else if(bank == 4) + phyaddr = GPIO4_BASE + GPIO_EXT_PORTA_OFFSET; + else; + +#elif (defined CONFIG_ORANGEPI_R1PLUS) + + unsigned int phyaddr; + if(bank == 2) + phyaddr = GPIO2_BASE + GPIO_EXT_PORTA_OFFSET; + else if(bank == 3) + phyaddr = GPIO3_BASE + GPIO_EXT_PORTA_OFFSET; + else; +#endif + + if (ORANGEPI_PIN_MASK[bank][index] != -1) { +#ifndef CONFIG_ORANGEPI_2G_IOT + val = readR(phyaddr); + val = val >> index; + val &= 1; + if (wiringPiDebug) + printf("Read reg val: 0x%#x, bank:%d, index:%d\n", val, bank, index); + return val; +#else + if (readR(phys_OEN_R) & GPIO_BIT(index)) /* Input */ + val = (readR(phys_VAL_R) & GPIO_BIT(index)) ? 1 : 0; + else /* Ouput */ + val = (readR(phys_SET_R) & GPIO_BIT(index)) ? 1 : 0; + return val; +#endif + } + return 0; +} + +/* + * Probe OrangePi Platform. + */ +int isOrangePi(void) +{ + FILE *cpuFd; + char line [120]; + char *d; +#ifdef CONFIG_ORANGEPI_2G_IOT + /* Support: OrangePi 2G-IOT and OrangePi i96 */ + char *OrangePi_string = "rda8810"; +#elif CONFIG_ORANGEPI_PC2 || CONFIG_ORANGEPI_ZEROPLUS || CONFIG_ORANGEPI_ZEROPLUS2_H5 || CONFIG_ORANGEPI_PRIME + /* Support: OrangePi PC2 */ + char *OrangePi_string = "sun50iw2"; +#elif CONFIG_ORANGEPI_WIN + /* Support: OrangePi Win/Win plus */ + char *OrangePi_string = "sun50iw1"; +#elif CONFIG_ORANGEPI_H3 || CONFIG_ORANGEPI_ZEROPLUS2_H3 + /* Support: OrangePi Win/Win plus */ + char *OrangePi_string = "sun8i"; +#elif CONFIG_ORANGEPI_ZERO || CONFIG_ORANGEPI_R1 + /* Support: OrangePi zero */ + char *OrangePi_string = "sun8i"; +#elif CONFIG_ORANGEPI_LITE2 || CONFIG_ORANGEPI_3 + /* Support: OrangePi zero */ + char *OrangePi_string = "sun50iw6"; +#elif CONFIG_ORANGEPI_ZERO2 + /* Support: OrangePi zero */ + char *OrangePi_string = "sun50iw9"; +#elif (defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800) + /* Support: OrangePi RK3399 */ + char *OrangePi_string = "rk3399"; +#elif (defined CONFIG_ORANGEPI_R1PLUS) + /* Support: OrangePi R1plus */ + char *OrangePi_string = "rk3328"; + + +#else + /* Non-support */ + char *OrangePi_string = "none"; +#endif + + //printf("OrangePi String is %s\n", OrangePi_string); + + return 1; + + if ((cpuFd = fopen("/proc/cpuinfo", "r")) == NULL) + piGpioLayoutOops ("Unable to open /proc/cpuinfo") ; + + while (fgets(line, 120, cpuFd) != NULL) { + if (strncmp(line, "Hardware", 8) == 0) + break; + } + + fclose(cpuFd); + +#if (defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800) + strcpy(line, "Hardware : Rockchip rk3399 Family"); +#elif (defined CONFIG_ORANGEPI_R1PLUS) + strcpy(line, "Hardware : Rockchip rk3328 Family"); +#endif + + if (strncmp(line, "Hardware", 8) != 0) + piGpioLayoutOops("No \"Hardware\" line"); + + for (d = &line [strlen (line) - 1]; (*d == '\n') || (*d == '\r') ; --d) + *d = 0; + + if (wiringPiDebug) + printf("piboardRev: Hardware string: %s\n", line); + + if (strstr(line, OrangePi_string) != NULL) { + if (wiringPiDebug) + printf("Hardware:%s\n",line); + return 1; + } else { + if (wiringPiDebug) + printf("Hardware:%s\n",line); + return 0; + } +} + +#endif /* CONFIG_ORANGEPI */ diff --git a/wiringPi/OrangePi.h b/wiringPi/OrangePi.h new file mode 100644 index 0000000..a3cf411 --- /dev/null +++ b/wiringPi/OrangePi.h @@ -0,0 +1,286 @@ +#ifndef _ORANGEPI_H +#define _ORANGEPI_H + +#ifdef CONFIG_ORANGEPI_2G_IOT +/********** OrangePi 2G-IOT *************/ +/* + * GPIOA_BASE 0x20930000 + * GPIOB_BASE 0x20931000 + * GPIOC_BASE 0x11A08000 + * GPIOD_BASE 0x20932000 + */ + +/********* local data ************/ +#define GPIOA_BASE 0x20930000 +#define GPIOB_BASE 0x20931000 +#define GPIOC_BASE 0x11A08000 +#define GPIOD_BASE 0x20932000 +#define GPIO_NUM (0x80) +#define GPIO_BIT(x) (1UL << (x)) + +#define OEN_VAL_REGISTER (0x00) +#define OEN_SET_OUT_REGISTER (0x04) +#define SET_IN_REGISTER (0x08) +#define VAL_REGISTER (0x0C) +#define SET_REGISTER (0x10) +#define CLR_REGISTER (0x14) + +#define MEM_INFO (512) +#define MAP_SIZE_L (4 * 4096) + +#endif /* CONFIG_ORANGEPI_2G_IOT */ + +#if CONFIG_ORANGEPI_PC2 || CONFIG_ORANGEPI_ZEROPLUS || CONFIG_ORANGEPI_ZEROPLUS2_H5 || CONFIG_ORANGEPI_PRIME +/************** OrangePi H5 ***********************/ +#define GPIOA_BASE (0x01C20000) +#define GPIO_NUM (0x40) +#define GPIO_BASE_MAP (0x01C20800) +#define MEM_INFO (1024) +#define GPIOL_BASE (0x01F02c00) +#define GPIOL_BASE_MAP (0x01F02000) +#define MAP_SIZE_L (4096 * 2) +#define GPIO_PWM_OP (0x01C21000) +#endif + +/************** OrangePi A64 ***********************/ +#ifdef CONFIG_ORANGEPI_WIN +#define GPIOA_BASE (0x01C20000) +#define GPIO_NUM (0x40) +#define GPIO_BASE_MAP (0x01C20800) +#define MEM_INFO (1024) +#define GPIOL_BASE (0x01F02c00) +#define GPIOL_BASE_MAP (0x01F02000) +#define MAP_SIZE_L (4096 * 2) +#define GPIO_PWM_OP (0x01C21000) +#endif + +/************** OrangePi H3 ***********************/ +#if CONFIG_ORANGEPI_H3 || CONFIG_ORANGEPI_ZEROPLUS2_H3 || CONFIG_ORANGEPI_ZERO +#define GPIOA_BASE (0x01C20000) +#define GPIO_NUM (0x40) +#define GPIO_BASE_MAP (0x01C20800) +#define MEM_INFO (1024) +#define GPIOL_BASE (0x01F02c00) +#define GPIOL_BASE_MAP (0x01F02000) +#define MAP_SIZE_L (4096 * 2) +#define GPIO_PWM_OP (0x01C21000) +#endif + +/*********** OrangePi LITE2/OnePlus/PC3 *************/ +#if CONFIG_ORANGEPI_LITE2 || CONFIG_ORANGEPI_3 +#define GPIOA_BASE (0x0300B000) +#define GPIO_NUM (0x40) +#define GPIO_BASE_MAP (0x0300B000) +#define MEM_INFO (1024) +#define GPIOL_BASE (0x07022000) +#define GPIOL_BASE_MAP (0x07022000) +#define MAP_SIZE_L (4096 * 1) +#define GPIO_PWM_OP (0x0300A000) +#endif + +/*********** OrangePi H616 *************/ +#if CONFIG_ORANGEPI_ZERO2 +#define GPIOA_BASE (0x0300B000) +#define GPIO_NUM (0x40) +#define GPIO_BASE_MAP (0x0300B000) +#define MEM_INFO (1024) +#define GPIOL_BASE (0x07022000) +#define GPIOL_BASE_MAP (0x07022000) +#define MAP_SIZE_L (4096 * 1) +#define GPIO_PWM_OP (0x0300A000) +#endif + +/*********** OrangePi RK3399 *************/ +#if CONFIG_ORANGEPI_RK3399 || CONFIG_ORANGEPI_4 || CONFIG_ORANGEPI_4_LTS || CONFIG_ORANGEPI_800 + +#define GPIO1_BASE 0xff730000 +#define GPIO2_BASE 0xff780000 +#define GPIO4_BASE 0xff790000 +#define GPIO_NUM (0x40) +#define GPIO_BIT(x) (1UL << (x)) +#define GPIO_SWPORTA_DR_OFFSET 0x00 +#define GPIO_SWPORTA_DDR_OFFSET 0x04 +#define GPIO_EXT_PORTA_OFFSET 0x50 + +#define RK3399_GRF_GPIO2_3_4_P_OFFSET 0x00040U +#define RK3399_PMUGRF_GPIO0_1_P_OFFSET 0x00040U + +#define PMUGRF_BASE 0xff320000 +#define PMUGRF_GPIO1A_IOMUX 0x00010 +#define PMUGRF_GPIO1B_IOMUX 0x00014 +#define PMUGRF_GPIO1C_IOMUX 0x00018 +#define PMUGRF_GPIO1D_IOMUX 0x0001c + +#define GRF_BASE 0xff77e000 +#define GRF_GPIO2A_IOMUX_OFFSET 0x00 +#define GRF_GPIO2B_IOMUX_OFFSET 0x04 +#define GRF_GPIO2C_IOMUX_OFFSET 0x08 +#define GRF_GPIO2D_IOMUX_OFFSET 0x0c + +#define GRF_GPIO4A_IOMUX_OFFSET 0x20 +#define GRF_GPIO4B_IOMUX_OFFSET 0x24 +#define GRF_GPIO4C_IOMUX_OFFSET 0x28 +#define GRF_GPIO4D_IOMUX_OFFSET 0x2c + + +#define CRU_BASE 0xff760000 +#define PMUCRU_BASE 0xff750000 +#define CRU_CLKGATE_CON31_OFFSET 0x037c //bit 3 4 5 +#define PMUCRU_CLKGATE_CON1_OFFSET 0x0104 + +#define MEM_INFO (2048) +#define MAP_SIZE_L (4*1024) + +extern volatile unsigned int *gpio2_base; +extern volatile unsigned int *grf_base; +extern volatile unsigned int *cru_base; +extern volatile unsigned int *pmucru_base; +extern volatile unsigned int *pmugrf_base; +extern volatile unsigned int *gpio1_base; +extern volatile unsigned int *gpio4_base; + +#endif /* CONFIG_ORANGEPI_RK3399 */ +//csy 2019.1.8 + + +/*********** OrangePi R1PLUS *************/ +#if CONFIG_ORANGEPI_R1PLUS + +#define GPIO2_BASE 0xff230000 +#define GPIO3_BASE 0xff240000 +#define GPIO_NUM (0x40) + +#define GPIO_SWPORTA_DR_OFFSET 0x00 +#define GPIO_SWPORTA_DDR_OFFSET 0x04 +#define GPIO_EXT_PORTA_OFFSET 0x50 + +#define GRF_BASE 0xff100000 +#define GRF_GPIO2A_IOMUX_OFFSET 0x20 +#define GRF_GPIO2BL_IOMUX_OFFSET 0x24 +#define GRF_GPIO2BH_IOMUX_OFFSET 0x28 +#define GRF_GPIO2CL_IOMUX_OFFSET 0x2c +#define GRF_GPIO2CH_IOMUX_OFFSET 0x30 +#define GRF_GPIO2D_IOMUX_OFFSET 0x34 + +#define GRF_GPIO3AL_IOMUX_OFFSET 0x38 +#define GRF_GPIO3AH_IOMUX_OFFSET 0x3c +#define GRF_GPIO3BL_IOMUX_OFFSET 0x40 +#define GRF_GPIO3BH_IOMUX_OFFSET 0x44 +#define GRF_GPIO3C_IOMUX_OFFSET 0x48 +#define GRF_GPIO3D_IOMUX_OFFSET 0x4c + +#define CRU_BASE 0xff440000 +#define CRU_CLKGATE_CON16_OFFSET 0x0240 //bit 7 8 9 10 9877 + +#define MEM_INFO (2048) +#define MAP_SIZE_L (4*1024) + +extern volatile unsigned int *gpio2_base; +extern volatile unsigned int *gpio3_base; +extern volatile unsigned int *cru_base; +extern volatile unsigned int *grf_base; + + +#endif /* CONFIG_ORANGEPI_R1PLUS */ +//FG 2020.11.26 + + + +/****************** Global data *********************/ +/* Current version */ +#define PI_MAKER_ORANGEPI 4 +#define MAX_PIN_NUM GPIO_NUM +#define MAP_SIZE MAP_SIZE_L +#define MAP_MASK (MAP_SIZE - 1) +#define PI_GPIO_MASK (~(GPIO_NUM - 1)) +#define GPIO_BASE GPIOA_BASE +#define ORANGEPI_MEM_INFO MEM_INFO +#define GPIO_PWM GPIO_PWM_OP + + +//sunxi_pwm +#define SUNXI_PWM_BASE (0x01c21400) +#define SUNXI_PWM_CTRL_REG (SUNXI_PWM_BASE) +#define SUNXI_PWM_CH0_PERIOD (SUNXI_PWM_BASE + 0x4) +#define SUNXI_PWM_CH1_PERIOD (SUNXI_PWM_BASE + 0x8) + +#define SUNXI_PWM_CH0_EN (1 << 4) +#define SUNXI_PWM_CH0_ACT_STA (1 << 5) +#define SUNXI_PWM_SCLK_CH0_GATING (1 << 6) +#define SUNXI_PWM_CH0_MS_MODE (1 << 7) //pulse mode +#define SUNXI_PWM_CH0_PUL_START (1 << 8) + +#define PWM_CLK_DIV_120 0 +#define PWM_CLK_DIV_180 1 +#define PWM_CLK_DIV_240 2 +#define PWM_CLK_DIV_360 3 +#define PWM_CLK_DIV_480 4 +#define PWM_CLK_DIV_12K 8 +#define PWM_CLK_DIV_24K 9 +#define PWM_CLK_DIV_36K 10 +#define PWM_CLK_DIV_48K 11 +#define PWM_CLK_DIV_72K 12 + +#define SUNXI_PUD_OFF 0 +#define SUNXI_PUD_UP 1 +#define SUNXI_PUD_DOWN 2 + +extern int pinToGpioOrangePi[64]; +extern int physToGpioOrangePi[64]; +extern int physToPinOrangePi[64]; +extern int physToWpiOrangePi[64]; +extern volatile unsigned int *OrangePi_gpio; +extern volatile unsigned int *OrangePi_gpioC; + +extern int pinToGpioR3[64]; +extern int physToGpioR3[64]; +extern int physToPinR3[64]; +extern int pwmmode; + +extern unsigned int readR(unsigned int addr); +extern void writeR(unsigned int val, unsigned int addr); +extern int OrangePi_set_gpio_mode(int pin, int mode); +extern int OrangePi_set_gpio_pullUpDnControl(int pin, int pud); +#if !(defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800 || defined CONFIG_ORANGEPI_R1PLUS || CONFIG_ORANGEPI_2G_IOT) +extern int OrangePi_set_gpio_alt(int pin, int mode); +#endif +extern int OrangePi_get_gpio_mode(int pin); +extern int isOrangePi_2G_IOT(void); +extern int isOrangePi(void); +extern unsigned int readR(unsigned int addr); +extern void writeR(unsigned int val, unsigned int addr); +extern int OrangePi_digitalWrite(int pin, int value); +extern int OrangePi_digitalRead(int pin); + +extern void print_pwm_reg(void); +extern void sunxi_pwm_set_enable(int en); +extern void sunxi_pwm_set_mode(int mode); +extern void sunxi_pwm_set_clk(int clk); +extern int sunxi_pwm_get_period(void); +extern int sunxi_pwm_get_act(void); +extern void sunxi_pwm_set_period(int period_cys); +extern void sunxi_pwm_set_act(int act_cys); + + +#ifdef CONFIG_ORANGEPI +extern const char *piModelNames[6]; +#endif + +#ifdef CONFIG_ORANGEPI_2G_IOT +extern int ORANGEPI_PIN_MASK[4][32]; +#elif CONFIG_ORANGEPI_PC2 || CONFIG_ORANGEPI_PRIME +extern int ORANGEPI_PIN_MASK[9][32]; +#elif CONFIG_ORANGEPI_WIN +extern int ORANGEPI_PIN_MASK[12][32]; +#elif CONFIG_ORANGEPI_H3 +extern int ORANGEPI_PIN_MASK[9][32]; +#elif CONFIG_ORANGEPI_ZERO || CONFIG_ORANGEPI_ZEROPLUS2_H3 || CONFIG_ORANGEPI_ZEROPLUS || CONFIG_ORANGEPI_ZEROPLUS2_H5 +extern int ORANGEPI_PIN_MASK[12][32]; +#elif CONFIG_ORANGEPI_RK3399 +extern int ORANGEPI_PIN_MASK[5][32]; +#elif CONFIG_ORANGEPI_R1PLUS +extern int ORANGEPI_PIN_MASK[5][32]; + + +#endif +#endif diff --git a/wiringPi/ads1115.c b/wiringPi/ads1115.c new file mode 100644 index 0000000..648e612 --- /dev/null +++ b/wiringPi/ads1115.c @@ -0,0 +1,293 @@ +/* + * ads1115.c: + * Extend wiringPi with the ADS1115 I2C 16-bit ADC + * Copyright (c) 2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +/* + ********************************************************************************* + * We're going to work in a hybrid mode to fit in with the wiringPi way of + * doing things, so there will be 4 analog pin which read the 4 single-ended + * channels as usual, also some fake digitalOutputs - these are the control + * registers that allow the user to put it into single/diff mode, set the + * gain and data rates. + ********************************************************************************* + */ + +#include +#include +#include + +#include +#include + +#include "ads1115.h" + +// Bits in the config register (it's a 16-bit register) + +#define CONFIG_OS_MASK (0x8000) // Operational Status Register +#define CONFIG_OS_SINGLE (0x8000) // Write - Starts a single-conversion + // Read 1 = Conversion complete + +// The multiplexor + +#define CONFIG_MUX_MASK (0x7000) + +// Differential modes + +#define CONFIG_MUX_DIFF_0_1 (0x0000) // Pos = AIN0, Neg = AIN1 (default) +#define CONFIG_MUX_DIFF_0_3 (0x1000) // Pos = AIN0, Neg = AIN3 +#define CONFIG_MUX_DIFF_1_3 (0x2000) // Pos = AIN1, Neg = AIN3 +#define CONFIG_MUX_DIFF_2_3 (0x3000) // Pos = AIN2, Neg = AIN3 (2nd differential channel) + +// Single-ended modes + +#define CONFIG_MUX_SINGLE_0 (0x4000) // AIN0 +#define CONFIG_MUX_SINGLE_1 (0x5000) // AIN1 +#define CONFIG_MUX_SINGLE_2 (0x6000) // AIN2 +#define CONFIG_MUX_SINGLE_3 (0x7000) // AIN3 + +// Programmable Gain Amplifier + +#define CONFIG_PGA_MASK (0x0E00) +#define CONFIG_PGA_6_144V (0x0000) // +/-6.144V range = Gain 2/3 +#define CONFIG_PGA_4_096V (0x0200) // +/-4.096V range = Gain 1 +#define CONFIG_PGA_2_048V (0x0400) // +/-2.048V range = Gain 2 (default) +#define CONFIG_PGA_1_024V (0x0600) // +/-1.024V range = Gain 4 +#define CONFIG_PGA_0_512V (0x0800) // +/-0.512V range = Gain 8 +#define CONFIG_PGA_0_256V (0x0A00) // +/-0.256V range = Gain 16 + +#define CONFIG_MODE (0x0100) // 0 is continuous, 1 is single-shot (default) + +// Data Rate + +#define CONFIG_DR_MASK (0x00E0) +#define CONFIG_DR_8SPS (0x0000) // 8 samples per second +#define CONFIG_DR_16SPS (0x0020) // 16 samples per second +#define CONFIG_DR_32SPS (0x0040) // 32 samples per second +#define CONFIG_DR_64SPS (0x0060) // 64 samples per second +#define CONFIG_DR_128SPS (0x0080) // 128 samples per second (default) +#define CONFIG_DR_475SPS (0x00A0) // 475 samples per second +#define CONFIG_DR_860SPS (0x00C0) // 860 samples per second + +// Comparator mode + +#define CONFIG_CMODE_MASK (0x0010) +#define CONFIG_CMODE_TRAD (0x0000) // Traditional comparator with hysteresis (default) +#define CONFIG_CMODE_WINDOW (0x0010) // Window comparator + +// Comparator polarity - the polarity of the output alert/rdy pin + +#define CONFIG_CPOL_MASK (0x0008) +#define CONFIG_CPOL_ACTVLOW (0x0000) // Active low (default) +#define CONFIG_CPOL_ACTVHI (0x0008) // Active high + +// Latching comparator - does the alert/rdy pin latch + +#define CONFIG_CLAT_MASK (0x0004) +#define CONFIG_CLAT_NONLAT (0x0000) // Non-latching comparator (default) +#define CONFIG_CLAT_LATCH (0x0004) // Latching comparator + +// Comparitor queue + +#define CONFIG_CQUE_MASK (0x0003) +#define CONFIG_CQUE_1CONV (0x0000) // Assert after one conversions +#define CONFIG_CQUE_2CONV (0x0001) // Assert after two conversions +#define CONFIG_CQUE_4CONV (0x0002) // Assert after four conversions +#define CONFIG_CQUE_NONE (0x0003) // Disable the comparator (default) + +#define CONFIG_DEFAULT (0x8583) // From the datasheet + + +static const uint16_t dataRates [8] = +{ + CONFIG_DR_8SPS, CONFIG_DR_16SPS, CONFIG_DR_32SPS, CONFIG_DR_64SPS, CONFIG_DR_128SPS, CONFIG_DR_475SPS, CONFIG_DR_860SPS +} ; + +static const uint16_t gains [6] = +{ + CONFIG_PGA_6_144V, CONFIG_PGA_4_096V, CONFIG_PGA_2_048V, CONFIG_PGA_1_024V, CONFIG_PGA_0_512V, CONFIG_PGA_0_256V +} ; + + +/* + * analogRead: + * Pin is the channel to sample on the device. + * Channels 0-3 are single ended inputs, + * channels 4-7 are the various differential combinations. + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + int chan = pin - node->pinBase ; + int16_t result ; + uint16_t config = CONFIG_DEFAULT ; + + chan &= 7 ; + +// Setup the configuration register + +// Set PGA/voltage range + + config &= ~CONFIG_PGA_MASK ; + config |= node->data0 ; + +// Set sample speed + + config &= ~CONFIG_DR_MASK ; + config |= node->data1 ; + +// Set single-ended channel or differential mode + + config &= ~CONFIG_MUX_MASK ; + + switch (chan) + { + case 0: config |= CONFIG_MUX_SINGLE_0 ; break ; + case 1: config |= CONFIG_MUX_SINGLE_1 ; break ; + case 2: config |= CONFIG_MUX_SINGLE_2 ; break ; + case 3: config |= CONFIG_MUX_SINGLE_3 ; break ; + + case 4: config |= CONFIG_MUX_DIFF_0_1 ; break ; + case 5: config |= CONFIG_MUX_DIFF_2_3 ; break ; + case 6: config |= CONFIG_MUX_DIFF_0_3 ; break ; + case 7: config |= CONFIG_MUX_DIFF_1_3 ; break ; + } + +// Start a single conversion + + config |= CONFIG_OS_SINGLE ; + config = __bswap_16 (config) ; + wiringPiI2CWriteReg16 (node->fd, 1, config) ; + +// Wait for the conversion to complete + + for (;;) + { + result = wiringPiI2CReadReg16 (node->fd, 1) ; + result = __bswap_16 (result) ; + if ((result & CONFIG_OS_MASK) != 0) + break ; + delayMicroseconds (100) ; + } + + result = wiringPiI2CReadReg16 (node->fd, 0) ; + result = __bswap_16 (result) ; + +// Sometimes with a 0v input on a single-ended channel the internal 0v reference +// can be higher than the input, so you get a negative result... + + if ( (chan < 4) && (result < 0) ) + return 0 ; + else + return (int)result ; +} + + +/* + * digitalWrite: + * It may seem odd to have a digital write here, but it's the best way + * to pass paramters into the chip in the wiringPi way of things. + * We have 2 digital registers: + * 0 is the gain control + * 1 is the data rate control + ********************************************************************************* + */ + +static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int data) +{ + int chan = pin - node->pinBase ; + chan &= 3 ; + + if (chan == 0) // Gain Control + { + if ( (data < 0) || (data > 6) ) // Use default if out of range + data = 2 ; + node->data0 = gains [data] ; + } + else // Data rate control + { + if ( (data < 0) || (data > 7) ) // Use default if out of range + data = 4 ; + node->data1 = dataRates [data] ; // Bugfix 0-1 by "Eric de jong (gm)" - Thanks. + } + +} + + +/* + * analogWrite: + * We're using this to write to the 2 comparitor threshold registers. + * We could use a digitalWrite here but as it's an analog comparison + * then it feels better to do it this way. + ********************************************************************************* + */ + +static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int data) +{ + int chan = pin - node->pinBase ; + int reg ; + int16_t ndata ; + + chan &= 3 ; + + reg = chan + 2 ; + + /**/ if (data < -32767) + ndata = -32767 ; + else if (data > 32767) + ndata = 32767 ; + else + ndata = (int16_t)data ; + + ndata = __bswap_16 (ndata) ; + wiringPiI2CWriteReg16 (node->fd, reg, data) ; +} + + + +/* + * ads1115Setup: + * Create a new wiringPi device node for an ads1115 on the Pi's + * I2C interface. + ********************************************************************************* + */ + +int ads1115Setup (const int pinBase, int i2cAddr) +{ + struct wiringPiNodeStruct *node ; + int fd ; + + if ((fd = wiringPiI2CSetup (i2cAddr)) < 0) + return FALSE ; + + node = wiringPiNewNode (pinBase, 8) ; + + node->fd = fd ; + node->data0 = CONFIG_PGA_4_096V ; // Gain in data0 + node->data1 = CONFIG_DR_128SPS ; // Samples/sec in data1 + node->analogRead = myAnalogRead ; + node->analogWrite = myAnalogWrite ; + node->digitalWrite = myDigitalWrite ; + + return TRUE ; +} diff --git a/wiringPi/ads1115.h b/wiringPi/ads1115.h new file mode 100644 index 0000000..5c91735 --- /dev/null +++ b/wiringPi/ads1115.h @@ -0,0 +1,55 @@ +/* + * ads1115.c: + * Extend wiringPi with the ADS1115 I2C 16-bit ADC + * Copyright (c) 2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +// Constants for some of the internal functions + +// Gain + +#define ADS1115_GAIN_6 0 +#define ADS1115_GAIN_4 1 +#define ADS1115_GAIN_2 2 +#define ADS1115_GAIN_1 3 +#define ADS1115_GAIN_HALF 4 +#define ADS1115_GAIN_QUARTER 5 + +// Data rate + +#define ADS1115_DR_8 0 +#define ADS1115_DR_16 1 +#define ADS1115_DR_32 2 +#define ADS1115_DR_64 3 +#define ADS1115_DR_128 4 +#define ADS1115_DR_250 5 +#define ADS1115_DR_475 6 +#define ADS1115_DR_860 7 + +#ifdef __cplusplus +extern "C" { +#endif + +extern int ads1115Setup (int pinBase, int i2cAddress) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/bmp180.c b/wiringPi/bmp180.c new file mode 100644 index 0000000..bad4bb3 --- /dev/null +++ b/wiringPi/bmp180.c @@ -0,0 +1,237 @@ +/* + * bmp180.c: + * Extend wiringPi with the BMP180 I2C Pressure and Temperature + * sensor. This is used in the Pi Weather Station + * Copyright (c) 2016 Gordon Henderson + * + * Information from the document held at: + * http://wmrx00.sourceforge.net/Arduino/BMP085-Calcs.pdf + * was very useful when building this code. + * + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include + +#include "wiringPi.h" +#include "wiringPiI2C.h" + +#include "bmp180.h" + +#undef DEBUG + +#define I2C_ADDRESS 0x77 +#define BMP180_OSS 0 + + +// Static calibration data +// The down-side of this is that there can only be one BMP180 in +// a system - which is practice isn't an issue as it's I2C +// address is fixed. + +static int16_t AC1, AC2, AC3 ; +static uint16_t AC4, AC5, AC6 ; +static int16_t VB1, VB2 ; +static int16_t MB, MC, MD ; + +static double c5, c6, mc, md, x0, x1, x2, yy0, yy1, yy2, p0, p1, p2 ; + +// Pressure & Temp variables + +uint32_t cPress, cTemp ; + +static int altitude ; + +/* + * read16: + * Quick hack to read the 16-bit data with the correct endian + ********************************************************************************* + */ + +uint16_t read16 (int fd, int reg) +{ + return (wiringPiI2CReadReg8 (fd, reg) << 8) | wiringPiI2CReadReg8 (fd, reg + 1) ; + +} + + +/* + * bmp180ReadTempPress: + * Does the hard work of reading the sensor + ********************************************************************************* + */ + +static void bmp180ReadTempPress (int fd) +{ + double fTemp, fPress ; + double tu, a ; + double pu, s, x, y, z ; + + uint8_t data [4] ; + +// Start a temperature sensor reading + + wiringPiI2CWriteReg8 (fd, 0xF4, 0x2E) ; + delay (5) ; + +// Read the raw data + + data [0] = wiringPiI2CReadReg8 (fd, 0xF6) ; + data [1] = wiringPiI2CReadReg8 (fd, 0xF7) ; + +// And calculate... + + tu = (data [0] * 256.0) + data [1] ; + + a = c5 * (tu - c6) ; + fTemp = a + (mc / (a + md)) ; + cTemp = (int)rint (((100.0 * fTemp) + 0.5) / 10.0) ; + +#ifdef DEBUG + printf ("fTemp: %f, cTemp: %6d\n", fTemp, cTemp) ; +#endif + +// Start a pressure snsor reading + + wiringPiI2CWriteReg8 (fd, 0xF4, 0x34 | (BMP180_OSS << 6)) ; + delay (5) ; + +// Read the raw data + + data [0] = wiringPiI2CReadReg8 (fd, 0xF6) ; + data [1] = wiringPiI2CReadReg8 (fd, 0xF7) ; + data [2] = wiringPiI2CReadReg8 (fd, 0xF8) ; + +// And calculate... + + pu = ((double)data [0] * 256.0) + (double)data [1] + ((double)data [2] / 256.0) ; + s = fTemp - 25.0 ; + x = (x2 * pow (s, 2.0)) + (x1 * s) + x0 ; + y = (yy2 * pow (s, 2.0)) + (yy1 * s) + yy0 ; + z = (pu - x) / y ; + fPress = (p2 * pow (z, 2.0)) + (p1 * z) + p0 ; + cPress = (int)rint (((100.0 * fPress) + 0.5) / 10.0) ; + +#ifdef DEBUG + printf ("fPress: %f, cPress: %6d\n", fPress, cPress) ; +#endif +} + + +/* + * myAnalogWrite: + * Write to a fake register to represent the height above sea level + * so that the peudo millibar register can read the pressure in mB + ********************************************************************************* + */ + +static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + int chan = pin - node->pinBase ; + + if (chan == 0) + altitude = value ; +} + +/* + * myAnalogRead: + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + int chan = pin - node->pinBase ; + + bmp180ReadTempPress (node->fd) ; + + /**/ if (chan == 0) // Read Temperature + return cTemp ; + else if (chan == 1) // Pressure + return cPress ; + else if (chan == 2) // Pressure in mB + return cPress / pow (1 - ((double)altitude / 44330.0), 5.255) ; + else + return -9999 ; + +} + + +/* + * bmp180Setup: + * Create a new instance of a PCF8591 I2C GPIO interface. We know it + * has 4 pins, (4 analog inputs and 1 analog output which we'll shadow + * input 0) so all we need to know here is the I2C address and the + * user-defined pin base. + ********************************************************************************* + */ + +int bmp180Setup (const int pinBase) +{ + double c3, c4, b1 ; + int fd ; + struct wiringPiNodeStruct *node ; + + if ((fd = wiringPiI2CSetup (I2C_ADDRESS)) < 0) + return FALSE ; + + node = wiringPiNewNode (pinBase, 4) ; + + node->fd = fd ; + node->analogRead = myAnalogRead ; + node->analogWrite = myAnalogWrite ; + +// Read calibration data + + AC1 = read16 (fd, 0xAA) ; + AC2 = read16 (fd, 0xAC) ; + AC3 = read16 (fd, 0xAE) ; + AC4 = read16 (fd, 0xB0) ; + AC5 = read16 (fd, 0xB2) ; + AC6 = read16 (fd, 0xB4) ; + VB1 = read16 (fd, 0xB6) ; + VB2 = read16 (fd, 0xB8) ; + MB = read16 (fd, 0xBA) ; + MC = read16 (fd, 0xBC) ; + MD = read16 (fd, 0xBE) ; + +// Calculate coefficients + + c3 = 160.0 * pow (2.0, -15.0) * AC3 ; + c4 = pow (10.0, -3.0) * pow(2.0,-15.0) * AC4 ; + b1 = pow (160.0, 2.0) * pow(2.0,-30.0) * VB1 ; + c5 = (pow (2.0, -15.0) / 160.0) * AC5 ; + c6 = AC6 ; + mc = (pow (2.0, 11.0) / pow(160.0,2.0)) * MC ; + md = MD / 160.0 ; + x0 = AC1 ; + x1 = 160.0 * pow (2.0, -13.0) * AC2 ; + x2 = pow (160.0, 2.0) * pow(2.0,-25.0) * VB2 ; + yy0 = c4 * pow (2.0, 15.0) ; + yy1 = c4 * c3 ; + yy2 = c4 * b1 ; + p0 = (3791.0 - 8.0) / 1600.0 ; + p1 = 1.0 - 7357.0 * pow (2.0, -20.0) ; + p2 = 3038.0 * 100.0 * pow (2.0, -36.0) ; + + return TRUE ; +} diff --git a/wiringPi/bmp180.h b/wiringPi/bmp180.h new file mode 100644 index 0000000..4a6d13a --- /dev/null +++ b/wiringPi/bmp180.h @@ -0,0 +1,34 @@ +/* + * bmp180.h: + * Extend wiringPi with the BMP180 I2C Pressure and Temperature + * sensor. + * Copyright (c) 2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int bmp180Setup (const int pinBase) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/drcNet.c b/wiringPi/drcNet.c new file mode 100644 index 0000000..3c01cf2 --- /dev/null +++ b/wiringPi/drcNet.c @@ -0,0 +1,405 @@ +/* + * drcNet.h: + * Extend wiringPi with the DRC Network protocol (e.g. to another Pi) + * Copyright (c) 2016-2017 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "wiringPi.h" +#include "drcNet.h" +#include "../wiringPiD/drcNetCmd.h" + + +/* + * remoteReadline: + * Read in a line of data from the remote server, ending with a newline + * character which is not stored. Returns the length or < 0 on + * any sort of failure. + ********************************************************************************* + */ + +static int remoteReadline (int fd, char *buf, int max) +{ + int len = 0 ; + char c ; + + for (;;) + { + if (read (fd, &c, 1) < 1) + return -1 ; + + if (c == '\n') + return len ; + + *buf++ = c ; + if (++len == max) + return len ; + } +} + + +/* + * getChallenge: + * Read in lines from the remote site until we get one identified + * as the challenge. This line contains the password salt. + ********************************************************************************* + */ + +static char *getChallenge (int fd) +{ + static char buf [1024] ; + int num ; + + for (;;) + { + if ((num = remoteReadline (fd, buf, 1023)) < 0) + return NULL ; + buf [num] = 0 ; + + if (strncmp (buf, "Challenge ", 10) == 0) + return &buf [10] ; + } +} + + +/* + * authenticate: + * Read in the challenge from the server, use it to encrypt our password + * and send it back to the server. Wait for a reply back from the server + * to say that we're good to go. + * The server will simply disconnect on a bad response. No 3 chances here. + ********************************************************************************* + */ + +static int authenticate (int fd, const char *pass) +{ + char *challenge ; + char *encrypted ; + char salted [1034] ; + + if ((challenge = getChallenge (fd)) == NULL) + return -1 ; + + sprintf (salted, "$6$%s$", challenge) ; + encrypted = crypt (pass, salted) ; + +// This is an assertion, or sanity check on my part... +// The '20' comes from the $6$ then the 16 characters of the salt, +// then the terminating $. + + if (strncmp (encrypted, salted, 20) != 0) + { + errno = EBADE ; + return -1 ; + } + +// 86 characters is the length of the SHA-256 hash + + if (write (fd, encrypted + 20, 86) == 86) + return 0 ; + else + return -1 ; +} + + +/* + * _drcSetupNet: + * Do the hard work of establishing a network connection and authenticating + * the password. + ********************************************************************************* + */ + +int _drcSetupNet (const char *ipAddress, const char *port, const char *password) +{ + struct addrinfo hints; + struct addrinfo *result, *rp ; + struct in6_addr serveraddr ; + int remoteFd ; + +// Start by seeing if we've been given a (textual) numeric IP address +// which will save lookups in getaddrinfo() + + memset (&hints, 0, sizeof (hints)) ; + hints.ai_flags = AI_NUMERICSERV ; + hints.ai_family = AF_UNSPEC ; + hints.ai_socktype = SOCK_STREAM ; + hints.ai_protocol = 0 ; + + if (inet_pton (AF_INET, ipAddress, &serveraddr) == 1) // Valid IPv4 + { + hints.ai_family = AF_INET ; + hints.ai_flags |= AI_NUMERICHOST ; + } + else + { + if (inet_pton (AF_INET6, ipAddress, &serveraddr) == 1) // Valid IPv6 + { + hints.ai_family = AF_INET6 ; + hints.ai_flags |= AI_NUMERICHOST ; + } + } + +// Now use getaddrinfo() with the newly supplied hints + + if (getaddrinfo (ipAddress, port, &hints, &result) != 0) + return -1 ; + +// Now try each address in-turn until we get one that connects... + + for (rp = result; rp != NULL; rp = rp->ai_next) + { + if ((remoteFd = socket (rp->ai_family, rp->ai_socktype, rp->ai_protocol)) < 0) + continue ; + + if (connect (remoteFd, rp->ai_addr, rp->ai_addrlen) < 0) + continue ; + + if (authenticate (remoteFd, password) < 0) + { + close (remoteFd) ; + errno = EACCES ; // Permission denied + return -1 ; + } + else + return remoteFd ; + } + + errno = EHOSTUNREACH ; // Host unreachable - may not be right, but good enough + return -1 ; // Nothing connected +} + + +/* + * myPinMode: + * Change the pin mode on the remote DRC device + ********************************************************************************* + */ + +static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode) +{ + struct drcNetComStruct cmd ; + + cmd.pin = pin - node->pinBase ; + cmd.cmd = DRCN_PIN_MODE ; + cmd.data = mode ; + + (void)send (node->fd, &cmd, sizeof (cmd), 0) ; + (void)recv (node->fd, &cmd, sizeof (cmd), 0) ; +} + + +/* + * myPullUpDnControl: + ********************************************************************************* + */ + +static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode) +{ + struct drcNetComStruct cmd ; + + cmd.pin = pin - node->pinBase ; + cmd.cmd = DRCN_PULL_UP_DN ; + cmd.data = mode ; + + (void)send (node->fd, &cmd, sizeof (cmd), 0) ; + (void)recv (node->fd, &cmd, sizeof (cmd), 0) ; +} + + +/* + * myDigitalWrite: + ********************************************************************************* + */ + +static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + struct drcNetComStruct cmd ; + + cmd.pin = pin - node->pinBase ; + cmd.cmd = DRCN_DIGITAL_WRITE ; + cmd.data = value ; + + (void)send (node->fd, &cmd, sizeof (cmd), 0) ; + (void)recv (node->fd, &cmd, sizeof (cmd), 0) ; +} + + +/* + * myDigitalWrite8: + ********************************************************************************* + +static void myDigitalWrite8 (struct wiringPiNodeStruct *node, int pin, int value) +{ + struct drcNetComStruct cmd ; + + cmd.pin = pin - node->pinBase ; + cmd.cmd = DRCN_DIGITAL_WRITE8 ; + cmd.data = value ; + + (void)send (node->fd, &cmd, sizeof (cmd), 0) ; + (void)recv (node->fd, &cmd, sizeof (cmd), 0) ; +} + */ + + +/* + * myAnalogWrite: + ********************************************************************************* + */ + +static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + struct drcNetComStruct cmd ; + + cmd.pin = pin - node->pinBase ; + cmd.cmd = DRCN_ANALOG_WRITE ; + cmd.data = value ; + + (void)send (node->fd, &cmd, sizeof (cmd), 0) ; + (void)recv (node->fd, &cmd, sizeof (cmd), 0) ; +} + + +/* + * myPwmWrite: + ********************************************************************************* + */ + +static void myPwmWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + struct drcNetComStruct cmd ; + + cmd.pin = pin - node->pinBase ; + cmd.cmd = DRCN_PWM_WRITE ; + cmd.data = value ; + + (void)send (node->fd, &cmd, sizeof (cmd), 0) ; + (void)recv (node->fd, &cmd, sizeof (cmd), 0) ; +} + + +/* + * myAnalogRead: + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + struct drcNetComStruct cmd ; + + cmd.pin = pin - node->pinBase ; + cmd.cmd = DRCN_ANALOG_READ ; + cmd.data = 0 ; + + (void)send (node->fd, &cmd, sizeof (cmd), 0) ; + (void)recv (node->fd, &cmd, sizeof (cmd), 0) ; + + return cmd.data ; +} + + +/* + * myDigitalRead: + ********************************************************************************* + */ + +static int myDigitalRead (struct wiringPiNodeStruct *node, int pin) +{ + struct drcNetComStruct cmd ; + + cmd.pin = pin - node->pinBase ; + cmd.cmd = DRCN_DIGITAL_READ ; + cmd.data = 0 ; + + (void)send (node->fd, &cmd, sizeof (cmd), 0) ; + (void)recv (node->fd, &cmd, sizeof (cmd), 0) ; + + return cmd.data ; +} + + +/* + * myDigitalRead8: + ********************************************************************************* + +static unsigned int myDigitalRead8 (struct wiringPiNodeStruct *node, int pin) +{ + struct drcNetComStruct cmd ; + + cmd.pin = pin - node->pinBase ; + cmd.cmd = DRCN_DIGITAL_READ8 ; + cmd.data = 0 ; + + (void)send (node->fd, &cmd, sizeof (cmd), 0) ; + (void)recv (node->fd, &cmd, sizeof (cmd), 0) ; + + return cmd.data ; +} + */ + + +/* + * drcNet: + * Create a new instance of an DRC GPIO interface. + * Could be a variable nunber of pins here - we might not know in advance. + ********************************************************************************* + */ + +int drcSetupNet (const int pinBase, const int numPins, const char *ipAddress, const char *port, const char *password) +{ + int fd, len ; + struct wiringPiNodeStruct *node ; + + if ((fd = _drcSetupNet (ipAddress, port, password)) < 0) + return FALSE ; + + len = sizeof (struct drcNetComStruct) ; + + if (setsockopt (fd, SOL_SOCKET, SO_RCVLOWAT, (void *)&len, sizeof (len)) < 0) + return FALSE ; + + node = wiringPiNewNode (pinBase, numPins) ; + + node->fd = fd ; + node->pinMode = myPinMode ; + node->pullUpDnControl = myPullUpDnControl ; + node->analogRead = myAnalogRead ; + node->analogRead = myAnalogRead ; + node->analogWrite = myAnalogWrite ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; +//node->digitalRead8 = myDigitalRead8 ; +//node->digitalWrite8 = myDigitalWrite8 ; + node->pwmWrite = myPwmWrite ; + + return TRUE ; +} diff --git a/wiringPi/drcNet.h b/wiringPi/drcNet.h new file mode 100644 index 0000000..00f9b05 --- /dev/null +++ b/wiringPi/drcNet.h @@ -0,0 +1,42 @@ +/* + * drcNet.h: + * Extend wiringPi with the DRC Network protocol (e.g. to another Pi) + * Copyright (c) 2016-2017 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +/********* +struct drcNetStruct +{ + uint32_t pin ; + uint32_t cmd ; + uint32_t data ; +} ; +**************/ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int drcSetupNet (const int pinBase, const int numPins, const char *ipAddress, const char *port, const char *password) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/drcSerial.c b/wiringPi/drcSerial.c new file mode 100644 index 0000000..db7cc09 --- /dev/null +++ b/wiringPi/drcSerial.c @@ -0,0 +1,196 @@ +/* + * drcSerial.c: + * Extend wiringPi with the DRC Serial protocol (e.g. to Arduino) + * Copyright (c) 2013-2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include + +#include "wiringPi.h" +#include "wiringSerial.h" + +#include "drcSerial.h" + + +/* + * myPinMode: + * Change the pin mode on the remote DRC device + ********************************************************************************* + */ + +static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode) +{ + /**/ if (mode == OUTPUT) + serialPutchar (node->fd, 'o') ; // Input + else if (mode == PWM_OUTPUT) + serialPutchar (node->fd, 'p') ; // PWM + else + serialPutchar (node->fd, 'i') ; // Default to input + + serialPutchar (node->fd, pin - node->pinBase) ; +} + + +/* + * myPullUpDnControl: + * ATmegas only have pull-up's on of off. No pull-downs. + ********************************************************************************* + */ + +static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode) +{ + +// Force pin into input mode + + serialPutchar (node->fd, 'i' ) ; + serialPutchar (node->fd, pin - node->pinBase) ; + + /**/ if (mode == PUD_UP) + { + serialPutchar (node->fd, '1') ; + serialPutchar (node->fd, pin - node->pinBase) ; + } + else if (mode == PUD_OFF) + { + serialPutchar (node->fd, '0') ; + serialPutchar (node->fd, pin - node->pinBase) ; + } +} + + +/* + * myDigitalWrite: + ********************************************************************************* + */ + +static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + serialPutchar (node->fd, value == 0 ? '0' : '1') ; + serialPutchar (node->fd, pin - node->pinBase) ; +} + + +/* + * myPwmWrite: + ********************************************************************************* + */ + +static void myPwmWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + serialPutchar (node->fd, 'v') ; + serialPutchar (node->fd, pin - node->pinBase) ; + serialPutchar (node->fd, value & 0xFF) ; +} + + +/* + * myAnalogRead: + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + int vHi, vLo ; + + serialPutchar (node->fd, 'a') ; + serialPutchar (node->fd, pin - node->pinBase) ; + vHi = serialGetchar (node->fd) ; + vLo = serialGetchar (node->fd) ; + + return (vHi << 8) | vLo ; +} + + +/* + * myDigitalRead: + ********************************************************************************* + */ + +static int myDigitalRead (struct wiringPiNodeStruct *node, int pin) +{ + serialPutchar (node->fd, 'r') ; // Send read command + serialPutchar (node->fd, pin - node->pinBase) ; + return (serialGetchar (node->fd) == '0') ? 0 : 1 ; +} + + +/* + * drcSetup: + * Create a new instance of an DRC GPIO interface. + * Could be a variable nunber of pins here - we might not know in advance + * if it's an ATmega with 14 pins, or something with less or more! + ********************************************************************************* + */ + +int drcSetupSerial (const int pinBase, const int numPins, const char *device, const int baud) +{ + int fd ; + int ok, tries ; + time_t then ; + struct wiringPiNodeStruct *node ; + + if ((fd = serialOpen (device, baud)) < 0) + return FALSE ; + + delay (10) ; // May need longer if it's an Uno that reboots on the open... + +// Flush any pending input + + while (serialDataAvail (fd)) + (void)serialGetchar (fd) ; + + ok = FALSE ; + for (tries = 1 ; (tries < 5) && (!ok) ; ++tries) + { + serialPutchar (fd, '@') ; // Ping + then = time (NULL) + 2 ; + while (time (NULL) < then) + if (serialDataAvail (fd)) + { + if (serialGetchar (fd) == '@') + { + ok = TRUE ; + break ; + } + } + } + + if (!ok) + { + serialClose (fd) ; + return FALSE ; + } + + node = wiringPiNewNode (pinBase, numPins) ; + + node->fd = fd ; + node->pinMode = myPinMode ; + node->pullUpDnControl = myPullUpDnControl ; + node->analogRead = myAnalogRead ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->pwmWrite = myPwmWrite ; + + return TRUE ; +} diff --git a/wiringPi/drcSerial.h b/wiringPi/drcSerial.h new file mode 100644 index 0000000..29e988e --- /dev/null +++ b/wiringPi/drcSerial.h @@ -0,0 +1,33 @@ +/* + * drcSerial.h: + * Extend wiringPi with the DRC Serial protocol (e.g. to Arduino) + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int drcSetupSerial (const int pinBase, const int numPins, const char *device, const int baud) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/ds18b20.c b/wiringPi/ds18b20.c new file mode 100644 index 0000000..533398e --- /dev/null +++ b/wiringPi/ds18b20.c @@ -0,0 +1,146 @@ +/* + * ds18b20.c: + * Extend wiringPi with the DS18B20 1-Wire temperature sensor. + * This is used in the Pi Weather Station and many other places. + * Copyright (c) 2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "wiringPi.h" + +#include "ds18b20.h" + +#define W1_PREFIX "/sys/bus/w1/devices/28-" +#define W1_POSTFIX "/w1_slave" + + +/* + * myAnalogRead: + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + int chan = pin - node->pinBase ; + int fd = node->fd ; + char buffer [4096] ; + char *p ; + int temp, sign ; + + if (chan != 0) + return -9999 ; + +// Rewind the file - we're keeping it open to keep things going +// smoothly + + lseek (fd, 0, SEEK_SET) ; + +// Read the file - we know it's only a couple of lines, so this ought to be +// more than enough + + if (read (fd, buffer, 4096) <= 0) // Read nothing, or it failed in some odd way + return -9998 ; + +// Look for YES, then t= + + if (strstr (buffer, "YES") == NULL) + return -9997 ; + + if ((p = strstr (buffer, "t=")) == NULL) + return -9996 ; + +// p points to the 't', so we skip over it... + + p += 2 ; + +// and extract the number +// (without caring about overflow) + + + if (*p == '-') // Negative number? + { + sign = -1 ; + ++p ; + } + else + sign = 1 ; + + temp = 0 ; + while (isdigit (*p)) + { + temp = temp * 10 + (*p - '0') ; + ++p ; + } + +// We know it returns temp * 1000, but we only really want temp * 10, so +// do a bit of rounding... + + temp = (temp + 50) / 100 ; + return temp * sign ; +} + + +/* + * ds18b20Setup: + * Create a new instance of a DS18B20 temperature sensor. + ********************************************************************************* + */ + +int ds18b20Setup (const int pinBase, const char *deviceId) +{ + int fd ; + struct wiringPiNodeStruct *node ; + char *fileName ; + +// Allocate space for the filename + + if ((fileName = malloc (strlen (W1_PREFIX) + strlen (W1_POSTFIX) + strlen (deviceId) + 1)) == NULL) + return FALSE ; + + sprintf (fileName, "%s%s%s", W1_PREFIX, deviceId, W1_POSTFIX) ; + + fd = open (fileName, O_RDONLY) ; + + free (fileName) ; + + if (fd < 0) + return FALSE ; + +// We'll keep the file open, to make access a little faster +// although it's very slow reading these things anyway )-: + + node = wiringPiNewNode (pinBase, 1) ; + + node->fd = fd ; + node->analogRead = myAnalogRead ; + + return TRUE ; +} diff --git a/wiringPi/ds18b20.h b/wiringPi/ds18b20.h new file mode 100644 index 0000000..a9ea291 --- /dev/null +++ b/wiringPi/ds18b20.h @@ -0,0 +1,34 @@ +/* + * bmp180.h: + * Extend wiringPi with the BMP180 I2C Pressure and Temperature + * sensor. + * Copyright (c) 2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int ds18b20Setup (const int pinBase, const char *serialNum) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/font.h b/wiringPi/font.h new file mode 100644 index 0000000..8090843 --- /dev/null +++ b/wiringPi/font.h @@ -0,0 +1,1808 @@ +/* + * This 5x7 font is sourced from Adafruit-GFX-Library on github. + */ + +#ifndef FONT_H +#define FONT_H + +struct font_info { + uint8_t width; + uint8_t height; + uint8_t spacing; + uint8_t offset; + uint8_t *data; +}; + +static const uint8_t font1_data[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, + 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, + 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, + 0x18, 0x3C, 0x7E, 0x3C, 0x18, + 0x1C, 0x57, 0x7D, 0x57, 0x1C, + 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, + 0x00, 0x18, 0x3C, 0x18, 0x00, + 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, + 0x00, 0x18, 0x24, 0x18, 0x00, + 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, + 0x30, 0x48, 0x3A, 0x06, 0x0E, + 0x26, 0x29, 0x79, 0x29, 0x26, + 0x40, 0x7F, 0x05, 0x05, 0x07, + 0x40, 0x7F, 0x05, 0x25, 0x3F, + 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, + 0x7F, 0x3E, 0x1C, 0x1C, 0x08, + 0x08, 0x1C, 0x1C, 0x3E, 0x7F, + 0x14, 0x22, 0x7F, 0x22, 0x14, + 0x5F, 0x5F, 0x00, 0x5F, 0x5F, + 0x06, 0x09, 0x7F, 0x01, 0x7F, + 0x00, 0x66, 0x89, 0x95, 0x6A, + 0x60, 0x60, 0x60, 0x60, 0x60, + 0x94, 0xA2, 0xFF, 0xA2, 0x94, + 0x08, 0x04, 0x7E, 0x04, 0x08, + 0x10, 0x20, 0x7E, 0x20, 0x10, + 0x08, 0x08, 0x2A, 0x1C, 0x08, + 0x08, 0x1C, 0x2A, 0x08, 0x08, + 0x1E, 0x10, 0x10, 0x10, 0x10, + 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, + 0x30, 0x38, 0x3E, 0x38, 0x30, + 0x06, 0x0E, 0x3E, 0x0E, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5F, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x07, 0x00, + 0x14, 0x7F, 0x14, 0x7F, 0x14, + 0x24, 0x2A, 0x7F, 0x2A, 0x12, + 0x23, 0x13, 0x08, 0x64, 0x62, + 0x36, 0x49, 0x56, 0x20, 0x50, + 0x00, 0x08, 0x07, 0x03, 0x00, + 0x00, 0x1C, 0x22, 0x41, 0x00, + 0x00, 0x41, 0x22, 0x1C, 0x00, + 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, + 0x08, 0x08, 0x3E, 0x08, 0x08, + 0x00, 0x80, 0x70, 0x30, 0x00, + 0x08, 0x08, 0x08, 0x08, 0x08, + 0x00, 0x00, 0x60, 0x60, 0x00, + 0x20, 0x10, 0x08, 0x04, 0x02, + 0x3E, 0x51, 0x49, 0x45, 0x3E, + 0x00, 0x42, 0x7F, 0x40, 0x00, + 0x72, 0x49, 0x49, 0x49, 0x46, + 0x21, 0x41, 0x49, 0x4D, 0x33, + 0x18, 0x14, 0x12, 0x7F, 0x10, + 0x27, 0x45, 0x45, 0x45, 0x39, + 0x3C, 0x4A, 0x49, 0x49, 0x31, + 0x41, 0x21, 0x11, 0x09, 0x07, + 0x36, 0x49, 0x49, 0x49, 0x36, + 0x46, 0x49, 0x49, 0x29, 0x1E, + 0x00, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x40, 0x34, 0x00, 0x00, + 0x00, 0x08, 0x14, 0x22, 0x41, + 0x14, 0x14, 0x14, 0x14, 0x14, + 0x00, 0x41, 0x22, 0x14, 0x08, + 0x02, 0x01, 0x59, 0x09, 0x06, + 0x3E, 0x41, 0x5D, 0x59, 0x4E, + 0x7C, 0x12, 0x11, 0x12, 0x7C, + 0x7F, 0x49, 0x49, 0x49, 0x36, + 0x3E, 0x41, 0x41, 0x41, 0x22, + 0x7F, 0x41, 0x41, 0x41, 0x3E, + 0x7F, 0x49, 0x49, 0x49, 0x41, + 0x7F, 0x09, 0x09, 0x09, 0x01, + 0x3E, 0x41, 0x41, 0x51, 0x73, + 0x7F, 0x08, 0x08, 0x08, 0x7F, + 0x00, 0x41, 0x7F, 0x41, 0x00, + 0x20, 0x40, 0x41, 0x3F, 0x01, + 0x7F, 0x08, 0x14, 0x22, 0x41, + 0x7F, 0x40, 0x40, 0x40, 0x40, + 0x7F, 0x02, 0x1C, 0x02, 0x7F, + 0x7F, 0x04, 0x08, 0x10, 0x7F, + 0x3E, 0x41, 0x41, 0x41, 0x3E, + 0x7F, 0x09, 0x09, 0x09, 0x06, + 0x3E, 0x41, 0x51, 0x21, 0x5E, + 0x7F, 0x09, 0x19, 0x29, 0x46, + 0x26, 0x49, 0x49, 0x49, 0x32, + 0x03, 0x01, 0x7F, 0x01, 0x03, + 0x3F, 0x40, 0x40, 0x40, 0x3F, + 0x1F, 0x20, 0x40, 0x20, 0x1F, + 0x3F, 0x40, 0x38, 0x40, 0x3F, + 0x63, 0x14, 0x08, 0x14, 0x63, + 0x03, 0x04, 0x78, 0x04, 0x03, + 0x61, 0x59, 0x49, 0x4D, 0x43, + 0x00, 0x7F, 0x41, 0x41, 0x41, + 0x02, 0x04, 0x08, 0x10, 0x20, + 0x00, 0x41, 0x41, 0x41, 0x7F, + 0x04, 0x02, 0x01, 0x02, 0x04, + 0x40, 0x40, 0x40, 0x40, 0x40, + 0x00, 0x03, 0x07, 0x08, 0x00, + 0x20, 0x54, 0x54, 0x78, 0x40, + 0x7F, 0x28, 0x44, 0x44, 0x38, + 0x38, 0x44, 0x44, 0x44, 0x28, + 0x38, 0x44, 0x44, 0x28, 0x7F, + 0x38, 0x54, 0x54, 0x54, 0x18, + 0x00, 0x08, 0x7E, 0x09, 0x02, + 0x18, 0xA4, 0xA4, 0x9C, 0x78, + 0x7F, 0x08, 0x04, 0x04, 0x78, + 0x00, 0x44, 0x7D, 0x40, 0x00, + 0x20, 0x40, 0x40, 0x3D, 0x00, + 0x7F, 0x10, 0x28, 0x44, 0x00, + 0x00, 0x41, 0x7F, 0x40, 0x00, + 0x7C, 0x04, 0x78, 0x04, 0x78, + 0x7C, 0x08, 0x04, 0x04, 0x78, + 0x38, 0x44, 0x44, 0x44, 0x38, + 0xFC, 0x18, 0x24, 0x24, 0x18, + 0x18, 0x24, 0x24, 0x18, 0xFC, + 0x7C, 0x08, 0x04, 0x04, 0x08, + 0x48, 0x54, 0x54, 0x54, 0x24, + 0x04, 0x04, 0x3F, 0x44, 0x24, + 0x3C, 0x40, 0x40, 0x20, 0x7C, + 0x1C, 0x20, 0x40, 0x20, 0x1C, + 0x3C, 0x40, 0x30, 0x40, 0x3C, + 0x44, 0x28, 0x10, 0x28, 0x44, + 0x4C, 0x90, 0x90, 0x90, 0x7C, + 0x44, 0x64, 0x54, 0x4C, 0x44, + 0x00, 0x08, 0x36, 0x41, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x00, + 0x00, 0x41, 0x36, 0x08, 0x00, + 0x02, 0x01, 0x02, 0x04, 0x02, + 0x3C, 0x26, 0x23, 0x26, 0x3C, + 0x1E, 0xA1, 0xA1, 0x61, 0x12, + 0x3A, 0x40, 0x40, 0x20, 0x7A, + 0x38, 0x54, 0x54, 0x55, 0x59, + 0x21, 0x55, 0x55, 0x79, 0x41, + 0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut + 0x21, 0x55, 0x54, 0x78, 0x40, + 0x20, 0x54, 0x55, 0x79, 0x40, + 0x0C, 0x1E, 0x52, 0x72, 0x12, + 0x39, 0x55, 0x55, 0x55, 0x59, + 0x39, 0x54, 0x54, 0x54, 0x59, + 0x39, 0x55, 0x54, 0x54, 0x58, + 0x00, 0x00, 0x45, 0x7C, 0x41, + 0x00, 0x02, 0x45, 0x7D, 0x42, + 0x00, 0x01, 0x45, 0x7C, 0x40, + 0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut + 0xF0, 0x28, 0x25, 0x28, 0xF0, + 0x7C, 0x54, 0x55, 0x45, 0x00, + 0x20, 0x54, 0x54, 0x7C, 0x54, + 0x7C, 0x0A, 0x09, 0x7F, 0x49, + 0x32, 0x49, 0x49, 0x49, 0x32, + 0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut + 0x32, 0x4A, 0x48, 0x48, 0x30, + 0x3A, 0x41, 0x41, 0x21, 0x7A, + 0x3A, 0x42, 0x40, 0x20, 0x78, + 0x00, 0x9D, 0xA0, 0xA0, 0x7D, + 0x3D, 0x42, 0x42, 0x42, 0x3D, // O-umlaut + 0x3D, 0x40, 0x40, 0x40, 0x3D, + 0x3C, 0x24, 0xFF, 0x24, 0x24, + 0x48, 0x7E, 0x49, 0x43, 0x66, + 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, + 0xFF, 0x09, 0x29, 0xF6, 0x20, + 0xC0, 0x88, 0x7E, 0x09, 0x03, + 0x20, 0x54, 0x54, 0x79, 0x41, + 0x00, 0x00, 0x44, 0x7D, 0x41, + 0x30, 0x48, 0x48, 0x4A, 0x32, + 0x38, 0x40, 0x40, 0x22, 0x7A, + 0x00, 0x7A, 0x0A, 0x0A, 0x72, + 0x7D, 0x0D, 0x19, 0x31, 0x7D, + 0x26, 0x29, 0x29, 0x2F, 0x28, + 0x26, 0x29, 0x29, 0x29, 0x26, + 0x30, 0x48, 0x4D, 0x40, 0x20, + 0x38, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x38, + 0x2F, 0x10, 0xC8, 0xAC, 0xBA, + 0x2F, 0x10, 0x28, 0x34, 0xFA, + 0x00, 0x00, 0x7B, 0x00, 0x00, + 0x08, 0x14, 0x2A, 0x14, 0x22, + 0x22, 0x14, 0x2A, 0x14, 0x08, + 0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old code + 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block + 0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block + 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x10, 0x10, 0x10, 0xFF, 0x00, + 0x14, 0x14, 0x14, 0xFF, 0x00, + 0x10, 0x10, 0xFF, 0x00, 0xFF, + 0x10, 0x10, 0xF0, 0x10, 0xF0, + 0x14, 0x14, 0x14, 0xFC, 0x00, + 0x14, 0x14, 0xF7, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0xFF, + 0x14, 0x14, 0xF4, 0x04, 0xFC, + 0x14, 0x14, 0x17, 0x10, 0x1F, + 0x10, 0x10, 0x1F, 0x10, 0x1F, + 0x14, 0x14, 0x14, 0x1F, 0x00, + 0x10, 0x10, 0x10, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0x10, + 0x10, 0x10, 0x10, 0x1F, 0x10, + 0x10, 0x10, 0x10, 0xF0, 0x10, + 0x00, 0x00, 0x00, 0xFF, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0xFF, 0x10, + 0x00, 0x00, 0x00, 0xFF, 0x14, + 0x00, 0x00, 0xFF, 0x00, 0xFF, + 0x00, 0x00, 0x1F, 0x10, 0x17, + 0x00, 0x00, 0xFC, 0x04, 0xF4, + 0x14, 0x14, 0x17, 0x10, 0x17, + 0x14, 0x14, 0xF4, 0x04, 0xF4, + 0x00, 0x00, 0xFF, 0x00, 0xF7, + 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0xF7, 0x00, 0xF7, + 0x14, 0x14, 0x14, 0x17, 0x14, + 0x10, 0x10, 0x1F, 0x10, 0x1F, + 0x14, 0x14, 0x14, 0xF4, 0x14, + 0x10, 0x10, 0xF0, 0x10, 0xF0, + 0x00, 0x00, 0x1F, 0x10, 0x1F, + 0x00, 0x00, 0x00, 0x1F, 0x14, + 0x00, 0x00, 0x00, 0xFC, 0x14, + 0x00, 0x00, 0xF0, 0x10, 0xF0, + 0x10, 0x10, 0xFF, 0x10, 0xFF, + 0x14, 0x14, 0x14, 0xFF, 0x14, + 0x10, 0x10, 0x10, 0x1F, 0x00, + 0x00, 0x00, 0x00, 0xF0, 0x10, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x38, 0x44, 0x44, 0x38, 0x44, + 0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta + 0x7E, 0x02, 0x02, 0x06, 0x06, + 0x02, 0x7E, 0x02, 0x7E, 0x02, + 0x63, 0x55, 0x49, 0x41, 0x63, + 0x38, 0x44, 0x44, 0x3C, 0x04, + 0x40, 0x7E, 0x20, 0x1E, 0x20, + 0x06, 0x02, 0x7E, 0x02, 0x02, + 0x99, 0xA5, 0xE7, 0xA5, 0x99, + 0x1C, 0x2A, 0x49, 0x2A, 0x1C, + 0x4C, 0x72, 0x01, 0x72, 0x4C, + 0x30, 0x4A, 0x4D, 0x4D, 0x30, + 0x30, 0x48, 0x78, 0x48, 0x30, + 0xBC, 0x62, 0x5A, 0x46, 0x3D, + 0x3E, 0x49, 0x49, 0x49, 0x00, + 0x7E, 0x01, 0x01, 0x01, 0x7E, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x44, 0x44, 0x5F, 0x44, 0x44, + 0x40, 0x51, 0x4A, 0x44, 0x40, + 0x40, 0x44, 0x4A, 0x51, 0x40, + 0x00, 0x00, 0xFF, 0x01, 0x03, + 0xE0, 0x80, 0xFF, 0x00, 0x00, + 0x08, 0x08, 0x6B, 0x6B, 0x08, + 0x36, 0x12, 0x36, 0x24, 0x36, + 0x06, 0x0F, 0x09, 0x0F, 0x06, + 0x00, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x10, 0x10, 0x00, + 0x30, 0x40, 0xFF, 0x01, 0x01, + 0x00, 0x1F, 0x01, 0x01, 0x1E, + 0x00, 0x19, 0x1D, 0x17, 0x12, + 0x00, 0x3C, 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP +}; + + +static const uint8_t font2_data[][6] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 32 + 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, // ! 0x21 33 + 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, // " 0x22 34 + 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14, // # 0x23 35 + 0x00, 0x24, 0x2A, 0x7F, 0x2A, 0x12, // $ 0x24 36 + 0x00, 0x23, 0x13, 0x08, 0x64, 0x62, // % 0x25 37 + 0x00, 0x36, 0x49, 0x56, 0x20, 0x50, // & 0x26 38 + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, // ' 0x27 39 + 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00, // ( 0x28 40 + 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00, // ) 0x29 41 + 0x00, 0x14, 0x08, 0x3e, 0x08, 0x14, // * 0x2a 42 + 0x00, 0x08, 0x08, 0x3e, 0x08, 0x08, // + 0x2b 43 + 0x00, 0x00, 0x50, 0x30, 0x00, 0x00, // , 0x2c 44 + 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, // - 0x2d 45 + 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, // . 0x2e 46 + 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, // / 0x2f 47 + 0x00, 0x3e, 0x51, 0x49, 0x45, 0x3e, // 0 0x30 48 + 0x00, 0x00, 0x42, 0x7f, 0x40, 0x00, // 1 0x31 49 + 0x00, 0x42, 0x61, 0x51, 0x49, 0x46, // 2 0x32 50 + 0x00, 0x21, 0x41, 0x45, 0x4b, 0x31, // 3 0x33 51 + 0x00, 0x18, 0x14, 0x12, 0x7f, 0x10, // 4 0x34 52 + 0x00, 0x27, 0x45, 0x45, 0x45, 0x39, // 5 0x35 53 + 0x00, 0x3c, 0x4a, 0x49, 0x49, 0x30, // 6 0x36 54 + 0x00, 0x01, 0x71, 0x09, 0x05, 0x03, // 7 0x37 55 + 0x00, 0x36, 0x49, 0x49, 0x49, 0x36, // 8 0x38 56 + 0x00, 0x06, 0x49, 0x49, 0x29, 0x1e, // 9 0x39 57 + 0x00, 0x00, 0x36, 0x36, 0x00, 0x00, // : 0x3a 58 + 0x00, 0x00, 0x56, 0x36, 0x00, 0x00, // ; 0x3b 59 + 0x00, 0x08, 0x14, 0x22, 0x41, 0x00, // < 0x3c 60 + 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, // = 0x3d 61 + 0x00, 0x00, 0x41, 0x22, 0x14, 0x08, // > 0x3e 62 + 0x00, 0x02, 0x01, 0x51, 0x09, 0x06, // ? 0x3f 63 + 0x00, 0x3e, 0x41, 0x5d, 0x49, 0x4e, // @ 0x40 64 + 0x00, 0x7e, 0x09, 0x09, 0x09, 0x7e, // A 0x41 65 + 0x00, 0x7f, 0x49, 0x49, 0x49, 0x36, // B 0x42 66 + 0x00, 0x3e, 0x41, 0x41, 0x41, 0x22, // C 0x43 67 + 0x00, 0x7f, 0x41, 0x41, 0x41, 0x3e, // D 0x44 68 + 0x00, 0x7f, 0x49, 0x49, 0x49, 0x41, // E 0x45 69 + 0x00, 0x7f, 0x09, 0x09, 0x09, 0x01, // F 0x46 70 + 0x00, 0x3e, 0x41, 0x49, 0x49, 0x7a, // G 0x47 71 + 0x00, 0x7f, 0x08, 0x08, 0x08, 0x7f, // H 0x48 72 + 0x00, 0x00, 0x41, 0x7f, 0x41, 0x00, // I 0x49 73 + 0x00, 0x20, 0x40, 0x41, 0x3f, 0x01, // J 0x4a 74 + 0x00, 0x7f, 0x08, 0x14, 0x22, 0x41, // K 0x4b 75 + 0x00, 0x7f, 0x40, 0x40, 0x40, 0x40, // L 0x4c 76 + 0x00, 0x7f, 0x02, 0x0c, 0x02, 0x7f, // M 0x4d 77 + 0x00, 0x7f, 0x04, 0x08, 0x10, 0x7f, // N 0x4e 78 + 0x00, 0x3e, 0x41, 0x41, 0x41, 0x3e, // O 0x4f 79 + 0x00, 0x7f, 0x09, 0x09, 0x09, 0x06, // P 0x50 80 + 0x00, 0x3e, 0x41, 0x51, 0x21, 0x5e, // Q 0x51 81 + 0x00, 0x7f, 0x09, 0x19, 0x29, 0x46, // R 0x52 82 + 0x00, 0x46, 0x49, 0x49, 0x49, 0x31, // S 0x53 83 + 0x00, 0x01, 0x01, 0x7f, 0x01, 0x01, // T 0x54 84 + 0x00, 0x3f, 0x40, 0x40, 0x40, 0x3f, // U 0x55 85 + 0x00, 0x0f, 0x30, 0x40, 0x30, 0x0f, // V 0x56 86 + 0x00, 0x3f, 0x40, 0x30, 0x40, 0x3f, // W 0x57 87 + 0x00, 0x63, 0x14, 0x08, 0x14, 0x63, // X 0x58 88 + 0x00, 0x07, 0x08, 0x70, 0x08, 0x07, // Y 0x59 89 + 0x00, 0x61, 0x51, 0x49, 0x45, 0x43, // Z 0x5a 90 + 0x00, 0x3c, 0x4a, 0x49, 0x29, 0x1e, // [ 0x5b 91 + 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, // \ 0x5c 92 + 0x00, 0x00, 0x41, 0x7f, 0x00, 0x00, // ] 0x5d 93 + 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, // ^ 0x5e 94 + 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, // _ 0x5f 95 + 0x00, 0x00, 0x00, 0x03, 0x04, 0x00, // ` 0x60 96 + 0x00, 0x20, 0x54, 0x54, 0x54, 0x78, // a 0x61 97 + 0x00, 0x7f, 0x48, 0x44, 0x44, 0x38, // b 0x62 98 + 0x00, 0x38, 0x44, 0x44, 0x44, 0x20, // c 0x63 99 + 0x00, 0x38, 0x44, 0x44, 0x48, 0x7f, // d 0x64 100 + 0x00, 0x38, 0x54, 0x54, 0x54, 0x18, // e 0x65 101 + 0x00, 0x08, 0x7e, 0x09, 0x01, 0x02, // f 0x66 102 + 0x00, 0x0c, 0x52, 0x52, 0x52, 0x3e, // g 0x67 103 + 0x00, 0x7f, 0x08, 0x04, 0x04, 0x78, // h 0x68 104 + 0x00, 0x00, 0x44, 0x7d, 0x40, 0x00, // i 0x69 105 + 0x00, 0x20, 0x40, 0x44, 0x3d, 0x00, // j 0x6a 106 + 0x00, 0x00, 0x7f, 0x10, 0x28, 0x44, // k 0x6b 107 + 0x00, 0x00, 0x41, 0x7f, 0x40, 0x00, // l 0x6c 108 + 0x00, 0x7c, 0x04, 0x18, 0x04, 0x78, // m 0x6d 109 + 0x00, 0x7c, 0x08, 0x04, 0x04, 0x78, // n 0x6e 110 + 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, // o 0x6f 111 + 0x00, 0x7c, 0x14, 0x14, 0x14, 0x08, // p 0x70 112 + 0x00, 0x08, 0x14, 0x14, 0x18, 0x7c, // q 0x71 113 + 0x00, 0x7c, 0x08, 0x04, 0x04, 0x08, // r 0x72 114 + 0x00, 0x48, 0x54, 0x54, 0x54, 0x20, // s 0x73 115 + 0x00, 0x04, 0x3f, 0x44, 0x40, 0x20, // t 0x74 116 + 0x00, 0x3c, 0x40, 0x40, 0x20, 0x7c, // u 0x75 117 + 0x00, 0x1c, 0x20, 0x40, 0x20, 0x1c, // v 0x76 118 + 0x00, 0x3c, 0x40, 0x30, 0x40, 0x3c, // w 0x77 119 + 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, // x 0x78 120 + 0x00, 0x0c, 0x50, 0x50, 0x50, 0x3c, // y 0x79 121 + 0x00, 0x44, 0x64, 0x54, 0x4c, 0x44, // z 0x7a 122 + 0x00, 0x00, 0x08, 0x36, 0x41, 0x41, // { 0x7b 123 + 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, // | 0x7c 124 + 0x00, 0x41, 0x41, 0x36, 0x08, 0x00, // } 0x7d 125 + 0x00, 0x04, 0x02, 0x04, 0x08, 0x04 // ~ 0x7e 126 +}; + +static const uint8_t font3_data[][5] = { + 0x2a, 0x40, 0x02, 0x54, 0x00, // 0 $00 'char0' + 0x00, 0x00, 0x00, 0x00, 0x00, // 32 $20 'space' + 0x00, 0x00, 0x5e, 0x00, 0x00, // 33 $21 'exclam' + 0x00, 0x0e, 0x00, 0x0e, 0x00, // 34 $22 'quotedbl' + 0x14, 0x7f, 0x14, 0x7f, 0x14, // 35 $23 'numbersign' + 0x04, 0x2a, 0x7f, 0x2a, 0x10, // 36 $24 'dollar' + 0x00, 0x16, 0x08, 0x34, 0x00, // 37 $25 'percent' + 0x36, 0x49, 0x36, 0x40, 0x00, // 38 $26 'ampersand' + 0x00, 0x00, 0x0e, 0x00, 0x00, // 39 $27 'quotesingle' + 0x00, 0x3c, 0x42, 0x00, 0x00, // 40 $28 'parenleft' + 0x00, 0x42, 0x3c, 0x00, 0x00, // 41 $29 'parenright' + 0x54, 0x38, 0x38, 0x54, 0x00, // 42 $2a 'asterisk' + 0x10, 0x10, 0x7c, 0x10, 0x10, // 43 $2b 'plus' + 0x00, 0x80, 0x60, 0x20, 0x00, // 44 $2c 'comma' + 0x10, 0x10, 0x10, 0x10, 0x00, // 45 $2d 'hyphen' + 0x00, 0x40, 0xe0, 0x40, 0x00, // 46 $2e 'period' + 0x60, 0x10, 0x08, 0x06, 0x00, // 47 $2f 'slash' + 0x00, 0x3c, 0x42, 0x3c, 0x00, // 48 $30 'zero' + 0x00, 0x44, 0x7e, 0x40, 0x00, // 49 $31 'one' + 0x64, 0x52, 0x52, 0x4c, 0x00, // 50 $32 'two' + 0x22, 0x4a, 0x4e, 0x32, 0x00, // 51 $33 'three' + 0x18, 0x14, 0x7e, 0x10, 0x00, // 52 $34 'four' + 0x2e, 0x4a, 0x4a, 0x32, 0x00, // 53 $35 'five' + 0x3c, 0x4a, 0x4a, 0x30, 0x00, // 54 $36 'six' + 0x02, 0x62, 0x1a, 0x06, 0x00, // 55 $37 'seven' + 0x34, 0x4a, 0x4a, 0x34, 0x00, // 56 $38 'eight' + 0x0c, 0x52, 0x52, 0x3c, 0x00, // 57 $39 'nine' + 0x00, 0x6c, 0x6c, 0x00, 0x00, // 58 $3a 'colon' + 0x00, 0x80, 0x6c, 0x2c, 0x00, // 59 $3b 'semicolon' + 0x00, 0x18, 0x24, 0x42, 0x00, // 60 $3c 'less' + 0x28, 0x28, 0x28, 0x28, 0x00, // 61 $3d 'equal' + 0x00, 0x42, 0x24, 0x18, 0x00, // 62 $3e 'greater' + 0x00, 0x04, 0x52, 0x0c, 0x00, // 63 $3f 'question' + 0x3c, 0x42, 0x99, 0xa5, 0x1e, // 64 $40 'at' + 0x7c, 0x12, 0x12, 0x7c, 0x00, // 65 $41 'A' + 0x7e, 0x4a, 0x4a, 0x34, 0x00, // 66 $42 'B' + 0x3c, 0x42, 0x42, 0x24, 0x00, // 67 $43 'C' + 0x7e, 0x42, 0x42, 0x3c, 0x00, // 68 $44 'D' + 0x7e, 0x4a, 0x4a, 0x42, 0x00, // 69 $45 'E' + 0x7e, 0x0a, 0x0a, 0x02, 0x00, // 70 $46 'F' + 0x3c, 0x42, 0x52, 0x34, 0x00, // 71 $47 'G' + 0x7e, 0x08, 0x08, 0x7e, 0x00, // 72 $48 'H' + 0x00, 0x42, 0x7e, 0x42, 0x00, // 73 $49 'I' + 0x20, 0x42, 0x3e, 0x02, 0x00, // 74 $4a 'J' + 0x7e, 0x08, 0x34, 0x42, 0x00, // 75 $4b 'K' + 0x7e, 0x40, 0x40, 0x40, 0x00, // 76 $4c 'L' + 0x7e, 0x0c, 0x0c, 0x7e, 0x00, // 77 $4d 'M' + 0x7e, 0x0c, 0x38, 0x7e, 0x00, // 78 $4e 'N' + 0x3c, 0x42, 0x42, 0x3c, 0x00, // 79 $4f 'O' + 0x7e, 0x12, 0x12, 0x0c, 0x00, // 80 $50 'P' + 0x3c, 0x52, 0x62, 0xbc, 0x00, // 81 $51 'Q' + 0x7e, 0x12, 0x12, 0x6c, 0x00, // 82 $52 'R' + 0x24, 0x4a, 0x52, 0x24, 0x00, // 83 $53 'S' + 0x00, 0x02, 0x7e, 0x02, 0x00, // 84 $54 'T' + 0x3e, 0x40, 0x40, 0x3e, 0x00, // 85 $55 'U' + 0x1e, 0x60, 0x60, 0x1e, 0x00, // 86 $56 'V' + 0x7e, 0x30, 0x30, 0x7e, 0x00, // 87 $57 'W' + 0x66, 0x18, 0x18, 0x66, 0x00, // 88 $58 'X' + 0x06, 0x08, 0x70, 0x08, 0x06, // 89 $59 'Y' + 0x62, 0x52, 0x4a, 0x46, 0x00, // 90 $5a 'Z' + 0x00, 0x7e, 0x42, 0x42, 0x00, // 91 $5b 'bracketleft' + 0x06, 0x08, 0x10, 0x60, 0x00, // 92 $5c 'backslash' + 0x00, 0x42, 0x42, 0x7e, 0x00, // 93 $5d 'bracketright' + 0x00, 0x04, 0x02, 0x04, 0x00, // 94 $5e 'asciicircum' + 0x80, 0x80, 0x80, 0x80, 0x00, // 95 $5f 'underscore' + 0x00, 0x02, 0x04, 0x00, 0x00, // 96 $60 'grave' + 0x30, 0x48, 0x48, 0x78, 0x00, // 97 $61 'a' + 0x7e, 0x48, 0x48, 0x30, 0x00, // 98 $62 'b' + 0x00, 0x30, 0x48, 0x48, 0x00, // 99 $63 'c' + 0x30, 0x48, 0x48, 0x7e, 0x00, // 100 $64 'd' + 0x30, 0x68, 0x58, 0x10, 0x00, // 101 $65 'e' + 0x10, 0x7c, 0x12, 0x04, 0x00, // 102 $66 'f' + 0x10, 0xa8, 0xa8, 0x70, 0x00, // 103 $67 'g' + 0x7e, 0x08, 0x08, 0x70, 0x00, // 104 $68 'h' + 0x00, 0x48, 0x7a, 0x40, 0x00, // 105 $69 'i' + 0x00, 0x40, 0x80, 0x7a, 0x00, // 106 $6a 'j' + 0x7e, 0x10, 0x10, 0x68, 0x00, // 107 $6b 'k' + 0x00, 0x42, 0x7e, 0x40, 0x00, // 108 $6c 'l' + 0x78, 0x08, 0x70, 0x08, 0x70, // 109 $6d 'm' + 0x78, 0x08, 0x08, 0x70, 0x00, // 110 $6e 'n' + 0x30, 0x48, 0x48, 0x30, 0x00, // 111 $6f 'o' + 0xf8, 0x28, 0x28, 0x10, 0x00, // 112 $70 'p' + 0x10, 0x28, 0x28, 0xf8, 0x00, // 113 $71 'q' + 0x78, 0x10, 0x08, 0x10, 0x00, // 114 $72 'r' + 0x00, 0x50, 0x58, 0x28, 0x00, // 115 $73 's' + 0x08, 0x3e, 0x48, 0x20, 0x00, // 116 $74 't' + 0x38, 0x40, 0x40, 0x78, 0x00, // 117 $75 'u' + 0x00, 0x38, 0x40, 0x38, 0x00, // 118 $76 'v' + 0x38, 0x40, 0x30, 0x40, 0x38, // 119 $77 'w' + 0x48, 0x30, 0x30, 0x48, 0x00, // 120 $78 'x' + 0x58, 0xa0, 0xa0, 0x78, 0x00, // 121 $79 'y' + 0x48, 0x68, 0x58, 0x48, 0x00, // 122 $7a 'z' + 0x08, 0x2a, 0x55, 0x41, 0x00, // 123 $7b 'braceleft' + 0x00, 0x00, 0x7e, 0x00, 0x00, // 124 $7c 'bar' + 0x41, 0x55, 0x2a, 0x08, 0x00, // 125 $7d 'braceright' + 0x04, 0x02, 0x04, 0x02, 0x00, // 126 $7e 'asciitilde' + 0x00, 0x00, 0x00, 0x00, 0x00, // 160 $a0 'space' + 0x00, 0x00, 0x7a, 0x00, 0x00, // 161 $a1 'exclamdown' + 0x30, 0x48, 0xfc, 0x48, 0x00, // 162 $a2 'cent' + 0x48, 0x3c, 0x4a, 0x24, 0x00, // 163 $a3 'sterling' + 0x44, 0x38, 0x28, 0x38, 0x44, // 164 $a4 'currency' + 0x2a, 0x2c, 0x78, 0x2c, 0x2a, // 165 $a5 'yen' + 0x00, 0x00, 0x77, 0x00, 0x00, // 166 $a6 'brokenbar' + 0x4e, 0x55, 0x55, 0x39, 0x00, // 167 $a7 'section' + 0x00, 0x02, 0x00, 0x02, 0x00, // 168 $a8 'dieresis' + 0x3c, 0x5a, 0x66, 0x42, 0x3c, // 169 $a9 'copyright' + 0x00, 0x12, 0x15, 0x17, 0x00, // 170 $aa 'ordfeminine' + 0x10, 0x28, 0x10, 0x28, 0x00, // 171 $ab 'guillemotleft' + 0x00, 0x10, 0x10, 0x70, 0x00, // 172 $ac 'logicalnot' + 0x00, 0x10, 0x10, 0x10, 0x00, // 173 $ad 'hyphen' + 0x3c, 0x7e, 0x56, 0x6a, 0x3c, // 174 $ae 'registered' + 0x00, 0x02, 0x02, 0x02, 0x00, // 175 $af 'macron' + 0x00, 0x04, 0x0a, 0x04, 0x00, // 176 $b0 'degree' + 0x00, 0x48, 0x5c, 0x48, 0x00, // 177 $b1 'plusminus' + 0x00, 0x12, 0x19, 0x16, 0x00, // 178 $b2 'twosuperior' + 0x00, 0x15, 0x15, 0x0a, 0x00, // 179 $b3 'threesuperior' + 0x00, 0x04, 0x02, 0x00, 0x00, // 180 $b4 'acute' + 0xf8, 0x40, 0x40, 0x38, 0x00, // 181 $b5 'mu' + 0x0c, 0x1e, 0x7e, 0x02, 0x7e, // 182 $b6 'paragraph' + 0x00, 0x00, 0x10, 0x00, 0x00, // 183 $b7 'periodcentered' + 0x00, 0x80, 0x40, 0x00, 0x00, // 184 $b8 'cedilla' + 0x00, 0x12, 0x1f, 0x10, 0x00, // 185 $b9 'onesuperior' + 0x00, 0x12, 0x15, 0x12, 0x00, // 186 $ba 'ordmasculine' + 0x28, 0x10, 0x28, 0x10, 0x00, // 187 $bb 'guillemotright' + 0x2f, 0x30, 0x78, 0x20, 0x00, // 188 $bc 'onequarter' + 0x0f, 0x48, 0x64, 0x58, 0x00, // 189 $bd 'onehalf' + 0x35, 0x2a, 0x78, 0x20, 0x00, // 190 $be 'threequarters' + 0x00, 0x30, 0x4a, 0x20, 0x00, // 191 $bf 'questiondown' + 0x78, 0x15, 0x16, 0x78, 0x00, // 192 $c0 'Agrave' + 0x78, 0x16, 0x15, 0x78, 0x00, // 193 $c1 'Aacute' + 0x7a, 0x15, 0x15, 0x7a, 0x00, // 194 $c2 'Acircumflex' + 0x7a, 0x15, 0x16, 0x79, 0x00, // 195 $c3 'Atilde' + 0x79, 0x14, 0x14, 0x79, 0x00, // 196 $c4 'Adieresis' + 0x7a, 0x15, 0x15, 0x7a, 0x00, // 197 $c5 'Aring' + 0x7c, 0x12, 0x7e, 0x52, 0x00, // 198 $c6 'AE' + 0x3c, 0xc2, 0x42, 0x24, 0x00, // 199 $c7 'Ccedilla' + 0x7c, 0x55, 0x56, 0x44, 0x00, // 200 $c8 'Egrave' + 0x7c, 0x56, 0x55, 0x44, 0x00, // 201 $c9 'Eacute' + 0x7e, 0x55, 0x55, 0x46, 0x00, // 202 $ca 'Ecircumflex' + 0x7d, 0x54, 0x54, 0x45, 0x00, // 203 $cb 'Edieresis' + 0x00, 0x45, 0x7e, 0x44, 0x00, // 204 $cc 'Igrave' + 0x00, 0x44, 0x7e, 0x45, 0x00, // 205 $cd 'Iacute' + 0x00, 0x46, 0x7d, 0x46, 0x00, // 206 $ce 'Icircumflex' + 0x00, 0x45, 0x7c, 0x45, 0x00, // 207 $cf 'Idieresis' + 0x08, 0x7e, 0x4a, 0x42, 0x3c, // 208 $d0 'Eth' + 0x7e, 0x09, 0x12, 0x7d, 0x00, // 209 $d1 'Ntilde' + 0x38, 0x45, 0x46, 0x38, 0x00, // 210 $d2 'Ograve' + 0x38, 0x46, 0x45, 0x38, 0x00, // 211 $d3 'Oacute' + 0x3a, 0x45, 0x45, 0x3a, 0x00, // 212 $d4 'Ocircumflex' + 0x3a, 0x45, 0x46, 0x39, 0x00, // 213 $d5 'Otilde' + 0x39, 0x44, 0x44, 0x39, 0x00, // 214 $d6 'Odieresis' + 0x00, 0x50, 0x20, 0x50, 0x00, // 215 $d7 'multiply' + 0x7c, 0x72, 0x4e, 0x3e, 0x00, // 216 $d8 'Oslash' + 0x3c, 0x41, 0x42, 0x3c, 0x00, // 217 $d9 'Ugrave' + 0x3c, 0x42, 0x41, 0x3c, 0x00, // 218 $da 'Uacute' + 0x3e, 0x41, 0x41, 0x3e, 0x00, // 219 $db 'Ucircumflex' + 0x3d, 0x40, 0x40, 0x3d, 0x00, // 220 $dc 'Udieresis' + 0x04, 0x08, 0x72, 0x09, 0x04, // 221 $dd 'Yacute' + 0x7e, 0x24, 0x24, 0x18, 0x00, // 222 $de 'Thorn' + 0x7c, 0x02, 0x5a, 0x24, 0x00, // 223 $df 'germandbls' + 0x30, 0x49, 0x4a, 0x78, 0x00, // 224 $e0 'agrave' + 0x30, 0x4a, 0x49, 0x78, 0x00, // 225 $e1 'aacute' + 0x30, 0x4a, 0x49, 0x7a, 0x00, // 226 $e2 'acircumflex' + 0x32, 0x49, 0x4a, 0x79, 0x00, // 227 $e3 'atilde' + 0x30, 0x4a, 0x48, 0x7a, 0x00, // 228 $e4 'adieresis' + 0x32, 0x4d, 0x4d, 0x7a, 0x00, // 229 $e5 'aring' + 0x28, 0x58, 0x78, 0x68, 0x50, // 230 $e6 'ae' + 0x00, 0x30, 0xc8, 0x48, 0x00, // 231 $e7 'ccedilla' + 0x30, 0x69, 0x5a, 0x10, 0x00, // 232 $e8 'egrave' + 0x30, 0x6a, 0x59, 0x10, 0x00, // 233 $e9 'eacute' + 0x32, 0x69, 0x59, 0x12, 0x00, // 234 $ea 'ecircumflex' + 0x30, 0x6a, 0x58, 0x12, 0x00, // 235 $eb 'edieresis' + 0x00, 0x49, 0x7a, 0x40, 0x00, // 236 $ec 'igrave' + 0x00, 0x48, 0x7a, 0x41, 0x00, // 237 $ed 'iacute' + 0x00, 0x4a, 0x79, 0x42, 0x00, // 238 $ee 'icircumflex' + 0x00, 0x4a, 0x78, 0x42, 0x00, // 239 $ef 'idieresis' + 0x25, 0x52, 0x55, 0x38, 0x00, // 240 $f0 'eth' + 0x7a, 0x09, 0x0a, 0x71, 0x00, // 241 $f1 'ntilde' + 0x30, 0x49, 0x4a, 0x30, 0x00, // 242 $f2 'ograve' + 0x30, 0x4a, 0x49, 0x30, 0x00, // 243 $f3 'oacute' + 0x32, 0x49, 0x49, 0x32, 0x00, // 244 $f4 'ocircumflex' + 0x32, 0x49, 0x4a, 0x31, 0x00, // 245 $f5 'otilde' + 0x32, 0x48, 0x48, 0x32, 0x00, // 246 $f6 'odieresis' + 0x00, 0x10, 0x54, 0x10, 0x00, // 247 $f7 'divide' + 0x70, 0x68, 0x58, 0x38, 0x00, // 248 $f8 'oslash' + 0x38, 0x41, 0x42, 0x78, 0x00, // 249 $f9 'ugrave' + 0x38, 0x42, 0x41, 0x78, 0x00, // 250 $fa 'uacute' + 0x3a, 0x41, 0x41, 0x7a, 0x00, // 251 $fb 'ucircumflex' + 0x3a, 0x40, 0x40, 0x7a, 0x00, // 252 $fc 'udieresis' + 0x58, 0xa2, 0xa1, 0x78, 0x00, // 253 $fd 'yacute' + 0xfe, 0x28, 0x28, 0x10, 0x00, // 254 $fe 'thorn' + 0x5a, 0xa0, 0xa0, 0x7a, 0x00, // 255 $ff 'ydieresis' + 0x79, 0x15, 0x15, 0x79, 0x00, // 256 $100 'Amacron' + 0x32, 0x4a, 0x4a, 0x7a, 0x00, // 257 $101 'amacron' + 0x79, 0x16, 0x16, 0x79, 0x00, // 258 $102 'Abreve' + 0x31, 0x4a, 0x4a, 0x79, 0x00, // 259 $103 'abreve' + 0x7c, 0x12, 0x92, 0xfc, 0x00, // 260 $104 'Aogonek' + 0x30, 0x48, 0xc8, 0x78, 0x00, // 261 $105 'aogonek' + 0x38, 0x46, 0x45, 0x28, 0x00, // 262 $106 'Cacute' + 0x00, 0x30, 0x4a, 0x49, 0x00, // 263 $107 'cacute' + 0x3a, 0x45, 0x45, 0x2a, 0x00, // 264 $108 'Ccircumflex' + 0x32, 0x49, 0x49, 0x02, 0x00, // 265 $109 'ccircumflex' + 0x38, 0x45, 0x44, 0x28, 0x00, // 266 $10a 'Cdotaccent' + 0x00, 0x30, 0x4a, 0x48, 0x00, // 267 $10b 'cdotaccent' + 0x39, 0x46, 0x46, 0x29, 0x00, // 268 $10c 'Ccaron' + 0x31, 0x4a, 0x4a, 0x01, 0x00, // 269 $10d 'ccaron' + 0x7d, 0x46, 0x46, 0x39, 0x00, // 270 $10e 'Dcaron' + 0x31, 0x4a, 0x49, 0x7e, 0x00, // 271 $10f 'dcaron' + 0x08, 0x7e, 0x4a, 0x42, 0x3c, // 272 $110 'Dcroat' + 0x20, 0x54, 0x7e, 0x04, 0x00, // 273 $111 'dcroat' + 0x7d, 0x55, 0x55, 0x45, 0x00, // 274 $112 'Emacron' + 0x32, 0x6a, 0x5a, 0x12, 0x00, // 275 $113 'emacron' + 0x7d, 0x56, 0x56, 0x45, 0x00, // 276 $114 'Ebreve' + 0x31, 0x6a, 0x5a, 0x11, 0x00, // 277 $115 'ebreve' + 0x7c, 0x55, 0x55, 0x44, 0x00, // 278 $116 'Edotaccent' + 0x30, 0x6a, 0x5a, 0x10, 0x00, // 279 $117 'edotaccent' + 0x7e, 0x4a, 0xca, 0x42, 0x00, // 280 $118 'Eogonek' + 0x30, 0x68, 0xd8, 0x10, 0x00, // 281 $119 'eogonek' + 0x7d, 0x56, 0x56, 0x45, 0x00, // 282 $11a 'Ecaron' + 0x31, 0x6a, 0x5a, 0x11, 0x00, // 283 $11b 'ecaron' + 0x3a, 0x45, 0x55, 0x36, 0x00, // 284 $11c 'Gcircumflex' + 0x12, 0xa9, 0xa9, 0x72, 0x00, // 285 $11d 'gcircumflex' + 0x39, 0x46, 0x56, 0x35, 0x00, // 286 $11e 'Gbreve' + 0x11, 0xaa, 0xaa, 0x71, 0x00, // 287 $11f 'gbreve' + 0x38, 0x45, 0x55, 0x34, 0x00, // 288 $120 'Gdotaccent' + 0x10, 0xaa, 0xaa, 0x70, 0x00, // 289 $121 'gdotaccent' + 0x3c, 0x42, 0xd2, 0x34, 0x00, // 290 $122 'Gcommaaccent' + 0x10, 0xab, 0xa9, 0x70, 0x00, // 291 $123 'gcommaaccent' + 0x7a, 0x11, 0x11, 0x7a, 0x00, // 292 $124 'Hcircumflex' + 0x7e, 0x09, 0x09, 0x72, 0x00, // 293 $125 'hcircumflex' + 0x04, 0x7e, 0x14, 0x7e, 0x04, // 294 $126 'Hbar' + 0x04, 0x7e, 0x14, 0x14, 0x60, // 295 $127 'hbar' + 0x46, 0x7d, 0x46, 0x01, 0x00, // 296 $128 'Itilde' + 0x4a, 0x79, 0x42, 0x01, 0x00, // 297 $129 'itilde' + 0x00, 0x45, 0x7d, 0x45, 0x00, // 298 $12a 'Imacron' + 0x00, 0x4a, 0x7a, 0x42, 0x00, // 299 $12b 'imacron' + 0x01, 0x46, 0x7e, 0x45, 0x00, // 300 $12c 'Ibreve' + 0x01, 0x4a, 0x7a, 0x41, 0x00, // 301 $12d 'ibreve' + 0x00, 0x42, 0x7e, 0xc2, 0x00, // 302 $12e 'Iogonek' + 0x00, 0x48, 0x7a, 0xc0, 0x00, // 303 $12f 'iogonek' + 0x00, 0x44, 0x7d, 0x44, 0x00, // 304 $130 'Idotaccent' + 0x00, 0x48, 0x78, 0x40, 0x00, // 305 $131 'dotlessi' + 0x7e, 0x20, 0x42, 0x3e, 0x00, // 306 $132 'IJ' + 0x00, 0x7a, 0x80, 0x7a, 0x00, // 307 $133 'ij' + 0x20, 0x46, 0x3d, 0x06, 0x00, // 308 $134 'Jcircumflex' + 0x40, 0x82, 0x79, 0x02, 0x00, // 309 $135 'jcircumflex' + 0x80, 0x7e, 0x08, 0x34, 0x42, // 310 $136 'Kcommaaccent' + 0x80, 0x7e, 0x10, 0x10, 0x68, // 311 $137 'kcommaaccent' + 0x00, 0x78, 0x10, 0x68, 0x00, // 312 $138 'kgreenlandic' + 0x7c, 0x40, 0x42, 0x41, 0x00, // 313 $139 'Lacute' + 0x00, 0x44, 0x7e, 0x41, 0x00, // 314 $13a 'lacute' + 0x7e, 0x40, 0xc0, 0x40, 0x00, // 315 $13b 'Lcommaaccent' + 0x00, 0x42, 0xfe, 0x40, 0x00, // 316 $13c 'lcommaaccent' + 0x7c, 0x41, 0x42, 0x41, 0x00, // 317 $13d 'Lcaron' + 0x00, 0x45, 0x7e, 0x41, 0x00, // 318 $13e 'lcaron' + 0x7e, 0x40, 0x48, 0x40, 0x00, // 319 $13f 'Ldot' + 0x42, 0x7e, 0x40, 0x08, 0x00, // 320 $140 'ldot' + 0x08, 0x7e, 0x44, 0x40, 0x40, // 321 $141 'Lslash' + 0x00, 0x52, 0x7e, 0x48, 0x00, // 322 $142 'lslash' + 0x7c, 0x0a, 0x11, 0x7c, 0x00, // 323 $143 'Nacute' + 0x78, 0x0a, 0x09, 0x70, 0x00, // 324 $144 'nacute' + 0x7e, 0x8c, 0x38, 0x7e, 0x00, // 325 $145 'Ncommaaccent' + 0x78, 0x88, 0x08, 0x70, 0x00, // 326 $146 'ncommaaccent' + 0x7d, 0x0a, 0x12, 0x7d, 0x00, // 327 $147 'Ncaron' + 0x79, 0x0a, 0x0a, 0x71, 0x00, // 328 $148 'ncaron' + 0x05, 0x03, 0x78, 0x08, 0x70, // 329 $149 'napostrophe' + 0x7e, 0x0c, 0xb8, 0x7e, 0x00, // 330 $14a 'Eng' + 0x78, 0x08, 0x88, 0x70, 0x00, // 331 $14b 'eng' + 0x39, 0x45, 0x45, 0x39, 0x00, // 332 $14c 'Omacron' + 0x32, 0x4a, 0x4a, 0x32, 0x00, // 333 $14d 'omacron' + 0x39, 0x46, 0x46, 0x39, 0x00, // 334 $14e 'Obreve' + 0x31, 0x4a, 0x4a, 0x31, 0x00, // 335 $14f 'obreve' + 0x02, 0x39, 0x44, 0x46, 0x39, // 336 $150 'Ohungarumlaut' + 0x02, 0x31, 0x48, 0x4a, 0x31, // 337 $151 'ohungarumlaut' + 0x3c, 0x42, 0x7e, 0x4a, 0x00, // 338 $152 'OE' + 0x30, 0x48, 0x78, 0x68, 0x50, // 339 $153 'oe' + 0x7c, 0x16, 0x15, 0x68, 0x00, // 340 $154 'Racute' + 0x78, 0x12, 0x09, 0x10, 0x00, // 341 $155 'racute' + 0x7e, 0x12, 0x92, 0x6c, 0x00, // 342 $156 'Rcommaaccent' + 0x80, 0x78, 0x10, 0x08, 0x10, // 343 $157 'rcommaaccent' + 0x7d, 0x16, 0x16, 0x69, 0x00, // 344 $158 'Rcaron' + 0x79, 0x12, 0x0a, 0x11, 0x00, // 345 $159 'rcaron' + 0x48, 0x56, 0x55, 0x24, 0x00, // 346 $15a 'Sacute' + 0x00, 0x50, 0x5a, 0x29, 0x00, // 347 $15b 'sacute' + 0x4a, 0x55, 0x55, 0x26, 0x00, // 348 $15c 'Scircumflex' + 0x00, 0x52, 0x59, 0x2a, 0x00, // 349 $15d 'scircumflex' + 0x24, 0x4a, 0xd2, 0x24, 0x00, // 350 $15e 'Scedilla' + 0x00, 0x50, 0xd8, 0x28, 0x00, // 351 $15f 'scedilla' + 0x49, 0x56, 0x56, 0x25, 0x00, // 352 $160 'Scaron' + 0x00, 0x51, 0x5a, 0x29, 0x00, // 353 $161 'scaron' + 0x00, 0x82, 0x7e, 0x02, 0x00, // 354 $162 'Tcommaaccent' + 0x08, 0xbe, 0x48, 0x20, 0x00, // 355 $163 'tcommaaccent' + 0x00, 0x05, 0x7e, 0x05, 0x00, // 356 $164 'Tcaron' + 0x09, 0x3e, 0x49, 0x20, 0x00, // 357 $165 'tcaron' + 0x00, 0x0a, 0x7e, 0x0a, 0x00, // 358 $166 'Tbar' + 0x0a, 0x3f, 0x4a, 0x20, 0x00, // 359 $167 'tbar' + 0x3a, 0x41, 0x42, 0x39, 0x00, // 360 $168 'Utilde' + 0x3a, 0x41, 0x42, 0x79, 0x00, // 361 $169 'utilde' + 0x3d, 0x41, 0x41, 0x3d, 0x00, // 362 $16a 'Umacron' + 0x3a, 0x42, 0x42, 0x7a, 0x00, // 363 $16b 'umacron' + 0x39, 0x42, 0x42, 0x39, 0x00, // 364 $16c 'Ubreve' + 0x39, 0x42, 0x42, 0x79, 0x00, // 365 $16d 'ubreve' + 0x38, 0x42, 0x45, 0x3a, 0x00, // 366 $16e 'Uring' + 0x38, 0x42, 0x45, 0x7a, 0x00, // 367 $16f 'uring' + 0x02, 0x39, 0x40, 0x42, 0x39, // 368 $170 'Uhungarumlaut' + 0x02, 0x39, 0x40, 0x42, 0x79, // 369 $171 'uhungarumlaut' + 0x3e, 0x40, 0xc0, 0x3e, 0x00, // 370 $172 'Uogonek' + 0x38, 0x40, 0xc0, 0x78, 0x00, // 371 $173 'uogonek' + 0x7c, 0x31, 0x31, 0x7c, 0x00, // 372 $174 'Wcircumflex' + 0x38, 0x42, 0x31, 0x42, 0x38, // 373 $175 'wcircumflex' + 0x00, 0x1a, 0x61, 0x1a, 0x00, // 374 $176 'Ycircumflex' + 0x5a, 0xa1, 0xa1, 0x7a, 0x00, // 375 $177 'ycircumflex' + 0x04, 0x09, 0x70, 0x09, 0x04, // 376 $178 'Ydieresis' + 0x64, 0x56, 0x4d, 0x44, 0x00, // 377 $179 'Zacute' + 0x48, 0x6a, 0x59, 0x48, 0x00, // 378 $17a 'zacute' + 0x64, 0x55, 0x4d, 0x44, 0x00, // 379 $17b 'Zdotaccent' + 0x48, 0x6a, 0x5a, 0x48, 0x00, // 380 $17c 'zdotaccent' + 0x65, 0x56, 0x4e, 0x45, 0x00, // 381 $17d 'Zcaron' + 0x49, 0x6a, 0x5a, 0x49, 0x00, // 382 $17e 'zcaron' + 0x10, 0x7c, 0x02, 0x04, 0x00, // 383 $17f 'longs' + 0x34, 0x52, 0x52, 0x3c, 0x00, // 399 $18f 'uni018F' + 0x40, 0x90, 0x7c, 0x12, 0x04, // 402 $192 'florin' + 0x3c, 0x42, 0x42, 0x3c, 0x02, // 416 $1a0 'Ohorn' + 0x30, 0x48, 0x48, 0x30, 0x08, // 417 $1a1 'ohorn' + 0x3e, 0x40, 0x3e, 0x04, 0x02, // 431 $1af 'Uhorn' + 0x38, 0x40, 0x78, 0x10, 0x08, // 432 $1b0 'uhorn' + 0x6a, 0x5a, 0x4a, 0x4e, 0x00, // 437 $1b5 'uni01B5' + 0x58, 0x78, 0x58, 0x58, 0x00, // 438 $1b6 'uni01B6' + 0x39, 0x46, 0x46, 0x39, 0x00, // 465 $1d1 'uni01D1' + 0x31, 0x4a, 0x4a, 0x31, 0x00, // 466 $1d2 'uni01D2' + 0x39, 0x46, 0x56, 0x75, 0x00, // 486 $1e6 'Gcaron' + 0x11, 0xaa, 0xaa, 0x71, 0x00, // 487 $1e7 'gcaron' + 0x74, 0x2a, 0x2a, 0x75, 0x00, // 506 $1fa 'Aringacute' + 0x24, 0x5a, 0x5a, 0x75, 0x00, // 507 $1fb 'aringacute' + 0x78, 0x14, 0x7e, 0x55, 0x00, // 508 $1fc 'AEacute' + 0x28, 0x58, 0x7a, 0x69, 0x50, // 509 $1fd 'aeacute' + 0x78, 0x74, 0x4e, 0x3d, 0x00, // 510 $1fe 'Oslashacute' + 0x70, 0x68, 0x5a, 0x39, 0x00, // 511 $1ff 'oslashacute' + 0x24, 0x4a, 0xd2, 0x24, 0x00, // 536 $218 'Scommaaccent' + 0x00, 0x50, 0xd8, 0x28, 0x00, // 537 $219 'scommaaccent' + 0x00, 0x82, 0x7e, 0x02, 0x00, // 538 $21a 'Tcommaaccent' + 0x08, 0xbe, 0x48, 0x20, 0x00, // 539 $21b 'tcommaaccent' + 0x20, 0x68, 0x58, 0x30, 0x00, // 601 $259 'uni0259' + 0x00, 0x0c, 0x0a, 0x00, 0x00, // 699 $2bb 'uni02BB' + 0x00, 0x0a, 0x06, 0x00, 0x00, // 700 $2bc 'afii57929' + 0x00, 0x06, 0x0a, 0x00, 0x00, // 701 $2bd 'afii64937' + 0x00, 0x0a, 0x04, 0x00, 0x00, // 702 $2be 'uni02BE' + 0x00, 0x04, 0x0a, 0x00, 0x00, // 703 $2bf 'uni02BF' + 0x00, 0x02, 0x01, 0x02, 0x00, // 710 $2c6 'circumflex' + 0x00, 0x01, 0x02, 0x01, 0x00, // 711 $2c7 'caron' + 0x00, 0x02, 0x02, 0x02, 0x00, // 713 $2c9 'macron' + 0x01, 0x02, 0x02, 0x02, 0x01, // 728 $2d8 'breve' + 0x00, 0x00, 0x01, 0x00, 0x00, // 729 $2d9 'dotaccent' + 0x00, 0x02, 0x05, 0x02, 0x00, // 730 $2da 'ring' + 0x00, 0xc0, 0x80, 0x00, 0x00, // 731 $2db 'ogonek' + 0x04, 0x02, 0x04, 0x02, 0x00, // 732 $2dc 'tilde' + 0x02, 0x01, 0x00, 0x02, 0x01, // 733 $2dd 'hungarumlaut' + 0x00, 0x01, 0x02, 0x00, 0x00, // 768 $300 'gravecomb' + 0x00, 0x02, 0x01, 0x00, 0x00, // 769 $301 'acutecomb' + 0x00, 0x02, 0x01, 0x02, 0x00, // 770 $302 'uni0302' + 0x02, 0x01, 0x02, 0x01, 0x00, // 771 $303 'tildecomb' + 0x01, 0x01, 0x01, 0x01, 0x00, // 772 $304 'uni0304' + 0x01, 0x01, 0x01, 0x01, 0x01, // 773 $305 'uni0305' + 0x01, 0x02, 0x02, 0x01, 0x00, // 774 $306 'uni0306' + 0x00, 0x00, 0x01, 0x00, 0x00, // 775 $307 'uni0307' + 0x00, 0x01, 0x00, 0x01, 0x00, // 776 $308 'uni0308' + 0x00, 0x01, 0x03, 0x00, 0x00, // 777 $309 'hookabovecomb' + 0x02, 0x05, 0x05, 0x02, 0x00, // 778 $30a 'uni030A' + 0x02, 0x01, 0x00, 0x02, 0x01, // 779 $30b 'uni030B' + 0x00, 0x01, 0x02, 0x01, 0x00, // 780 $30c 'uni030C' + 0x00, 0x00, 0x03, 0x00, 0x00, // 781 $30d 'uni030D' + 0x00, 0x03, 0x00, 0x03, 0x00, // 782 $30e 'uni030E' + 0x01, 0x02, 0x00, 0x01, 0x02, // 783 $30f 'uni030F' + 0x01, 0x02, 0x03, 0x02, 0x01, // 784 $310 'uni0310' + 0x02, 0x01, 0x01, 0x02, 0x00, // 785 $311 'uni0311' + 0x00, 0x06, 0x05, 0x00, 0x00, // 786 $312 'uni0312' + 0x00, 0x05, 0x03, 0x00, 0x00, // 787 $313 'uni0313' + 0x00, 0x03, 0x05, 0x00, 0x00, // 788 $314 'uni0314' + 0x00, 0x00, 0x00, 0x05, 0x03, // 789 $315 'uni0315' + 0x00, 0x00, 0x80, 0x00, 0x00, // 803 $323 'dotbelowcomb' + 0x00, 0x80, 0x00, 0x80, 0x00, // 804 $324 'uni0324' + 0x80, 0x80, 0x80, 0x80, 0x00, // 817 $331 'uni0331' + 0x80, 0x80, 0x80, 0x80, 0x80, // 818 $332 'uni0332' + 0x40, 0x30, 0x0c, 0x02, 0x00, // 824 $338 'uni0338' + 0x00, 0x01, 0x02, 0x00, 0x00, // 832 $340 'uni0340' + 0x00, 0x02, 0x01, 0x00, 0x00, // 833 $341 'uni0341' + 0x00, 0x02, 0x01, 0x00, 0x00, // 884 $374 'uni0374' + 0x00, 0x80, 0x40, 0x00, 0x00, // 885 $375 'uni0375' + 0x00, 0xc0, 0x80, 0x00, 0x00, // 890 $37a 'uni037A' + 0x00, 0x80, 0x6c, 0x2c, 0x00, // 894 $37e 'uni037E' + 0x00, 0x02, 0x01, 0x00, 0x00, // 900 $384 'tonos' + 0x00, 0x04, 0x02, 0x05, 0x00, // 901 $385 'dieresistonos' + 0x78, 0x16, 0x15, 0x78, 0x00, // 902 $386 'Alphatonos' + 0x00, 0x00, 0x08, 0x00, 0x00, // 903 $387 'anoteleia' + 0x7c, 0x56, 0x55, 0x44, 0x00, // 904 $388 'Epsilontonos' + 0x7c, 0x12, 0x11, 0x7c, 0x00, // 905 $389 'Etatonos' + 0x00, 0x44, 0x7e, 0x45, 0x00, // 906 $38a 'Iotatonos' + 0x38, 0x46, 0x45, 0x38, 0x00, // 908 $38c 'Omicrontonos' + 0x04, 0x08, 0x72, 0x09, 0x04, // 910 $38e 'Upsilontonos' + 0x58, 0x64, 0x06, 0x65, 0x58, // 911 $38f 'Omegatonos' + 0x04, 0x3a, 0x45, 0x20, 0x00, // 912 $390 'iotadieresistonos' + 0x7c, 0x12, 0x12, 0x7c, 0x00, // 913 $391 'Alpha' + 0x7e, 0x4a, 0x4a, 0x34, 0x00, // 914 $392 'Beta' + 0x7e, 0x02, 0x02, 0x02, 0x00, // 915 $393 'Gamma' + 0x60, 0x58, 0x46, 0x58, 0x60, // 916 $394 'Delta' + 0x7e, 0x4a, 0x4a, 0x42, 0x00, // 917 $395 'Epsilon' + 0x62, 0x52, 0x4a, 0x46, 0x00, // 918 $396 'Zeta' + 0x7e, 0x08, 0x08, 0x7e, 0x00, // 919 $397 'Eta' + 0x3c, 0x4a, 0x4a, 0x3c, 0x00, // 920 $398 'Theta' + 0x00, 0x42, 0x7e, 0x42, 0x00, // 921 $399 'Iota' + 0x7e, 0x08, 0x34, 0x42, 0x00, // 922 $39a 'Kappa' + 0x78, 0x06, 0x06, 0x78, 0x00, // 923 $39b 'Lambda' + 0x7e, 0x0c, 0x0c, 0x7e, 0x00, // 924 $39c 'Mu' + 0x7e, 0x0c, 0x38, 0x7e, 0x00, // 925 $39d 'Nu' + 0x42, 0x4a, 0x4a, 0x42, 0x00, // 926 $39e 'Xi' + 0x3c, 0x42, 0x42, 0x3c, 0x00, // 927 $39f 'Omicron' + 0x7e, 0x02, 0x02, 0x7e, 0x00, // 928 $3a0 'Pi' + 0x7e, 0x12, 0x12, 0x0c, 0x00, // 929 $3a1 'Rho' + 0x66, 0x5a, 0x42, 0x42, 0x00, // 931 $3a3 'Sigma' + 0x00, 0x02, 0x7e, 0x02, 0x00, // 932 $3a4 'Tau' + 0x06, 0x08, 0x70, 0x08, 0x06, // 933 $3a5 'Upsilon' + 0x18, 0x24, 0x7e, 0x24, 0x18, // 934 $3a6 'Phi' + 0x66, 0x18, 0x18, 0x66, 0x00, // 935 $3a7 'Chi' + 0x06, 0x08, 0x7e, 0x08, 0x06, // 936 $3a8 'Psi' + 0x5c, 0x62, 0x02, 0x62, 0x5c, // 937 $3a9 'Omega' + 0x00, 0x45, 0x7c, 0x45, 0x00, // 938 $3aa 'Iotadieresis' + 0x00, 0x0d, 0x70, 0x0d, 0x00, // 939 $3ab 'Upsilondieresis' + 0x30, 0x4a, 0x49, 0x78, 0x00, // 940 $3ac 'alphatonos' + 0x30, 0x5a, 0x59, 0x48, 0x00, // 941 $3ad 'epsilontonos' + 0x78, 0x12, 0x09, 0xf0, 0x00, // 942 $3ae 'etatonos' + 0x00, 0x3a, 0x41, 0x20, 0x00, // 943 $3af 'iotatonos' + 0x3a, 0x42, 0x41, 0x3a, 0x00, // 944 $3b0 'upsilondieresistonos' + 0x30, 0x48, 0x48, 0x78, 0x00, // 945 $3b1 'alpha' + 0xfc, 0x4a, 0x4a, 0x34, 0x00, // 946 $3b2 'beta' + 0x00, 0x38, 0xc0, 0x38, 0x00, // 947 $3b3 'gamma' + 0x34, 0x4a, 0x4a, 0x30, 0x00, // 948 $3b4 'delta' + 0x30, 0x58, 0x58, 0x48, 0x00, // 949 $3b5 'epsilon' + 0x14, 0x2c, 0xa4, 0x44, 0x00, // 950 $3b6 'zeta' + 0x78, 0x10, 0x08, 0xf0, 0x00, // 951 $3b7 'eta' + 0x3c, 0x4a, 0x4a, 0x3c, 0x00, // 952 $3b8 'theta' + 0x00, 0x38, 0x40, 0x20, 0x00, // 953 $3b9 'iota' + 0x78, 0x10, 0x30, 0x48, 0x00, // 954 $3ba 'kappa' + 0x72, 0x0a, 0x0a, 0x7c, 0x00, // 955 $3bb 'lambda' + 0xf8, 0x40, 0x40, 0x38, 0x00, // 956 $3bc 'mu' + 0x00, 0x18, 0x60, 0x18, 0x00, // 957 $3bd 'nu' + 0x12, 0xae, 0xaa, 0x42, 0x00, // 958 $3be 'xi' + 0x30, 0x48, 0x48, 0x30, 0x00, // 959 $3bf 'omicron' + 0x08, 0x78, 0x08, 0x78, 0x08, // 960 $3c0 'pi' + 0xf0, 0x48, 0x48, 0x30, 0x00, // 961 $3c1 'rho' + 0x10, 0xa8, 0xa8, 0x40, 0x00, // 962 $3c2 'sigma1' + 0x30, 0x48, 0x48, 0x38, 0x00, // 963 $3c3 'sigma' + 0x08, 0x38, 0x48, 0x28, 0x00, // 964 $3c4 'tau' + 0x38, 0x40, 0x40, 0x38, 0x00, // 965 $3c5 'upsilon' + 0x38, 0x40, 0xf8, 0x48, 0x30, // 966 $3c6 'phi' + 0x00, 0xd8, 0x20, 0xd8, 0x00, // 967 $3c7 'chi' + 0x18, 0x20, 0xf8, 0x20, 0x18, // 968 $3c8 'psi' + 0x38, 0x40, 0x30, 0x40, 0x38, // 969 $3c9 'omega' + 0x02, 0x38, 0x42, 0x20, 0x00, // 970 $3ca 'iotadieresis' + 0x3a, 0x40, 0x40, 0x3a, 0x00, // 971 $3cb 'upsilondieresis' + 0x30, 0x4a, 0x49, 0x30, 0x00, // 972 $3cc 'omicrontonos' + 0x38, 0x42, 0x41, 0x38, 0x00, // 973 $3cd 'upsilontonos' + 0x38, 0x40, 0x32, 0x41, 0x38, // 974 $3ce 'omegatonos' + 0x24, 0x4a, 0x4a, 0x3c, 0x08, // 977 $3d1 'theta1' + 0x02, 0x04, 0x7c, 0x02, 0x04, // 978 $3d2 'Upsilon1' + 0x1a, 0x02, 0x7c, 0x02, 0x04, // 979 $3d3 'uni03D3' + 0x05, 0x08, 0x78, 0x05, 0x08, // 980 $3d4 'uni03D4' + 0x38, 0x44, 0xfe, 0x44, 0x38, // 981 $3d5 'phi1' + 0x38, 0x48, 0x28, 0x48, 0x38, // 982 $3d6 'omega1' + 0x3e, 0x10, 0x08, 0x7c, 0x00, // 990 $3de 'uni03DE' + 0x08, 0x4c, 0x2a, 0x18, 0x00, // 991 $3df 'uni03DF' + 0x50, 0xa8, 0xa8, 0x90, 0x00, // 1001 $3e9 'uni03E9' + 0x48, 0x30, 0x20, 0x58, 0x00, // 1008 $3f0 'uni03F0' + 0x70, 0xa8, 0xa8, 0x90, 0x00, // 1009 $3f1 'uni03F1' + 0x30, 0x48, 0x48, 0x48, 0x00, // 1010 $3f2 'uni03F2' + 0x40, 0x80, 0x88, 0x7a, 0x00, // 1011 $3f3 'uni03F3' + 0x3c, 0x4a, 0x4a, 0x3c, 0x00, // 1012 $3f4 'uni03F4' + 0x30, 0x58, 0x58, 0x48, 0x00, // 1013 $3f5 'uni03F5' + 0x7e, 0x4a, 0x4a, 0x42, 0x00, // 1025 $401 'afii10023' + 0x02, 0x3e, 0x8a, 0x70, 0x00, // 1026 $402 'afii10051' + 0x7e, 0x02, 0x02, 0x02, 0x00, // 1027 $403 'afii10052' + 0x3c, 0x4a, 0x42, 0x24, 0x00, // 1028 $404 'afii10053' + 0x24, 0x4a, 0x52, 0x24, 0x00, // 1029 $405 'afii10054' + 0x00, 0x42, 0x7e, 0x42, 0x00, // 1030 $406 'afii10055' + 0x00, 0x42, 0x7e, 0x42, 0x00, // 1031 $407 'afii10056' + 0x20, 0x40, 0x40, 0x3e, 0x00, // 1032 $408 'afii10057' + 0x7c, 0x02, 0x7e, 0x48, 0x30, // 1033 $409 'afii10058' + 0x7e, 0x08, 0x7e, 0x48, 0x30, // 1034 $40a 'afii10059' + 0x02, 0x7e, 0x0a, 0x70, 0x00, // 1035 $40b 'afii10060' + 0x7e, 0x18, 0x24, 0x42, 0x00, // 1036 $40c 'afii10061' + 0x00, 0x00, 0x00, 0x00, 0x00, // 1037 $40d 'uni040D' + 0x00, 0x4e, 0x30, 0x0e, 0x00, // 1038 $40e 'afii10062' + 0x00, 0x7e, 0xc0, 0x7e, 0x00, // 1039 $40f 'afii10145' + 0x7c, 0x12, 0x12, 0x7c, 0x00, // 1040 $410 'afii10017' + 0x7e, 0x4a, 0x4a, 0x30, 0x00, // 1041 $411 'afii10018' + 0x7e, 0x4a, 0x4a, 0x34, 0x00, // 1042 $412 'afii10019' + 0x7e, 0x02, 0x02, 0x06, 0x00, // 1043 $413 'afii10020' + 0xfc, 0x42, 0x7e, 0xc0, 0x00, // 1044 $414 'afii10021' + 0x7e, 0x4a, 0x4a, 0x42, 0x00, // 1045 $415 'afii10022' + 0x76, 0x08, 0x7e, 0x08, 0x76, // 1046 $416 'afii10024' + 0x24, 0x42, 0x4a, 0x34, 0x00, // 1047 $417 'afii10025' + 0x7e, 0x10, 0x08, 0x7e, 0x00, // 1048 $418 'afii10026' + 0x7d, 0x12, 0x0a, 0x7d, 0x00, // 1049 $419 'afii10027' + 0x7e, 0x08, 0x14, 0x62, 0x00, // 1050 $41a 'afii10028' + 0x40, 0x3c, 0x02, 0x7e, 0x00, // 1051 $41b 'afii10029' + 0x7e, 0x0c, 0x0c, 0x7e, 0x00, // 1052 $41c 'afii10030' + 0x7e, 0x08, 0x08, 0x7e, 0x00, // 1053 $41d 'afii10031' + 0x3c, 0x42, 0x42, 0x3c, 0x00, // 1054 $41e 'afii10032' + 0x7e, 0x02, 0x02, 0x7e, 0x00, // 1055 $41f 'afii10033' + 0x7e, 0x12, 0x12, 0x0c, 0x00, // 1056 $420 'afii10034' + 0x3c, 0x42, 0x42, 0x24, 0x00, // 1057 $421 'afii10035' + 0x00, 0x02, 0x7e, 0x02, 0x00, // 1058 $422 'afii10036' + 0x4e, 0x50, 0x50, 0x3e, 0x00, // 1059 $423 'afii10037' + 0x18, 0x24, 0x7e, 0x24, 0x18, // 1060 $424 'afii10038' + 0x00, 0x66, 0x18, 0x66, 0x00, // 1061 $425 'afii10039' + 0x7e, 0x40, 0x7e, 0xc0, 0x00, // 1062 $426 'afii10040' + 0x00, 0x0e, 0x10, 0x7e, 0x00, // 1063 $427 'afii10041' + 0x7e, 0x40, 0x7e, 0x40, 0x7e, // 1064 $428 'afii10042' + 0x7e, 0x40, 0x7e, 0x40, 0xfe, // 1065 $429 'afii10043' + 0x02, 0x02, 0x7e, 0x48, 0x30, // 1066 $42a 'afii10044' + 0x7e, 0x48, 0x30, 0x00, 0x7e, // 1067 $42b 'afii10045' + 0x00, 0x7e, 0x48, 0x30, 0x00, // 1068 $42c 'afii10046' + 0x42, 0x4a, 0x4a, 0x3c, 0x00, // 1069 $42d 'afii10047' + 0x7e, 0x08, 0x3c, 0x42, 0x3c, // 1070 $42e 'afii10048' + 0x6c, 0x12, 0x12, 0x7e, 0x00, // 1071 $42f 'afii10049' + 0x30, 0x48, 0x48, 0x78, 0x00, // 1072 $430 'afii10065' + 0x3c, 0x4a, 0x4a, 0x30, 0x00, // 1073 $431 'afii10066' + 0x78, 0x58, 0x58, 0x20, 0x00, // 1074 $432 'afii10067' + 0x00, 0x78, 0x08, 0x08, 0x00, // 1075 $433 'afii10068' + 0xe0, 0x58, 0x48, 0xf8, 0x00, // 1076 $434 'afii10069' + 0x30, 0x68, 0x58, 0x10, 0x00, // 1077 $435 'afii10070' + 0x68, 0x10, 0x78, 0x10, 0x68, // 1078 $436 'afii10072' + 0x00, 0x48, 0x58, 0x38, 0x00, // 1079 $437 'afii10073' + 0x78, 0x20, 0x10, 0x78, 0x00, // 1080 $438 'afii10074' + 0x7a, 0x24, 0x14, 0x7a, 0x00, // 1081 $439 'afii10075' + 0x78, 0x10, 0x30, 0x48, 0x00, // 1082 $43a 'afii10076' + 0x40, 0x30, 0x08, 0x78, 0x00, // 1083 $43b 'afii10077' + 0x78, 0x10, 0x60, 0x10, 0x78, // 1084 $43c 'afii10078' + 0x78, 0x10, 0x10, 0x78, 0x00, // 1085 $43d 'afii10079' + 0x30, 0x48, 0x48, 0x30, 0x00, // 1086 $43e 'afii10080' + 0x78, 0x08, 0x08, 0x78, 0x00, // 1087 $43f 'afii10081' + 0xf8, 0x48, 0x48, 0x30, 0x00, // 1088 $440 'afii10082' + 0x00, 0x30, 0x48, 0x48, 0x00, // 1089 $441 'afii10083' + 0x00, 0x08, 0x78, 0x08, 0x00, // 1090 $442 'afii10084' + 0x18, 0xa0, 0x40, 0x38, 0x00, // 1091 $443 'afii10085' + 0x00, 0x72, 0xde, 0x70, 0x00, // 1092 $444 'afii10086' + 0x48, 0x30, 0x30, 0x48, 0x00, // 1093 $445 'afii10087' + 0x78, 0x40, 0x40, 0xf8, 0x00, // 1094 $446 'afii10088' + 0x18, 0x20, 0x20, 0x78, 0x00, // 1095 $447 'afii10089' + 0x78, 0x40, 0x78, 0x40, 0x78, // 1096 $448 'afii10090' + 0x78, 0x40, 0x78, 0x40, 0xf8, // 1097 $449 'afii10091' + 0x08, 0x78, 0x50, 0x20, 0x00, // 1098 $44a 'afii10092' + 0x78, 0x50, 0x20, 0x78, 0x00, // 1099 $44b 'afii10093' + 0x78, 0x50, 0x50, 0x20, 0x00, // 1100 $44c 'afii10094' + 0x00, 0x48, 0x58, 0x30, 0x00, // 1101 $44d 'afii10095' + 0x78, 0x30, 0x48, 0x30, 0x00, // 1102 $44e 'afii10096' + 0x00, 0x50, 0x28, 0x78, 0x00, // 1103 $44f 'afii10097' + 0x32, 0x68, 0x5a, 0x10, 0x00, // 1105 $451 'afii10071' + 0x04, 0x3e, 0x94, 0x60, 0x00, // 1106 $452 'afii10099' + 0x78, 0x0c, 0x0a, 0x08, 0x00, // 1107 $453 'afii10100' + 0x00, 0x30, 0x58, 0x48, 0x00, // 1108 $454 'afii10101' + 0x50, 0x58, 0x68, 0x28, 0x00, // 1109 $455 'afii10102' + 0x00, 0x48, 0x7a, 0x40, 0x00, // 1110 $456 'afii10103' + 0x00, 0x4a, 0x78, 0x42, 0x00, // 1111 $457 'afii10104' + 0x00, 0x40, 0x80, 0x7a, 0x00, // 1112 $458 'afii10105' + 0x70, 0x08, 0x78, 0x50, 0x30, // 1113 $459 'afii10106' + 0x78, 0x10, 0x78, 0x50, 0x20, // 1114 $45a 'afii10107' + 0x04, 0x7e, 0x14, 0x60, 0x00, // 1115 $45b 'afii10108' + 0x78, 0x14, 0x32, 0x48, 0x00, // 1116 $45c 'afii10109' + 0x00, 0x00, 0x00, 0x00, 0x00, // 1117 $45d 'uni045D' + 0x12, 0xa4, 0x44, 0x32, 0x00, // 1118 $45e 'afii10110' + 0x00, 0x78, 0xc0, 0x78, 0x00, // 1119 $45f 'afii10193' + 0x7c, 0x04, 0x04, 0x06, 0x00, // 1168 $490 'afii10050' + 0x78, 0x08, 0x08, 0x0c, 0x00, // 1169 $491 'afii10098' + 0x08, 0x7e, 0x0a, 0x02, 0x00, // 1170 $492 'uni0492' + 0x20, 0x78, 0x28, 0x08, 0x00, // 1171 $493 'uni0493' + 0x76, 0x08, 0x7e, 0x08, 0xf6, // 1174 $496 'uni0496' + 0x68, 0x10, 0x78, 0x10, 0xe8, // 1175 $497 'uni0497' + 0x7e, 0x08, 0x14, 0x22, 0xc0, // 1178 $49a 'uni049A' + 0x78, 0x10, 0x30, 0x48, 0x80, // 1179 $49b 'uni049B' + 0x06, 0x08, 0x70, 0x08, 0x06, // 1198 $4ae 'uni04AE' + 0x08, 0x10, 0xe0, 0x10, 0x08, // 1199 $4af 'uni04AF' + 0x16, 0x18, 0x70, 0x18, 0x16, // 1200 $4b0 'uni04B0' + 0x28, 0x30, 0xe0, 0x30, 0x28, // 1201 $4b1 'uni04B1' + 0x00, 0x66, 0x18, 0x66, 0x80, // 1202 $4b2 'uni04B2' + 0x48, 0x30, 0x30, 0x48, 0x80, // 1203 $4b3 'uni04B3' + 0x7e, 0x08, 0x08, 0x70, 0x00, // 1210 $4ba 'uni04BA' + 0x00, 0x7e, 0x08, 0x70, 0x00, // 1211 $4bb 'uni04BB' + 0x34, 0x52, 0x52, 0x3c, 0x00, // 1240 $4d8 'uni04D8' + 0x20, 0x68, 0x58, 0x30, 0x00, // 1241 $4d9 'afii10846' + 0x00, 0x45, 0x7d, 0x45, 0x00, // 1250 $4e2 'uni04E2' + 0x00, 0x4a, 0x7a, 0x42, 0x00, // 1251 $4e3 'uni04E3' + 0x3c, 0x4a, 0x4a, 0x3c, 0x00, // 1256 $4e8 'uni04E8' + 0x30, 0x58, 0x58, 0x30, 0x00, // 1257 $4e9 'uni04E9' + 0x3d, 0x41, 0x41, 0x3d, 0x00, // 1262 $4ee 'uni04EE' + 0x3a, 0x42, 0x42, 0x7a, 0x00, // 1263 $4ef 'uni04EF' + 0x68, 0x10, 0x20, 0x58, 0x00, // 1488 $5d0 'afii57664' + 0x48, 0x48, 0x78, 0x40, 0x00, // 1489 $5d1 'afii57665' + 0x40, 0x44, 0x38, 0x40, 0x00, // 1490 $5d2 'afii57666' + 0x08, 0x08, 0x78, 0x08, 0x00, // 1491 $5d3 'afii57667' + 0x68, 0x08, 0x08, 0x78, 0x00, // 1492 $5d4 'afii57668' + 0x00, 0x04, 0x78, 0x00, 0x00, // 1493 $5d5 'afii57669' + 0x00, 0x08, 0x78, 0x08, 0x00, // 1494 $5d6 'afii57670' + 0x08, 0x78, 0x08, 0x78, 0x00, // 1495 $5d7 'afii57671' + 0x78, 0x40, 0x40, 0x78, 0x00, // 1496 $5d8 'afii57672' + 0x00, 0x04, 0x08, 0x00, 0x00, // 1497 $5d9 'afii57673' + 0x08, 0x08, 0x68, 0x18, 0x00, // 1498 $5da 'afii57674' + 0x44, 0x48, 0x48, 0x38, 0x00, // 1499 $5db 'afii57675' + 0x04, 0x48, 0x28, 0x18, 0x00, // 1500 $5dc 'afii57676' + 0x74, 0x48, 0x48, 0x78, 0x00, // 1501 $5dd 'afii57677' + 0x74, 0x08, 0x48, 0x78, 0x00, // 1502 $5de 'afii57678' + 0x00, 0x74, 0x08, 0x00, 0x00, // 1503 $5df 'afii57679' + 0x00, 0x44, 0x78, 0x00, 0x00, // 1504 $5e0 'afii57680' + 0x04, 0x38, 0x48, 0x48, 0x38, // 1505 $5e1 'afii57681' + 0x48, 0x70, 0x40, 0x78, 0x00, // 1506 $5e2 'afii57682' + 0x10, 0x08, 0x08, 0x78, 0x00, // 1507 $5e3 'afii57683' + 0x58, 0x48, 0x48, 0x78, 0x00, // 1508 $5e4 'afii57684' + 0x00, 0x78, 0x10, 0x08, 0x00, // 1509 $5e5 'afii57685' + 0x48, 0x50, 0x70, 0x48, 0x00, // 1510 $5e6 'afii57686' + 0x68, 0x08, 0x28, 0x10, 0x00, // 1511 $5e7 'afii57687' + 0x08, 0x08, 0x08, 0x78, 0x00, // 1512 $5e8 'afii57688' + 0x78, 0x50, 0x48, 0x40, 0x38, // 1513 $5e9 'afii57689' + 0x48, 0x78, 0x08, 0x78, 0x00, // 1514 $5ea 'afii57690' + 0x7c, 0x54, 0x55, 0x28, 0x00, // 7682 $1e02 'uni1E02' + 0x7e, 0x48, 0x49, 0x30, 0x00, // 7683 $1e03 'uni1E03' + 0x7c, 0x44, 0x45, 0x38, 0x00, // 7690 $1e0a 'uni1E0A' + 0x30, 0x49, 0x48, 0x7e, 0x00, // 7691 $1e0b 'uni1E0B' + 0x7c, 0x14, 0x15, 0x04, 0x00, // 7710 $1e1e 'uni1E1E' + 0x11, 0x7c, 0x12, 0x04, 0x00, // 7711 $1e1f 'uni1E1F' + 0x7c, 0x18, 0x19, 0x7c, 0x00, // 7744 $1e40 'uni1E40' + 0x78, 0x08, 0x72, 0x08, 0x70, // 7745 $1e41 'uni1E41' + 0x7c, 0x15, 0x14, 0x08, 0x00, // 7766 $1e56 'uni1E56' + 0xf8, 0x2a, 0x28, 0x10, 0x00, // 7767 $1e57 'uni1E57' + 0x48, 0x54, 0x55, 0x24, 0x00, // 7776 $1e60 'uni1E60' + 0x00, 0x50, 0x5a, 0x28, 0x00, // 7777 $1e61 'uni1E61' + 0x00, 0x04, 0x7d, 0x04, 0x00, // 7786 $1e6a 'uni1E6A' + 0x08, 0x3d, 0x48, 0x20, 0x00, // 7787 $1e6b 'uni1E6B' + 0x7c, 0x31, 0x32, 0x7c, 0x00, // 7808 $1e80 'Wgrave' + 0x38, 0x41, 0x32, 0x40, 0x38, // 7809 $1e81 'wgrave' + 0x7c, 0x32, 0x31, 0x7c, 0x00, // 7810 $1e82 'Wacute' + 0x38, 0x40, 0x32, 0x41, 0x38, // 7811 $1e83 'wacute' + 0x7d, 0x30, 0x30, 0x7d, 0x00, // 7812 $1e84 'Wdieresis' + 0x38, 0x42, 0x30, 0x42, 0x38, // 7813 $1e85 'wdieresis' + 0x04, 0x09, 0x72, 0x08, 0x04, // 7922 $1ef2 'Ygrave' + 0x58, 0xa1, 0xa2, 0x78, 0x00, // 7923 $1ef3 'ygrave' + 0x00, 0x10, 0x10, 0x10, 0x00, // 8208 $2010 'uni2010' + 0x00, 0x10, 0x10, 0x10, 0x00, // 8209 $2011 'uni2011' + 0x10, 0x10, 0x10, 0x10, 0x00, // 8210 $2012 'figuredash' + 0x10, 0x10, 0x10, 0x10, 0x00, // 8211 $2013 'endash' + 0x10, 0x10, 0x10, 0x10, 0x10, // 8212 $2014 'emdash' + 0x10, 0x10, 0x10, 0x10, 0x10, // 8213 $2015 'afii00208' + 0x00, 0x7e, 0x00, 0x7e, 0x00, // 8214 $2016 'uni2016' + 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, // 8215 $2017 'underscoredbl' + 0x00, 0x06, 0x05, 0x00, 0x00, // 8216 $2018 'quoteleft' + 0x00, 0x05, 0x03, 0x00, 0x00, // 8217 $2019 'quoteright' + 0x00, 0xa0, 0x60, 0x00, 0x00, // 8218 $201a 'quotesinglbase' + 0x00, 0x03, 0x05, 0x00, 0x00, // 8219 $201b 'quotereversed' + 0x06, 0x05, 0x00, 0x06, 0x05, // 8220 $201c 'quotedblleft' + 0x05, 0x03, 0x00, 0x05, 0x03, // 8221 $201d 'quotedblright' + 0xa0, 0x60, 0x00, 0xa0, 0x60, // 8222 $201e 'quotedblbase' + 0x03, 0x05, 0x00, 0x03, 0x05, // 8223 $201f 'uni201F' + 0x00, 0x04, 0x7e, 0x04, 0x00, // 8224 $2020 'dagger' + 0x00, 0x14, 0x7e, 0x14, 0x00, // 8225 $2021 'daggerdbl' + 0x30, 0x78, 0x78, 0x30, 0x00, // 8226 $2022 'bullet' + 0x40, 0x00, 0x40, 0x00, 0x40, // 8230 $2026 'ellipsis' + 0x16, 0x08, 0x34, 0x00, 0x30, // 8240 $2030 'perthousand' + 0x00, 0x08, 0x06, 0x00, 0x00, // 8242 $2032 'minute' + 0x08, 0x06, 0x08, 0x06, 0x00, // 8243 $2033 'second' + 0x0e, 0x08, 0x06, 0x08, 0x06, // 8244 $2034 'uni2034' + 0x00, 0x06, 0x08, 0x00, 0x00, // 8245 $2035 'uni2035' + 0x06, 0x08, 0x06, 0x08, 0x00, // 8246 $2036 'uni2036' + 0x00, 0x10, 0x28, 0x00, 0x00, // 8249 $2039 'guilsinglleft' + 0x00, 0x28, 0x10, 0x00, 0x00, // 8250 $203a 'guilsinglright' + 0x00, 0x5e, 0x00, 0x5e, 0x00, // 8252 $203c 'exclamdbl' + 0x00, 0x04, 0x5e, 0x0c, 0x00, // 8253 $203d 'uni203D' + 0x01, 0x01, 0x01, 0x01, 0x01, // 8254 $203e 'uni203E' + 0x40, 0x30, 0x0c, 0x02, 0x00, // 8260 $2044 'fraction' + 0x00, 0x0e, 0x11, 0x0e, 0x00, // 8304 $2070 'zerosuperior' + 0x00, 0x14, 0x1d, 0x10, 0x00, // 8305 $2071 'uni2071' + 0x00, 0x0f, 0x1c, 0x08, 0x00, // 8308 $2074 'foursuperior' + 0x00, 0x17, 0x15, 0x09, 0x00, // 8309 $2075 'fivesuperior' + 0x00, 0x0e, 0x15, 0x09, 0x00, // 8310 $2076 'sixsuperior' + 0x00, 0x01, 0x1d, 0x03, 0x00, // 8311 $2077 'sevensuperior' + 0x00, 0x0a, 0x15, 0x0a, 0x00, // 8312 $2078 'eightsuperior' + 0x00, 0x12, 0x15, 0x0e, 0x00, // 8313 $2079 'ninesuperior' + 0x00, 0x04, 0x0e, 0x04, 0x00, // 8314 $207a 'uni207A' + 0x00, 0x04, 0x04, 0x04, 0x00, // 8315 $207b 'uni207B' + 0x00, 0x0a, 0x0a, 0x0a, 0x00, // 8316 $207c 'uni207C' + 0x00, 0x0e, 0x11, 0x00, 0x00, // 8317 $207d 'parenleftsuperior' + 0x00, 0x11, 0x0e, 0x00, 0x00, // 8318 $207e 'parenrightsuperior' + 0x00, 0x1c, 0x04, 0x18, 0x00, // 8319 $207f 'nsuperior' + 0x00, 0x70, 0x88, 0x70, 0x00, // 8320 $2080 'zeroinferior' + 0x00, 0x90, 0xf8, 0x80, 0x00, // 8321 $2081 'oneinferior' + 0x00, 0x90, 0xc8, 0xb0, 0x00, // 8322 $2082 'twoinferior' + 0x00, 0xa8, 0xa8, 0x50, 0x00, // 8323 $2083 'threeinferior' + 0x00, 0x78, 0xe0, 0x40, 0x00, // 8324 $2084 'fourinferior' + 0x00, 0xb8, 0xa8, 0x48, 0x00, // 8325 $2085 'fiveinferior' + 0x00, 0x70, 0xa8, 0x48, 0x00, // 8326 $2086 'sixinferior' + 0x00, 0x08, 0xe8, 0x18, 0x00, // 8327 $2087 'seveninferior' + 0x00, 0x50, 0xa8, 0x50, 0x00, // 8328 $2088 'eightinferior' + 0x00, 0x90, 0xa8, 0x70, 0x00, // 8329 $2089 'nineinferior' + 0x00, 0x20, 0x70, 0x20, 0x00, // 8330 $208a 'uni208A' + 0x00, 0x20, 0x20, 0x20, 0x00, // 8331 $208b 'uni208B' + 0x00, 0x50, 0x50, 0x50, 0x00, // 8332 $208c 'uni208C' + 0x00, 0x70, 0x88, 0x00, 0x00, // 8333 $208d 'parenleftinferior' + 0x00, 0x88, 0x70, 0x00, 0x00, // 8334 $208e 'parenrightinferior' + 0x7e, 0x0a, 0x7a, 0x0a, 0x00, // 8355 $20a3 'franc' + 0x58, 0x3c, 0x5a, 0x24, 0x00, // 8356 $20a4 'lira' + 0x08, 0x7e, 0x1a, 0x1a, 0x0c, // 8359 $20a7 'peseta' + 0xb0, 0xc8, 0xcc, 0xfe, 0x04, // 8363 $20ab 'dong' + 0x14, 0x3e, 0x55, 0x41, 0x00, // 8364 $20ac 'Euro' + 0x62, 0x7f, 0x42, 0x3c, 0x00, // 8367 $20af 'uni20AF' + 0x02, 0x03, 0x02, 0x02, 0x00, // 8400 $20d0 'uni20D0' + 0x02, 0x02, 0x03, 0x02, 0x00, // 8401 $20d1 'uni20D1' + 0x00, 0x00, 0xff, 0x00, 0x00, // 8402 $20d2 'uni20D2' + 0x00, 0x00, 0xfc, 0x00, 0x00, // 8403 $20d3 'uni20D3' + 0x03, 0x03, 0x01, 0x02, 0x00, // 8404 $20d4 'uni20D4' + 0x02, 0x01, 0x03, 0x03, 0x00, // 8405 $20d5 'uni20D5' + 0x02, 0x07, 0x02, 0x02, 0x00, // 8406 $20d6 'uni20D6' + 0x02, 0x02, 0x07, 0x02, 0x00, // 8407 $20d7 'uni20D7' + 0x3c, 0x42, 0x7e, 0x24, 0x00, // 8450 $2102 'uni2102' + 0x46, 0x29, 0x3c, 0x4a, 0x30, // 8453 $2105 'afii61248' + 0x40, 0x3c, 0x52, 0x4c, 0x00, // 8467 $2113 'afii61289' + 0x7e, 0x7e, 0x18, 0x7e, 0x00, // 8469 $2115 'uni2115' + 0x7e, 0x02, 0x7c, 0x54, 0x48, // 8470 $2116 'afii61352' + 0x3c, 0x7e, 0x62, 0xbc, 0x00, // 8474 $211a 'uni211A' + 0x7e, 0x7e, 0x12, 0x6c, 0x00, // 8477 $211d 'uni211D' + 0x00, 0x71, 0x37, 0x71, 0x00, // 8482 $2122 'trademark' + 0x72, 0x4e, 0x72, 0x4e, 0x00, // 8484 $2124 'uni2124' + 0x5c, 0x62, 0x02, 0x62, 0x5c, // 8486 $2126 'Omega' + 0x3c, 0x7e, 0x4a, 0x2c, 0x00, // 8494 $212e 'estimated' + 0x1f, 0x28, 0x54, 0x28, 0x00, // 8539 $215b 'oneeighth' + 0x15, 0x0a, 0x28, 0x54, 0x28, // 8540 $215c 'threeeighths' + 0x17, 0x0d, 0x28, 0x54, 0x28, // 8541 $215d 'fiveeighths' + 0x19, 0x07, 0x28, 0x54, 0x28, // 8542 $215e 'seveneighths' + 0x10, 0x38, 0x54, 0x10, 0x10, // 8592 $2190 'arrowleft' + 0x08, 0x04, 0x7e, 0x04, 0x08, // 8593 $2191 'arrowup' + 0x10, 0x10, 0x54, 0x38, 0x10, // 8594 $2192 'arrowright' + 0x10, 0x20, 0x7e, 0x20, 0x10, // 8595 $2193 'arrowdown' + 0x10, 0x38, 0x10, 0x38, 0x10, // 8596 $2194 'arrowboth' + 0x00, 0x24, 0x7e, 0x24, 0x00, // 8597 $2195 'arrowupdn' + 0x0e, 0x06, 0x1a, 0x60, 0x00, // 8598 $2196 'uni2196' + 0x60, 0x1a, 0x06, 0x0e, 0x00, // 8599 $2197 'uni2197' + 0x06, 0x58, 0x60, 0x70, 0x00, // 8600 $2198 'uni2198' + 0x70, 0x60, 0x58, 0x06, 0x00, // 8601 $2199 'uni2199' + 0x10, 0x38, 0x54, 0x10, 0x38, // 8612 $21a4 'uni21A4' + 0x08, 0x44, 0x7e, 0x44, 0x08, // 8613 $21a5 'uni21A5' + 0x38, 0x10, 0x54, 0x38, 0x10, // 8614 $21a6 'uni21A6' + 0x10, 0x22, 0x7e, 0x22, 0x10, // 8615 $21a7 'uni21A7' + 0x00, 0xa4, 0xfe, 0xa4, 0x00, // 8616 $21a8 'arrowupdnbse' + 0x04, 0x0e, 0x04, 0x7c, 0x00, // 8624 $21b0 'uni21B0' + 0x7c, 0x04, 0x0e, 0x04, 0x00, // 8625 $21b1 'uni21B1' + 0x20, 0x70, 0x20, 0x3e, 0x00, // 8626 $21b2 'uni21B2' + 0x3e, 0x20, 0x70, 0x20, 0x00, // 8627 $21b3 'uni21B3' + 0x04, 0x24, 0x7c, 0x20, 0x00, // 8628 $21b4 'uni21B4' + 0x20, 0x70, 0x20, 0x3c, 0x00, // 8629 $21b5 'carriagereturn' + 0x10, 0x18, 0x14, 0x10, 0x10, // 8636 $21bc 'uni21BC' + 0x10, 0x30, 0x50, 0x10, 0x10, // 8637 $21bd 'uni21BD' + 0x00, 0x00, 0x7e, 0x04, 0x08, // 8638 $21be 'uni21BE' + 0x08, 0x04, 0x7e, 0x00, 0x00, // 8639 $21bf 'uni21BF' + 0x10, 0x10, 0x14, 0x18, 0x10, // 8640 $21c0 'uni21C0' + 0x10, 0x10, 0x50, 0x30, 0x10, // 8641 $21c1 'uni21C1' + 0x00, 0x00, 0x7e, 0x20, 0x10, // 8642 $21c2 'uni21C2' + 0x10, 0x20, 0x7e, 0x00, 0x00, // 8643 $21c3 'uni21C3' + 0x28, 0x2c, 0x68, 0x28, 0x00, // 8651 $21cb 'uni21CB' + 0x28, 0x68, 0x2c, 0x28, 0x00, // 8652 $21cc 'uni21CC' + 0x08, 0x14, 0x36, 0x14, 0x14, // 8656 $21d0 'arrowdblleft' + 0x08, 0x7c, 0x02, 0x7c, 0x08, // 8657 $21d1 'arrowdblup' + 0x14, 0x14, 0x36, 0x14, 0x08, // 8658 $21d2 'arrowdblright' + 0x10, 0x3e, 0x40, 0x3e, 0x10, // 8659 $21d3 'arrowdbldown' + 0x08, 0x14, 0x36, 0x14, 0x08, // 8660 $21d4 'arrowdblboth' + 0x28, 0x7c, 0x82, 0x7c, 0x28, // 8661 $21d5 'uni21D5' + 0x3c, 0x14, 0x2c, 0x54, 0x20, // 8662 $21d6 'uni21D6' + 0x20, 0x54, 0x2c, 0x14, 0x3c, // 8663 $21d7 'uni21D7' + 0x08, 0x54, 0x68, 0x50, 0x78, // 8664 $21d8 'uni21D8' + 0x78, 0x50, 0x68, 0x54, 0x08, // 8665 $21d9 'uni21D9' + 0x10, 0x28, 0x54, 0x00, 0x10, // 8672 $21e0 'uni21E0' + 0x08, 0x04, 0x56, 0x04, 0x08, // 8673 $21e1 'uni21E1' + 0x10, 0x00, 0x54, 0x28, 0x10, // 8674 $21e2 'uni21E2' + 0x10, 0x20, 0x6a, 0x20, 0x10, // 8675 $21e3 'uni21E3' + 0x7c, 0x38, 0x54, 0x10, 0x10, // 8676 $21e4 'uni21E4' + 0x10, 0x10, 0x54, 0x38, 0x7c, // 8677 $21e5 'uni21E5' + 0x08, 0x14, 0x36, 0x14, 0x1c, // 8678 $21e6 'uni21E6' + 0x08, 0x7c, 0x42, 0x7c, 0x08, // 8679 $21e7 'uni21E7' + 0x1c, 0x14, 0x36, 0x14, 0x08, // 8680 $21e8 'uni21E8' + 0x10, 0x3e, 0x42, 0x3e, 0x10, // 8681 $21e9 'uni21E9' + 0x3e, 0x48, 0x48, 0x3e, 0x00, // 8704 $2200 'universal' + 0x00, 0x3c, 0x42, 0x24, 0x00, // 8705 $2201 'uni2201' + 0x30, 0x4a, 0x52, 0x3c, 0x00, // 8706 $2202 'partialdiff' + 0x42, 0x4a, 0x4a, 0x7e, 0x00, // 8707 $2203 'existential' + 0x42, 0xfa, 0x4f, 0x7e, 0x00, // 8708 $2204 'uni2204' + 0x7c, 0x72, 0x4e, 0x3e, 0x00, // 8709 $2205 'emptyset' + 0x60, 0x58, 0x46, 0x58, 0x60, // 8710 $2206 'Delta' + 0x06, 0x1a, 0x62, 0x1a, 0x06, // 8711 $2207 'gradient' + 0x38, 0x54, 0x54, 0x44, 0x00, // 8712 $2208 'element' + 0x38, 0xf4, 0x5e, 0x44, 0x00, // 8713 $2209 'notelement' + 0x44, 0x54, 0x54, 0x38, 0x00, // 8715 $220b 'suchthat' + 0x44, 0xf4, 0x5e, 0x38, 0x00, // 8716 $220c 'uni220C' + 0x00, 0x3c, 0x3c, 0x3c, 0x00, // 8718 $220e 'uni220E' + 0x81, 0xff, 0x01, 0xff, 0x81, // 8719 $220f 'product' + 0x81, 0xff, 0x80, 0xff, 0x81, // 8720 $2210 'uni2210' + 0xc3, 0xa5, 0x99, 0x81, 0x81, // 8721 $2211 'summation' + 0x10, 0x10, 0x10, 0x10, 0x00, // 8722 $2212 'minus' + 0x00, 0x24, 0x74, 0x24, 0x00, // 8723 $2213 'uni2213' + 0x00, 0x20, 0x74, 0x20, 0x00, // 8724 $2214 'uni2214' + 0x40, 0x30, 0x0c, 0x02, 0x00, // 8725 $2215 'fraction' + 0x02, 0x0c, 0x30, 0x40, 0x00, // 8726 $2216 'uni2216' + 0x54, 0x38, 0x38, 0x54, 0x00, // 8727 $2217 'asteriskmath' + 0x00, 0x10, 0x28, 0x10, 0x00, // 8728 $2218 'uni2218' + 0x00, 0x10, 0x38, 0x10, 0x00, // 8729 $2219 'periodcentered' + 0x10, 0x30, 0xc0, 0x3f, 0x01, // 8730 $221a 'radical' + 0x18, 0x24, 0x18, 0x24, 0x00, // 8733 $221d 'proportional' + 0x18, 0x24, 0x18, 0x24, 0x18, // 8734 $221e 'infinity' + 0x78, 0x40, 0x40, 0x40, 0x00, // 8735 $221f 'orthogonal' + 0x60, 0x50, 0x48, 0x44, 0x00, // 8736 $2220 'angle' + 0x68, 0x50, 0xe8, 0x44, 0x00, // 8737 $2221 'uni2221' + 0x5a, 0x24, 0x3c, 0x42, 0x00, // 8738 $2222 'uni2222' + 0x00, 0x00, 0x7e, 0x00, 0x00, // 8739 $2223 'uni2223' + 0x00, 0x10, 0x7e, 0x08, 0x00, // 8740 $2224 'uni2224' + 0x00, 0x7e, 0x00, 0x7e, 0x00, // 8741 $2225 'uni2225' + 0x10, 0x7e, 0x08, 0x7e, 0x04, // 8742 $2226 'uni2226' + 0x60, 0x18, 0x18, 0x60, 0x00, // 8743 $2227 'logicaland' + 0x18, 0x60, 0x60, 0x18, 0x00, // 8744 $2228 'logicalor' + 0x70, 0x08, 0x08, 0x70, 0x00, // 8745 $2229 'intersection' + 0x38, 0x40, 0x40, 0x38, 0x00, // 8746 $222a 'union' + 0x40, 0x80, 0x7e, 0x01, 0x02, // 8747 $222b 'integral' + 0x40, 0x98, 0x7e, 0x19, 0x02, // 8750 $222e 'uni222E' + 0x00, 0x20, 0x08, 0x20, 0x00, // 8756 $2234 'therefore' + 0x00, 0x08, 0x20, 0x08, 0x00, // 8757 $2235 'uni2235' + 0x00, 0x00, 0x28, 0x00, 0x00, // 8758 $2236 'uni2236' + 0x00, 0x28, 0x00, 0x28, 0x00, // 8759 $2237 'uni2237' + 0x10, 0x14, 0x14, 0x10, 0x00, // 8760 $2238 'uni2238' + 0x10, 0x10, 0x00, 0x28, 0x00, // 8761 $2239 'uni2239' + 0x54, 0x10, 0x10, 0x54, 0x00, // 8762 $223a 'uni223A' + 0x10, 0x48, 0x12, 0x08, 0x00, // 8763 $223b 'uni223B' + 0x10, 0x08, 0x10, 0x08, 0x00, // 8764 $223c 'similar' + 0x08, 0x10, 0x08, 0x10, 0x00, // 8765 $223d 'uni223D' + 0x00, 0x32, 0x4c, 0x00, 0x00, // 8768 $2240 'uni2240' + 0x48, 0x28, 0x48, 0x28, 0x00, // 8770 $2242 'uni2242' + 0x50, 0x48, 0x50, 0x48, 0x00, // 8771 $2243 'uni2243' + 0x54, 0x52, 0x54, 0x52, 0x00, // 8773 $2245 'congruent' + 0x50, 0x28, 0x50, 0x28, 0x00, // 8776 $2248 'approxequal' + 0x50, 0xe8, 0x5c, 0x28, 0x00, // 8777 $2249 'uni2249' + 0x54, 0x4a, 0x54, 0x4a, 0x00, // 8778 $224a 'uni224A' + 0x54, 0x2a, 0x54, 0x2a, 0x00, // 8779 $224b 'uni224B' + 0x54, 0x52, 0x52, 0x54, 0x00, // 8792 $2258 'uni2258' + 0x50, 0x54, 0x52, 0x54, 0x00, // 8793 $2259 'uni2259' + 0x50, 0x52, 0x54, 0x52, 0x00, // 8794 $225a 'uni225A' + 0xa0, 0xb5, 0xa2, 0xa0, 0x00, // 8799 $225f 'uni225F' + 0x28, 0x78, 0x3c, 0x28, 0x00, // 8800 $2260 'notequal' + 0x54, 0x54, 0x54, 0x54, 0x00, // 8801 $2261 'equivalence' + 0xd4, 0x74, 0x5c, 0x56, 0x00, // 8802 $2262 'uni2262' + 0x55, 0x55, 0x55, 0x55, 0x00, // 8803 $2263 'uni2263' + 0x00, 0x48, 0x54, 0x62, 0x00, // 8804 $2264 'lessequal' + 0x00, 0x62, 0x54, 0x48, 0x00, // 8805 $2265 'greaterequal' + 0x10, 0x28, 0x54, 0x28, 0x44, // 8810 $226a 'uni226A' + 0x44, 0x28, 0x54, 0x28, 0x10, // 8811 $226b 'uni226B' + 0x10, 0x28, 0x28, 0x28, 0x00, // 8834 $2282 'propersubset' + 0x28, 0x28, 0x28, 0x10, 0x00, // 8835 $2283 'propersuperset' + 0x10, 0x28, 0x7c, 0x28, 0x00, // 8836 $2284 'notsubset' + 0x28, 0x7c, 0x28, 0x10, 0x00, // 8837 $2285 'uni2285' + 0x48, 0x54, 0x54, 0x54, 0x00, // 8838 $2286 'reflexsubset' + 0x54, 0x54, 0x54, 0x48, 0x00, // 8839 $2287 'reflexsuperset' + 0x48, 0x54, 0xfe, 0x54, 0x00, // 8840 $2288 'uni2288' + 0x54, 0xfe, 0x54, 0x48, 0x00, // 8841 $2289 'uni2289' + 0x48, 0xd4, 0x74, 0x54, 0x00, // 8842 $228a 'uni228A' + 0x54, 0xd4, 0x74, 0x48, 0x00, // 8843 $228b 'uni228B' + 0x38, 0x54, 0x7c, 0x54, 0x38, // 8853 $2295 'circleplus' + 0x38, 0x54, 0x54, 0x54, 0x38, // 8854 $2296 'uni2296' + 0x38, 0x6c, 0x54, 0x6c, 0x38, // 8855 $2297 'circlemultiply' + 0x38, 0x64, 0x54, 0x4c, 0x38, // 8856 $2298 'uni2298' + 0x38, 0x44, 0x54, 0x44, 0x38, // 8857 $2299 'uni2299' + 0x7c, 0x54, 0x7c, 0x54, 0x7c, // 8862 $229e 'uni229E' + 0x7c, 0x54, 0x54, 0x54, 0x7c, // 8863 $229f 'uni229F' + 0x7c, 0x6c, 0x54, 0x6c, 0x7c, // 8864 $22a0 'uni22A0' + 0x7c, 0x44, 0x54, 0x44, 0x7c, // 8865 $22a1 'uni22A1' + 0x7c, 0x10, 0x10, 0x10, 0x00, // 8866 $22a2 'uni22A2' + 0x10, 0x10, 0x10, 0x7c, 0x00, // 8867 $22a3 'uni22A3' + 0x02, 0x02, 0x7e, 0x02, 0x02, // 8868 $22a4 'uni22A4' + 0x40, 0x40, 0x7e, 0x40, 0x40, // 8869 $22a5 'perpendicular' + 0x00, 0x7c, 0x10, 0x10, 0x00, // 8870 $22a6 'uni22A6' + 0x00, 0x7c, 0x28, 0x28, 0x00, // 8871 $22a7 'uni22A7' + 0x7c, 0x28, 0x28, 0x28, 0x00, // 8872 $22a8 'uni22A8' + 0xe0, 0x1c, 0x03, 0x1c, 0xe0, // 8896 $22c0 'uni22C0' + 0x07, 0x38, 0xc0, 0x38, 0x07, // 8897 $22c1 'uni22C1' + 0xfc, 0x02, 0x01, 0x02, 0xfc, // 8898 $22c2 'uni22C2' + 0x3f, 0x40, 0x80, 0x40, 0x3f, // 8899 $22c3 'uni22C3' + 0x00, 0x00, 0x10, 0x00, 0x00, // 8901 $22c5 'dotmath' + 0x50, 0x28, 0x50, 0x28, 0x00, // 8960 $2300 'uni2300' + 0x7c, 0x42, 0x42, 0x7c, 0x00, // 8962 $2302 'house' + 0x00, 0x7e, 0x02, 0x02, 0x00, // 8968 $2308 'uni2308' + 0x00, 0x02, 0x02, 0x7e, 0x00, // 8969 $2309 'uni2309' + 0x00, 0x7e, 0x40, 0x40, 0x00, // 8970 $230a 'uni230A' + 0x00, 0x40, 0x40, 0x7e, 0x00, // 8971 $230b 'uni230B' + 0x00, 0x70, 0x10, 0x10, 0x00, // 8976 $2310 'revlogicalnot' + 0x70, 0x68, 0x48, 0x30, 0x00, // 8981 $2315 'uni2315' + 0x00, 0x00, 0xfc, 0x02, 0x04, // 8992 $2320 'integraltp' + 0x20, 0x40, 0x3f, 0x00, 0x00, // 8993 $2321 'integralbt' + 0x01, 0x01, 0x01, 0x01, 0x01, // 9146 $23ba 'uni23BA' + 0x02, 0x02, 0x02, 0x02, 0x02, // 9147 $23bb 'uni23BB' + 0x40, 0x40, 0x40, 0x40, 0x40, // 9148 $23bc 'uni23BC' + 0x80, 0x80, 0x80, 0x80, 0x80, // 9149 $23bd 'uni23BD' + 0x1f, 0x24, 0xff, 0x20, 0x00, // 9225 $2409 'uni2409' + 0x0f, 0x08, 0xf8, 0x50, 0x10, // 9226 $240a 'uni240A' + 0x07, 0x08, 0x17, 0xf0, 0x10, // 9227 $240b 'uni240B' + 0x1f, 0x05, 0xf9, 0x28, 0x08, // 9228 $240c 'uni240C' + 0x06, 0x09, 0xf9, 0x50, 0xa0, // 9229 $240d 'uni240D' + 0x0f, 0x02, 0xf4, 0x8f, 0x80, // 9252 $2424 'uni2424' + 0x08, 0x08, 0x08, 0x08, 0x08, // 9472 $2500 'SF100000' + 0x18, 0x18, 0x18, 0x18, 0x18, // 9473 $2501 'uni2501' + 0x00, 0x00, 0xff, 0x00, 0x00, // 9474 $2502 'SF110000' + 0x00, 0x00, 0xff, 0xff, 0x00, // 9475 $2503 'uni2503' + 0x08, 0x00, 0x08, 0x00, 0x08, // 9476 $2504 'uni2504' + 0x18, 0x00, 0x18, 0x00, 0x18, // 9477 $2505 'uni2505' + 0x00, 0x00, 0xdb, 0x00, 0x00, // 9478 $2506 'uni2506' + 0x00, 0x00, 0xdb, 0xdb, 0x00, // 9479 $2507 'uni2507' + 0x08, 0x00, 0x08, 0x00, 0x08, // 9480 $2508 'uni2508' + 0x18, 0x00, 0x18, 0x00, 0x18, // 9481 $2509 'uni2509' + 0x00, 0x00, 0x55, 0x00, 0x00, // 9482 $250a 'uni250A' + 0x00, 0x00, 0x55, 0x55, 0x00, // 9483 $250b 'uni250B' + 0x00, 0x00, 0xf8, 0x08, 0x08, // 9484 $250c 'SF010000' + 0x00, 0x00, 0xf8, 0x18, 0x18, // 9485 $250d 'uni250D' + 0x00, 0x00, 0xf8, 0xf8, 0x08, // 9486 $250e 'uni250E' + 0x00, 0x00, 0xf8, 0xf8, 0x18, // 9487 $250f 'uni250F' + 0x08, 0x08, 0xf8, 0x00, 0x00, // 9488 $2510 'SF030000' + 0x18, 0x18, 0xf8, 0x00, 0x00, // 9489 $2511 'uni2511' + 0x08, 0x08, 0xf8, 0xf8, 0x00, // 9490 $2512 'uni2512' + 0x18, 0x18, 0xf8, 0xf8, 0x00, // 9491 $2513 'uni2513' + 0x00, 0x00, 0x0f, 0x08, 0x08, // 9492 $2514 'SF020000' + 0x00, 0x00, 0x1f, 0x18, 0x18, // 9493 $2515 'uni2515' + 0x00, 0x00, 0x0f, 0x0f, 0x08, // 9494 $2516 'uni2516' + 0x00, 0x00, 0x1f, 0x1f, 0x18, // 9495 $2517 'uni2517' + 0x08, 0x08, 0x0f, 0x00, 0x00, // 9496 $2518 'SF040000' + 0x18, 0x18, 0x1f, 0x00, 0x00, // 9497 $2519 'uni2519' + 0x08, 0x08, 0x0f, 0x0f, 0x00, // 9498 $251a 'uni251A' + 0x18, 0x18, 0x1f, 0x1f, 0x00, // 9499 $251b 'uni251B' + 0x00, 0x00, 0xff, 0x08, 0x08, // 9500 $251c 'SF080000' + 0x00, 0x00, 0xff, 0x18, 0x18, // 9501 $251d 'uni251D' + 0x00, 0x00, 0xff, 0x0f, 0x08, // 9502 $251e 'uni251E' + 0x00, 0x00, 0xff, 0xf8, 0x08, // 9503 $251f 'uni251F' + 0x00, 0x00, 0xff, 0xff, 0x08, // 9504 $2520 'uni2520' + 0x00, 0x00, 0xff, 0x1f, 0x18, // 9505 $2521 'uni2521' + 0x00, 0x00, 0xff, 0xf8, 0x18, // 9506 $2522 'uni2522' + 0x00, 0x00, 0xff, 0xff, 0x18, // 9507 $2523 'uni2523' + 0x08, 0x08, 0xff, 0x00, 0x00, // 9508 $2524 'SF090000' + 0x18, 0x18, 0xff, 0x00, 0x00, // 9509 $2525 'uni2525' + 0x08, 0x08, 0xff, 0x0f, 0x00, // 9510 $2526 'uni2526' + 0x08, 0x08, 0xff, 0xf8, 0x00, // 9511 $2527 'uni2527' + 0x08, 0x08, 0xff, 0xff, 0x00, // 9512 $2528 'uni2528' + 0x18, 0x18, 0xff, 0x1f, 0x00, // 9513 $2529 'uni2529' + 0x18, 0x18, 0xff, 0xf8, 0x00, // 9514 $252a 'uni252A' + 0x18, 0x18, 0xff, 0xff, 0x00, // 9515 $252b 'uni252B' + 0x08, 0x08, 0xf8, 0x08, 0x08, // 9516 $252c 'SF060000' + 0x18, 0x18, 0xf8, 0x08, 0x08, // 9517 $252d 'uni252D' + 0x08, 0x08, 0xf8, 0x18, 0x18, // 9518 $252e 'uni252E' + 0x18, 0x18, 0xf8, 0x18, 0x18, // 9519 $252f 'uni252F' + 0x08, 0x08, 0xf8, 0xf8, 0x08, // 9520 $2530 'uni2530' + 0x18, 0x18, 0xf8, 0xf8, 0x08, // 9521 $2531 'uni2531' + 0x08, 0x08, 0xf8, 0xf8, 0x18, // 9522 $2532 'uni2532' + 0x18, 0x18, 0xf8, 0xf8, 0x18, // 9523 $2533 'uni2533' + 0x08, 0x08, 0x0f, 0x08, 0x08, // 9524 $2534 'SF070000' + 0x18, 0x18, 0x1f, 0x08, 0x08, // 9525 $2535 'uni2535' + 0x08, 0x08, 0x1f, 0x18, 0x18, // 9526 $2536 'uni2536' + 0x18, 0x18, 0x1f, 0x18, 0x18, // 9527 $2537 'uni2537' + 0x08, 0x08, 0x0f, 0x0f, 0x08, // 9528 $2538 'uni2538' + 0x18, 0x18, 0x1f, 0x1f, 0x08, // 9529 $2539 'uni2539' + 0x08, 0x08, 0x1f, 0x1f, 0x18, // 9530 $253a 'uni253A' + 0x18, 0x18, 0x1f, 0x1f, 0x18, // 9531 $253b 'uni253B' + 0x08, 0x08, 0xff, 0x08, 0x08, // 9532 $253c 'SF050000' + 0x18, 0x18, 0xff, 0x08, 0x08, // 9533 $253d 'uni253D' + 0x08, 0x08, 0xff, 0x18, 0x18, // 9534 $253e 'uni253E' + 0x18, 0x18, 0xff, 0x18, 0x18, // 9535 $253f 'uni253F' + 0x08, 0x08, 0xff, 0x0f, 0x08, // 9536 $2540 'uni2540' + 0x08, 0x08, 0xff, 0xf8, 0x08, // 9537 $2541 'uni2541' + 0x08, 0x08, 0xff, 0xff, 0x08, // 9538 $2542 'uni2542' + 0x18, 0x18, 0xff, 0x1f, 0x08, // 9539 $2543 'uni2543' + 0x08, 0x08, 0xff, 0x1f, 0x18, // 9540 $2544 'uni2544' + 0x18, 0x18, 0xff, 0xf8, 0x08, // 9541 $2545 'uni2545' + 0x08, 0x08, 0xff, 0xf8, 0x18, // 9542 $2546 'uni2546' + 0x18, 0x18, 0xff, 0x1f, 0x18, // 9543 $2547 'uni2547' + 0x18, 0x18, 0xff, 0xf8, 0x18, // 9544 $2548 'uni2548' + 0x18, 0x18, 0xff, 0xff, 0x08, // 9545 $2549 'uni2549' + 0x08, 0x08, 0xff, 0xff, 0x18, // 9546 $254a 'uni254A' + 0x18, 0x18, 0xff, 0xff, 0x18, // 9547 $254b 'uni254B' + 0x08, 0x00, 0x08, 0x08, 0x00, // 9548 $254c 'uni254C' + 0x18, 0x00, 0x18, 0x18, 0x00, // 9549 $254d 'uni254D' + 0x00, 0x00, 0x77, 0x00, 0x00, // 9550 $254e 'uni254E' + 0x00, 0x00, 0x77, 0x77, 0x00, // 9551 $254f 'uni254F' + 0x14, 0x14, 0x14, 0x14, 0x14, // 9552 $2550 'SF430000' + 0x00, 0xff, 0x00, 0xff, 0x00, // 9553 $2551 'SF240000' + 0x00, 0x00, 0xfc, 0x14, 0x14, // 9554 $2552 'SF510000' + 0x00, 0xf8, 0x08, 0xf8, 0x08, // 9555 $2553 'SF520000' + 0x00, 0xfc, 0x04, 0xf4, 0x14, // 9556 $2554 'SF390000' + 0x14, 0x14, 0xfc, 0x00, 0x00, // 9557 $2555 'SF220000' + 0x08, 0xf8, 0x08, 0xf8, 0x00, // 9558 $2556 'SF210000' + 0x14, 0xf4, 0x04, 0xfc, 0x00, // 9559 $2557 'SF250000' + 0x00, 0x00, 0x1f, 0x14, 0x14, // 9560 $2558 'SF500000' + 0x00, 0x0f, 0x08, 0x0f, 0x08, // 9561 $2559 'SF490000' + 0x00, 0x1f, 0x10, 0x17, 0x14, // 9562 $255a 'SF380000' + 0x14, 0x14, 0x1f, 0x00, 0x00, // 9563 $255b 'SF280000' + 0x08, 0x0f, 0x08, 0x0f, 0x00, // 9564 $255c 'SF270000' + 0x14, 0x17, 0x10, 0x1f, 0x00, // 9565 $255d 'SF260000' + 0x00, 0x00, 0xff, 0x14, 0x14, // 9566 $255e 'SF360000' + 0x00, 0xff, 0x00, 0xff, 0x08, // 9567 $255f 'SF370000' + 0x00, 0xff, 0x00, 0xf7, 0x14, // 9568 $2560 'SF420000' + 0x14, 0x14, 0xff, 0x00, 0x00, // 9569 $2561 'SF190000' + 0x08, 0xff, 0x00, 0xff, 0x00, // 9570 $2562 'SF200000' + 0x14, 0xf7, 0x00, 0xff, 0x00, // 9571 $2563 'SF230000' + 0x14, 0x14, 0xf4, 0x14, 0x14, // 9572 $2564 'SF470000' + 0x08, 0xf8, 0x08, 0xf8, 0x08, // 9573 $2565 'SF480000' + 0x14, 0xf4, 0x04, 0xf4, 0x14, // 9574 $2566 'SF410000' + 0x14, 0x14, 0x17, 0x14, 0x14, // 9575 $2567 'SF450000' + 0x08, 0x0f, 0x08, 0x0f, 0x08, // 9576 $2568 'SF460000' + 0x14, 0x17, 0x10, 0x17, 0x14, // 9577 $2569 'SF400000' + 0x14, 0x14, 0xff, 0x14, 0x14, // 9578 $256a 'SF540000' + 0x08, 0xff, 0x08, 0xff, 0x08, // 9579 $256b 'SF530000' + 0x14, 0xf7, 0x00, 0xf7, 0x14, // 9580 $256c 'SF440000' + 0x00, 0x00, 0xf0, 0x08, 0x08, // 9581 $256d 'uni256D' + 0x08, 0x08, 0xf0, 0x00, 0x00, // 9582 $256e 'uni256E' + 0x08, 0x08, 0x07, 0x00, 0x00, // 9583 $256f 'uni256F' + 0x00, 0x00, 0x07, 0x08, 0x08, // 9584 $2570 'uni2570' + 0x80, 0x60, 0x18, 0x06, 0x01, // 9585 $2571 'uni2571' + 0x01, 0x06, 0x18, 0x60, 0x80, // 9586 $2572 'uni2572' + 0x81, 0x66, 0x18, 0x66, 0x81, // 9587 $2573 'uni2573' + 0x08, 0x08, 0x08, 0x00, 0x00, // 9588 $2574 'uni2574' + 0x00, 0x00, 0x0f, 0x00, 0x00, // 9589 $2575 'uni2575' + 0x00, 0x00, 0x08, 0x08, 0x08, // 9590 $2576 'uni2576' + 0x00, 0x00, 0xf8, 0x00, 0x00, // 9591 $2577 'uni2577' + 0x18, 0x18, 0x18, 0x00, 0x00, // 9592 $2578 'uni2578' + 0x00, 0x00, 0x0f, 0x0f, 0x00, // 9593 $2579 'uni2579' + 0x00, 0x00, 0x18, 0x18, 0x18, // 9594 $257a 'uni257A' + 0x00, 0x00, 0xf8, 0xf8, 0x00, // 9595 $257b 'uni257B' + 0x08, 0x08, 0x18, 0x18, 0x18, // 9596 $257c 'uni257C' + 0x00, 0x00, 0xff, 0xf8, 0x00, // 9597 $257d 'uni257D' + 0x18, 0x18, 0x18, 0x08, 0x08, // 9598 $257e 'uni257E' + 0x00, 0x00, 0xff, 0x1f, 0x00, // 9599 $257f 'uni257F' + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, // 9600 $2580 'upblock' + 0x80, 0x80, 0x80, 0x80, 0x80, // 9601 $2581 'uni2581' + 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, // 9602 $2582 'uni2582' + 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, // 9603 $2583 'uni2583' + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 9604 $2584 'dnblock' + 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, // 9605 $2585 'uni2585' + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, // 9606 $2586 'uni2586' + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, // 9607 $2587 'uni2587' + 0xff, 0xff, 0xff, 0xff, 0xff, // 9608 $2588 'block' + 0xff, 0xff, 0xff, 0xff, 0x00, // 9609 $2589 'uni2589' + 0xff, 0xff, 0xff, 0xff, 0x00, // 9610 $258a 'uni258A' + 0xff, 0xff, 0xff, 0x00, 0x00, // 9611 $258b 'uni258B' + 0xff, 0xff, 0xff, 0x00, 0x00, // 9612 $258c 'lfblock' + 0xff, 0xff, 0x00, 0x00, 0x00, // 9613 $258d 'uni258D' + 0xff, 0xff, 0x00, 0x00, 0x00, // 9614 $258e 'uni258E' + 0xff, 0x00, 0x00, 0x00, 0x00, // 9615 $258f 'uni258F' + 0x00, 0x00, 0x00, 0xff, 0xff, // 9616 $2590 'rtblock' + 0x11, 0x44, 0x11, 0x44, 0x11, // 9617 $2591 'ltshade' + 0xaa, 0x55, 0xaa, 0x55, 0xaa, // 9618 $2592 'shade' + 0xee, 0xbb, 0xee, 0xbb, 0xee, // 9619 $2593 'dkshade' + 0x01, 0x01, 0x01, 0x01, 0x01, // 9620 $2594 'uni2594' + 0x00, 0x00, 0x00, 0x00, 0xff, // 9621 $2595 'uni2595' + 0xf0, 0xf0, 0xf0, 0x00, 0x00, // 9622 $2596 'uni2596' + 0x00, 0x00, 0x00, 0xf0, 0xf0, // 9623 $2597 'uni2597' + 0x0f, 0x0f, 0x0f, 0x00, 0x00, // 9624 $2598 'uni2598' + 0xff, 0xff, 0xff, 0xf0, 0xf0, // 9625 $2599 'uni2599' + 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, // 9626 $259a 'uni259A' + 0xff, 0xff, 0xff, 0x0f, 0x0f, // 9627 $259b 'uni259B' + 0x0f, 0x0f, 0x0f, 0xff, 0xff, // 9628 $259c 'uni259C' + 0x00, 0x00, 0x00, 0x0f, 0x0f, // 9629 $259d 'uni259D' + 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, // 9630 $259e 'uni259E' + 0xf0, 0xf0, 0xf0, 0xff, 0xff, // 9631 $259f 'uni259F' + 0x78, 0x78, 0x78, 0x78, 0x00, // 9632 $25a0 'filledbox' + 0x78, 0x48, 0x48, 0x78, 0x00, // 9633 $25a1 'H22073' + 0x30, 0x48, 0x48, 0x30, 0x00, // 9634 $25a2 'uni25A2' + 0x78, 0x58, 0x68, 0x78, 0x00, // 9639 $25a7 'uni25A7' + 0x78, 0x68, 0x58, 0x78, 0x00, // 9640 $25a8 'uni25A8' + 0x00, 0x38, 0x38, 0x38, 0x00, // 9642 $25aa 'H18543' + 0x00, 0x38, 0x28, 0x38, 0x00, // 9643 $25ab 'H18551' + 0x38, 0x38, 0x38, 0x38, 0x00, // 9644 $25ac 'filledrect' + 0x38, 0x28, 0x28, 0x38, 0x00, // 9645 $25ad 'uni25AD' + 0x00, 0x7e, 0x7e, 0x7e, 0x00, // 9646 $25ae 'uni25AE' + 0x00, 0x7e, 0x42, 0x7e, 0x00, // 9647 $25af 'uni25AF' + 0x20, 0x30, 0x38, 0x18, 0x08, // 9648 $25b0 'uni25B0' + 0x20, 0x30, 0x28, 0x18, 0x08, // 9649 $25b1 'uni25B1' + 0x60, 0x78, 0x7e, 0x78, 0x60, // 9650 $25b2 'triagup' + 0x60, 0x58, 0x46, 0x58, 0x60, // 9651 $25b3 'uni25B3' + 0x00, 0x30, 0x3c, 0x30, 0x00, // 9652 $25b4 'uni25B4' + 0x00, 0x30, 0x2c, 0x30, 0x00, // 9653 $25b5 'uni25B5' + 0x00, 0x7e, 0x3c, 0x18, 0x00, // 9654 $25b6 'uni25B6' + 0x00, 0x7e, 0x24, 0x18, 0x00, // 9655 $25b7 'uni25B7' + 0x00, 0x7c, 0x38, 0x10, 0x00, // 9656 $25b8 'uni25B8' + 0x00, 0x7c, 0x28, 0x10, 0x00, // 9657 $25b9 'uni25B9' + 0x7c, 0x38, 0x38, 0x10, 0x10, // 9658 $25ba 'triagrt' + 0x7c, 0x28, 0x28, 0x10, 0x10, // 9659 $25bb 'uni25BB' + 0x06, 0x1e, 0x7e, 0x1e, 0x06, // 9660 $25bc 'triagdn' + 0x06, 0x1a, 0x62, 0x1a, 0x06, // 9661 $25bd 'uni25BD' + 0x00, 0x0c, 0x3c, 0x0c, 0x00, // 9662 $25be 'uni25BE' + 0x00, 0x0c, 0x34, 0x0c, 0x00, // 9663 $25bf 'uni25BF' + 0x00, 0x18, 0x3c, 0x7e, 0x00, // 9664 $25c0 'uni25C0' + 0x00, 0x18, 0x24, 0x7e, 0x00, // 9665 $25c1 'uni25C1' + 0x00, 0x10, 0x38, 0x7c, 0x00, // 9666 $25c2 'uni25C2' + 0x00, 0x10, 0x28, 0x7c, 0x00, // 9667 $25c3 'uni25C3' + 0x10, 0x10, 0x38, 0x38, 0x7c, // 9668 $25c4 'triaglf' + 0x10, 0x10, 0x28, 0x28, 0x7c, // 9669 $25c5 'uni25C5' + 0x10, 0x38, 0x7c, 0x38, 0x10, // 9670 $25c6 'uni25C6' + 0x10, 0x28, 0x44, 0x28, 0x10, // 9671 $25c7 'uni25C7' + 0x08, 0x36, 0x41, 0x36, 0x08, // 9674 $25ca 'lozenge' + 0x38, 0x44, 0x44, 0x44, 0x38, // 9675 $25cb 'circle' + 0x10, 0x44, 0x00, 0x44, 0x10, // 9676 $25cc 'uni25CC' + 0x38, 0x44, 0x7c, 0x44, 0x38, // 9677 $25cd 'uni25CD' + 0x38, 0x54, 0x6c, 0x54, 0x38, // 9678 $25ce 'uni25CE' + 0x38, 0x7c, 0x7c, 0x7c, 0x38, // 9679 $25cf 'H18533' + 0x38, 0x7c, 0x7c, 0x44, 0x38, // 9680 $25d0 'uni25D0' + 0x38, 0x44, 0x7c, 0x7c, 0x38, // 9681 $25d1 'uni25D1' + 0x38, 0x74, 0x74, 0x74, 0x38, // 9682 $25d2 'uni25D2' + 0x38, 0x5c, 0x5c, 0x5c, 0x38, // 9683 $25d3 'uni25D3' + 0x38, 0x44, 0x5c, 0x5c, 0x38, // 9684 $25d4 'uni25D4' + 0x38, 0x64, 0x64, 0x7c, 0x38, // 9685 $25d5 'uni25D5' + 0xff, 0xe7, 0xc3, 0xe7, 0xff, // 9688 $25d8 'invbullet' + 0xe7, 0xdb, 0xbd, 0xdb, 0xe7, // 9689 $25d9 'invcircle' + 0x07, 0x0b, 0x0d, 0x0b, 0x07, // 9690 $25da 'uni25DA' + 0xe0, 0xd0, 0xb0, 0xd0, 0xe0, // 9691 $25db 'uni25DB' + 0x40, 0x60, 0x70, 0x78, 0x00, // 9698 $25e2 'uni25E2' + 0x78, 0x70, 0x60, 0x40, 0x00, // 9699 $25e3 'uni25E3' + 0x78, 0x38, 0x18, 0x08, 0x00, // 9700 $25e4 'uni25E4' + 0x08, 0x18, 0x38, 0x78, 0x00, // 9701 $25e5 'uni25E5' + 0x30, 0x48, 0x48, 0x30, 0x00, // 9702 $25e6 'openbullet' + 0x78, 0x78, 0x48, 0x78, 0x00, // 9703 $25e7 'uni25E7' + 0x78, 0x48, 0x78, 0x78, 0x00, // 9704 $25e8 'uni25E8' + 0x78, 0x78, 0x58, 0x78, 0x00, // 9705 $25e9 'uni25E9' + 0x78, 0x68, 0x78, 0x78, 0x00, // 9706 $25ea 'uni25EA' + 0x08, 0x0a, 0xfd, 0x0a, 0x08, // 9765 $2625 'uni2625' + 0x08, 0x4a, 0xff, 0x2a, 0x08, // 9766 $2626 'uni2626' + 0x50, 0x20, 0x7f, 0x25, 0x52, // 9767 $2627 'uni2627' + 0x08, 0x0a, 0xff, 0x0a, 0x08, // 9768 $2628 'uni2628' + 0x1c, 0x49, 0x7f, 0x49, 0x1c, // 9769 $2629 'uni2629' + 0x00, 0x54, 0x54, 0x54, 0x00, // 9776 $2630 'uni2630' + 0x00, 0x54, 0x50, 0x54, 0x00, // 9777 $2631 'uni2631' + 0x00, 0x54, 0x44, 0x54, 0x00, // 9778 $2632 'uni2632' + 0x00, 0x54, 0x40, 0x54, 0x00, // 9779 $2633 'uni2633' + 0x00, 0x54, 0x14, 0x54, 0x00, // 9780 $2634 'uni2634' + 0x00, 0x54, 0x10, 0x54, 0x00, // 9781 $2635 'uni2635' + 0x00, 0x54, 0x04, 0x54, 0x00, // 9782 $2636 'uni2636' + 0x00, 0x54, 0x00, 0x54, 0x00, // 9783 $2637 'uni2637' + 0x44, 0x38, 0xee, 0x38, 0x44, // 9784 $2638 'uni2638' + 0x7c, 0x8a, 0xa2, 0x8a, 0x7c, // 9786 $263a 'smileface' + 0x3c, 0x6a, 0x5e, 0x6a, 0x3c, // 9787 $263b 'invsmileface' + 0x44, 0x10, 0xaa, 0x10, 0x44, // 9788 $263c 'sun' + 0x24, 0x66, 0x5a, 0x42, 0x3c, // 9789 $263d 'uni263D' + 0x3c, 0x42, 0x5a, 0x66, 0x24, // 9790 $263e 'uni263E' + 0x0c, 0x52, 0xf2, 0x52, 0x0c, // 9792 $2640 'female' + 0x60, 0x94, 0x9e, 0x94, 0x60, // 9793 $2641 'uni2641' + 0x60, 0x90, 0x94, 0x6c, 0x1c, // 9794 $2642 'male' + 0x10, 0x58, 0x7e, 0x58, 0x10, // 9824 $2660 'spade' + 0x0c, 0x12, 0x64, 0x12, 0x0c, // 9825 $2661 'uni2661' + 0x08, 0x14, 0x22, 0x14, 0x08, // 9826 $2662 'uni2662' + 0x38, 0x54, 0x7e, 0x54, 0x38, // 9827 $2663 'club' + 0x10, 0x5c, 0x72, 0x5c, 0x10, // 9828 $2664 'uni2664' + 0x0c, 0x1e, 0x7c, 0x1e, 0x0c, // 9829 $2665 'heart' + 0x08, 0x1c, 0x3e, 0x1c, 0x08, // 9830 $2666 'diamond' + 0x08, 0x54, 0x7e, 0x54, 0x08, // 9831 $2667 'uni2667' + 0x00, 0x20, 0x70, 0x7e, 0x00, // 9833 $2669 'uni2669' + 0x20, 0x70, 0x7e, 0x02, 0x04, // 9834 $266a 'musicalnote' + 0x18, 0x1f, 0x62, 0x7c, 0x00, // 9835 $266b 'musicalnotedbl' + 0x18, 0x1f, 0x6a, 0x7c, 0x00, // 9836 $266c 'uni266C' + 0x7e, 0x48, 0x24, 0x18, 0x00, // 9837 $266d 'uni266D' + 0x3f, 0x28, 0x14, 0xfc, 0x00, // 9838 $266e 'uni266E' + 0x28, 0x7e, 0x14, 0x3f, 0x12, // 9839 $266f 'uni266F' + 0x00, 0x18, 0x66, 0x00, 0x00, // 10216 $27e8 'uni27E8' + 0x00, 0x66, 0x18, 0x00, 0x00, // 10217 $27e9 'uni27E9' + 0x00, 0x00, 0x00, 0x00, 0x00, // 10240 $2800 'uni2800' + 0x00, 0x02, 0x00, 0x00, 0x00, // 10241 $2801 'uni2801' + 0x00, 0x08, 0x00, 0x00, 0x00, // 10242 $2802 'uni2802' + 0x00, 0x0a, 0x00, 0x00, 0x00, // 10243 $2803 'uni2803' + 0x00, 0x20, 0x00, 0x00, 0x00, // 10244 $2804 'uni2804' + 0x00, 0x22, 0x00, 0x00, 0x00, // 10245 $2805 'uni2805' + 0x00, 0x28, 0x00, 0x00, 0x00, // 10246 $2806 'uni2806' + 0x00, 0x2a, 0x00, 0x00, 0x00, // 10247 $2807 'uni2807' + 0x00, 0x00, 0x00, 0x02, 0x00, // 10248 $2808 'uni2808' + 0x00, 0x02, 0x00, 0x02, 0x00, // 10249 $2809 'uni2809' + 0x00, 0x08, 0x00, 0x02, 0x00, // 10250 $280a 'uni280A' + 0x00, 0x0a, 0x00, 0x02, 0x00, // 10251 $280b 'uni280B' + 0x00, 0x20, 0x00, 0x02, 0x00, // 10252 $280c 'uni280C' + 0x00, 0x22, 0x00, 0x02, 0x00, // 10253 $280d 'uni280D' + 0x00, 0x28, 0x00, 0x02, 0x00, // 10254 $280e 'uni280E' + 0x00, 0x2a, 0x00, 0x02, 0x00, // 10255 $280f 'uni280F' + 0x00, 0x00, 0x00, 0x08, 0x00, // 10256 $2810 'uni2810' + 0x00, 0x02, 0x00, 0x08, 0x00, // 10257 $2811 'uni2811' + 0x00, 0x08, 0x00, 0x08, 0x00, // 10258 $2812 'uni2812' + 0x00, 0x0a, 0x00, 0x08, 0x00, // 10259 $2813 'uni2813' + 0x00, 0x20, 0x00, 0x08, 0x00, // 10260 $2814 'uni2814' + 0x00, 0x22, 0x00, 0x08, 0x00, // 10261 $2815 'uni2815' + 0x00, 0x28, 0x00, 0x08, 0x00, // 10262 $2816 'uni2816' + 0x00, 0x2a, 0x00, 0x08, 0x00, // 10263 $2817 'uni2817' + 0x00, 0x00, 0x00, 0x0a, 0x00, // 10264 $2818 'uni2818' + 0x00, 0x02, 0x00, 0x0a, 0x00, // 10265 $2819 'uni2819' + 0x00, 0x08, 0x00, 0x0a, 0x00, // 10266 $281a 'uni281A' + 0x00, 0x0a, 0x00, 0x0a, 0x00, // 10267 $281b 'uni281B' + 0x00, 0x20, 0x00, 0x0a, 0x00, // 10268 $281c 'uni281C' + 0x00, 0x22, 0x00, 0x0a, 0x00, // 10269 $281d 'uni281D' + 0x00, 0x28, 0x00, 0x0a, 0x00, // 10270 $281e 'uni281E' + 0x00, 0x2a, 0x00, 0x0a, 0x00, // 10271 $281f 'uni281F' + 0x00, 0x00, 0x00, 0x20, 0x00, // 10272 $2820 'uni2820' + 0x00, 0x02, 0x00, 0x20, 0x00, // 10273 $2821 'uni2821' + 0x00, 0x08, 0x00, 0x20, 0x00, // 10274 $2822 'uni2822' + 0x00, 0x0a, 0x00, 0x20, 0x00, // 10275 $2823 'uni2823' + 0x00, 0x20, 0x00, 0x20, 0x00, // 10276 $2824 'uni2824' + 0x00, 0x22, 0x00, 0x20, 0x00, // 10277 $2825 'uni2825' + 0x00, 0x28, 0x00, 0x20, 0x00, // 10278 $2826 'uni2826' + 0x00, 0x2a, 0x00, 0x20, 0x00, // 10279 $2827 'uni2827' + 0x00, 0x00, 0x00, 0x22, 0x00, // 10280 $2828 'uni2828' + 0x00, 0x02, 0x00, 0x22, 0x00, // 10281 $2829 'uni2829' + 0x00, 0x08, 0x00, 0x22, 0x00, // 10282 $282a 'uni282A' + 0x00, 0x0a, 0x00, 0x22, 0x00, // 10283 $282b 'uni282B' + 0x00, 0x20, 0x00, 0x22, 0x00, // 10284 $282c 'uni282C' + 0x00, 0x22, 0x00, 0x22, 0x00, // 10285 $282d 'uni282D' + 0x00, 0x28, 0x00, 0x22, 0x00, // 10286 $282e 'uni282E' + 0x00, 0x2a, 0x00, 0x22, 0x00, // 10287 $282f 'uni282F' + 0x00, 0x00, 0x00, 0x28, 0x00, // 10288 $2830 'uni2830' + 0x00, 0x02, 0x00, 0x28, 0x00, // 10289 $2831 'uni2831' + 0x00, 0x08, 0x00, 0x28, 0x00, // 10290 $2832 'uni2832' + 0x00, 0x0a, 0x00, 0x28, 0x00, // 10291 $2833 'uni2833' + 0x00, 0x20, 0x00, 0x28, 0x00, // 10292 $2834 'uni2834' + 0x00, 0x22, 0x00, 0x28, 0x00, // 10293 $2835 'uni2835' + 0x00, 0x28, 0x00, 0x28, 0x00, // 10294 $2836 'uni2836' + 0x00, 0x2a, 0x00, 0x28, 0x00, // 10295 $2837 'uni2837' + 0x00, 0x00, 0x00, 0x2a, 0x00, // 10296 $2838 'uni2838' + 0x00, 0x02, 0x00, 0x2a, 0x00, // 10297 $2839 'uni2839' + 0x00, 0x08, 0x00, 0x2a, 0x00, // 10298 $283a 'uni283A' + 0x00, 0x0a, 0x00, 0x2a, 0x00, // 10299 $283b 'uni283B' + 0x00, 0x20, 0x00, 0x2a, 0x00, // 10300 $283c 'uni283C' + 0x00, 0x22, 0x00, 0x2a, 0x00, // 10301 $283d 'uni283D' + 0x00, 0x28, 0x00, 0x2a, 0x00, // 10302 $283e 'uni283E' + 0x00, 0x2a, 0x00, 0x2a, 0x00, // 10303 $283f 'uni283F' + 0x00, 0x80, 0x00, 0x00, 0x00, // 10304 $2840 'uni2840' + 0x00, 0x82, 0x00, 0x00, 0x00, // 10305 $2841 'uni2841' + 0x00, 0x88, 0x00, 0x00, 0x00, // 10306 $2842 'uni2842' + 0x00, 0x8a, 0x00, 0x00, 0x00, // 10307 $2843 'uni2843' + 0x00, 0xa0, 0x00, 0x00, 0x00, // 10308 $2844 'uni2844' + 0x00, 0xa2, 0x00, 0x00, 0x00, // 10309 $2845 'uni2845' + 0x00, 0xa8, 0x00, 0x00, 0x00, // 10310 $2846 'uni2846' + 0x00, 0xaa, 0x00, 0x00, 0x00, // 10311 $2847 'uni2847' + 0x00, 0x80, 0x00, 0x02, 0x00, // 10312 $2848 'uni2848' + 0x00, 0x82, 0x00, 0x02, 0x00, // 10313 $2849 'uni2849' + 0x00, 0x88, 0x00, 0x02, 0x00, // 10314 $284a 'uni284A' + 0x00, 0x8a, 0x00, 0x02, 0x00, // 10315 $284b 'uni284B' + 0x00, 0xa0, 0x00, 0x02, 0x00, // 10316 $284c 'uni284C' + 0x00, 0xa2, 0x00, 0x02, 0x00, // 10317 $284d 'uni284D' + 0x00, 0xa8, 0x00, 0x02, 0x00, // 10318 $284e 'uni284E' + 0x00, 0xaa, 0x00, 0x02, 0x00, // 10319 $284f 'uni284F' + 0x00, 0x80, 0x00, 0x08, 0x00, // 10320 $2850 'uni2850' + 0x00, 0x82, 0x00, 0x08, 0x00, // 10321 $2851 'uni2851' + 0x00, 0x88, 0x00, 0x08, 0x00, // 10322 $2852 'uni2852' + 0x00, 0x8a, 0x00, 0x08, 0x00, // 10323 $2853 'uni2853' + 0x00, 0xa0, 0x00, 0x08, 0x00, // 10324 $2854 'uni2854' + 0x00, 0xa2, 0x00, 0x08, 0x00, // 10325 $2855 'uni2855' + 0x00, 0xa8, 0x00, 0x08, 0x00, // 10326 $2856 'uni2856' + 0x00, 0xaa, 0x00, 0x08, 0x00, // 10327 $2857 'uni2857' + 0x00, 0x80, 0x00, 0x0a, 0x00, // 10328 $2858 'uni2858' + 0x00, 0x82, 0x00, 0x0a, 0x00, // 10329 $2859 'uni2859' + 0x00, 0x88, 0x00, 0x0a, 0x00, // 10330 $285a 'uni285A' + 0x00, 0x8a, 0x00, 0x0a, 0x00, // 10331 $285b 'uni285B' + 0x00, 0xa0, 0x00, 0x0a, 0x00, // 10332 $285c 'uni285C' + 0x00, 0xa2, 0x00, 0x0a, 0x00, // 10333 $285d 'uni285D' + 0x00, 0xa8, 0x00, 0x0a, 0x00, // 10334 $285e 'uni285E' + 0x00, 0xaa, 0x00, 0x0a, 0x00, // 10335 $285f 'uni285F' + 0x00, 0x80, 0x00, 0x20, 0x00, // 10336 $2860 'uni2860' + 0x00, 0x82, 0x00, 0x20, 0x00, // 10337 $2861 'uni2861' + 0x00, 0x88, 0x00, 0x20, 0x00, // 10338 $2862 'uni2862' + 0x00, 0x8a, 0x00, 0x20, 0x00, // 10339 $2863 'uni2863' + 0x00, 0xa0, 0x00, 0x20, 0x00, // 10340 $2864 'uni2864' + 0x00, 0xa2, 0x00, 0x20, 0x00, // 10341 $2865 'uni2865' + 0x00, 0xa8, 0x00, 0x20, 0x00, // 10342 $2866 'uni2866' + 0x00, 0xaa, 0x00, 0x20, 0x00, // 10343 $2867 'uni2867' + 0x00, 0x80, 0x00, 0x22, 0x00, // 10344 $2868 'uni2868' + 0x00, 0x82, 0x00, 0x22, 0x00, // 10345 $2869 'uni2869' + 0x00, 0x88, 0x00, 0x22, 0x00, // 10346 $286a 'uni286A' + 0x00, 0x8a, 0x00, 0x22, 0x00, // 10347 $286b 'uni286B' + 0x00, 0xa0, 0x00, 0x22, 0x00, // 10348 $286c 'uni286C' + 0x00, 0xa2, 0x00, 0x22, 0x00, // 10349 $286d 'uni286D' + 0x00, 0xa8, 0x00, 0x22, 0x00, // 10350 $286e 'uni286E' + 0x00, 0xaa, 0x00, 0x22, 0x00, // 10351 $286f 'uni286F' + 0x00, 0x80, 0x00, 0x28, 0x00, // 10352 $2870 'uni2870' + 0x00, 0x82, 0x00, 0x28, 0x00, // 10353 $2871 'uni2871' + 0x00, 0x88, 0x00, 0x28, 0x00, // 10354 $2872 'uni2872' + 0x00, 0x8a, 0x00, 0x28, 0x00, // 10355 $2873 'uni2873' + 0x00, 0xa0, 0x00, 0x28, 0x00, // 10356 $2874 'uni2874' + 0x00, 0xa2, 0x00, 0x28, 0x00, // 10357 $2875 'uni2875' + 0x00, 0xa8, 0x00, 0x28, 0x00, // 10358 $2876 'uni2876' + 0x00, 0xaa, 0x00, 0x28, 0x00, // 10359 $2877 'uni2877' + 0x00, 0x80, 0x00, 0x2a, 0x00, // 10360 $2878 'uni2878' + 0x00, 0x82, 0x00, 0x2a, 0x00, // 10361 $2879 'uni2879' + 0x00, 0x88, 0x00, 0x2a, 0x00, // 10362 $287a 'uni287A' + 0x00, 0x8a, 0x00, 0x2a, 0x00, // 10363 $287b 'uni287B' + 0x00, 0xa0, 0x00, 0x2a, 0x00, // 10364 $287c 'uni287C' + 0x00, 0xa2, 0x00, 0x2a, 0x00, // 10365 $287d 'uni287D' + 0x00, 0xa8, 0x00, 0x2a, 0x00, // 10366 $287e 'uni287E' + 0x00, 0xaa, 0x00, 0x2a, 0x00, // 10367 $287f 'uni287F' + 0x00, 0x00, 0x00, 0x80, 0x00, // 10368 $2880 'uni2880' + 0x00, 0x02, 0x00, 0x80, 0x00, // 10369 $2881 'uni2881' + 0x00, 0x08, 0x00, 0x80, 0x00, // 10370 $2882 'uni2882' + 0x00, 0x0a, 0x00, 0x80, 0x00, // 10371 $2883 'uni2883' + 0x00, 0x20, 0x00, 0x80, 0x00, // 10372 $2884 'uni2884' + 0x00, 0x22, 0x00, 0x80, 0x00, // 10373 $2885 'uni2885' + 0x00, 0x28, 0x00, 0x80, 0x00, // 10374 $2886 'uni2886' + 0x00, 0x2a, 0x00, 0x80, 0x00, // 10375 $2887 'uni2887' + 0x00, 0x00, 0x00, 0x82, 0x00, // 10376 $2888 'uni2888' + 0x00, 0x02, 0x00, 0x82, 0x00, // 10377 $2889 'uni2889' + 0x00, 0x08, 0x00, 0x82, 0x00, // 10378 $288a 'uni288A' + 0x00, 0x0a, 0x00, 0x82, 0x00, // 10379 $288b 'uni288B' + 0x00, 0x20, 0x00, 0x82, 0x00, // 10380 $288c 'uni288C' + 0x00, 0x22, 0x00, 0x82, 0x00, // 10381 $288d 'uni288D' + 0x00, 0x28, 0x00, 0x82, 0x00, // 10382 $288e 'uni288E' + 0x00, 0x2a, 0x00, 0x82, 0x00, // 10383 $288f 'uni288F' + 0x00, 0x00, 0x00, 0x88, 0x00, // 10384 $2890 'uni2890' + 0x00, 0x02, 0x00, 0x88, 0x00, // 10385 $2891 'uni2891' + 0x00, 0x08, 0x00, 0x88, 0x00, // 10386 $2892 'uni2892' + 0x00, 0x0a, 0x00, 0x88, 0x00, // 10387 $2893 'uni2893' + 0x00, 0x20, 0x00, 0x88, 0x00, // 10388 $2894 'uni2894' + 0x00, 0x22, 0x00, 0x88, 0x00, // 10389 $2895 'uni2895' + 0x00, 0x28, 0x00, 0x88, 0x00, // 10390 $2896 'uni2896' + 0x00, 0x2a, 0x00, 0x88, 0x00, // 10391 $2897 'uni2897' + 0x00, 0x00, 0x00, 0x8a, 0x00, // 10392 $2898 'uni2898' + 0x00, 0x02, 0x00, 0x8a, 0x00, // 10393 $2899 'uni2899' + 0x00, 0x08, 0x00, 0x8a, 0x00, // 10394 $289a 'uni289A' + 0x00, 0x0a, 0x00, 0x8a, 0x00, // 10395 $289b 'uni289B' + 0x00, 0x20, 0x00, 0x8a, 0x00, // 10396 $289c 'uni289C' + 0x00, 0x22, 0x00, 0x8a, 0x00, // 10397 $289d 'uni289D' + 0x00, 0x28, 0x00, 0x8a, 0x00, // 10398 $289e 'uni289E' + 0x00, 0x2a, 0x00, 0x8a, 0x00, // 10399 $289f 'uni289F' + 0x00, 0x00, 0x00, 0xa0, 0x00, // 10400 $28a0 'uni28A0' + 0x00, 0x02, 0x00, 0xa0, 0x00, // 10401 $28a1 'uni28A1' + 0x00, 0x08, 0x00, 0xa0, 0x00, // 10402 $28a2 'uni28A2' + 0x00, 0x0a, 0x00, 0xa0, 0x00, // 10403 $28a3 'uni28A3' + 0x00, 0x20, 0x00, 0xa0, 0x00, // 10404 $28a4 'uni28A4' + 0x00, 0x22, 0x00, 0xa0, 0x00, // 10405 $28a5 'uni28A5' + 0x00, 0x28, 0x00, 0xa0, 0x00, // 10406 $28a6 'uni28A6' + 0x00, 0x2a, 0x00, 0xa0, 0x00, // 10407 $28a7 'uni28A7' + 0x00, 0x00, 0x00, 0xa2, 0x00, // 10408 $28a8 'uni28A8' + 0x00, 0x02, 0x00, 0xa2, 0x00, // 10409 $28a9 'uni28A9' + 0x00, 0x08, 0x00, 0xa2, 0x00, // 10410 $28aa 'uni28AA' + 0x00, 0x0a, 0x00, 0xa2, 0x00, // 10411 $28ab 'uni28AB' + 0x00, 0x20, 0x00, 0xa2, 0x00, // 10412 $28ac 'uni28AC' + 0x00, 0x22, 0x00, 0xa2, 0x00, // 10413 $28ad 'uni28AD' + 0x00, 0x28, 0x00, 0xa2, 0x00, // 10414 $28ae 'uni28AE' + 0x00, 0x2a, 0x00, 0xa2, 0x00, // 10415 $28af 'uni28AF' + 0x00, 0x00, 0x00, 0xa8, 0x00, // 10416 $28b0 'uni28B0' + 0x00, 0x02, 0x00, 0xa8, 0x00, // 10417 $28b1 'uni28B1' + 0x00, 0x08, 0x00, 0xa8, 0x00, // 10418 $28b2 'uni28B2' + 0x00, 0x0a, 0x00, 0xa8, 0x00, // 10419 $28b3 'uni28B3' + 0x00, 0x20, 0x00, 0xa8, 0x00, // 10420 $28b4 'uni28B4' + 0x00, 0x22, 0x00, 0xa8, 0x00, // 10421 $28b5 'uni28B5' + 0x00, 0x28, 0x00, 0xa8, 0x00, // 10422 $28b6 'uni28B6' + 0x00, 0x2a, 0x00, 0xa8, 0x00, // 10423 $28b7 'uni28B7' + 0x00, 0x00, 0x00, 0xaa, 0x00, // 10424 $28b8 'uni28B8' + 0x00, 0x02, 0x00, 0xaa, 0x00, // 10425 $28b9 'uni28B9' + 0x00, 0x08, 0x00, 0xaa, 0x00, // 10426 $28ba 'uni28BA' + 0x00, 0x0a, 0x00, 0xaa, 0x00, // 10427 $28bb 'uni28BB' + 0x00, 0x20, 0x00, 0xaa, 0x00, // 10428 $28bc 'uni28BC' + 0x00, 0x22, 0x00, 0xaa, 0x00, // 10429 $28bd 'uni28BD' + 0x00, 0x28, 0x00, 0xaa, 0x00, // 10430 $28be 'uni28BE' + 0x00, 0x2a, 0x00, 0xaa, 0x00, // 10431 $28bf 'uni28BF' + 0x00, 0x80, 0x00, 0x80, 0x00, // 10432 $28c0 'uni28C0' + 0x00, 0x82, 0x00, 0x80, 0x00, // 10433 $28c1 'uni28C1' + 0x00, 0x88, 0x00, 0x80, 0x00, // 10434 $28c2 'uni28C2' + 0x00, 0x8a, 0x00, 0x80, 0x00, // 10435 $28c3 'uni28C3' + 0x00, 0xa0, 0x00, 0x80, 0x00, // 10436 $28c4 'uni28C4' + 0x00, 0xa2, 0x00, 0x80, 0x00, // 10437 $28c5 'uni28C5' + 0x00, 0xa8, 0x00, 0x80, 0x00, // 10438 $28c6 'uni28C6' + 0x00, 0xaa, 0x00, 0x80, 0x00, // 10439 $28c7 'uni28C7' + 0x00, 0x80, 0x00, 0x82, 0x00, // 10440 $28c8 'uni28C8' + 0x00, 0x82, 0x00, 0x82, 0x00, // 10441 $28c9 'uni28C9' + 0x00, 0x88, 0x00, 0x82, 0x00, // 10442 $28ca 'uni28CA' + 0x00, 0x8a, 0x00, 0x82, 0x00, // 10443 $28cb 'uni28CB' + 0x00, 0xa0, 0x00, 0x82, 0x00, // 10444 $28cc 'uni28CC' + 0x00, 0xa2, 0x00, 0x82, 0x00, // 10445 $28cd 'uni28CD' + 0x00, 0xa8, 0x00, 0x82, 0x00, // 10446 $28ce 'uni28CE' + 0x00, 0xaa, 0x00, 0x82, 0x00, // 10447 $28cf 'uni28CF' + 0x00, 0x80, 0x00, 0x88, 0x00, // 10448 $28d0 'uni28D0' + 0x00, 0x82, 0x00, 0x88, 0x00, // 10449 $28d1 'uni28D1' + 0x00, 0x88, 0x00, 0x88, 0x00, // 10450 $28d2 'uni28D2' + 0x00, 0x8a, 0x00, 0x88, 0x00, // 10451 $28d3 'uni28D3' + 0x00, 0xa0, 0x00, 0x88, 0x00, // 10452 $28d4 'uni28D4' + 0x00, 0xa2, 0x00, 0x88, 0x00, // 10453 $28d5 'uni28D5' + 0x00, 0xa8, 0x00, 0x88, 0x00, // 10454 $28d6 'uni28D6' + 0x00, 0xaa, 0x00, 0x88, 0x00, // 10455 $28d7 'uni28D7' + 0x00, 0x80, 0x00, 0x8a, 0x00, // 10456 $28d8 'uni28D8' + 0x00, 0x82, 0x00, 0x8a, 0x00, // 10457 $28d9 'uni28D9' + 0x00, 0x88, 0x00, 0x8a, 0x00, // 10458 $28da 'uni28DA' + 0x00, 0x8a, 0x00, 0x8a, 0x00, // 10459 $28db 'uni28DB' + 0x00, 0xa0, 0x00, 0x8a, 0x00, // 10460 $28dc 'uni28DC' + 0x00, 0xa2, 0x00, 0x8a, 0x00, // 10461 $28dd 'uni28DD' + 0x00, 0xa8, 0x00, 0x8a, 0x00, // 10462 $28de 'uni28DE' + 0x00, 0xaa, 0x00, 0x8a, 0x00, // 10463 $28df 'uni28DF' + 0x00, 0x80, 0x00, 0xa0, 0x00, // 10464 $28e0 'uni28E0' + 0x00, 0x82, 0x00, 0xa0, 0x00, // 10465 $28e1 'uni28E1' + 0x00, 0x88, 0x00, 0xa0, 0x00, // 10466 $28e2 'uni28E2' + 0x00, 0x8a, 0x00, 0xa0, 0x00, // 10467 $28e3 'uni28E3' + 0x00, 0xa0, 0x00, 0xa0, 0x00, // 10468 $28e4 'uni28E4' + 0x00, 0xa2, 0x00, 0xa0, 0x00, // 10469 $28e5 'uni28E5' + 0x00, 0xa8, 0x00, 0xa0, 0x00, // 10470 $28e6 'uni28E6' + 0x00, 0xaa, 0x00, 0xa0, 0x00, // 10471 $28e7 'uni28E7' + 0x00, 0x80, 0x00, 0xa2, 0x00, // 10472 $28e8 'uni28E8' + 0x00, 0x82, 0x00, 0xa2, 0x00, // 10473 $28e9 'uni28E9' + 0x00, 0x88, 0x00, 0xa2, 0x00, // 10474 $28ea 'uni28EA' + 0x00, 0x8a, 0x00, 0xa2, 0x00, // 10475 $28eb 'uni28EB' + 0x00, 0xa0, 0x00, 0xa2, 0x00, // 10476 $28ec 'uni28EC' + 0x00, 0xa2, 0x00, 0xa2, 0x00, // 10477 $28ed 'uni28ED' + 0x00, 0xa8, 0x00, 0xa2, 0x00, // 10478 $28ee 'uni28EE' + 0x00, 0xaa, 0x00, 0xa2, 0x00, // 10479 $28ef 'uni28EF' + 0x00, 0x80, 0x00, 0xa8, 0x00, // 10480 $28f0 'uni28F0' + 0x00, 0x82, 0x00, 0xa8, 0x00, // 10481 $28f1 'uni28F1' + 0x00, 0x88, 0x00, 0xa8, 0x00, // 10482 $28f2 'uni28F2' + 0x00, 0x8a, 0x00, 0xa8, 0x00, // 10483 $28f3 'uni28F3' + 0x00, 0xa0, 0x00, 0xa8, 0x00, // 10484 $28f4 'uni28F4' + 0x00, 0xa2, 0x00, 0xa8, 0x00, // 10485 $28f5 'uni28F5' + 0x00, 0xa8, 0x00, 0xa8, 0x00, // 10486 $28f6 'uni28F6' + 0x00, 0xaa, 0x00, 0xa8, 0x00, // 10487 $28f7 'uni28F7' + 0x00, 0x80, 0x00, 0xaa, 0x00, // 10488 $28f8 'uni28F8' + 0x00, 0x82, 0x00, 0xaa, 0x00, // 10489 $28f9 'uni28F9' + 0x00, 0x88, 0x00, 0xaa, 0x00, // 10490 $28fa 'uni28FA' + 0x00, 0x8a, 0x00, 0xaa, 0x00, // 10491 $28fb 'uni28FB' + 0x00, 0xa0, 0x00, 0xaa, 0x00, // 10492 $28fc 'uni28FC' + 0x00, 0xa2, 0x00, 0xaa, 0x00, // 10493 $28fd 'uni28FD' + 0x00, 0xa8, 0x00, 0xaa, 0x00, // 10494 $28fe 'uni28FE' + 0x00, 0xaa, 0x00, 0xaa, 0x00, // 10495 $28ff 'uni28FF' + 0x7c, 0x12, 0x7c, 0x12, 0x04, // 64256 $fb00 'ff' + 0x10, 0x7c, 0x12, 0x74, 0x00, // 64257 $fb01 'fi' + 0x10, 0x7c, 0x12, 0x7e, 0x00 // 64258 $fb02 'fl' +}; + + +static struct font_info font1 = { 5, 7, 1, 0, (uint8_t *)font1_data }; +static struct font_info font2 = { 6, 8, 0, 32, (uint8_t *)font2_data }; +static struct font_info font3 = { 5, 8, 0, 31, (uint8_t *)font3_data }; + +#endif // FONT_H + diff --git a/wiringPi/htu21d.c b/wiringPi/htu21d.c new file mode 100644 index 0000000..46c0fcb --- /dev/null +++ b/wiringPi/htu21d.c @@ -0,0 +1,150 @@ +/* + * htu21d.c: + * Extend wiringPi with the HTU21D I2C humidity and Temperature + * sensor. This is used in the Pi Weather station. + * Copyright (c) 2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include + +#include "wiringPi.h" +#include "wiringPiI2C.h" + +#include "htu21d.h" + +#define DEBUG +#undef FAKE_SENSOR + +#define I2C_ADDRESS 0x40 + +int checksum (UNU uint8_t data [4]) +{ + return TRUE ; +} + + + +/* + * myAnalogRead: + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + int chan = pin - node->pinBase ; + int fd = node->fd ; + uint8_t data [4] ; + uint32_t sTemp, sHumid ; + double fTemp, fHumid ; + int cTemp, cHumid ; + + /**/ if (chan == 0) // Read Temperature + { + +// Send read temperature command: + + data [0] = 0xF3 ; + if (write (fd, data, 1) != 1) + return -9999 ; + +// Wait then read the data + + delay (50) ; + if (read (fd, data, 3) != 3) + return -9998 ; + + if (!checksum (data)) + return -9997 ; + +// Do the calculation + + sTemp = (data [0] << 8) | data [1] ; + fTemp = -48.85 + 175.72 * (double)sTemp / 63356.0 ; + cTemp = (int)rint (((100.0 * fTemp) + 0.5) / 10.0) ; + return cTemp ; + } + else if (chan == 1) // humidity + { +// Send read humidity command: + + data [0] = 0xF5 ; + if (write (fd, data, 1) != 1) + return -9999 ; + +// Wait then read the data + + delay (50) ; + if (read (fd, data, 3) != 3) + return -9998 ; + + if (!checksum (data)) + return -9997 ; + + sHumid = (data [0] << 8) | data [1] ; + fHumid = -6.0 + 125.0 * (double)sHumid / 65536.0 ; + cHumid = (int)rint (((100.0 * fHumid) + 0.5) / 10.0) ; + return cHumid ; + } + else + return -9999 ; +} + + +/* + * htu21dSetup: + * Create a new instance of a HTU21D I2C GPIO interface. + * This chip has a fixed I2C address, so we are not providing any + * allowance to change this. + ********************************************************************************* + */ + +int htu21dSetup (const int pinBase) +{ + int fd ; + struct wiringPiNodeStruct *node ; + uint8_t data ; + int status ; + + if ((fd = wiringPiI2CSetup (I2C_ADDRESS)) < 0) + return FALSE ; + + node = wiringPiNewNode (pinBase, 2) ; + + node->fd = fd ; + node->analogRead = myAnalogRead ; + +// Send a reset code to it: + + data = 0xFE ; + if (write (fd, &data, 1) != 1) + return FALSE ; + + delay (15) ; + +// Read the status register to check it's really there + + status = wiringPiI2CReadReg8 (fd, 0xE7) ; + + return (status == 0x02) ? TRUE : FALSE ; +} diff --git a/wiringPi/htu21d.h b/wiringPi/htu21d.h new file mode 100644 index 0000000..3965c54 --- /dev/null +++ b/wiringPi/htu21d.h @@ -0,0 +1,34 @@ +/* + * htu21d.h: + * Extend wiringPi with the HTU21D I2C Humidity and Temperature + * sensor. + * Copyright (c) 2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int htu21dSetup (const int pinBase) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/max31855.c b/wiringPi/max31855.c new file mode 100644 index 0000000..d86cabd --- /dev/null +++ b/wiringPi/max31855.c @@ -0,0 +1,99 @@ +/* + * max31855.c: + * Extend wiringPi with the max31855 SPI Analog to Digital convertor + * Copyright (c) 2012-2015 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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 FALSE ; + + node = wiringPiNewNode (pinBase, 4) ; + + node->fd = spiChannel ; + node->analogRead = myAnalogRead ; + + return TRUE ; +} diff --git a/wiringPi/max31855.h b/wiringPi/max31855.h new file mode 100644 index 0000000..385c4bd --- /dev/null +++ b/wiringPi/max31855.h @@ -0,0 +1,33 @@ +/* + * max31855.c: + * Extend wiringPi with the MAX31855 SPI Thermocouple driver + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int max31855Setup (int pinBase, int spiChannel) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/max5322.c b/wiringPi/max5322.c new file mode 100644 index 0000000..e56b085 --- /dev/null +++ b/wiringPi/max5322.c @@ -0,0 +1,84 @@ +/* + * max5322.c: + * Extend wiringPi with the MAX5322 SPI Digital to Analog convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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 FALSE ; + + node = wiringPiNewNode (pinBase, 2) ; + + node->fd = spiChannel ; + node->analogWrite = myAnalogWrite ; + +// Enable both DACs + + spiData [0] = 0b11100000 ; + spiData [1] = 0 ; + + wiringPiSPIDataRW (node->fd, spiData, 2) ; + + return TRUE ; +} diff --git a/wiringPi/max5322.h b/wiringPi/max5322.h new file mode 100644 index 0000000..a217cf8 --- /dev/null +++ b/wiringPi/max5322.h @@ -0,0 +1,33 @@ +/* + * max5322.h: + * Extend wiringPi with the MAX5322 SPI Digital to Analog convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int max5322Setup (int pinBase, int spiChannel) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp23008.c b/wiringPi/mcp23008.c new file mode 100644 index 0000000..71757a8 --- /dev/null +++ b/wiringPi/mcp23008.c @@ -0,0 +1,149 @@ +/* + * mcp23008.c: + * Extend wiringPi with the MCP 23008 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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 FALSE ; + + wiringPiI2CWriteReg8 (fd, MCP23x08_IOCON, IOCON_INIT) ; + + node = wiringPiNewNode (pinBase, 8) ; + + node->fd = fd ; + node->pinMode = myPinMode ; + node->pullUpDnControl = myPullUpDnControl ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->data2 = wiringPiI2CReadReg8 (fd, MCP23x08_OLAT) ; + + return TRUE ; +} diff --git a/wiringPi/mcp23008.h b/wiringPi/mcp23008.h new file mode 100644 index 0000000..e9299a8 --- /dev/null +++ b/wiringPi/mcp23008.h @@ -0,0 +1,33 @@ +/* + * 23008.h: + * Extend wiringPi with the MCP 23008 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp23008Setup (const int pinBase, const int i2cAddress) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp23016.c b/wiringPi/mcp23016.c new file mode 100644 index 0000000..928d9e5 --- /dev/null +++ b/wiringPi/mcp23016.c @@ -0,0 +1,164 @@ +/* + * mcp23016.c: + * Extend wiringPi with the MCP 23016 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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 FALSE ; + + wiringPiI2CWriteReg8 (fd, MCP23016_IOCON0, IOCON_INIT) ; + wiringPiI2CWriteReg8 (fd, MCP23016_IOCON1, IOCON_INIT) ; + + node = wiringPiNewNode (pinBase, 16) ; + + node->fd = fd ; + node->pinMode = myPinMode ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->data2 = wiringPiI2CReadReg8 (fd, MCP23016_OLAT0) ; + node->data3 = wiringPiI2CReadReg8 (fd, MCP23016_OLAT1) ; + + return TRUE ; +} diff --git a/wiringPi/mcp23016.h b/wiringPi/mcp23016.h new file mode 100644 index 0000000..f9b5cc5 --- /dev/null +++ b/wiringPi/mcp23016.h @@ -0,0 +1,33 @@ +/* + * mcp23016.h: + * Extend wiringPi with the MCP 23016 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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..4c3952d --- /dev/null +++ b/wiringPi/mcp23017.c @@ -0,0 +1,195 @@ +/* + * mcp23017.c: + * Extend wiringPi with the MCP 23017 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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 FALSE ; + + wiringPiI2CWriteReg8 (fd, MCP23x17_IOCON, IOCON_INIT) ; + + node = wiringPiNewNode (pinBase, 16) ; + + node->fd = fd ; + node->pinMode = myPinMode ; + node->pullUpDnControl = myPullUpDnControl ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->data2 = wiringPiI2CReadReg8 (fd, MCP23x17_OLATA) ; + node->data3 = wiringPiI2CReadReg8 (fd, MCP23x17_OLATB) ; + + return TRUE ; +} diff --git a/wiringPi/mcp23017.h b/wiringPi/mcp23017.h new file mode 100644 index 0000000..79b4d7b --- /dev/null +++ b/wiringPi/mcp23017.h @@ -0,0 +1,33 @@ +/* + * 23017.h: + * Extend wiringPi with the MCP 23017 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp23017Setup (const int pinBase, const int i2cAddress) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp23s08.c b/wiringPi/mcp23s08.c new file mode 100644 index 0000000..f293f3a --- /dev/null +++ b/wiringPi/mcp23s08.c @@ -0,0 +1,188 @@ +/* + * mcp23s08.c: + * Extend wiringPi with the MCP 23s08 SPI GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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) +{ + struct wiringPiNodeStruct *node ; + + if (wiringPiSPISetup (spiPort, MCP_SPEED) < 0) + return FALSE ; + + writeByte (spiPort, devId, MCP23x08_IOCON, IOCON_INIT) ; + + node = wiringPiNewNode (pinBase, 8) ; + + node->data0 = spiPort ; + node->data1 = devId ; + node->pinMode = myPinMode ; + node->pullUpDnControl = myPullUpDnControl ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->data2 = readByte (spiPort, devId, MCP23x08_OLAT) ; + + return TRUE ; +} diff --git a/wiringPi/mcp23s08.h b/wiringPi/mcp23s08.h new file mode 100644 index 0000000..ebf93d1 --- /dev/null +++ b/wiringPi/mcp23s08.h @@ -0,0 +1,33 @@ +/* + * 23s08.h: + * Extend wiringPi with the MCP 23s08 SPI GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp23s08Setup (const int pinBase, const int spiPort, const int devId) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp23s17.c b/wiringPi/mcp23s17.c new file mode 100644 index 0000000..42b0358 --- /dev/null +++ b/wiringPi/mcp23s17.c @@ -0,0 +1,235 @@ +/* + * mcp23s17.c: + * Extend wiringPi with the MCP 23s17 SPI GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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) +{ + struct wiringPiNodeStruct *node ; + + if (wiringPiSPISetup (spiPort, MCP_SPEED) < 0) + return FALSE ; + + writeByte (spiPort, devId, MCP23x17_IOCON, IOCON_INIT | IOCON_HAEN) ; + writeByte (spiPort, devId, MCP23x17_IOCONB, IOCON_INIT | IOCON_HAEN) ; + + node = wiringPiNewNode (pinBase, 16) ; + + node->data0 = spiPort ; + node->data1 = devId ; + node->pinMode = myPinMode ; + node->pullUpDnControl = myPullUpDnControl ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->data2 = readByte (spiPort, devId, MCP23x17_OLATA) ; + node->data3 = readByte (spiPort, devId, MCP23x17_OLATB) ; + + return TRUE ; +} diff --git a/wiringPi/mcp23s17.h b/wiringPi/mcp23s17.h new file mode 100644 index 0000000..3b2a808 --- /dev/null +++ b/wiringPi/mcp23s17.h @@ -0,0 +1,33 @@ +/* + * 23s17.h: + * Extend wiringPi with the MCP 23s17 SPI GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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..9ebf3e4 --- /dev/null +++ b/wiringPi/mcp3002.c @@ -0,0 +1,76 @@ +/* + * mcp3002.c: + * Extend wiringPi with the MCP3002 SPI Analog to Digital convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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] << 8) | (spiData [1] >> 1)) & 0x3FF ; +} + + +/* + * mcp3002Setup: + * Create a new wiringPi device node for an mcp3002 on the Pi's + * SPI interface. + ********************************************************************************* + */ + +int mcp3002Setup (const int pinBase, int spiChannel) +{ + struct wiringPiNodeStruct *node ; + + if (wiringPiSPISetup (spiChannel, 1000000) < 0) + return FALSE ; + + node = wiringPiNewNode (pinBase, 2) ; + + node->fd = spiChannel ; + node->analogRead = myAnalogRead ; + + return TRUE ; +} diff --git a/wiringPi/mcp3002.h b/wiringPi/mcp3002.h new file mode 100644 index 0000000..0cd727f --- /dev/null +++ b/wiringPi/mcp3002.h @@ -0,0 +1,33 @@ +/* + * mcp3002.c: + * Extend wiringPi with the MCP3002 SPI Analog to Digital convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp3002Setup (int pinBase, int spiChannel) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp3004.c b/wiringPi/mcp3004.c new file mode 100644 index 0000000..be8383e --- /dev/null +++ b/wiringPi/mcp3004.c @@ -0,0 +1,76 @@ +/* + * mcp3004.c: + * Extend wiringPi with the MCP3004 SPI Analog to Digital convertor + * Copyright (c) 2012-2013 Gordon Henderson + * + * Thanks also to "ShorTie" on IRC for some remote debugging help! + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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 FALSE ; + + node = wiringPiNewNode (pinBase, 8) ; + + node->fd = spiChannel ; + node->analogRead = myAnalogRead ; + + return TRUE ; +} diff --git a/wiringPi/mcp3004.h b/wiringPi/mcp3004.h new file mode 100644 index 0000000..a07c0bf --- /dev/null +++ b/wiringPi/mcp3004.h @@ -0,0 +1,33 @@ +/* + * mcp3004.c: + * Extend wiringPi with the MCP3004 SPI Analog to Digital convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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..12eba1a --- /dev/null +++ b/wiringPi/mcp3422.c @@ -0,0 +1,125 @@ +/* + * mcp3422.c: + * Extend wiringPi with the MCP3422/3/4 I2C ADC chip + * This code assumes single-ended mode only. + * Tested on actual hardware: 20th Feb 2016. + * Copyright (c) 2013-2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + + +#include +#include +#include +#include +#include + +#include +#include + +#include "mcp3422.h" + + +/* + * waitForConversion: + * Common code to wait for the ADC to finish conversion + ********************************************************************************* + */ + +void waitForConversion (int fd, unsigned char *buffer, int n) +{ + for (;;) + { + if ( read (fd, buffer, n) ){;} + if ((buffer [n-1] & 0x80) == 0) + break ; + delay (1) ; + } +} + +/* + * myAnalogRead: + * Read a channel from the device + ********************************************************************************* + */ + +int myAnalogRead (struct wiringPiNodeStruct *node, int chan) +{ + unsigned char config ; + unsigned char buffer [4] ; + int value = 0 ; + int realChan = (chan & 3) - node->pinBase ; + +// One-shot mode, trigger plus the other configs. + + config = 0x80 | (realChan << 5) | (node->data0 << 2) | (node->data1) ; + + wiringPiI2CWrite (node->fd, config) ; + + switch (node->data0) // Sample rate + { + case MCP3422_SR_3_75: // 18 bits + waitForConversion (node->fd, &buffer [0], 4) ; + value = ((buffer [0] & 3) << 16) | (buffer [1] << 8) | buffer [2] ; + break ; + + case MCP3422_SR_15: // 16 bits + waitForConversion (node->fd, buffer, 3) ; + value = (buffer [0] << 8) | buffer [1] ; + break ; + + case MCP3422_SR_60: // 14 bits + waitForConversion (node->fd, buffer, 3) ; + value = ((buffer [0] & 0x3F) << 8) | buffer [1] ; + break ; + + case MCP3422_SR_240: // 12 bits - default + waitForConversion (node->fd, buffer, 3) ; + value = ((buffer [0] & 0x0F) << 8) | buffer [1] ; + break ; + } + + return value ; +} + + +/* + * mcp3422Setup: + * Create a new wiringPi device node for the mcp3422 + ********************************************************************************* + */ + +int mcp3422Setup (int pinBase, int i2cAddress, int sampleRate, int gain) +{ + int fd ; + struct wiringPiNodeStruct *node ; + + if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) + return FALSE ; + + node = wiringPiNewNode (pinBase, 4) ; + + node->fd = fd ; + node->data0 = sampleRate ; + node->data1 = gain ; + node->analogRead = myAnalogRead ; + + return TRUE ; +} diff --git a/wiringPi/mcp3422.h b/wiringPi/mcp3422.h new file mode 100644 index 0000000..72647d4 --- /dev/null +++ b/wiringPi/mcp3422.h @@ -0,0 +1,43 @@ +/* + * mcp3422.h: + * Extend wiringPi with the MCP3422/3/4 I2C ADC chip + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#define MCP3422_SR_240 0 +#define MCP3422_SR_60 1 +#define MCP3422_SR_15 2 +#define MCP3422_SR_3_75 3 + +#define MCP3422_GAIN_1 0 +#define MCP3422_GAIN_2 1 +#define MCP3422_GAIN_4 2 +#define MCP3422_GAIN_8 3 + + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp3422Setup (int pinBase, int i2cAddress, int sampleRate, int gain) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp4802.c b/wiringPi/mcp4802.c new file mode 100644 index 0000000..ef104ed --- /dev/null +++ b/wiringPi/mcp4802.c @@ -0,0 +1,76 @@ +/* + * mcp4802.c: + * Extend wiringPi with the MCP4802 SPI Digital to Analog convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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 FALSE ; + + node = wiringPiNewNode (pinBase, 2) ; + + node->fd = spiChannel ; + node->analogWrite = myAnalogWrite ; + + return TRUE ; +} diff --git a/wiringPi/mcp4802.h b/wiringPi/mcp4802.h new file mode 100644 index 0000000..effa024 --- /dev/null +++ b/wiringPi/mcp4802.h @@ -0,0 +1,33 @@ +/* + * mcp4802.c: + * Extend wiringPi with the MCP4802 SPI Digital to Analog convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp4802Setup (int pinBase, int spiChannel) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/noMoreStatic b/wiringPi/noMoreStatic new file mode 100644 index 0000000..1d25942 --- /dev/null +++ b/wiringPi/noMoreStatic @@ -0,0 +1,20 @@ + +wiringPi is no-longer shipped with the ability to statically link it. + +Many reasons but the biggest issue is people who have statically linked +wiringPi into their product - for example a Pi UPS device or a Tetris-like +game and not subsequently shipped their modified sources. These people are +no better than common thieves with complete disregard to the conditions +of the LGPL that wiringPi ships with. + +Additionally, many think it's a good idea to statically link wiringPi +into their favourite language - like Node, and Java and other itsy bitsy +little things. These people have a complete and utter disregard to what +happens underneath when e.g. the Linux kernel changes on the Pi then +wiringPi stops as it depends on some Pi kernel features, then the poor +user get in-touch with me and I've had over 10,000 emails so-far and +it's now beyond a joke. + +DO NOT STATICALLY LINK WIRINGPI. + +Gordon Henderson, March 2018. diff --git a/wiringPi/oled.c b/wiringPi/oled.c new file mode 100644 index 0000000..aa83e4d --- /dev/null +++ b/wiringPi/oled.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2015, Vladimir Komendantskiy + * MIT License + * + * OLED is a 128x64 dot matrix display driver and controller by Solomon + * Systech. It is used by HelTec display modules. + * + * Reference: + * + * [1] OLED Advance Information. 128x64 Dot Matrix Segment/Common + * Driver with Controller. (Solomon Systech) + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +// real-time features +#include +#include + +#include "oled.h" +#include "font.h" +#include + + +int oled_close(struct display_info *disp) { + if (close(disp->file) < 0) + return -1; + + return 0; +} + +void cleanup(int status, void *disp) { + oled_close((struct display_info *)disp); +} + +int oled_open(struct display_info *disp, char *filename) { + + disp->file = wiringPiI2CSetupInterface (filename, disp->address); + if (disp->file < 0) + return -1; + + return 0; +} + +// write commands and data to /dev/i2c* +int oled_send(struct display_info *disp, struct sized_array *payload) { + if (write(disp->file, payload->array, payload->size) != payload->size) + return -1; + + return 0; +} + +int oled_init(struct display_info *disp) { + struct sched_param sch; + int status = 0; + struct sized_array payload; + + // sch.sched_priority = 49; + // + // status = sched_setscheduler(0, SCHED_FIFO, &sch); + // if (status < 0) + // return status; + // + // status = mlockall(MCL_CURRENT | MCL_FUTURE); + // if (status < 0) + // return status; + + payload.size = sizeof(display_config); + payload.array = display_config; + + status = oled_send(disp, &payload); + if (status < 0) + return 666; + + memset(disp->buffer, 0, sizeof(disp->buffer)); + + return 0; +} + +// send buffer to oled (show) +int oled_send_buffer(struct display_info *disp) { + struct sized_array payload; + uint8_t packet[129]; + int index; + + for (index = 0; index < 8; index++) { + packet[0] = OLED_CTRL_BYTE_DATA_STREAM; + memcpy(packet + 1, disp->buffer[index], 128); + payload.size = 129; + payload.array = packet; + oled_send(disp, &payload); + } + return 0; +} + +// clear screen +void oled_clear(struct display_info *disp) { + memset(disp->buffer, 0, sizeof(disp->buffer)); + oled_send_buffer(disp); +} + +// put string to one of the 8 pages (128x8 px) +void oled_putstr(struct display_info *disp, uint8_t line, uint8_t *str) { + uint8_t a; + int slen = strlen(str); + uint8_t fwidth = disp->font.width; + uint8_t foffset = disp->font.offset; + uint8_t fspacing = disp->font.spacing; + int i=0; + + for (i=0; i= 128/fwidth) + break; // no text wrap + memcpy(disp->buffer[line] + i*fwidth + fspacing, &disp->font.data[(a-foffset) * fwidth], fwidth); + } +} + +// put one pixel at xy, on=1|0 (turn on|off pixel) +void oled_putpixel(struct display_info *disp, uint8_t x, uint8_t y, uint8_t on) { + uint8_t pageId = y / 8; + uint8_t bitOffset = y % 8; + if (x < 128-2) { + if (on == 1) + disp->buffer[pageId][x] |= (1<buffer[pageId][x] &= ~(1<font.width; + uint8_t fheight = disp->font.height; + uint8_t foffset = disp->font.offset; + uint8_t fspacing = disp->font.spacing; + int i=0; + int j=0; + int k=0; + + for (k=0; kfont.data[(a-foffset)*fwidth + i] >> j) & 0x01)) + oled_putpixel(disp, x+i, y+j, 1); + else + oled_putpixel(disp, x+i, y+j, 0); + } + } + x+=fwidth+fspacing; + } +} + diff --git a/wiringPi/oled.h b/wiringPi/oled.h new file mode 100644 index 0000000..1cda15c --- /dev/null +++ b/wiringPi/oled.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2015, Vladimir Komendantskiy + * MIT License + * + * IOCTL interface to SSD1306 modules. + * + * Command sequences are sourced from an Arduino library by Sonal Pinto. + */ + +#ifndef OLED_H +#define OLED_H + +#include +#include "font.h" + +#define OLED_I2C_ADDR 0x3c + +// Control byte +#define OLED_CTRL_BYTE_CMD_SINGLE 0x80 +#define OLED_CTRL_BYTE_CMD_STREAM 0x00 +#define OLED_CTRL_BYTE_DATA_STREAM 0x40 +// Fundamental commands (page 28) +#define OLED_CMD_SET_CONTRAST 0x81 +#define OLED_CMD_DISPLAY_RAM 0xA4 +#define OLED_CMD_DISPLAY_ALLON 0xA5 +#define OLED_CMD_DISPLAY_NORMAL 0xA6 +#define OLED_CMD_DISPLAY_INVERTED 0xA7 +#define OLED_CMD_DISPLAY_OFF 0xAE +#define OLED_CMD_DISPLAY_ON 0xAF +// Addressing Command Table (page 30) +#define OLED_CMD_SET_MEMORY_ADDR_MODE 0x20 +#define OLED_CMD_SET_COLUMN_RANGE 0x21 +#define OLED_CMD_SET_PAGE_RANGE 0x22 +// Hardware Config (page 31) +#define OLED_CMD_SET_DISPLAY_START_LINE 0x40 +#define OLED_CMD_SET_SEGMENT_REMAP 0xA1 +#define OLED_CMD_SET_MUX_RATIO 0xA8 +#define OLED_CMD_SET_COM_SCAN_MODE 0xC8 +#define OLED_CMD_SET_DISPLAY_OFFSET 0xD3 +#define OLED_CMD_SET_COM_PIN_MAP 0xDA +#define OLED_CMD_NOP 0xE3 +// Timing and Driving Scheme (page 32) +#define OLED_CMD_SET_DISPLAY_CLK_DIV 0xD5 +#define OLED_CMD_SET_PRECHARGE 0xD9 +#define OLED_CMD_SET_VCOMH_DESELCT 0xDB +// Charge Pump (page 62) +#define OLED_CMD_SET_CHARGE_PUMP 0x8D +// SH1106 Display +#define OLED_SET_PAGE_ADDRESS 0xB0 + + +static const unsigned char display_config[] = { + OLED_CTRL_BYTE_CMD_STREAM, + OLED_CMD_DISPLAY_OFF, + + OLED_SET_PAGE_ADDRESS, + 0x02, /*set lower column address*/ + 0x10, /*set higher column address*/ + + OLED_CMD_SET_MUX_RATIO, 0x3F, + // Set the display offset to 0 + OLED_CMD_SET_DISPLAY_OFFSET, 0x00, + // Display start line to 0 + OLED_CMD_SET_DISPLAY_START_LINE, + // Mirror the x-axis. In case you set it up such that the pins are north. + // 0xA0 - in case pins are south - default + OLED_CMD_SET_SEGMENT_REMAP, + // Mirror the y-axis. In case you set it up such that the pins are north. + // 0xC0 - in case pins are south - default + OLED_CMD_SET_COM_SCAN_MODE, + // Default - alternate COM pin map + OLED_CMD_SET_COM_PIN_MAP, 0x12, + // set contrast + OLED_CMD_SET_CONTRAST, 0x7F, + // Set display to enable rendering from GDDRAM (Graphic Display Data RAM) + OLED_CMD_DISPLAY_RAM, + // Normal mode! + OLED_CMD_DISPLAY_NORMAL, + // Default oscillator clock + OLED_CMD_SET_DISPLAY_CLK_DIV, 0x80, + // Enable the charge pump + OLED_CMD_SET_CHARGE_PUMP, 0x14, + // Set precharge cycles to high cap type + OLED_CMD_SET_PRECHARGE, 0x22, + // Set the V_COMH deselect volatage to max + OLED_CMD_SET_VCOMH_DESELCT, 0x30, + // Horizonatal addressing mode - same as the KS108 GLCD + OLED_CMD_SET_MEMORY_ADDR_MODE, 0x00, + // Turn the Display ON + OLED_CMD_DISPLAY_ON +}; + +static const unsigned char display_draw[] = { + OLED_CTRL_BYTE_CMD_STREAM, + // column 0 to 127 + OLED_CMD_SET_COLUMN_RANGE, + 0x00, + 0x7F, + // page 0 to 7 + OLED_CMD_SET_PAGE_RANGE, + 0x00, + 0x07 +}; + +struct display_info { + int address; + int file; + struct font_info font; + uint8_t buffer[8][128]; +}; + +struct sized_array { + int size; + const uint8_t* array; +}; + +extern int oled_close (struct display_info* disp); +extern int oled_open (struct display_info* disp, char* filename); +extern int oled_send (struct display_info* disp, struct sized_array* payload); +extern int oled_init (struct display_info* disp); +extern int oled_send_buffer (struct display_info* disp); +extern void oled_clear(struct display_info *disp); +extern void oled_putstr(struct display_info *disp, uint8_t line, uint8_t *str); +extern void oled_putpixel(struct display_info *disp, uint8_t x, uint8_t y, uint8_t on); +extern void oled_putstrto(struct display_info *disp, uint8_t x, uint8_t y, char *str); + +#endif // OLED_H diff --git a/wiringPi/pcf8574.c b/wiringPi/pcf8574.c new file mode 100644 index 0000000..e0b686a --- /dev/null +++ b/wiringPi/pcf8574.c @@ -0,0 +1,126 @@ +/* + * pcf8574.c: + * Extend wiringPi with the PCF8574 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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 FALSE ; + + node = wiringPiNewNode (pinBase, 8) ; + + node->fd = fd ; + node->pinMode = myPinMode ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->data2 = wiringPiI2CRead (fd) ; + + return TRUE ; +} diff --git a/wiringPi/pcf8574.h b/wiringPi/pcf8574.h new file mode 100644 index 0000000..8e2d818 --- /dev/null +++ b/wiringPi/pcf8574.h @@ -0,0 +1,33 @@ +/* + * pcf8574.h: + * Extend wiringPi with the PCF8574 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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..de5f51f --- /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, UNU int pin, int value) +{ + unsigned char b [2] ; + b [0] = 0x40 ; + b [1] = value & 0xFF ; + if ( 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 FALSE ; + + node = wiringPiNewNode (pinBase, 4) ; + + node->fd = fd ; + node->analogRead = myAnalogRead ; + node->analogWrite = myAnalogWrite ; + + return TRUE ; +} diff --git a/wiringPi/pcf8591.h b/wiringPi/pcf8591.h new file mode 100644 index 0000000..6b44ccf --- /dev/null +++ b/wiringPi/pcf8591.h @@ -0,0 +1,33 @@ +/* + * pcf8591.h: + * Extend wiringPi with the PCF8591 I2C GPIO Analog expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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 new file mode 100644 index 0000000..d2f3b4e --- /dev/null +++ b/wiringPi/piHiPri.c @@ -0,0 +1,51 @@ +/* + * piHiPri: + * Simple way to get your program running at high priority + * with realtime schedulling. + * + * 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 "wiringPi.h" + + +/* + * piHiPri: + * Attempt to set a high priority schedulling for the running program + ********************************************************************************* + */ + +int piHiPri (const int pri) +{ + struct sched_param sched ; + + memset (&sched, 0, sizeof(sched)) ; + + if (pri > sched_get_priority_max (SCHED_RR)) + sched.sched_priority = sched_get_priority_max (SCHED_RR) ; + else + sched.sched_priority = pri ; + + return sched_setscheduler (0, SCHED_RR, &sched) ; +} diff --git a/wiringPi/piThread.c b/wiringPi/piThread.c new file mode 100644 index 0000000..b0499be --- /dev/null +++ b/wiringPi/piThread.c @@ -0,0 +1,63 @@ +/* + * piThread.c: + * Provide a simplified interface to pthreads + * + * 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 "wiringPi.h" + +static pthread_mutex_t piMutexes [4] ; + + + +/* + * piThreadCreate: + * Create and start a thread + ********************************************************************************* + */ + +int piThreadCreate (void *(*fn)(void *)) +{ + pthread_t myThread ; + + return pthread_create (&myThread, NULL, fn, NULL) ; +} + +/* + * piLock: piUnlock: + * Activate/Deactivate a mutex. + * We're keeping things simple here and only tracking 4 mutexes which + * is more than enough for out entry-level pthread programming + ********************************************************************************* + */ + +void piLock (int key) +{ + pthread_mutex_lock (&piMutexes [key]) ; +} + +void piUnlock (int key) +{ + pthread_mutex_unlock (&piMutexes [key]) ; +} + diff --git a/wiringPi/pseudoPins.c b/wiringPi/pseudoPins.c new file mode 100644 index 0000000..c2bf5e0 --- /dev/null +++ b/wiringPi/pseudoPins.c @@ -0,0 +1,95 @@ +/* + * pseudoPins.c: + * Extend wiringPi with a number of pseudo pins which can be + * digitally or analog written/read. + * + * Note: + * Just one set of pseudo pins can exist per Raspberry Pi. + * These pins are shared between all programs running on + * that Raspberry Pi. The values are also persistant as + * they live in shared RAM. This gives you a means for + * temporary variable storing/sharing between programs, + * or for other cunning things I've not thought of yet.. + * + * Copyright (c) 2012-2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#define SHARED_NAME "wiringPiPseudoPins" +#define PSEUDO_PINS 64 + +#include +#include +#include +#include +#include + +#include + +#include "pseudoPins.h" + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + int *ptr = (int *)node->data0 ; + int myPin = pin - node->pinBase ; + + return *(ptr + myPin) ; +} + + +static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + int *ptr = (int *)node->data0 ; + int myPin = pin - node->pinBase ; + + *(ptr + myPin) = value ; +} + + +/* + * pseudoPinsSetup: + * Create a new wiringPi device node for the pseudoPins driver + ********************************************************************************* + */ + +int pseudoPinsSetup (const int pinBase) +{ + struct wiringPiNodeStruct *node ; + void *ptr ; + + node = wiringPiNewNode (pinBase, PSEUDO_PINS) ; + + node->fd = shm_open (SHARED_NAME, O_CREAT | O_RDWR, 0666) ; + + if (node->fd < 0) + return FALSE ; + + if (ftruncate (node->fd, PSEUDO_PINS * sizeof (int)) < 0) + return FALSE ; + + ptr = mmap (NULL, PSEUDO_PINS * sizeof (int), PROT_READ | PROT_WRITE, MAP_SHARED, node->fd, 0) ; + + node->data0 = (unsigned int)ptr ; + + node->analogRead = myAnalogRead ; + node->analogWrite = myAnalogWrite ; + + return TRUE ; +} diff --git a/wiringPi/pseudoPins.h b/wiringPi/pseudoPins.h new file mode 100644 index 0000000..bef4660 --- /dev/null +++ b/wiringPi/pseudoPins.h @@ -0,0 +1,26 @@ +/* + * pseudoPins.h: + * Extend wiringPi with a number of pseudo pins which can be + * digitally or analog written/read. + * Copyright (c) 2012-2016 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +extern int pseudoPinsSetup (const int pinBase) ; diff --git a/wiringPi/rht03.c b/wiringPi/rht03.c new file mode 100644 index 0000000..5cf3a99 --- /dev/null +++ b/wiringPi/rht03.c @@ -0,0 +1,256 @@ +/* + * rht03.c: + * Extend wiringPi with the rht03 Maxdetect 1-Wire sensor. + * Copyright (c) 2016-2017 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include + +#include "wiringPi.h" +#include "rht03.h" + +#ifdef CONFIG_ORANGEPI +#include "OrangePi.h" +#endif + +/* + * maxDetectLowHighWait: + * Wait for a transition from low to high on the bus + ********************************************************************************* + */ + +static int maxDetectLowHighWait (const int pin) +{ + struct timeval now, timeOut, timeUp ; + +// If already high then wait for pin to go low + + gettimeofday (&now, NULL) ; + timerclear (&timeOut) ; + timeOut.tv_usec = 1000 ; + timeradd (&now, &timeOut, &timeUp) ; + + while (digitalRead (pin) == HIGH) + { + gettimeofday (&now, NULL) ; + if (timercmp (&now, &timeUp, >)) + return FALSE ; + } + +// Wait for it to go HIGH + + gettimeofday (&now, NULL) ; + timerclear (&timeOut) ; + timeOut.tv_usec = 1000 ; + timeradd (&now, &timeOut, &timeUp) ; + + while (digitalRead (pin) == LOW) + { + gettimeofday (&now, NULL) ; + if (timercmp (&now, &timeUp, >)) + return FALSE ; + } + + return TRUE ; +} + + +/* + * maxDetectClockByte: + * Read in a single byte from the MaxDetect bus + ********************************************************************************* + */ + +static unsigned int maxDetectClockByte (const int pin) +{ + unsigned int byte = 0 ; + int bit ; + + for (bit = 0 ; bit < 8 ; ++bit) + { + if (!maxDetectLowHighWait (pin)) + return 0 ; + +// bit starting now - we need to time it. + + delayMicroseconds (30) ; + byte <<= 1 ; + if (digitalRead (pin) == HIGH) // It's a 1 + byte |= 1 ; + } + + return byte ; +} + + +/* + * maxDetectRead: + * Read in and return the 4 data bytes from the MaxDetect sensor. + * Return TRUE/FALSE depending on the checksum validity + ********************************************************************************* + */ + +static int maxDetectRead (const int pin, unsigned char buffer [4]) +{ + int i ; + unsigned int checksum ; + unsigned char localBuf [5] ; + struct timeval now, then, took ; + +// See how long we took + + gettimeofday (&then, NULL) ; + +// Wake up the RHT03 by pulling the data line low, then high +// Low for 10mS, high for 40uS. + + pinMode (pin, OUTPUT) ; + digitalWrite (pin, 0) ; delay (10) ; + digitalWrite (pin, 1) ; delayMicroseconds (40) ; + pinMode (pin, INPUT) ; + +// Now wait for sensor to pull pin low + + if (!maxDetectLowHighWait (pin)) + return FALSE ; + +// and read in 5 bytes (40 bits) + + for (i = 0 ; i < 5 ; ++i) + localBuf [i] = maxDetectClockByte (pin) ; + + checksum = 0 ; + for (i = 0 ; i < 4 ; ++i) + { + buffer [i] = localBuf [i] ; + checksum += localBuf [i] ; + } + checksum &= 0xFF ; + +// See how long we took + + gettimeofday (&now, NULL) ; + timersub (&now, &then, &took) ; + +// Total time to do this should be: +// 10mS + 40µS - reset +// + 80µS + 80µS - sensor doing its low -> high thing +// + 40 * (50µS + 27µS (0) or 70µS (1) ) +// = 15010µS +// so if we take more than that, we've had a scheduling interruption and the +// reading is probably bogus. + + if ((took.tv_sec != 0) || (took.tv_usec > 16000)) + return FALSE ; + + return checksum == localBuf [4] ; +} + + +/* + * myReadRHT03: + * Read the Temperature & Humidity from an RHT03 sensor + * Values returned are *10, so 123 is 12.3. + ********************************************************************************* + */ + +static int myReadRHT03 (const int pin, int *temp, int *rh) +{ + int result ; + unsigned char buffer [4] ; + +// Read ... + + result = maxDetectRead (pin, buffer) ; + + if (!result) + return FALSE ; + + *rh = (buffer [0] * 256 + buffer [1]) ; + *temp = (buffer [2] * 256 + buffer [3]) ; + + if ((*temp & 0x8000) != 0) // Negative + { + *temp &= 0x7FFF ; + *temp = -*temp ; + } + +// Discard obviously bogus readings - the checksum can't detect a 2-bit error +// (which does seem to happen - no realtime here) + + if ((*rh > 999) || (*temp > 800) || (*temp < -400)) + return FALSE ; + + return TRUE ; +} + + +/* + * myAnalogRead: + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + int piPin = node->fd ; + int chan = pin - node->pinBase ; + int temp = -9997 ; + int rh = -9997 ; + int try ; + + if (chan > 1) + return -9999 ; // Bad parameters + + for (try = 0 ; try < 10 ; ++try) + { + if (myReadRHT03 (piPin, &temp, &rh)) + return chan == 0 ? temp : rh ; + } + + return -9998 ; +} + + +/* + * rht03Setup: + * Create a new instance of an RHT03 temperature sensor. + ********************************************************************************* + */ + +int rht03Setup (const int pinBase, const int piPin) +{ + struct wiringPiNodeStruct *node ; + + if ((piPin & PI_GPIO_MASK) != 0) // Must be an on-board pin + return FALSE ; + +// 2 pins - temperature and humidity + + node = wiringPiNewNode (pinBase, 2) ; + + node->fd = piPin ; + node->analogRead = myAnalogRead ; + + return TRUE ; +} diff --git a/wiringPi/rht03.h b/wiringPi/rht03.h new file mode 100644 index 0000000..9523fbf --- /dev/null +++ b/wiringPi/rht03.h @@ -0,0 +1,25 @@ +/* + * rht03.h: + * Extend wiringPi with the rht03 Maxdetect 1-Wire sensor. + * Copyright (c) 2016-2017 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +extern int rht03Setup (const int pinBase, const int devicePin) ; diff --git a/wiringPi/sn3218.c b/wiringPi/sn3218.c new file mode 100644 index 0000000..d9b9113 --- /dev/null +++ b/wiringPi/sn3218.c @@ -0,0 +1,75 @@ +/* + * sn3218.c: + * Extend wiringPi with the SN3218 I2C LEd Driver + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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 FALSE ; + +// Setup the chip - initialise all 18 LEDs to off + +//wiringPiI2CWriteReg8 (fd, 0x17, 0) ; // Reset + wiringPiI2CWriteReg8 (fd, 0x00, 1) ; // Not Shutdown + wiringPiI2CWriteReg8 (fd, 0x13, 0x3F) ; // Enable LEDs 0- 5 + wiringPiI2CWriteReg8 (fd, 0x14, 0x3F) ; // Enable LEDs 6-11 + wiringPiI2CWriteReg8 (fd, 0x15, 0x3F) ; // Enable LEDs 12-17 + wiringPiI2CWriteReg8 (fd, 0x16, 0x00) ; // Update + + node = wiringPiNewNode (pinBase, 18) ; + + node->fd = fd ; + node->analogWrite = myAnalogWrite ; + + return TRUE ; +} diff --git a/wiringPi/sn3218.h b/wiringPi/sn3218.h new file mode 100644 index 0000000..580d5f9 --- /dev/null +++ b/wiringPi/sn3218.h @@ -0,0 +1,33 @@ +/* + * sn3218.c: + * Extend wiringPi with the SN3218 I2C LED driver board. + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int sn3218Setup (int pinBase) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/softPwm.c b/wiringPi/softPwm.c new file mode 100644 index 0000000..d99fa00 --- /dev/null +++ b/wiringPi/softPwm.c @@ -0,0 +1,183 @@ +/* + * softPwm.c: + * Provide many channels of software driven PWM. + * Copyright (c) 2012-2017 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#include "wiringPi.h" +#include "softPwm.h" + +// MAX_PINS: +// This is more than the number of Pi pins because we can actually softPwm. +// Once upon a time I let pins on gpio expanders be softPwm'd, but it's really +// really not a good thing. + +#define MAX_PINS 64 + +// 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 µ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 100µS - this is because the Linux timer calls are just +// not accurate at all, and have an overhead. +// +// Another way to increase the frequency is to reduce the range - however +// that reduces the overall output accuracy... + +#define PULSE_TIME 100 + +static volatile int marks [MAX_PINS] ; +static volatile int range [MAX_PINS] ; +static volatile pthread_t threads [MAX_PINS] ; +static volatile int newPin = -1 ; + + +/* + * softPwmThread: + * Thread to do the actual PWM output + ********************************************************************************* + */ + +static void *softPwmThread (void *arg) +{ + 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 = *((int *)arg) ; + free (arg) ; + + pin = newPin ; + newPin = -1 ; + + piHiPri (90) ; + + for (;;) + { + mark = marks [pin] ; + space = range [pin] - mark ; + + if (mark != 0) + digitalWrite (pin, HIGH) ; + delayMicroseconds (mark * 100) ; + + if (space != 0) + digitalWrite (pin, LOW) ; + delayMicroseconds (space * 100) ; + } + + return NULL ; +} + + +/* + * softPwmWrite: + * Write a PWM value to the given pin + ********************************************************************************* + */ + +void softPwmWrite (int pin, int value) +{ + if (pin < MAX_PINS) + { + /**/ if (value < 0) + value = 0 ; + else if (value > range [pin]) + value = range [pin] ; + + marks [pin] = value ; + } +} + + +/* + * softPwmCreate: + * Create a new softPWM thread. + ********************************************************************************* + */ + +int softPwmCreate (int pin, int initialValue, int pwmRange) +{ + int res ; + pthread_t myThread ; + int *passPin ; + + if (pin >= MAX_PINS) + return -1 ; + + if (range [pin] != 0) // Already running on this pin + return -1 ; + + if (pwmRange <= 0) + return -1 ; + + passPin = malloc (sizeof (*passPin)) ; + if (passPin == NULL) + return -1 ; + + digitalWrite (pin, LOW) ; + pinMode (pin, OUTPUT) ; + + marks [pin] = initialValue ; + range [pin] = pwmRange ; + + *passPin = pin ; + newPin = pin ; + res = pthread_create (&myThread, NULL, softPwmThread, (void *)passPin) ; + + while (newPin != -1) + delay (1) ; + + threads [pin] = myThread ; + + return res ; +} + + +/* + * softPwmStop: + * Stop an existing softPWM thread + ********************************************************************************* + */ + +void softPwmStop (int pin) +{ + if (pin < MAX_PINS) + { + 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 new file mode 100644 index 0000000..0351da5 --- /dev/null +++ b/wiringPi/softPwm.h @@ -0,0 +1,35 @@ +/* + * softPwm.h: + * Provide 2 channels of software driven PWM. + * 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 . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int softPwmCreate (int pin, int value, int range) ; +extern void softPwmWrite (int pin, int value) ; +extern void softPwmStop (int pin) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/softServo.c b/wiringPi/softServo.c new file mode 100644 index 0000000..9de9f4f --- /dev/null +++ b/wiringPi/softServo.c @@ -0,0 +1,211 @@ +/* + * softServo.c: + * Provide N channels of software driven PWM suitable for RC + * servo motors. + * 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 + +#include "wiringPi.h" +#include "softServo.h" + +// RC Servo motors are a bit of an oddity - designed in the days when +// radio control was experimental and people were tryin to make +// things as simple as possible as it was all very expensive... +// +// So... To drive an RC Servo motor, you need to send it a modified PWM +// signal - it needs anything from 1ms to 2ms - with 1ms meaning +// to move the server fully left, and 2ms meaning to move it fully +// right. Then you need a long gap before sending the next pulse. +// The reason for this is that you send a multiplexed stream of these +// pulses up the radio signal into the reciever which de-multiplexes +// them into the signals for each individual servo. Typically there +// might be 8 channels, so you need at least 8 "slots" of 2mS pulses +// meaning the entire frame must fit into a 16mS slot - which would +// then be repeated... +// +// In practice we have a total slot width of about 20mS - so we're sending 50 +// updates per second to each servo. +// +// In this code, we don't need to be too fussy about the gap as we're not doing +// the multipexing, but it does need to be at least 10mS, and preferably 16 +// from what I've been able to determine. + +// WARNING: +// This code is really experimental. It was written in response to some people +// asking for a servo driver, however while it works, there is too much +// jitter to successfully drive a small servo - I have tried it with a micro +// servo and it worked, but the servo ran hot due to the jitter in the signal +// being sent to it. +// +// If you want servo control for the Pi, then use the servoblaster kernel +// module. + +#define MAX_SERVOS 8 + +static int pinMap [MAX_SERVOS] ; // Keep track of our pins +static int pulseWidth [MAX_SERVOS] ; // microseconds + + +/* + * softServoThread: + * Thread to do the actual Servo PWM output + ********************************************************************************* + */ + +static PI_THREAD (softServoThread) +{ + register int i, j, k, m, tmp ; + int lastDelay, pin, servo ; + + int myDelays [MAX_SERVOS] ; + int myPins [MAX_SERVOS] ; + + struct timeval tNow, tStart, tPeriod, tGap, tTotal ; + struct timespec tNs ; + + tTotal.tv_sec = 0 ; + tTotal.tv_usec = 8000 ; + + piHiPri (50) ; + + for (;;) + { + gettimeofday (&tStart, NULL) ; + + memcpy (myDelays, pulseWidth, sizeof (myDelays)) ; + memcpy (myPins, pinMap, sizeof (myPins)) ; + +// Sort the delays (& pins), shortest first + + for (m = MAX_SERVOS / 2 ; m > 0 ; m /= 2 ) + for (j = m ; j < MAX_SERVOS ; ++j) + for (i = j - m ; i >= 0 ; i -= m) + { + k = i + m ; + if (myDelays [k] >= myDelays [i]) + break ; + else // Swap + { + tmp = myDelays [i] ; myDelays [i] = myDelays [k] ; myDelays [k] = tmp ; + tmp = myPins [i] ; myPins [i] = myPins [k] ; myPins [k] = tmp ; + } + } + +// All on + + lastDelay = 0 ; + for (servo = 0 ; servo < MAX_SERVOS ; ++servo) + { + if ((pin = myPins [servo]) == -1) + continue ; + + digitalWrite (pin, HIGH) ; + myDelays [servo] = myDelays [servo] - lastDelay ; + lastDelay += myDelays [servo] ; + } + +// Now loop, turning them all off as required + + for (servo = 0 ; servo < MAX_SERVOS ; ++servo) + { + if ((pin = myPins [servo]) == -1) + continue ; + + delayMicroseconds (myDelays [servo]) ; + digitalWrite (pin, LOW) ; + } + +// Wait until the end of an 8mS time-slot + + gettimeofday (&tNow, NULL) ; + timersub (&tNow, &tStart, &tPeriod) ; + timersub (&tTotal, &tPeriod, &tGap) ; + tNs.tv_sec = tGap.tv_sec ; + tNs.tv_nsec = tGap.tv_usec * 1000 ; + nanosleep (&tNs, NULL) ; + } + + return NULL ; +} + + +/* + * softServoWrite: + * Write a Servo value to the given pin + ********************************************************************************* + */ + +void softServoWrite (int servoPin, int value) +{ + int servo ; + + servoPin &= 63 ; + + /**/ if (value < -250) + value = -250 ; + else if (value > 1250) + value = 1250 ; + + for (servo = 0 ; servo < MAX_SERVOS ; ++servo) + if (pinMap [servo] == servoPin) + pulseWidth [servo] = value + 1000 ; // uS +} + + +/* + * softServoSetup: + * Setup the software servo system + ********************************************************************************* + */ + +int softServoSetup (int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7) +{ + int servo ; + + if (p0 != -1) { pinMode (p0, OUTPUT) ; digitalWrite (p0, LOW) ; } + if (p1 != -1) { pinMode (p1, OUTPUT) ; digitalWrite (p1, LOW) ; } + if (p2 != -1) { pinMode (p2, OUTPUT) ; digitalWrite (p2, LOW) ; } + if (p3 != -1) { pinMode (p3, OUTPUT) ; digitalWrite (p3, LOW) ; } + if (p4 != -1) { pinMode (p4, OUTPUT) ; digitalWrite (p4, LOW) ; } + if (p5 != -1) { pinMode (p5, OUTPUT) ; digitalWrite (p5, LOW) ; } + if (p6 != -1) { pinMode (p6, OUTPUT) ; digitalWrite (p6, LOW) ; } + if (p7 != -1) { pinMode (p7, OUTPUT) ; digitalWrite (p7, LOW) ; } + + pinMap [0] = p0 ; + pinMap [1] = p1 ; + pinMap [2] = p2 ; + pinMap [3] = p3 ; + pinMap [4] = p4 ; + pinMap [5] = p5 ; + pinMap [6] = p6 ; + pinMap [7] = p7 ; + + for (servo = 0 ; servo < MAX_SERVOS ; ++servo) + pulseWidth [servo] = 1500 ; // Mid point + + return piThreadCreate (softServoThread) ; +} diff --git a/wiringPi/softServo.h b/wiringPi/softServo.h new file mode 100644 index 0000000..794cf55 --- /dev/null +++ b/wiringPi/softServo.h @@ -0,0 +1,35 @@ +/* + * softServo.h: + * Provide N channels of software driven PWM suitable for RC + * servo motors. + * 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 . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern void softServoWrite (int pin, int value) ; +extern int softServoSetup (int p0, int p1, int p2, int p3, int p4, int p5, int p6, int p7) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/softTone.c b/wiringPi/softTone.c new file mode 100644 index 0000000..e2fb737 --- /dev/null +++ b/wiringPi/softTone.c @@ -0,0 +1,150 @@ +/* + * softTone.c: + * For that authentic retro sound... + * Er... A little experiment to produce tones out of a Pi using + * one (or 2) GPIO pins and a piezeo "speaker" element. + * (Or a high impedance speaker, but don'y blame me if you blow-up + * the GPIO pins!) + * 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 "wiringPi.h" +#include "softTone.h" + +#define MAX_PINS 64 + +#define PULSE_TIME 100 + +static int freqs [MAX_PINS] ; +static pthread_t threads [MAX_PINS] ; + +static int newPin = -1 ; + + +/* + * softToneThread: + * Thread to do the actual PWM output + ********************************************************************************* + */ + +static PI_THREAD (softToneThread) +{ + 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 ; + + piHiPri (50) ; + + for (;;) + { + freq = freqs [pin] ; + if (freq == 0) + delay (1) ; + else + { + halfPeriod = 500000 / freq ; + + digitalWrite (pin, HIGH) ; + delayMicroseconds (halfPeriod) ; + + digitalWrite (pin, LOW) ; + delayMicroseconds (halfPeriod) ; + } + } + + return NULL ; +} + + +/* + * softToneWrite: + * Write a frequency value to the given pin + ********************************************************************************* + */ + +void softToneWrite (int pin, int freq) +{ + pin &= 63 ; + + /**/ if (freq < 0) + freq = 0 ; + else if (freq > 5000) // Max 5KHz + freq = 5000 ; + + freqs [pin] = freq ; +} + + +/* + * softToneCreate: + * Create a new tone thread. + ********************************************************************************* + */ + +int softToneCreate (int pin) +{ + int res ; + pthread_t myThread ; + + pinMode (pin, OUTPUT) ; + digitalWrite (pin, LOW) ; + + if (threads [pin] != 0) + return -1 ; + + freqs [pin] = 0 ; + + newPin = pin ; + 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 new file mode 100644 index 0000000..a93c5af --- /dev/null +++ b/wiringPi/softTone.h @@ -0,0 +1,39 @@ +/* + * softTone.c: + * For that authentic retro sound... + * Er... A little experiment to produce tones out of a Pi using + * one (or 2) GPIO pins and a piezeo "speaker" element. + * (Or a high impedance speaker, but don'y blame me if you blow-up + * the GPIO pins!) + * 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 . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int softToneCreate (int pin) ; +extern void softToneStop (int pin) ; +extern void softToneWrite (int pin, int freq) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/sr595.c b/wiringPi/sr595.c new file mode 100644 index 0000000..8280618 --- /dev/null +++ b/wiringPi/sr595.c @@ -0,0 +1,109 @@ +/* + * sr595.c: + * Extend wiringPi with the 74x595 shift register as a GPIO + * expander chip. + * Note that the code can cope with a number of 595's + * daisy-chained together - up to 4 for now as we're storing + * the output "register" in a single unsigned int. + * + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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 TRUE ; +} diff --git a/wiringPi/sr595.h b/wiringPi/sr595.h new file mode 100644 index 0000000..4a26dc7 --- /dev/null +++ b/wiringPi/sr595.h @@ -0,0 +1,34 @@ +/* + * sr595.h: + * Extend wiringPi with the 74x595 shift registers. + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#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/w25q64.c b/wiringPi/w25q64.c new file mode 100644 index 0000000..db8ca99 --- /dev/null +++ b/wiringPi/w25q64.c @@ -0,0 +1,362 @@ +// +// Flash Memory W25Q64 Access Library for RaspberryPi +// + +#include +#include +#include +#include +#include +#include +#include +#include "w25q64.h" + +#define SPI_SLAVE_SEL_PIN 10 // ãƒãƒƒãƒ—ã‚»ãƒ¬ã‚¯ãƒˆãƒ”ãƒ³ç•ªå· +#define MAX_BLOCKSIZE 128 // ブロックç·æ•° +#define MAX_SECTORSIZE 2048 // ç·ã‚»ã‚¯ã‚¿æ•° + +#define CMD_WRIRE_ENABLE 0x06 +#define CMD_WRITE_DISABLE 0x04 +#define CMD_READ_STATUS_R1 0x05 +#define CMD_READ_STATUS_R2 0x35 +#define CMD_WRITE_STATUS_R 0x01 // 未実装 +#define CMD_PAGE_PROGRAM 0x02 +#define CMD_QUAD_PAGE_PROGRAM 0x32 // 未実装 +#define CMD_BLOCK_ERASE64KB 0xd8 +#define CMD_BLOCK_ERASE32KB 0x52 +#define CMD_SECTOR_ERASE 0x20 +#define CMD_CHIP_ERASE 0xC7 +#define CMD_ERASE_SUPPEND 0x75 // 未実装 +#define CMD_ERASE_RESUME 0x7A // 未実装 +#define CMD_POWER_DOWN 0xB9 +#define CMD_HIGH_PERFORM_MODE 0xA3 // 未実装 +#define CMD_CNT_READ_MODE_RST 0xFF // 未実装 +#define CMD_RELEASE_PDOWN_ID 0xAB // 未実装 +#define CMD_MANUFACURER_ID 0x90 +#define CMD_READ_UNIQUE_ID 0x4B +#define CMD_JEDEC_ID 0x9f + +#define CMD_READ_DATA 0x03 +#define CMD_FAST_READ 0x0B +#define CMD_READ_DUAL_OUTPUT 0x3B // 未実装 +#define CMD_READ_DUAL_IO 0xBB // 未実装 +#define CMD_READ_QUAD_OUTPUT 0x6B // 未実装 +#define CMD_READ_QUAD_IO 0xEB // 未実装 +#define CMD_WORD_READ 0xE3 // 未実装 + +#define SR1_BUSY_MASK 0x01 +#define SR1_WEN_MASK 0x02 + +//#define SPI_CHANNEL 0 // /dev/spidev0.0 +#define SPI_CHANNEL 1 // /dev/spidev0.1 + +//static uint8_t cspin ; +static uint8_t _spich; + +void spcDump(char *id,int rc, uint8_t *data,int len) { + int i; + printf("[%s] = %d\n",id,rc); + for(i=0;i>16) & 0xFF; // A23-A16 + data[2] = (addr>>8) & 0xFF; // A15-A08 + data[3] = addr & 0xFF; // A07-A00 + rc = wiringPiSPIDataRW (_spich,data,n+4); +// spcDump("read",rc,data,rc); + memcpy(buf,&data[4],n); + free(data); + return rc-4; +} + +// +// 高速データã®èª­ã¿è¾¼ã¿ +// addr(in): 読込開始アドレス (24ビット 0x00000 - 0xFFFFF) +// n(in):読込データ数 +// +uint16_t W25Q64_fastread(uint32_t addr,uint8_t *buf,uint16_t n) { + uint8_t *data; + int rc; + + data = (char*)malloc(n+5); + data[0] = CMD_FAST_READ; + data[1] = (addr>>16) & 0xFF; // A23-A16 + data[2] = (addr>>8) & 0xFF; // A15-A08 + data[3] = addr & 0xFF; // A07-A00 + data[4] = 0; + rc = wiringPiSPIDataRW (_spich,data,n+5); +// spcDump("fastread",rc,data,rc); + memcpy(buf,&data[5],n); + return rc-5; +} + +// +// セクタå˜ä½æ¶ˆåŽ»(4kb空間å˜ä½ã§ãƒ‡ãƒ¼ã‚¿ã®æ¶ˆåŽ»ã‚’è¡Œã†) +// sect_no(in) セクタ番å·(0 - 2048) +// flgwait(in) true:処ç†å¾…ã¡ã‚’行ㆠfalse:å¾…ã¡ç„¡ã— +// 戻り値: true:正常終了 false:失敗 +// 補足: データシートã§ã¯æ¶ˆåŽ»ã«é€šå¸¸ 30ms ã€æœ€å¤§400msã‹ã‹ã‚‹ã¨è¨˜è¼‰ã•ã‚Œã¦ã„ã‚‹ +// アドレス23ビットã®ã†ã¡ä¸Šä½ 11ビットãŒã‚»ã‚¯ã‚¿ç•ªå·ã®ç›¸å½“ã™ã‚‹ã€‚下ä½12ビットã¯ã‚»ã‚¯ã‚¿å†…アドレスã¨ãªã‚‹ã€‚ +// +bool W25Q64_eraseSector(uint16_t sect_no, bool flgwait) { + uint8_t data[4]; + int rc; + uint32_t addr = sect_no; + addr<<=12; + + W25Q64_WriteEnable(); + data[0] = CMD_SECTOR_ERASE; + data[1] = (addr>>16) & 0xff; + data[2] = (addr>>8) & 0xff; + data[3] = addr & 0xff; + rc = wiringPiSPIDataRW (_spich,data,sizeof(data)); + + // 処ç†å¾…ã¡ + while(W25Q64_IsBusy() & flgwait) { + delay(10); + } + return true; +} + +// +// 64KBブロックå˜ä½æ¶ˆåŽ»(64kb空間å˜ä½ã§ãƒ‡ãƒ¼ã‚¿ã®æ¶ˆåŽ»ã‚’è¡Œã†) +// blk_no(in) ブロック番å·(0 - 127) +// flgwait(in) true:処ç†å¾…ã¡ã‚’行ㆠfalse:å¾…ã¡ç„¡ã— +// 戻り値: true:正常終了 false:失敗 +// 補足: データシートã§ã¯æ¶ˆåŽ»ã«é€šå¸¸ 150ms ã€æœ€å¤§1000msã‹ã‹ã‚‹ã¨è¨˜è¼‰ã•ã‚Œã¦ã„ã‚‹ +// アドレス23ビットã®ã†ã¡ä¸Šä½ 7ビットãŒãƒ–ロックã®ç›¸å½“ã™ã‚‹ã€‚下ä½16ビットã¯ãƒ–ロック内アドレスã¨ãªã‚‹ã€‚ +// +bool W25Q64_erase64Block(uint16_t blk_no, bool flgwait) { + uint8_t data[4]; + int rc; + uint32_t addr = blk_no; + addr<<=16; + + W25Q64_WriteEnable(); + data[0] = CMD_BLOCK_ERASE64KB; + data[1] = (addr>>16) & 0xff; + data[2] = (addr>>8) & 0xff; + data[3] = addr & 0xff; + rc = wiringPiSPIDataRW (_spich,data,sizeof(data)); + + // 処ç†å¾…ã¡ + while(W25Q64_IsBusy() & flgwait) { + delay(50); + } + return true; +} + +// +// 32KBブロックå˜ä½æ¶ˆåŽ»(32kb空間å˜ä½ã§ãƒ‡ãƒ¼ã‚¿ã®æ¶ˆåŽ»ã‚’è¡Œã†) +// blk_no(in) ブロック番å·(0 - 255) +// flgwait(in) true:処ç†å¾…ã¡ã‚’行ㆠfalse:å¾…ã¡ç„¡ã— +// 戻り値: true:正常終了 false:失敗 +// 補足: データシートã§ã¯æ¶ˆåŽ»ã«é€šå¸¸ 120ms ã€æœ€å¤§800msã‹ã‹ã‚‹ã¨è¨˜è¼‰ã•ã‚Œã¦ã„ã‚‹ +// アドレス23ビットã®ã†ã¡ä¸Šä½ 8ビットãŒãƒ–ロックã®ç›¸å½“ã™ã‚‹ã€‚下ä½15ビットã¯ãƒ–ロック内アドレスã¨ãªã‚‹ã€‚ +// +bool W25Q64_erase32Block(uint16_t blk_no, bool flgwait) { + uint8_t data[4]; + int rc; + uint32_t addr = blk_no; + addr<<=15; + + W25Q64_WriteEnable(); + data[0] = CMD_BLOCK_ERASE32KB; + data[1] = (addr>>16) & 0xff; + data[2] = (addr>>8) & 0xff; + data[3] = addr & 0xff; + rc = wiringPiSPIDataRW (_spich,data,sizeof(data)); + + // 処ç†å¾…ã¡ + while(W25Q64_IsBusy() & flgwait) { + delay(50); + } + return true; +} + +// +// 全領域ã®æ¶ˆåŽ» +// flgwait(in) true:処ç†å¾…ã¡ã‚’行ㆠfalse:å¾…ã¡ç„¡ã— +// 戻り値: true:正常終了 false:失敗 +// 補足: データシートã§ã¯æ¶ˆåŽ»ã«é€šå¸¸ 15s ã€æœ€å¤§30sã‹ã‹ã‚‹ã¨è¨˜è¼‰ã•ã‚Œã¦ã„ã‚‹ +// +bool W25Q64_eraseAll(bool flgwait) { + uint8_t data[1]; + int rc; + + W25Q64_WriteEnable(); + data[0] = CMD_CHIP_ERASE; + rc = wiringPiSPIDataRW (_spich,data,sizeof(data)); + + // 処ç†å¾…ã¡ + while(W25Q64_IsBusy() & flgwait) { + delay(500); + } + return true; +} + +// データã®æ›¸ã込㿠+// sect_no(in) : セクタ番å·(0x00 - 0x7FF) +// inaddr(in) : セクタ内アドレス(0x00-0xFFF) +// data(in) : 書込ã¿ãƒ‡ãƒ¼ã‚¿æ ¼ç´ã‚¢ãƒ‰ãƒ¬ã‚¹ +// n(in) : 書込ã¿ãƒã‚¤ãƒˆæ•°(0~256) +// +uint16_t W25Q64_pageWrite(uint16_t sect_no, uint16_t inaddr, uint8_t* buf, uint8_t n) { +// uint8_t data[4]; + uint8_t *data; + int rc; + + uint32_t addr = sect_no; + int i; + addr<<=12; + addr += inaddr; + + W25Q64_WriteEnable(); + + if (W25Q64_IsBusy()) { + return 0; + } + + data = (char*)malloc(n+4); + data[0] = CMD_PAGE_PROGRAM; + data[1] = (addr>>16) & 0xff; + data[2] = (addr>>8) & 0xff; + data[3] = addr & 0xFF; + memcpy(&data[4],buf,n); + rc = wiringPiSPIDataRW (_spich,data,n+4); +// spcDump("pageWrite",rc,buf,n); + + while(W25Q64_IsBusy()) ; + free(data); + return rc; +} diff --git a/wiringPi/w25q64.h b/wiringPi/w25q64.h new file mode 100644 index 0000000..543479b --- /dev/null +++ b/wiringPi/w25q64.h @@ -0,0 +1,36 @@ +//#include +//#include + +// フラッシュメモリ W25Q64ã®åˆ©ç”¨é–‹å§‹ +void W25Q64_begin(uint8_t cs); +// ステータスレジスタ1ã®å€¤å–å¾— +uint8_t W25Q64_readStatusReg1(void); +// ステータスレジスタ2ã®å€¤å–å¾— +uint8_t W25Q64_readStatusReg2(); +// JEDEC ID(Manufacture, Memory Type,Capacity)ã®å–å¾— +void W25Q64_readManufacturer(uint8_t* d); +// Unique IDã®å–å¾— +void W25Q64_readUniqieID(uint8_t* d); +// 書込ã¿ç­‰ã®å‡¦ç†ä¸­ãƒã‚§ãƒƒã‚¯ +bool W25Q64_IsBusy(); +// パワーダウン指定 +void W25Q64_powerDown(void); +// 書込ã¿è¨±å¯è¨­å®š +void W25Q64_WriteEnable(void); +// 書込ã¿ç¦æ­¢è¨­å®š +void W25Q64_WriteDisable(void); +// データã®èª­ã¿è¾¼ã¿ +uint16_t W25Q64_read(uint32_t addr,uint8_t *buf,uint16_t n); +// 高速データã®èª­ã¿è¾¼ã¿ +uint16_t W25Q64_fastread(uint32_t addr,uint8_t *buf,uint16_t n); +// セクタå˜ä½æ¶ˆåŽ» +bool W25Q64_eraseSector(uint16_t sect_no, bool flgwait); +// 64KBブロックå˜ä½æ¶ˆåŽ» +bool W25Q64_erase64Block(uint16_t blk_no, bool flgwait); +// 32KBブロックå˜ä½æ¶ˆåŽ» +bool W25Q64_erase32Block(uint16_t blk_no, bool flgwait); +// 全領域ã®æ¶ˆåŽ» +bool W25Q64_eraseAll(bool flgwait); +// データã®æ›¸ã込㿠+uint16_t W25Q64_pageWrite(uint16_t sect_no, uint16_t inaddr, uint8_t* data, uint8_t n); + diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c new file mode 100644 index 0000000..3e3b924 --- /dev/null +++ b/wiringPi/wiringPi.c @@ -0,0 +1,2698 @@ +/* + * wiringPi: + * Arduino look-a-like Wiring library for the Raspberry Pi + * Copyright (c) 2012-2017 Gordon Henderson + * Additional code for pwmSetClock by Chris Hall + * + * Thanks to code samples from Gert Jan van Loo and the + * BCM2835 ARM Peripherals manual, however it's missing + * the clock section /grr/mutter/ + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +// Revisions: +// 19 Jul 2012: +// Moved to the LGPL +// Added an abstraction layer to the main routines to save a tiny +// bit of run-time and make the clode a little cleaner (if a little +// larger) +// Added waitForInterrupt code +// Added piHiPri code +// +// 9 Jul 2012: +// Added in support to use the /sys/class/gpio interface. +// 2 Jul 2012: +// Fixed a few more bugs to do with range-checking when in GPIO mode. +// 11 Jun 2012: +// Fixed some typos. +// Added c++ support for the .h file +// Added a new function to allow for using my "pin" numbers, or native +// GPIO pin numbers. +// Removed my busy-loop delay and replaced it with a call to delayMicroseconds +// +// 02 May 2012: +// Added in the 2 UART pins +// Change maxPins to numPins to more accurately reflect purpose + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "softPwm.h" +#include "softTone.h" + +#include "wiringPi.h" +#include "../version.h" + +#ifdef CONFIG_ORANGEPI +#include "OrangePi.h" +#endif + +// Environment Variables + +#define ENV_DEBUG "WIRINGPI_DEBUG" +#define ENV_CODES "WIRINGPI_CODES" +#define ENV_GPIOMEM "WIRINGPI_GPIOMEM" + +#ifdef CONFIG_ORANGEPI +static int version=0; +static int *physToPin; +static int wiringPinMode = WPI_MODE_UNINITIALISED ; +#endif + +// Extend wiringPi with other pin-based devices and keep track of +// them in this structure + +struct wiringPiNodeStruct *wiringPiNodes = NULL ; + +// BCM Magic + +#define BCM_PASSWORD 0x5A000000 + + +// The BCM2835 has 54 GPIO pins. +// BCM2835 data sheet, Page 90 onwards. +// There are 6 control registers, each control the functions of a block +// of 10 pins. +// Each control register has 10 sets of 3 bits per GPIO pin - the ALT values +// +// 000 = GPIO Pin X is an input +// 001 = GPIO Pin X is an output +// 100 = GPIO Pin X takes alternate function 0 +// 101 = GPIO Pin X takes alternate function 1 +// 110 = GPIO Pin X takes alternate function 2 +// 111 = GPIO Pin X takes alternate function 3 +// 011 = GPIO Pin X takes alternate function 4 +// 010 = GPIO Pin X takes alternate function 5 +// +// So the 3 bits for port X are: +// X / 10 + ((X % 10) * 3) + +// Port function select bits + +#define FSEL_INPT 0b000 +#define FSEL_OUTP 0b001 +#define FSEL_ALT0 0b100 +#define FSEL_ALT1 0b101 +#define FSEL_ALT2 0b110 +#define FSEL_ALT3 0b111 +#define FSEL_ALT4 0b011 +#define FSEL_ALT5 0b010 + +// 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, v3, etc. and the new /dev/gpiomem interface + +static volatile unsigned int GPIO_PADS ; +static volatile unsigned int GPIO_CLOCK_BASE ; + +#ifndef CONFIG_ORANGEPI +static volatile unsigned int GPIO_BASE ; +#endif + +static volatile unsigned int GPIO_TIMER ; +//static volatile unsigned int GPIO_PWM; + +#define PAGE_SIZE (4*1024) +#define BLOCK_SIZE (4*1024) + +static unsigned int usingGpioMem = FALSE ; +static int wiringPiSetuped = FALSE ; +static int wiringPiSysSetuped = FALSE ; + + +// PWM +// Word offsets into the PWM control region + +#define PWM_CONTROL 0 +#define PWM_STATUS 1 +#define PWM0_RANGE 4 +#define PWM0_DATA 5 +#define PWM1_RANGE 8 +#define PWM1_DATA 9 + +// Clock regsiter offsets + +#define PWMCLK_CNTL 40 +#define PWMCLK_DIV 41 + +#define PWM0_MS_MODE 0x0080 // Run in MS mode +#define PWM0_USEFIFO 0x0020 // Data from FIFO +#define PWM0_REVPOLAR 0x0010 // Reverse polarity +#define PWM0_OFFSTATE 0x0008 // Ouput Off state +#define PWM0_REPEATFF 0x0004 // Repeat last value if FIFO empty +#define PWM0_SERIAL 0x0002 // Run in serial mode +#define PWM0_ENABLE 0x0001 // Channel Enable + +#define PWM1_MS_MODE 0x8000 // Run in MS mode +#define PWM1_USEFIFO 0x2000 // Data from FIFO +#define PWM1_REVPOLAR 0x1000 // Reverse polarity +#define PWM1_OFFSTATE 0x0800 // Ouput Off state +#define PWM1_REPEATFF 0x0400 // Repeat last value if FIFO empty +#define PWM1_SERIAL 0x0200 // Run in serial mode +#define PWM1_ENABLE 0x0100 // Channel Enable + +// Timer +// Word offsets + +#define TIMER_LOAD (0x400 >> 2) +#define TIMER_VALUE (0x404 >> 2) +#define TIMER_CONTROL (0x408 >> 2) +#define TIMER_IRQ_CLR (0x40C >> 2) +#define TIMER_IRQ_RAW (0x410 >> 2) +#define TIMER_IRQ_MASK (0x414 >> 2) +#define TIMER_RELOAD (0x418 >> 2) +#define TIMER_PRE_DIV (0x41C >> 2) +#define TIMER_COUNTER (0x420 >> 2) + +// Locals to hold pointers to the hardware + +static volatile unsigned int *gpio ; +static volatile unsigned int *pwm ; +static volatile unsigned int *clk ; +static volatile unsigned int *pads ; +//static volatile unsigned int *timer ; +//static volatile unsigned int *timerIrqRaw ; + +// Export variables for the hardware pointers + +volatile unsigned int *_wiringPiGpio ; +volatile unsigned int *_wiringPiPwm ; +volatile unsigned int *_wiringPiClk ; +volatile unsigned int *_wiringPiPads ; +volatile unsigned int *_wiringPiTimer ; +volatile unsigned int *_wiringPiTimerIrqRaw ; + + +// 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! + +// piGpioBase: +// The base address of the GPIO memory mapped hardware IO + +#define GPIO_PERI_BASE_OLD 0x20000000 +#define GPIO_PERI_BASE_NEW 0x3F000000 + +static volatile unsigned int piGpioBase = 0 ; + +#ifndef CONFIG_ORANGEPI +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 + "Pi 3", // 08 + "Pi Zero", // 09 + "CM3", // 10 + "Unknown11", // 11 + "Pi Zero-W", // 12 + "Pi 3+", // 13 + "Unknown14", // 14 + "Unknown15", // 15 +} ; +#endif + +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 + +static uint64_t epochMilli, epochMicro ; + +// Misc + +static int wiringPiMode = WPI_MODE_UNINITIALISED ; +static volatile int pinPass = -1 ; +static pthread_mutex_t pinMutex ; + +// Debugging & Return codes + +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[384] = + { + -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,-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,-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,-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,-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,-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 + +static void (*isrFunctions [64])(void) ; + + +// Doing it the Arduino way with lookup tables... +// Yes, it's probably more innefficient than all the bit-twidling, but it +// does tend to make it all a bit clearer. At least to me! + +// pinToGpio: +// Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin +// 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: 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: + + -1, -1, -1, -1, -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 +}; + +// 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 + 2, 3, // I2C - SDA0, SCL0 wpi 8 - 9 + 8, 7, // SPI - CE1, CE0 wpi 10 - 11 + 10, 9, 11, // SPI - MOSI, MISO, SCLK wpi 12 - 14 + 14, 15, // UART - Tx, Rx wpi 15 - 16 + 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, -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 Function Selection +// control port. (GPFSEL 0-5) +// Groups of 10 - 3 bits per Function - 30 bits per port + +static uint8_t gpioToGPFSEL [] = +{ + 0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5, +} ; + + +// gpioToShift +// Define the shift up for the 3 bits per pin in each GPFSEL port + +static uint8_t gpioToShift [] = +{ + 0,3,6,9,12,15,18,21,24,27, + 0,3,6,9,12,15,18,21,24,27, + 0,3,6,9,12,15,18,21,24,27, + 0,3,6,9,12,15,18,21,24,27, + 0,3,6,9,12,15,18,21,24,27, + 0,3,6,9,12,15,18,21,24,27, +} ; + + +// gpioToGPSET: +// (Word) offset to the GPIO Set registers for each GPIO pin + +static uint8_t gpioToGPSET [] = +{ + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 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 + +static uint8_t gpioToGPCLR [] = +{ + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, +} ; + + +// gpioToGPLEV: +// (Word) offset to the GPIO Input level registers for each GPIO pin + +static uint8_t gpioToGPLEV [] = +{ + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, +} ; + + +#ifdef notYetReady +// gpioToEDS +// (Word) offset to the Event Detect Status + +static uint8_t gpioToEDS [] = +{ + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, +} ; + +// gpioToREN +// (Word) offset to the Rising edge ENable register + +static uint8_t gpioToREN [] = +{ + 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, +} ; + +// gpioToFEN +// (Word) offset to the Falling edgde ENable register + +static uint8_t gpioToFEN [] = +{ + 22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, +} ; +#endif + + +// GPPUD: +// GPIO Pin pull up/down register + +#define GPPUD 37 + +// gpioToPUDCLK +// (Word) offset to the Pull Up Down Clock regsiter + +static uint8_t gpioToPUDCLK [] = +{ + 38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38, + 39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39, +} ; + + +// gpioToPwmALT +// the ALT value to put a GPIO pin into PWM mode + +static uint8_t gpioToPwmALT [] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7 + 0, 0, 0, 0, FSEL_ALT0, FSEL_ALT0, 0, 0, // 8 -> 15 + 0, 0, FSEL_ALT5, FSEL_ALT5, 0, 0, 0, 0, // 16 -> 23 + 0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31 + 0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39 + FSEL_ALT0, FSEL_ALT0, 0, 0, 0, FSEL_ALT0, 0, 0, // 40 -> 47 + 0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55 + 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63 +} ; + + +// gpioToPwmPort +// The port value to put a GPIO pin into PWM mode + +/*static uint8_t gpioToPwmPort [] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7 + 0, 0, 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, // 8 -> 15 + 0, 0, PWM0_DATA, PWM1_DATA, 0, 0, 0, 0, // 16 -> 23 + 0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31 + 0, 0, 0, 0, 0, 0, 0, 0, // 32 -> 39 + PWM0_DATA, PWM1_DATA, 0, 0, 0, PWM1_DATA, 0, 0, // 40 -> 47 + 0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55 + 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63 + +} ;*/ + +// 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 respectively, however I'll include the full +// list for completeness - maybe one day... + +#define GPIO_CLOCK_SOURCE 1 + +// gpioToGpClkALT0: + +static uint8_t gpioToGpClkALT0 [] = +{ + 0, 0, 0, 0, FSEL_ALT0, FSEL_ALT0, FSEL_ALT0, 0, // 0 -> 7 + 0, 0, 0, 0, 0, 0, 0, 0, // 8 -> 15 + 0, 0, 0, 0, FSEL_ALT5, FSEL_ALT5, 0, 0, // 16 -> 23 + 0, 0, 0, 0, 0, 0, 0, 0, // 24 -> 31 + FSEL_ALT0, 0, FSEL_ALT0, 0, 0, 0, 0, 0, // 32 -> 39 + 0, 0, FSEL_ALT0, FSEL_ALT0, FSEL_ALT0, 0, 0, 0, // 40 -> 47 + 0, 0, 0, 0, 0, 0, 0, 0, // 48 -> 55 + 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63 +} ; + +// gpioToClk: +// (word) Offsets to the clock Control and Divisor register + +static uint8_t gpioToClkCon [] = +{ + -1, -1, -1, -1, 28, 30, 32, -1, // 0 -> 7 + -1, -1, -1, -1, -1, -1, -1, -1, // 8 -> 15 + -1, -1, -1, -1, 28, 30, -1, -1, // 16 -> 23 + -1, -1, -1, -1, -1, -1, -1, -1, // 24 -> 31 + 28, -1, 28, -1, -1, -1, -1, -1, // 32 -> 39 + -1, -1, 28, 30, 28, -1, -1, -1, // 40 -> 47 + -1, -1, -1, -1, -1, -1, -1, -1, // 48 -> 55 + -1, -1, -1, -1, -1, -1, -1, -1, // 56 -> 63 +} ; + +static uint8_t gpioToClkDiv [] = +{ + -1, -1, -1, -1, 29, 31, 33, -1, // 0 -> 7 + -1, -1, -1, -1, -1, -1, -1, -1, // 8 -> 15 + -1, -1, -1, -1, 29, 31, -1, -1, // 16 -> 23 + -1, -1, -1, -1, -1, -1, -1, -1, // 24 -> 31 + 29, -1, 29, -1, -1, -1, -1, -1, // 32 -> 39 + -1, -1, 29, 31, 29, -1, -1, -1, // 40 -> 47 + -1, -1, -1, -1, -1, -1, -1, -1, // 48 -> 55 + -1, -1, -1, -1, -1, -1, -1, -1, // 56 -> 63 +} ; + + +/* + * Functions + ********************************************************************************* + */ + + +/* + * wiringPiFailure: + * Fail. Or not. + ********************************************************************************* + */ + +int wiringPiFailure (int fatal, const char *message, ...) +{ + 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 ; +} + + +/* + * setupCheck + * Another sanity check because some users forget to call the setup + * function. Mosty because they need feeding C drip by drip )-: + ********************************************************************************* + */ + +static void setupCheck (const char *fName) +{ + if (!wiringPiSetuped) + { + fprintf (stderr, "%s: You have not called one of the wiringPiSetup\n" + " functions, so I'm aborting your program before it crashes anyway.\n", fName) ; + exit (EXIT_FAILURE) ; + } +} + +/* + * gpioMemCheck: + * See if we're using the /dev/gpiomem interface, if-so then some operations + * can't be done and will crash the Pi. + ********************************************************************************* + */ + +static void usingGpioMemCheck (const char *what) +{ + if (usingGpioMem) + { + fprintf (stderr, "%s: Unable to do this when using /dev/gpiomem. Try sudo?\n", what) ; + exit (EXIT_FAILURE) ; + } +} + +/* + * piGpioLayout: + * Return a number representing the hardware revision of the board. + * 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 .... + * + * 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+ ... + * + * 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. + * + * Additionally, here we set the piModel2 flag too. This is again, nothing to + * do with the actual model, but the major version numbers - the GPIO base + * hardware address changed at model 2 and above (not the Zero though) + * + ********************************************************************************* + */ + +void piGpioLayoutOops (const char *why) +{ + fprintf (stderr, "Oops: Unable to determine board revision from /proc/cpuinfo\n") ; + fprintf (stderr, " -> %s\n", why) ; + fprintf (stderr, " -> You'd best google the error to find out why.\n") ; +//fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ; + exit (EXIT_FAILURE) ; +} + +int piGpioLayout (void) +{ + FILE *cpuFd ; + char line [120] ; + char *c ; + static int gpioLayout = -1 ; + +#ifdef CONFIG_ORANGEPI + if(isOrangePi()) { + version = ORANGEPI; + + return ORANGEPI; + } +#endif + + if (gpioLayout != -1) // No point checking twice + return gpioLayout ; + + if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL) + piGpioLayoutOops ("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 CONFIG_ORANGEPI_RK3399 || CONFIG_ORANGEPI_4 || CONFIG_ORANGEPI_4_LTS || CONFIG_ORANGEPI_800 + strcpy(line, "Hardware : Rockchip rk3399 Family"); +#elif CONFIG_ORANGEPI_R1PLUS + strcpy(line, "Hardware : Rockchip rk3328 Family"); +#endif + + if (strncmp (line, "Hardware", 8) != 0) + piGpioLayoutOops ("No \"Hardware\" line") ; + + if (wiringPiDebug) + printf ("piGpioLayout: Hardware: %s\n", line) ; + + rewind (cpuFd) ; + + while (fgets (line, 120, cpuFd) != NULL) + if (strncmp (line, "Revision", 8) == 0) + break ; + + fclose (cpuFd) ; + +#if CONFIG_ORANGEPI_RK3399 || CONFIG_ORANGEPI_4 || CONFIG_ORANGEPI_4_LTS || CONFIG_ORANGEPI_R1PLUS || CONFIG_ORANGEPI_800 + strcpy(line, "Revision : 0000"); +#endif + + if (strncmp (line, "Revision", 8) != 0) + piGpioLayoutOops ("No \"Revision\" line") ; + +// Chomp trailing CR/NL + + for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c) + *c = 0 ; + + if (wiringPiDebug) + printf ("piGpioLayout: Revision string: %s\n", line) ; + +// Scan to the first character of the revision number + + for (c = line ; *c ; ++c) + if (*c == ':') + break ; + + if (*c != ':') + piGpioLayoutOops ("Bogus \"Revision\" line (no colon)") ; + +// Chomp spaces + + ++c ; + while (isspace (*c)) + ++c ; + + if (!isxdigit (*c)) + piGpioLayoutOops ("Bogus \"Revision\" line (no hex digit at start of revision)") ; + +// Make sure its long enough + + if (strlen (c) < 4) + piGpioLayoutOops ("Bogus revision line (too small)") ; + +// Isolate last 4 characters: (in-case of overvolting or new encoding scheme) + + c = c + strlen (c) - 4 ; + + if (wiringPiDebug) + printf ("piGpioLayout: last4Chars are: \"%s\"\n", c) ; + + if ( (strcmp (c, "0002") == 0) || (strcmp (c, "0003") == 0)) + gpioLayout = 1 ; + else + gpioLayout = 2 ; // Covers everything else from the B revision 2 to the B+, the Pi v2, v3, zero and CM's. + + if (wiringPiDebug) + printf ("piGpioLayoutOops: Returning revision: %d\n", gpioLayout) ; + + return gpioLayout ; +} + +/* + * piBoardRev: + * Deprecated, but does the same as piGpioLayout + ********************************************************************************* + */ + +int piBoardRev (void) +{ + return piGpioLayout () ; +} + +/* + * 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 1.2, 256MB, Sony + * 0005 - Model B, Rev 1.2, 256MB, Egoman + * 0006 - Model B, Rev 1.2, 256MB, Egoman + * + * 0007 - Model A, Rev 1.2, 256MB, Egoman + * 0008 - Model A, Rev 1.2, 256MB, Sony + * 0009 - Model A, Rev 1.2, 256MB, Egoman + * + * 000d - Model B, Rev 1.2, 512MB, Egoman (Red Pi, Blue Pi?) + * 000e - Model B, Rev 1.2, 512MB, Sony + * 000f - Model B, Rev 1.2, 512MB, Egoman + * + * 0010 - Model B+, Rev 1.2, 512MB, Sony + * 0013 - Model B+ Rev 1.2, 512MB, Embest + * 0016 - Model B+ Rev 1.2, 512MB, Sony + * 0019 - Model B+ Rev 1.2, 512MB, Egoman + * + * 0011 - Pi CM, Rev 1.1, 512MB, Sony + * 0014 - Pi CM, Rev 1.1, 512MB, Embest + * 0017 - Pi CM, Rev 1.1, 512MB, Sony + * 001a - Pi CM, Rev 1.1, 512MB, Egoman + * + * 0012 - Model A+ Rev 1.1, 256MB, Sony + * 0015 - Model A+ Rev 1.1, 512MB, Embest + * 0018 - Model A+ Rev 1.1, 256MB, Sony + * 001b - Model A+ Rev 1.1, 256MB, Egoman + * + * 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 ; + +#ifdef CONFIG_ORANGEPI + if(isOrangePi()) { + *model = PI_MODEL_ORANGEPI; + *rev = PI_VERSION_1_2; + *mem = ORANGEPI_MEM_INFO; + *maker = PI_MAKER_ORANGEPI; + + return; + } +#endif + + (void)piGpioLayout () ; // Call this first to make sure all's OK. Don't care about the result. + + if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL) + piGpioLayoutOops ("Unable to open /proc/cpuinfo") ; + + while (fgets (line, 120, cpuFd) != NULL) + if (strncmp (line, "Revision", 8) == 0) + break ; + + fclose (cpuFd) ; +#if (defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_800 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_R1PLUS) + strcpy(line, "Revision : 0000"); +#endif + + if (strncmp (line, "Revision", 8) != 0) + piGpioLayoutOops ("No \"Revision\" line") ; + +// Chomp trailing CR/NL + + for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c) + *c = 0 ; + + if (wiringPiDebug) + 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 (*c == ':') + break ; + + if (*c != ':') + piGpioLayoutOops ("Bogus \"Revision\" line (no colon)") ; + +// Chomp spaces + + ++c ; + while (isspace (*c)) + ++c ; + + if (!isxdigit (*c)) + piGpioLayoutOops ("Bogus \"Revision\" line (no hex digit at start of revision)") ; + + revision = (unsigned int)strtol (c, NULL, 16) ; // Hex number with no leading 0x + +// Check for new way: + + if ((revision & (1 << 23)) != 0) // New way + { + if (wiringPiDebug) + printf ("piBoardId: New Way: revision is: %08X\n", revision) ; + + 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)) + piGpioLayoutOops ("Bogus \"Revision\" line (no digit at start of revision)") ; + +// Make sure its long enough + + if (strlen (c) < 4) + piGpioLayoutOops ("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_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0005") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0006") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + + else if (strcmp (c, "0007") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0008") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; ; } + else if (strcmp (c, "0009") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + + else if (strcmp (c, "000d") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "000e") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "000f") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_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, "0013") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; } + else if (strcmp (c, "0016") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0019") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + + else if (strcmp (c, "0011") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0014") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; } + else if (strcmp (c, "0017") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "001a") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + + else if (strcmp (c, "0012") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0015") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; } + else if (strcmp (c, "0018") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "001b") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + #ifdef CONFIG_ORANGEPI + else if (strcmp (c, "0000") == 0) { *model = PI_MODEL_ORANGEPI; *rev = PI_VERSION_1_2; *mem = ORANGEPI_MEM_INFO; *maker = PI_MAKER_ORANGEPI; } + #endif + 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 ((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: + * Returns the ALT bits for a given port. Only really of-use + * for the gpio readall command (I think) + ********************************************************************************* + */ + +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; + + alt = OrangePi_get_gpio_mode(pin); + + return alt; +} + +/* + * pwmSetMode: + * Select the native "balanced" mode, or standard mark:space mode + ********************************************************************************* + */ + +void pwmSetMode(int mode) { + sunxi_pwm_set_mode(mode); + return; +} + +/* + * pwmSetRange: + * Set the PWM range register. We set both range registers to the same + * value. If you want different in your own code, then write your own. + ********************************************************************************* + */ + +void pwmSetRange(unsigned int range) { + sunxi_pwm_set_period(range); + return; +} + +/* + * 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 pwmSetClock(int divisor) { + sunxi_pwm_set_clk(divisor); + sunxi_pwm_set_enable(1); + return; +} + +/* + * gpioClockSet: + * Set the frequency on a GPIO clock pin + ********************************************************************************* + */ + +void gpioClockSet (int pin, int freq) +{ + int divi, divr, divf ; + + pin &= 63 ; + + /**/ if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [pin] ; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio [pin] ; + else if (wiringPiMode != WPI_MODE_GPIO) + return ; + + divi = 19200000 / freq ; + divr = 19200000 % freq ; + divf = (int)((double)divr * 4096.0 / 19200000.0) ; + + 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 (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int mode) { return ; } +static void pullUpDnControlDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int pud) { return ; } +//static unsigned int digitalRead8Dummy (UNU struct wiringPiNodeStruct *node, UNU int UNU pin) { return 0 ; } +//static void digitalWrite8Dummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } +static int digitalReadDummy (UNU struct wiringPiNodeStruct *node, UNU int UNU pin) { return LOW ; } +static void digitalWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } +static void pwmWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } +static int analogReadDummy (UNU struct wiringPiNodeStruct *node, UNU int pin) { return 0 ; } +static void analogWriteDummy (UNU struct wiringPiNodeStruct *node, UNU int pin, UNU int value) { return ; } + +struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) +{ + int pin ; + struct wiringPiNodeStruct *node ; + +// Minimum pin base is 64 + + if (pinBase < 64) + (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: pinBase of %d is < 64\n", pinBase) ; + +// Check all pins in-case there is overlap: + + for (pin = pinBase ; pin < (pinBase + numPins) ; ++pin) + if (wiringPiFindNode (pin) != NULL) + (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Pin %d overlaps with existing definition\n", pin) ; + + node = (struct wiringPiNodeStruct *)calloc (sizeof (struct wiringPiNodeStruct), 1) ; // calloc zeros + if (node == NULL) + (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Unable to allocate memory: %s\n", strerror (errno)) ; + + node->pinBase = pinBase ; + node->pinMax = pinBase + numPins - 1 ; + node->pinMode = pinModeDummy ; + node->pullUpDnControl = pullUpDnControlDummy ; + node->digitalRead = digitalReadDummy ; +//node->digitalRead8 = digitalRead8Dummy ; + node->digitalWrite = digitalWriteDummy ; +//node->digitalWrite8 = digitalWrite8Dummy ; + node->pwmWrite = pwmWriteDummy ; + node->analogRead = analogReadDummy ; + node->analogWrite = analogWriteDummy ; + node->next = wiringPiNodes ; + wiringPiNodes = node ; + + return node ; +} + + +#ifdef notYetReady +/* + * pinED01: + * pinED10: + * Enables edge-detect mode on a pin - from a 0 to a 1 or 1 to 0 + * Pin must already be in input mode with appropriate pull up/downs set. + ********************************************************************************* + */ + +void pinEnableED01Pi (int pin) +{ + pin = pinToGpio [pin & 63] ; +} +#endif + +/* + ********************************************************************************* + * Core Functions + ********************************************************************************* + */ + +/* + * pinModeAlt: + * This is an un-documented special to let you set any pin to any mode + ********************************************************************************* + */ + +void pinModeAlt (int pin, int mode) +{ + int fSel, shift ; + + setupCheck ("pinModeAlt") ; + + +#ifdef CONFIG_ORANGEPI +#if !(defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800 || defined CONFIG_ORANGEPI_R1PLUS || CONFIG_ORANGEPI_2G_IOT) + if(version == ORANGEPI) { + if (wiringPiDebug) + printf("PinModeAlt: pin:%d,mode:%d\n", pin, mode); + if ((pin & PI_GPIO_MASK) == 0) { + 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 (-1 == pin) { + printf("[%s:L%d] the pin:%d is invaild,please check it over!\n", + __func__, __LINE__, pin); + return; + } + + if ( mode <= 1 || mode >= 8){ + printf("[%s:L%d] the mode:%d is invaild,please check it over!\n", + __func__, __LINE__, mode); + return; + } + + OrangePi_set_gpio_alt(pin, mode); + + return; + } else { + return ; + } + } +#endif +#endif + 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 ; + + setupCheck ("pinMode") ; + +#ifdef CONFIG_ORANGEPI + if(version == ORANGEPI ) { + if (wiringPiDebug) + printf("PinMode: pin:%d,mode:%d\n", pin, mode); + if ((pin & PI_GPIO_MASK) == 0) { + 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 (-1 == pin) { + printf("[%s:L%d] the pin:%d is invaild,please check it over!\n", + __func__, __LINE__, pin); + return; + } + + if (mode == INPUT) { + OrangePi_set_gpio_mode(pin, INPUT); + wiringPinMode = INPUT; + return; + } else if (mode == OUTPUT) { + OrangePi_set_gpio_mode(pin, OUTPUT); + wiringPinMode = OUTPUT; + return ; + } else if (mode == PWM_OUTPUT) { + if(pin != 5) { + printf("the pin you choose doesn't support hardware PWM\n"); + printf("you can select wiringPi pin %d for PWM pin\n", 42); + printf("or you can use it in softPwm mode\n"); + return; + } + OrangePi_set_gpio_mode(pin, PWM_OUTPUT); + wiringPinMode = PWM_OUTPUT; + return; + } else + return; + } else { + if ((node = wiringPiFindNode (pin)) != NULL) + node->pinMode(node, pin, mode); + return ; + } + } +#endif + + 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) + { + pinMode (origPin, PWM_OUTPUT) ; // Call myself to enable PWM mode + pwmSetMode (PWM_MODE_MS) ; + } + else if (mode == PWM_OUTPUT) + { + if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin + return ; + + usingGpioMemCheck ("pinMode PWM") ; + +// 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 ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin + return ; + + usingGpioMemCheck ("pinMode CLOCK") ; + +// Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz + + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; + delayMicroseconds (110) ; + gpioClockSet (pin, 100000) ; + } + } + else + { + if ((node = wiringPiFindNode (pin)) != NULL) + node->pinMode (node, pin, mode) ; + return ; + } +} + + +/* + * pullUpDownCtrl: + * Control the internal pull-up/down resistors on a GPIO pin. + ********************************************************************************* + */ + +void pullUpDnControl (int pin, int pud) +{ + struct wiringPiNodeStruct *node = wiringPiNodes ; + + setupCheck ("pullUpDnControl") ; + +#ifdef CONFIG_ORANGEPI + if(version == ORANGEPI ) { + if (wiringPiDebug) + printf("PinMode: pin:%d,pull up/down:%d\n", pin, pud); + if ((pin & PI_GPIO_MASK) == 0) { + 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 (-1 == pin) { + printf("[%s:L%d] the pin:%d is invaild,please check it over!\n", + __func__, __LINE__, pin); + return; + } + + if (pud == PUD_UP || pud == PUD_DOWN || pud == PUD_OFF) { + OrangePi_set_gpio_pullUpDnControl(pin, pud); + return; + } else + return; + } else { + if ((node = wiringPiFindNode (pin)) != NULL) + node->pullUpDnControl (node, pin, pud) ; + return ; + } + } +#endif + + 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 ; + + *(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 ; + } +} + + +/* + * digitalRead: + * Read the value of a given Pin, returning HIGH or LOW + ********************************************************************************* + */ + +int digitalRead (int pin) +{ + char c ; + int ret; + struct wiringPiNodeStruct *node = wiringPiNodes ; + +#ifdef CONFIG_ORANGEPI + if(ORANGEPI == version) { + if ((pin & PI_GPIO_MASK) == 0) { + /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode + { + if (sysFds [pin] == -1) + return LOW ; + + ret = lseek (sysFds [pin], 0L, SEEK_SET) ; + ret = read (sysFds [pin], &c, 1); + if (ret < 0) + return -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 -1; + + if (pin == -1) { + printf("[%s %d]Pin %d is invalid, please check it over!\n", __func__, __LINE__, pin); + return LOW; + } + /* Basic digital Read */ + return OrangePi_digitalRead(pin); + } else { + if ((node = wiringPiFindNode (pin)) == NULL) + return LOW ; + return node->digitalRead (node, pin) ; + } + } +#endif + + if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin + { + /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode + { + if (sysFds [pin] == -1) + return LOW ; + + lseek (sysFds [pin], 0L, SEEK_SET) ; + ret = read (sysFds [pin], &c, 1) ; + if (ret < 0) + return -1; + return (c == '0') ? LOW : HIGH ; + } + else if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [pin] ; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio [pin] ; + else if (wiringPiMode != WPI_MODE_GPIO) + return LOW ; + + if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0) + return HIGH ; + else + return LOW ; + } + else + { + if ((node = wiringPiFindNode (pin)) == NULL) + return LOW ; + return node->digitalRead (node, pin) ; + } +} + + +/* + * digitalRead8: + * Read 8-bits (a byte) from given start pin. + ********************************************************************************* + +unsigned int digitalRead8 (int pin) +{ + struct wiringPiNodeStruct *node = wiringPiNodes ; + + if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin + return 0 ; + else + { + if ((node = wiringPiFindNode (pin)) == NULL) + return LOW ; + return node->digitalRead8 (node, pin) ; + } +} + */ + + +/* + * digitalWrite: + * Set an output bit + ********************************************************************************* + */ + +void digitalWrite (int pin, int value) +{ + struct wiringPiNodeStruct *node = wiringPiNodes ; + int ret; + + if(version == ORANGEPI) { + if ((pin & PI_GPIO_MASK) == 0) { + if (wiringPiMode == WPI_MODE_GPIO_SYS) { // Sys mode + if (sysFds [pin] != -1) { + if (value == LOW) + { + ret = write (sysFds [pin], "0\n", 2); + if (ret < 0) + return; + } + else{ + ret = write (sysFds [pin], "1\n", 2); + if (ret < 0) + return; + } + } + return ; + } else if (wiringPiMode == WPI_MODE_PINS) { + pin = pinToGpio[pin]; + } + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio[pin]; + else + return; + + if(-1 == pin) { + printf("[%s:L%d] the pin:%d is invaild,please check it over!\n", __func__, __LINE__, pin); + printf("[%s:L%d] the mode is: %d, please check it over!\n", __func__, __LINE__, wiringPiMode); + + return; + } + + OrangePi_digitalWrite(pin, value); + } else { + if ((node = wiringPiFindNode(pin)) != NULL) + node->digitalWrite(node, pin, value); + } + return; + } +} + +/* + * digitalWrite8: + * Set an output 8-bit byte on the device from the given pin number + ********************************************************************************* + +void digitalWrite8 (int pin, int value) +{ + struct wiringPiNodeStruct *node = wiringPiNodes ; + + if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin + return ; + else + { + if ((node = wiringPiFindNode (pin)) != NULL) + node->digitalWrite8 (node, pin, value) ; + } +} + */ + +/* + * pwmWrite: + * Set an output PWM value + ********************************************************************************* + */ + +void pwmWrite(int pin, int value) { + struct wiringPiNodeStruct *node = wiringPiNodes; + + if (pinToGpio == 0 || physToGpio == 0) { + printf("please call wiringPiSetup first.\n"); + return; + } + + int a_val = 0; + if (pwmmode == 1)//sycle + { + sunxi_pwm_set_mode(1); + } else { + //sunxi_pwm_set_mode(0); + } + if (pin < MAX_PIN_NUM) // On-Board Pin needto fix me Jim + { + 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 (-1 == pin) { + printf("[%s:L%d] the pin:%d is invaild,please check it over!\n", __func__, __LINE__, pin); + return; + } + if (pin != 5) { + printf("please use soft pwmmode or choose PWM pin\n"); + return; + } + a_val = sunxi_pwm_get_period(); + if (wiringPiDebug) + printf("==> no:%d period now is :%d,act_val to be set:%d\n", __LINE__, a_val, value); + if (value > a_val) { + printf("val pwmWrite 0 <= X <= 1024\n"); + printf("Or you can set new range by yourself by pwmSetRange(range\n"); + return; + } + //if value changed chang it + sunxi_pwm_set_enable(0); + sunxi_pwm_set_act(value); + sunxi_pwm_set_enable(1); + } else { + printf("not on board :%s,%d\n", __func__, __LINE__); + if ((node = wiringPiFindNode(pin)) != NULL) { + if (wiringPiDebug) + printf("Jim find node%s,%d\n", __func__, __LINE__); + node->digitalWrite(node, pin, value); + } + } + if (wiringPiDebug) + printf("this fun is ok now %s,%d\n", __func__, __LINE__); + + return; +} + +/* + * 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 ; + + setupCheck ("pwmToneWrite") ; + + if (freq == 0) + pwmWrite (pin, 0) ; // Off + else + { + range = 600000 / freq ; + pwmSetRange (range) ; + pwmWrite (pin, freq / 2) ; + } +} + + + +/* + * digitalWriteByte: + * digitalReadByte: + * 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 + * Reading is just bit fiddling. + * These are wiringPi pin numbers 0..7, or BCM_GPIO pin numbers + * 17, 18, 22, 23, 24, 24, 4 on a Pi v1 rev 0-3 + * 17, 18, 27, 23, 24, 24, 4 on a Pi v1 rev 3 onwards or B+, 2, 3, zero + ********************************************************************************* + */ + +void digitalWriteByte (const int value) +{ + int mask = 1 ; + int pin ; + + + for (pin = 0 ; pin < 8 ; ++pin) { + digitalWrite (pin, (value >> pin) & mask) ; + } + + return ; +} + +unsigned int digitalReadByte (void) +{ + int pin, x ; + uint32_t data = 0 ; + + for (pin = 7 ; pin >= 0 ; --pin){ + x = digitalRead(pin); + + data = (data << 1) | x ; + } + + return data ; +} + +/* + * digitalWriteByte2: + * digitalReadByte2: + * Pi Specific + * Write an 8-bit byte to the second set of 8 GPIO pins. This is marginally + * faster than the first lot as these are consecutive BCM_GPIO pin numbers. + * However they overlap with the original read/write bytes. + ********************************************************************************* + */ + +void digitalWriteByte2 (const int value) +{ + register int mask = 1 ; + register int pin ; + + /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) + { + for (pin = 20 ; pin < 28 ; ++pin) + { + digitalWrite (pin, value & mask) ; + mask <<= 1 ; + } + return ; + } + else + { + *(gpio + gpioToGPCLR [0]) = (~value & 0xFF) << 20 ; // 0x0FF00000; ILJ > CHANGE: Old causes glitch + *(gpio + gpioToGPSET [0]) = ( value & 0xFF) << 20 ; + } +} + +unsigned int digitalReadByte2 (void) +{ + int pin, x ; + uint32_t data = 0 ; + + /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) + { + for (pin = 20 ; pin < 28 ; ++pin) + { + x = digitalRead (pin) ; + data = (data << 1) | x ; + } + } + else + data = ((*(gpio + gpioToGPLEV [0])) >> 20) & 0xFF ; // First bank for these pins + + return data ; +} + + +/* + * 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 + * way for a bit more efficiency. + ********************************************************************************* + */ + +int waitForInterrupt (int pin, int mS) +{ + int fd, x ; + uint8_t c ; + struct pollfd polls ; + int ret; + + /**/ 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 + + polls.fd = fd ; + polls.events = POLLPRI | POLLERR ; + +// Wait for it ... + + x = poll (&polls, 1, mS) ; + +// If no error, do a dummy read to clear the interrupt +// A one character read appars to be enough. + + if (x > 0) + { + lseek (fd, 0, SEEK_SET) ; // Rewind + ret = read (fd, &c, 1) ; // Read & clear + if (ret < 0) + return -1; + } + + return x ; +} + + +/* + * interruptHandler: + * This is a thread and gets started to wait for the interrupt we're + * hoping to catch. It will call the user-function when the interrupt + * fires. + ********************************************************************************* + */ + +static void *interruptHandler (UNU void *arg) +{ + int myPin ; + + (void)piHiPri (55) ; // Only effective if we run as root + + myPin = pinPass ; + pinPass = -1 ; + + for (;;) + if (waitForInterrupt (myPin, -1) > 0) + isrFunctions [myPin] () ; + + return NULL ; +} + + +/* + * wiringPiISR: + * Pi Specific. + * Take the details and create an interrupt handler that will do a call- + * back to the user supplied function. + ********************************************************************************* + */ + +int wiringPiISR (int pin, int mode, void (*function)(void)) +{ + pthread_t threadId ; + const char *modeS ; + char fName [64] ; + char pinS [8] ; + pid_t pid ; + int count, i ; + char c ; + int bcmGpioPin ; + int ret; + + if ((pin < 0) || (pin > 63)) + return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-63 (%d)\n", pin) ; + + /**/ 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) + 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 +// a full installation of wiringPi. It's a bit 'clunky', but it +// is a way that will work when we're running in "Sys" mode, as +// a non-root user. (without sudo) + + if (mode != INT_EDGE_SETUP) + { + /**/ if (mode == INT_EDGE_FALLING) + modeS = "falling" ; + else if (mode == INT_EDGE_RISING) + modeS = "rising" ; + else + modeS = "both" ; + + sprintf (pinS, "%d", pin) ; + + if ((pid = fork ()) < 0) // Fail + return wiringPiFailure (WPI_FATAL, "wiringPiISR: fork failed: %s\n", strerror (errno)) ; + + if (pid == 0) // Child, exec + { + /**/ 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 - but it may already be open if +// we are in Sys mode... + + 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 [bcmGpioPin], FIONREAD, &count) ; + for (i = 0 ; i < count ; ++i){ + ret = read (sysFds [bcmGpioPin], &c, 1) ; + if (ret < 0) + return -1; + } + + isrFunctions [pin] = function ; + + pthread_mutex_lock (&pinMutex) ; + pinPass = pin ; + pthread_create (&threadId, NULL, interruptHandler, NULL) ; + while (pinPass != -1) + delay (1) ; + pthread_mutex_unlock (&pinMutex) ; + + return 0 ; +} + + +/* + * initialiseEpoch: + * Initialise our start-of-time variable to be the current unix + * time in milliseconds and microseconds. + ********************************************************************************* + */ + +static void initialiseEpoch (void) +{ +#ifdef OLD_WAY + struct timeval tv ; + + gettimeofday (&tv, NULL) ; + epochMilli = (uint64_t)tv.tv_sec * (uint64_t)1000 + (uint64_t)(tv.tv_usec / 1000) ; + epochMicro = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)(tv.tv_usec) ; +#else + struct timespec ts ; + + clock_gettime (CLOCK_MONOTONIC_RAW, &ts) ; + epochMilli = (uint64_t)ts.tv_sec * (uint64_t)1000 + (uint64_t)(ts.tv_nsec / 1000000L) ; + epochMicro = (uint64_t)ts.tv_sec * (uint64_t)1000000 + (uint64_t)(ts.tv_nsec / 1000L) ; +#endif +} + + +/* + * delay: + * Wait for some number of milliseconds + ********************************************************************************* + */ + +void delay (unsigned int howLong) +{ + struct timespec sleeper, dummy ; + + sleeper.tv_sec = (time_t)(howLong / 1000) ; + sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ; + + nanosleep (&sleeper, &dummy) ; +} + + +/* + * delayMicroseconds: + * This is somewhat intersting. It seems that on the Pi, a single call + * to nanosleep takes some 80 to 130 microseconds anyway, so while + * obeying the standards (may take longer), it's not always what we + * want! + * + * So what I'll do now is if the delay is less than 100uS we'll do it + * in a hard loop, watching a built-in counter on the ARM chip. This is + * somewhat sub-optimal in that it uses 100% CPU, something not an issue + * in a microcontroller, but under a multi-tasking, multi-user OS, it's + * wastefull, however we've no real choice )-: + * + * Plan B: It seems all might not be well with that plan, so changing it + * to use gettimeofday () and poll on that instead... + ********************************************************************************* + */ + +void delayMicrosecondsHard (unsigned int howLong) +{ + struct timeval tNow, tLong, tEnd ; + + gettimeofday (&tNow, NULL) ; + tLong.tv_sec = howLong / 1000000 ; + tLong.tv_usec = howLong % 1000000 ; + timeradd (&tNow, &tLong, &tEnd) ; + + while (timercmp (&tNow, &tEnd, <)) + gettimeofday (&tNow, NULL) ; +} + +void delayMicroseconds (unsigned int howLong) +{ + struct timespec sleeper ; + unsigned int uSecs = howLong % 1000000 ; + unsigned int wSecs = howLong / 1000000 ; + + /**/ if (howLong == 0) + return ; + else if (howLong < 100) + delayMicrosecondsHard (howLong) ; + else + { + sleeper.tv_sec = wSecs ; + sleeper.tv_nsec = (long)(uSecs * 1000L) ; + nanosleep (&sleeper, NULL) ; + } +} + + +/* + * millis: + * Return a number of milliseconds as an unsigned int. + * Wraps at 49 days. + ********************************************************************************* + */ + +unsigned int millis (void) +{ + uint64_t now ; + +#ifdef OLD_WAY + struct timeval tv ; + + gettimeofday (&tv, NULL) ; + now = (uint64_t)tv.tv_sec * (uint64_t)1000 + (uint64_t)(tv.tv_usec / 1000) ; + +#else + struct timespec ts ; + + clock_gettime (CLOCK_MONOTONIC_RAW, &ts) ; + now = (uint64_t)ts.tv_sec * (uint64_t)1000 + (uint64_t)(ts.tv_nsec / 1000000L) ; +#endif + + return (uint32_t)(now - epochMilli) ; +} + + +/* + * micros: + * Return a number of microseconds as an unsigned int. + * Wraps after 71 minutes. + ********************************************************************************* + */ + +unsigned int micros (void) +{ + uint64_t now ; +#ifdef OLD_WAY + struct timeval tv ; + + gettimeofday (&tv, NULL) ; + now = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)tv.tv_usec ; +#else + struct timespec ts ; + + clock_gettime (CLOCK_MONOTONIC_RAW, &ts) ; + now = (uint64_t)ts.tv_sec * (uint64_t)1000000 + (uint64_t)(ts.tv_nsec / 1000) ; +#endif + + + return (uint32_t)(now - epochMicro) ; +} + +/* + * wiringPiVersion: + * Return our current version number + ********************************************************************************* + */ + +void wiringPiVersion (int *major, int *minor) +{ + *major = VERSION_MAJOR ; + *minor = VERSION_MINOR ; +} + + +/* + * wiringPiSetup: + * Must be called once at the start of your program execution. + * + * 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 model, rev, mem, maker, overVolted ; + +// It's actually a fatal error to call any of the wiringPiSetup routines more than once, +// (you run out of file handles!) but I'm fed-up with the useless twats who email +// me bleating that there is a bug in my code, so screw-em. + + if (wiringPiSetuped) + return 0 ; + + wiringPiSetuped = TRUE ; + + if (getenv (ENV_DEBUG) != NULL) + wiringPiDebug = TRUE ; + + if (getenv (ENV_CODES) != NULL) + wiringPiReturnCodes = TRUE ; + + if (wiringPiDebug) + printf ("wiringPi: wiringPiSetup called\n") ; + +// Get the board ID information. We're not really using the information here, +// but it will give us information like the GPIO layout scheme (2 variants +// on the older 26-pin Pi's) and the GPIO peripheral base address. +// and if we're running on a compute module, then wiringPi pin numbers +// don't really many anything, so force native BCM mode anyway. + + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; + + if ((model == PI_MODEL_CM) || (model == PI_MODEL_CM3)) + wiringPiMode = WPI_MODE_GPIO ; + else + wiringPiMode = WPI_MODE_PINS ; + + /**/ if (piGpioLayout () == 1) // A, B, Rev 1, 1.1 + { + pinToGpio = pinToGpioR1 ; + physToGpio = physToGpioR1 ; + } + else if (piGpioLayout () == ORANGEPI) + { + pinToGpio = pinToGpioOrangePi; + physToGpio = physToGpioOrangePi; + physToPin = physToPinOrangePi; + } + else // A2, B2, A+, B+, CM, Pi2, Pi3, Zero + { + pinToGpio = pinToGpioR2 ; + physToGpio = physToGpioR2 ; + } + +// ... + + switch (model) + { + case PI_MODEL_A: case PI_MODEL_B: + case PI_MODEL_AP: case PI_MODEL_BP: + case PI_ALPHA: case PI_MODEL_CM: + case PI_MODEL_ZERO: case PI_MODEL_ZERO_W: + piGpioBase = GPIO_PERI_BASE_OLD ; + break ; + + default: + piGpioBase = GPIO_PERI_BASE_NEW ; + break ; + } + +// Open the master /dev/ memory control device +// Device strategy: December 2016: +// Try /dev/mem. If that fails, then +// try /dev/gpiomem. If that fails then game over. + + if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC)) < 0) + { + if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) >= 0) // We're using gpiomem + { + piGpioBase = 0 ; + usingGpioMem = TRUE ; + } + else + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem or /dev/gpiomem: %s.\n" + " Aborting your program because if it can not access the GPIO\n" + " hardware then it most certianly won't work\n" + " Try running with sudo?\n", strerror (errno)) ; + } + + +#ifdef CONFIG_ORANGEPI + +#ifdef CONFIG_ORANGEPI_2G_IOT + /* GPIO */ + gpio = (uint32_t *)mmap(0, BLOCK_SIZE * 3, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO_BASE); + if ((int32_t)(unsigned long)gpio == -1) + return wiringPiFailure(WPI_ALMOST, + "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror(errno)); + OrangePi_gpio = gpio; + /* GPIOC connect CPU with Modem */ + OrangePi_gpioC = (uint32_t *)mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIOC_BASE); + if ((int32_t)(unsigned long)OrangePi_gpioC == -1) + return wiringPiFailure(WPI_ALMOST, + "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror(errno)); +#else + +#if ! (defined CONFIG_ORANGEPI_RK3399 || defined CONFIG_ORANGEPI_4 || defined CONFIG_ORANGEPI_4_LTS || defined CONFIG_ORANGEPI_800 || defined CONFIG_ORANGEPI_R1PLUS) + + /* GPIO */ +#if CONFIG_ORANGEPI_LITE2 || CONFIG_ORANGEPI_3 || CONFIG_ORANGEPI_ZERO2 + gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO_BASE); +#else + gpio = (uint32_t *)mmap(0, BLOCK_SIZE * 10, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO_BASE); +#endif + if ((int32_t)(unsigned long)gpio == -1) + return wiringPiFailure(WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror(errno)); + OrangePi_gpio = gpio; + + /* PWM */ + pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ; + if (pwm == MAP_FAILED) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PWM) failed: %s\n", strerror (errno)) ; + +#if CONFIG_ORANGEPI_WIN || CONFIG_ORANGEPI_ZEROPLUS2_H3 || CONFIG_ORANGEPI_3 || CONFIG_ORANGEPI_ZEROPLUS2_H5 + /* GPIOC connect CPU with Modem */ + OrangePi_gpioC = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, GPIOL_BASE_MAP); + if ((int32_t)(unsigned long)OrangePi_gpioC == -1) + return wiringPiFailure(WPI_ALMOST, + "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror(errno)); +#endif + + +#elif CONFIG_ORANGEPI_R1PLUS + cru_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, CRU_BASE); + if ((int32_t)(unsigned long)cru_base == -1) + return wiringPiFailure(WPI_ALMOST, + "wiringPiSetup: mmap (CRU_BASE) failed: %s\n", strerror(errno)); + grf_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GRF_BASE); + if ((int32_t)(unsigned long)grf_base == -1) + return wiringPiFailure(WPI_ALMOST, + "wiringPiSetup: mmap (GRF_BASE) failed: %s\n", strerror(errno)); + gpio2_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO2_BASE); + if ((int32_t)(unsigned long)gpio2_base == -1) + return wiringPiFailure(WPI_ALMOST, + "wiringPiSetup: mmap (GPIO2_BASE) failed: %s\n", strerror(errno)); + gpio3_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO3_BASE); + if ((int32_t)(unsigned long)gpio3_base == -1) + return wiringPiFailure(WPI_ALMOST, + "wiringPiSetup: mmap (GPIO3_BASE) failed: %s\n", strerror(errno)); + +#else /* CONFIG_ORANGEPI_RK3399 */ + gpio2_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO2_BASE); + if ((int32_t)(unsigned long)gpio2_base == -1) + return wiringPiFailure(WPI_ALMOST, + "wiringPiSetup: mmap (GPIO2_BASE) failed: %s\n", strerror(errno)); + cru_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, CRU_BASE); + if ((int32_t)(unsigned long)cru_base == -1) + return wiringPiFailure(WPI_ALMOST, + "wiringPiSetup: mmap (CRU_BASE) failed: %s\n", strerror(errno)); + pmucru_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, PMUCRU_BASE); + if ((int32_t)(unsigned long)pmucru_base == -1) + return wiringPiFailure(WPI_ALMOST, + "wiringPiSetup: mmap (PMUCRU_BASE) failed: %s\n", strerror(errno)); + grf_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GRF_BASE); + if ((int32_t)(unsigned long)grf_base == -1) + return wiringPiFailure(WPI_ALMOST, + "wiringPiSetup: mmap (GRF_BASE) failed: %s\n", strerror(errno)); + pmugrf_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, PMUGRF_BASE); + if ((int32_t)(unsigned long)pmugrf_base == -1) + return wiringPiFailure(WPI_ALMOST, + "wiringPiSetup: mmap (PMUGRF_BASE) failed: %s\n", strerror(errno)); + gpio1_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO1_BASE); + if ((int32_t)(unsigned long)grf_base == -1) + return wiringPiFailure(WPI_ALMOST, + "wiringPiSetup: mmap (GPIO1_BASE) failed: %s\n", strerror(errno)); + gpio4_base = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO4_BASE); + if ((int32_t)(unsigned long)gpio4_base == -1) + return wiringPiFailure(WPI_ALMOST, + "wiringPiSetup: mmap (GPIO4_BASE) failed: %s\n", strerror(errno)); +#endif /* CONFIG_ORANGEPI_RK3399 */ +#endif + +#else +// Set the offsets into the memory interface. + + GPIO_PADS = piGpioBase + 0x00100000 ; + GPIO_CLOCK_BASE = piGpioBase + 0x00101000 ; + + #ifndef CONFIG_ORANGEPI + GPIO_BASE = piGpioBase + 0x00200000 ; + #endif + + GPIO_TIMER = piGpioBase + 0x0000B000 ; + GPIO_PWM = piGpioBase + 0x0020C000 ; + +// Map the individual hardware components + +// GPIO: + + gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ; + if (gpio == MAP_FAILED) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ; + +// PWM + + pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ; + if (pwm == MAP_FAILED) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PWM) failed: %s\n", strerror (errno)) ; + +// Clock control (needed for PWM) + + clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_CLOCK_BASE) ; + if (clk == MAP_FAILED) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (CLOCK) failed: %s\n", strerror (errno)) ; + +// The drive pads + + pads = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PADS) ; + if (pads == MAP_FAILED) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PADS) failed: %s\n", strerror (errno)) ; + +// The system timer + + timer = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_TIMER) ; + if (timer == MAP_FAILED) + 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) +// so base clock is 250MHz / 250 = 1MHz. + + *(timer + TIMER_CONTROL) = 0x0000280 ; + *(timer + TIMER_PRE_DIV) = 0x00000F9 ; + timerIrqRaw = timer + TIMER_IRQ_RAW ; + +// Export the base addresses for any external software that might need them + + _wiringPiGpio = gpio ; + _wiringPiPwm = pwm ; + _wiringPiClk = clk ; + _wiringPiPads = pads ; + _wiringPiTimer = timer ; +#endif + + initialiseEpoch () ; + + return 0 ; +} + + +/* + * wiringPiSetupGpio: + * Must be called once at the start of your program execution. + * + * GPIO setup: Initialises the system into GPIO Pin mode and uses the + * memory mapped hardware directly. + ********************************************************************************* + */ + +int wiringPiSetupGpio (void) +{ + (void)wiringPiSetup () ; + + if (wiringPiDebug) + printf ("wiringPi: wiringPiSetupGpio called\n") ; + + 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. + * + * Initialisation (again), however this time we are using the /sys/class/gpio + * interface to the GPIO systems - slightly slower, but always usable as + * a non-root user, assuming the devices are already exported and setup correctly. + */ + +int wiringPiSetupSys (void) +{ + int pin ; + int tmpGpio; + char fName [128] ; + + if (wiringPiSysSetuped) + return 0 ; + + wiringPiSysSetuped = TRUE ; + + if (getenv (ENV_DEBUG) != NULL) + wiringPiDebug = TRUE ; + + if (getenv (ENV_CODES) != NULL) + wiringPiReturnCodes = TRUE ; + + if (wiringPiDebug) + printf ("wiringPi: wiringPiSetupSys called\n") ; + + version = piGpioLayout () ; + if (ORANGEPI == version) + { + pinToGpio = pinToGpioOrangePi; + physToGpio = physToGpioOrangePi; + physToPin = physToPinOrangePi; + } + else if (piGpioLayout () == 1) + { + pinToGpio = pinToGpioR1 ; + physToGpio = physToGpioR1 ; + } + else + { + 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 + if(ORANGEPI == version) + { + for (pin = 1 ; pin < 28 ; ++pin) + { + tmpGpio = pinToGpioOrangePi[pin]; + sprintf (fName, "/sys/class/gpio/gpio%d/value", tmpGpio) ; + sysFds [pin] = open (fName, O_RDWR) ; + } + } + else + { + for (pin = 0 ; pin < 64 ; ++pin) + { + sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; + sysFds [pin] = open (fName, O_RDWR) ; + } + } + initialiseEpoch () ; + + wiringPiMode = WPI_MODE_GPIO_SYS; + + return 0 ; +} diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h new file mode 100644 index 0000000..ba9f064 --- /dev/null +++ b/wiringPi/wiringPi.h @@ -0,0 +1,283 @@ +/* + * wiringPi.h: + * Arduino like Wiring library for the Raspberry Pi. + * Copyright (c) 2012-2017 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#ifndef __WIRING_PI_H__ +#define __WIRING_PI_H__ + +// C doesn't have true/false by default and I can never remember which +// way round they are, so ... +// (and yes, I know about stdbool.h but I like capitals for these and I'm old) + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (!TRUE) +#endif + +// GCC warning suppressor + +#define UNU __attribute__((unused)) + +// Mask for the bottom 64 pins which belong to the Raspberry Pi +// The others are available for the other devices + +#ifndef CONFIG_ORANGEPI +#define PI_GPIO_MASK (0xFFFFFFC0) +#endif + +// Handy defines + +#ifdef CONFIG_ORANGEPI +#define ORANGEPI 8888 + +extern int wiringPiDebug; + +//#define CONFIG_ORANGEPI 1 +//#define CONFIG_ORANGEPI_H3 1 +#endif + +// wiringPi modes + +#define WPI_MODE_PINS 0 +#define WPI_MODE_GPIO 1 +#define WPI_MODE_GPIO_SYS 2 +#define WPI_MODE_PHYS 3 +#define WPI_MODE_PIFACE 4 +#define WPI_MODE_UNINITIALISED -1 + +// Pin modes + +#define INPUT 0 +#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 + +// Pull up/down/none + +#define PUD_OFF 0 +#define PUD_DOWN 1 +#define PUD_UP 2 + +// PWM + +#define PWM_MODE_MS 0 +#define PWM_MODE_BAL 1 + +// Interrupt levels + +#define INT_EDGE_SETUP 0 +#define INT_EDGE_FALLING 1 +#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_3 8 +#define PI_MODEL_ZERO 9 +#define PI_MODEL_CM3 10 +#define PI_MODEL_ZERO_W 12 +#define PI_MODEL_3P 13 +#define PI_MODEL_ORANGEPI 14 + +#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_EMBEST 2 +#define PI_MAKER_UNKNOWN 3 + +#ifndef CONFIG_ORANGEPI +extern const char *piModelNames [16] ; +#endif + +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 (UNU 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) ; +//unsigned int (*digitalRead8) (struct wiringPiNodeStruct *node, int pin) ; + void (*digitalWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; +// void (*digitalWrite8) (struct wiringPiNodeStruct *node, int pin, int value) ; + void (*pwmWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; + int (*analogRead) (struct wiringPiNodeStruct *node, int pin) ; + void (*analogWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; + + struct wiringPiNodeStruct *next ; +} ; + +extern struct wiringPiNodeStruct *wiringPiNodes ; + +// Export variables for the hardware pointers + +extern volatile unsigned int *_wiringPiGpio ; +extern volatile unsigned int *_wiringPiPwm ; +extern volatile unsigned int *_wiringPiClk ; +extern volatile unsigned int *_wiringPiPads ; +extern volatile unsigned int *_wiringPiTimer ; +extern volatile unsigned int *_wiringPiTimerIrqRaw ; + + +// Function prototypes +// c++ wrappers thanks to a comment by Nick Lott +// (and others on the Raspberry Pi forums) + +#ifdef __cplusplus +extern "C" { +#endif + +// Data + +// Internal + +#ifdef CONFIG_ORANGEPI +extern void piGpioLayoutOops (const char *why); +#endif + +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 void wiringPiVersion (int *major, int *minor) ; +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 unsigned int digitalRead8 (int pin) ; +extern void digitalWrite8 (int pin, int value) ; +extern void pwmWrite (int pin, int value) ; +extern int analogRead (int pin) ; +extern void analogWrite (int pin, int value) ; + +// PiFace specifics +// (Deprecated) + +extern int wiringPiSetupPiFace (void) ; +extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only + +// On-Board Raspberry Pi hardware specific stuff + +extern int piGpioLayout (void) ; +extern int piBoardRev (void) ; // Deprecated +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 pwmSetMode (int mode) ; +extern void pwmSetRange (unsigned int range) ; +extern void pwmSetClock (int divisor) ; +extern void gpioClockSet (int pin, int freq) ; +extern unsigned int digitalReadByte (void) ; +extern unsigned int digitalReadByte2 (void) ; +extern void digitalWriteByte (int value) ; +extern void digitalWriteByte2 (int value) ; + +// Interrupts +// (Also Pi hardware specific) + +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) ; + +// Schedulling priority + +extern int piHiPri (const int pri) ; + +// Extras from arduino land + +extern void delay (unsigned int howLong) ; +extern void delayMicroseconds (unsigned int howLong) ; +extern unsigned int millis (void) ; +extern unsigned int micros (void) ; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/wiringPi/wiringPiI2C.c b/wiringPi/wiringPiI2C.c new file mode 100644 index 0000000..b0ee5d3 --- /dev/null +++ b/wiringPi/wiringPiI2C.c @@ -0,0 +1,233 @@ +/* + * wiringPiI2C.c: + * Simplified I2C access routines + * 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 . + *********************************************************************** + */ + +/* + * 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: + * Simple device read + ********************************************************************************* + */ + +int wiringPiI2CRead (int 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 ; +} + + +/* + * wiringPiI2CReadReg8: wiringPiI2CReadReg16: + * Read an 8 or 16-bit value from a regsiter on the device + ********************************************************************************* + */ + +int wiringPiI2CReadReg8 (int fd, int 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) +{ + 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 ; +} + + +/* + * wiringPiI2CWrite: + * Simple device write + ********************************************************************************* + */ + +int wiringPiI2CWrite (int fd, int data) +{ + return i2c_smbus_access (fd, I2C_SMBUS_WRITE, data, I2C_SMBUS_BYTE, NULL) ; +} + + +/* + * wiringPiI2CWriteReg8: wiringPiI2CWriteReg16: + * Write an 8 or 16-bit value to the given register + ********************************************************************************* + */ + +int wiringPiI2CWriteReg8 (int fd, int reg, int value) +{ + 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 value) +{ + 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 ; +} + + +/* + * wiringPiI2CSetup: + * Open the I2C device, and regsiter the target device + ********************************************************************************* + */ + +int wiringPiI2CSetup (const int devId) +{ + int rev ; + const char *device ; + + rev = piGpioLayout () ; + + if (rev == 1) + device = "/dev/i2c-0" ; + else + device = "/dev/i2c-1" ; + + return wiringPiI2CSetupInterface (device, devId) ; +} diff --git a/wiringPi/wiringPiI2C.h b/wiringPi/wiringPiI2C.h new file mode 100644 index 0000000..6db8c68 --- /dev/null +++ b/wiringPi/wiringPiI2C.h @@ -0,0 +1,42 @@ +/* + * wiringPiI2C.h: + * Simplified I2C access routines + * 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 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 wiringPiI2CSetupInterface (const char *device, int devId) ; +extern int wiringPiI2CSetup (const int devId) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/wiringPiSPI.c b/wiringPi/wiringPiSPI.c new file mode 100644 index 0000000..e65da1e --- /dev/null +++ b/wiringPi/wiringPiSPI.c @@ -0,0 +1,145 @@ +/* + * wiringPiSPI.c: + * Simplified SPI access routines + * 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 "wiringPi.h" + +#include "wiringPiSPI.h" + + +// The SPI bus parameters +// Variables as they need to be passed as pointers later on + +static const uint8_t spiBPW = 8 ; +static const uint16_t spiDelay = 0 ; + +static uint32_t spiSpeeds [2] ; +static int spiFds [2] ; + + +/* + * wiringPiSPIGetFd: + * Return the file-descriptor for the given channel + ********************************************************************************* + */ + +int wiringPiSPIGetFd (int channel) +{ + return spiFds [channel & 1] ; +} + + +/* + * wiringPiSPIDataRW: + * Write and Read a block of data over the SPI bus. + * Note the data ia being read into the transmit buffer, so will + * overwrite it! + * This is also a full-duplex operation. + ********************************************************************************* + */ + +int wiringPiSPIDataRW (int channel, unsigned char *data, int len) +{ + struct spi_ioc_transfer spi ; + + 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 ; + spi.delay_usecs = spiDelay ; + spi.speed_hz = spiSpeeds [channel] ; + spi.bits_per_word = spiBPW ; + + return ioctl (spiFds [channel], SPI_IOC_MESSAGE(1), &spi) ; +} + + +/* + * wiringPiSPISetupMode: + * Open the SPI device, and set it up, with the mode, etc. + ********************************************************************************* + */ + +void getDevice(char* spidev, int channel, int port) { + sprintf(spidev, "/dev/spidev%i.%i", channel, port); +} + +int wiringPiSPISetupMode (int channel, int port, int speed, int mode) +{ + int fd ; + + mode &= 3 ; // Mode is 0, 1, 2 or 3 + channel &= 1 ; // Channel is 0 or 1 + + static char spidev[14]; + + getDevice(spidev, channel, port); + printf("Opening device %s\n", spidev); + + if ((fd = open (spidev, O_RDWR)) < 0) + return wiringPiFailure (WPI_ALMOST, "Unable to open SPI device: %s\n", strerror (errno)) ; + + spiSpeeds [channel] = speed ; + spiFds [channel] = fd ; + +// Set SPI parameters. + + 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_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, 0, speed, 0) ; +} diff --git a/wiringPi/wiringPiSPI.h b/wiringPi/wiringPiSPI.h new file mode 100644 index 0000000..62c7aed --- /dev/null +++ b/wiringPi/wiringPiSPI.h @@ -0,0 +1,36 @@ +/* + * wiringPiSPI.h: + * Simplified SPI access routines + * 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 . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +int wiringPiSPIGetFd (int channel) ; +int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ; +int wiringPiSPISetupMode (int channel, int port, int speed, int mode) ; +int wiringPiSPISetup (int channel, int speed) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/wiringSerial.c b/wiringPi/wiringSerial.c new file mode 100644 index 0000000..fe5a888 --- /dev/null +++ b/wiringPi/wiringSerial.c @@ -0,0 +1,231 @@ +/* + * wiringSerial.c: + * Handle a serial port + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General 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 "wiringSerial.h" + +/* + * serialOpen: + * Open and initialise the serial port, setting all the right + * port parameters - or as many as are required - hopefully! + ********************************************************************************* + */ + +int serialOpen (const char *device, const int baud) +{ + struct termios options ; + speed_t myBaud ; + int status, fd ; + + switch (baud) + { + case 50: myBaud = B50 ; break ; + case 75: myBaud = B75 ; break ; + case 110: myBaud = B110 ; break ; + case 134: myBaud = B134 ; break ; + case 150: myBaud = B150 ; break ; + case 200: myBaud = B200 ; break ; + case 300: myBaud = B300 ; break ; + case 600: myBaud = B600 ; break ; + case 1200: myBaud = B1200 ; break ; + case 1800: myBaud = B1800 ; break ; + case 2400: myBaud = B2400 ; break ; + case 4800: myBaud = B4800 ; break ; + case 9600: myBaud = B9600 ; break ; + case 19200: myBaud = B19200 ; break ; + case 38400: myBaud = B38400 ; break ; + case 57600: myBaud = B57600 ; break ; + case 115200: myBaud = B115200 ; break ; + case 230400: myBaud = B230400 ; break ; + case 460800: myBaud = B460800 ; break ; + case 500000: myBaud = B500000 ; break ; + case 576000: myBaud = B576000 ; break ; + case 921600: myBaud = B921600 ; break ; + case 1000000: myBaud = B1000000 ; break ; + case 1152000: myBaud = B1152000 ; break ; + case 1500000: myBaud = B1500000 ; break ; + case 2000000: myBaud = B2000000 ; break ; + case 2500000: myBaud = B2500000 ; break ; + case 3000000: myBaud = B3000000 ; break ; + case 3500000: myBaud = B3500000 ; break ; + case 4000000: myBaud = B4000000 ; break ; + + default: + return -2 ; + } + + if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1) + return -1 ; + + fcntl (fd, F_SETFL, O_RDWR) ; + +// Get and modify current options: + + tcgetattr (fd, &options) ; + + cfmakeraw (&options) ; + cfsetispeed (&options, myBaud) ; + cfsetospeed (&options, myBaud) ; + + options.c_cflag |= (CLOCAL | CREAD) ; + options.c_cflag &= ~PARENB ; + options.c_cflag &= ~CSTOPB ; + options.c_cflag &= ~CSIZE ; + options.c_cflag |= CS8 ; + options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ; + options.c_oflag &= ~OPOST ; + + options.c_cc [VMIN] = 0 ; + options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds) + + tcsetattr (fd, TCSANOW, &options) ; + + ioctl (fd, TIOCMGET, &status); + + status |= TIOCM_DTR ; + status |= TIOCM_RTS ; + + ioctl (fd, TIOCMSET, &status); + + usleep (10000) ; // 10mS + + return fd ; +} + + +/* + * serialFlush: + * Flush the serial buffers (both tx & rx) + ********************************************************************************* + */ + +void serialFlush (const int fd) +{ + tcflush (fd, TCIOFLUSH) ; +} + + +/* + * serialClose: + * Release the serial port + ********************************************************************************* + */ + +void serialClose (const int fd) +{ + close (fd) ; +} + + +/* + * serialPutchar: + * Send a single character to the serial port + ********************************************************************************* + */ + +void serialPutchar (const int fd, const unsigned char c) +{ + int ret; + ret = write (fd, &c, 1) ; + if (ret < 0) + printf("Serial Putchar Error\n"); +} + + +/* + * serialPuts: + * Send a string to the serial port + ********************************************************************************* + */ + +void serialPuts (const int fd, const char *s) +{ + int ret; + ret = write (fd, s, strlen (s)); + if (ret < 0) + printf("Serial Puts Error\n"); +} + +/* + * serialPrintf: + * Printf over Serial + ********************************************************************************* + */ + +void serialPrintf (const int fd, const char *message, ...) +{ + va_list argp ; + char buffer [1024] ; + + va_start (argp, message) ; + vsnprintf (buffer, 1023, message, argp) ; + va_end (argp) ; + + serialPuts (fd, buffer) ; +} + + +/* + * serialDataAvail: + * Return the number of bytes of data avalable to be read in the serial port + ********************************************************************************* + */ + +int serialDataAvail (const int fd) +{ + int result ; + + if (ioctl (fd, FIONREAD, &result) == -1) + return -1 ; + + return result ; +} + + +/* + * serialGetchar: + * Get a single character from the serial device. + * Note: Zero is a valid character and this function will time-out after + * 10 seconds. + ********************************************************************************* + */ + +int serialGetchar (const int fd) +{ + uint8_t x ; + + if (read (fd, &x, 1) != 1) + return -1 ; + + return ((int)x) & 0xFF ; +} diff --git a/wiringPi/wiringSerial.h b/wiringPi/wiringSerial.h new file mode 100644 index 0000000..430dc73 --- /dev/null +++ b/wiringPi/wiringSerial.h @@ -0,0 +1,38 @@ +/* + * wiringSerial.h: + * Handle a serial port + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General 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 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 +} +#endif diff --git a/wiringPi/wiringShift.c b/wiringPi/wiringShift.c new file mode 100644 index 0000000..3df94e8 --- /dev/null +++ b/wiringPi/wiringShift.c @@ -0,0 +1,83 @@ +/* + * wiringShift.c: + * Emulate some of the Arduino wiring functionality. + * + * Copyright (c) 2009-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 "wiringPi.h" +#include "wiringShift.h" + +/* + * shiftIn: + * Shift data in from a clocked source + ********************************************************************************* + */ + +uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) +{ + uint8_t value = 0 ; + int8_t i ; + + if (order == MSBFIRST) + for (i = 7 ; i >= 0 ; --i) + { + digitalWrite (cPin, HIGH) ; + value |= digitalRead (dPin) << i ; + digitalWrite (cPin, LOW) ; + } + else + for (i = 0 ; i < 8 ; ++i) + { + digitalWrite (cPin, HIGH) ; + value |= digitalRead (dPin) << i ; + digitalWrite (cPin, LOW) ; + } + + return value; +} + +/* + * shiftOut: + * Shift data out to a clocked source + ********************************************************************************* + */ + +void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) +{ + int8_t i; + + if (order == MSBFIRST) + for (i = 7 ; i >= 0 ; --i) + { + digitalWrite (dPin, val & (1 << i)) ; + digitalWrite (cPin, HIGH) ; + digitalWrite (cPin, LOW) ; + } + else + for (i = 0 ; i < 8 ; ++i) + { + digitalWrite (dPin, val & (1 << i)) ; + digitalWrite (cPin, HIGH) ; + digitalWrite (cPin, LOW) ; + } +} diff --git a/wiringPi/wiringShift.h b/wiringPi/wiringShift.h new file mode 100644 index 0000000..419ade4 --- /dev/null +++ b/wiringPi/wiringShift.h @@ -0,0 +1,41 @@ +/* + * wiringShift.h: + * Emulate some of the Arduino wiring functionality. + * + * Copyright (c) 2009-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 LSBFIRST 0 +#define MSBFIRST 1 + +#ifndef _STDINT_H +# include +#endif + +#ifdef __cplusplus +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) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/wpiExtensions.c b/wiringPi/wpiExtensions.c new file mode 100644 index 0000000..bef126f --- /dev/null +++ b/wiringPi/wpiExtensions.c @@ -0,0 +1,928 @@ +/* + * extensions.c: + * Originally part of the GPIO program to test, peek, poke and otherwise + * noodle with the GPIO hardware on the Raspberry Pi. + * Now used as a general purpose library to allow systems to dynamically + * add in new devices into wiringPi at program run-time. + * Copyright (c) 2012-2015 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + + +#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 "ads1115.h" +#include "sn3218.h" +#include "drcSerial.h" +#include "drcNet.h" +#include "../wiringPiD/drcNetCmd.h" +#include "pseudoPins.h" +#include "bmp180.h" +#include "htu21d.h" +#include "ds18b20.h" +#include "rht03.h" + +#include "wpiExtensions.h" + +extern int wiringPiDebug ; + +static int verbose ; +static char errorMessage [1024] ; + + +// Local structure to hold details + +struct extensionFunctionStruct +{ + const char *name ; + int (*function)(char *progName, int pinBase, char *params) ; +} ; + + +/* + * verbError: + * Convenient error handling + ********************************************************************************* + */ + +static void verbError (const char *message, ...) +{ + va_list argp ; + va_start (argp, message) ; + vsnprintf (errorMessage, 1023, message, argp) ; + va_end (argp) ; + + if (verbose) + fprintf (stderr, "%s\n", errorMessage) ; +} + + +/* + * extractInt: + * Check & return an integer at the given location (prefixed by a :) + ********************************************************************************* + */ + +static char *extractInt (char *progName, char *p, int *num) +{ + if (*p != ':') + { + verbError ("%s: colon expected", progName) ; + return NULL ; + } + + ++p ; + + if (!isdigit (*p)) + { + verbError ("%s: digit expected", progName) ; + return NULL ; + } + + *num = strtol (p, NULL, 0) ; + +// Increment p, but we need to check for hex 0x + + if ((*p == '0') && (*(p + 1) == 'x')) + p +=2 ; + + while (isxdigit (*p)) + ++p ; + + return p ; +} + + +/* + * extractStr: + * Check & return a string at the given location (prefixed by a :) + * Note: The string can be enclosed in []'s to escape colons. This is + * so we can handle IPv6 addresses which contain colons and the []'s is + * a common way to prepresent them. + ********************************************************************************* + */ + +static char *extractStr (char *progName, char *p, char **str) +{ + char *q, *r ; + int quoted = FALSE ; + + if (*p != ':') + { + verbError ("%s: colon expected", progName) ; + return NULL ; + } + + ++p ; + + if (*p == '[') + { + quoted = TRUE ; + ++p ; + } + + if (!isprint (*p)) // Is this needed? + { + verbError ("%s: character expected", progName) ; + return NULL ; + } + + q = p ; + if (quoted) + { + while ((*q != 0) && (*q != ']')) + ++q ; + } + else + { + while ((*q != 0) && (*q != ':')) + ++q ; + } + + *str = r = calloc (q - p + 2, 1) ; // Zeros it + + while (p != q) + *r++ = *p++ ; + + if (quoted) // Skip over the ] to the : + ++p ; + + return p ; +} + + + +/* + * doExtensionMcp23008: + * MCP23008 - 8-bit I2C GPIO expansion chip + * mcp23002:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionMcp23008 (char *progName, int pinBase, char *params) +{ + int i2c ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x01) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + mcp23008Setup (pinBase, i2c) ; + + return TRUE ; +} + + +/* + * doExtensionMcp23016: + * MCP230016- 16-bit I2C GPIO expansion chip + * mcp23016:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionMcp23016 (char *progName, int pinBase, char *params) +{ + int i2c ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x03) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + mcp23016Setup (pinBase, i2c) ; + + return TRUE ; +} + + +/* + * doExtensionMcp23017: + * MCP230017- 16-bit I2C GPIO expansion chip + * mcp23017:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionMcp23017 (char *progName, int pinBase, char *params) +{ + int i2c ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x03) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + mcp23017Setup (pinBase, i2c) ; + + return TRUE ; +} + + +/* + * doExtensionMcp23s08: + * MCP23s08 - 8-bit SPI GPIO expansion chip + * mcp23s08:base:spi:port + ********************************************************************************* + */ + +static int doExtensionMcp23s08 (char *progName, int pinBase, char *params) +{ + int spi, port ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI address (%d) out of range", progName, spi) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &port)) == NULL) + return FALSE ; + + if ((port < 0) || (port > 7)) + { + verbError ("%s: port address (%d) out of range", progName, port) ; + return FALSE ; + } + + mcp23s08Setup (pinBase, spi, port) ; + + return TRUE ; +} + + +/* + * doExtensionMcp23s17: + * MCP23s17 - 16-bit SPI GPIO expansion chip + * mcp23s17:base:spi:port + ********************************************************************************* + */ + +static int doExtensionMcp23s17 (char *progName, int pinBase, char *params) +{ + int spi, port ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI address (%d) out of range", progName, spi) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &port)) == NULL) + return FALSE ; + + if ((port < 0) || (port > 7)) + { + verbError ("%s: port address (%d) out of range", progName, port) ; + return FALSE ; + } + + mcp23s17Setup (pinBase, spi, port) ; + + return TRUE ; +} + + +/* + * doExtensionSr595: + * Shift Register 74x595 + * sr595:base:pins:data:clock:latch + ********************************************************************************* + */ + +static int doExtensionSr595 (char *progName, int pinBase, char *params) +{ + int pins, data, clock, latch ; + +// Extract pins + + if ((params = extractInt (progName, params, &pins)) == NULL) + return FALSE ; + + if ((pins < 8) || (pins > 32)) + { + verbError ("%s: pin count (%d) out of range - 8-32 expected.", progName, pins) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &data)) == NULL) + return FALSE ; + + if ((params = extractInt (progName, params, &clock)) == NULL) + return FALSE ; + + if ((params = extractInt (progName, params, &latch)) == NULL) + return FALSE ; + + sr595Setup (pinBase, pins, data, clock, latch) ; + + return TRUE ; +} + + +/* + * doExtensionPcf8574: + * Digital IO (Crude!) + * pcf8574:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionPcf8574 (char *progName, int pinBase, char *params) +{ + int i2c ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x03) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + pcf8574Setup (pinBase, i2c) ; + + return TRUE ; +} + + +/* + * doExtensionAds1115: + * Analog Input + * ads1115:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionAds1115 (char *progName, int pinBase, char *params) +{ + int i2c ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x03) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + ads1115Setup (pinBase, i2c) ; + + return TRUE ; +} + + +/* + * doExtensionPcf8591: + * Analog IO + * pcf8591:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionPcf8591 (char *progName, int pinBase, char *params) +{ + int i2c ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x03) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + pcf8591Setup (pinBase, i2c) ; + + return TRUE ; +} + + +/* + * doExtensionPseudoPins: + * 64 Memory resident pseudo pins + * pseudoPins:base + ********************************************************************************* + */ + +static int doExtensionPseudoPins (UNU char *progName, int pinBase, UNU char *params) +{ + pseudoPinsSetup (pinBase) ; + + return TRUE ; +} + + +/* + * doExtensionBmp180: + * Analog Temp + Pressure + * bmp180:base + ********************************************************************************* + */ + +static int doExtensionBmp180 (UNU char *progName, int pinBase, UNU char *params) +{ + bmp180Setup (pinBase) ; + + return TRUE ; +} + + +/* + * doExtensionHtu21d: + * Analog humidity + Pressure + * htu21d:base + ********************************************************************************* + */ + +static int doExtensionHtu21d (UNU char *progName, int pinBase, UNU char *params) +{ + htu21dSetup (pinBase) ; + + return TRUE ; +} + + +/* + * doExtensionDs18b20: + * 1-Wire Temperature + * htu21d:base:serialNum + ********************************************************************************* + */ + +static int doExtensionDs18b20 (char *progName, int pinBase, char *params) +{ + char *serialNum ; + + if ((params = extractStr (progName, params, &serialNum)) == NULL) + return FALSE ; + + return ds18b20Setup (pinBase, serialNum) ; +} + + +/* + * doExtensionRht03: + * Maxdetect 1-Wire Temperature & Humidity + * rht03:base:piPin + ********************************************************************************* + */ + +static int doExtensionRht03 (char *progName, int pinBase, char *params) +{ + int piPin ; + + if ((params = extractInt (progName, params, &piPin)) == NULL) + return FALSE ; + + return rht03Setup (pinBase, piPin) ; +} + + +/* + * doExtensionMax31855: + * Analog IO + * max31855:base:spiChan + ********************************************************************************* + */ + +static int doExtensionMax31855 (char *progName, int pinBase, char *params) +{ + int spi ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI channel (%d) out of range", progName, spi) ; + return FALSE ; + } + + max31855Setup (pinBase, spi) ; + + return TRUE ; +} + + +/* + * doExtensionMcp3002: + * Analog IO + * mcp3002:base:spiChan + ********************************************************************************* + */ + +static int doExtensionMcp3002 (char *progName, int pinBase, char *params) +{ + int spi ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI channel (%d) out of range", progName, spi) ; + return FALSE ; + } + + mcp3002Setup (pinBase, spi) ; + + return TRUE ; +} + + +/* + * doExtensionMcp3004: + * Analog IO + * mcp3004:base:spiChan + ********************************************************************************* + */ + +static int doExtensionMcp3004 (char *progName, int pinBase, char *params) +{ + int spi ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI channel (%d) out of range", progName, spi) ; + return FALSE ; + } + + mcp3004Setup (pinBase, spi) ; + + return TRUE ; +} + + +/* + * doExtensionMax5322: + * Analog O + * max5322:base:spiChan + ********************************************************************************* + */ + +static int doExtensionMax5322 (char *progName, int pinBase, char *params) +{ + int spi ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI channel (%d) out of range", progName, spi) ; + return FALSE ; + } + + max5322Setup (pinBase, spi) ; + + return TRUE ; +} + + +/* + * doExtensionMcp4802: + * Analog IO + * mcp4802:base:spiChan + ********************************************************************************* + */ + +static int doExtensionMcp4802 (char *progName, int pinBase, char *params) +{ + int spi ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI channel (%d) out of range", progName, spi) ; + return FALSE ; + } + + mcp4802Setup (pinBase, spi) ; + + return TRUE ; +} + + +/* + * doExtensionSn3218: + * Analog Output (LED Driver) + * sn3218:base + ********************************************************************************* + */ + +static int doExtensionSn3218 (UNU char *progName, int pinBase, UNU char *params) +{ + sn3218Setup (pinBase) ; + return TRUE ; +} + + +/* + * doExtensionMcp3422: + * Analog IO + * mcp3422:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionMcp3422 (char *progName, int pinBase, char *params) +{ + int i2c, sampleRate, gain ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x03) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &sampleRate)) == NULL) + return FALSE ; + + if ((sampleRate < 0) || (sampleRate > 3)) + { + verbError ("%s: sample rate (%d) out of range", progName, sampleRate) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &gain)) == NULL) + return FALSE ; + + if ((gain < 0) || (gain > 3)) + { + verbError ("%s: gain (%d) out of range", progName, gain) ; + return FALSE ; + } + + mcp3422Setup (pinBase, i2c, sampleRate, gain) ; + + return TRUE ; +} + + +/* + * doExtensionDrcS: + * Interface to a DRC Serial system + * drcs:base:pins:serialPort:baud + ********************************************************************************* + */ + +static int doExtensionDrcS (char *progName, int pinBase, char *params) +{ + char *port ; + int pins, baud ; + + if ((params = extractInt (progName, params, &pins)) == NULL) + return FALSE ; + + if ((pins < 1) || (pins > 1000)) + { + verbError ("%s: pins (%d) out of range (2-1000)", progName, pins) ; + return FALSE ; + } + + if ((params = extractStr (progName, params, &port)) == NULL) + return FALSE ; + + if (strlen (port) == 0) + { + verbError ("%s: serial port device name required", progName) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &baud)) == NULL) + return FALSE ; + + if ((baud < 1) || (baud > 4000000)) + { + verbError ("%s: baud rate (%d) out of range", progName, baud) ; + return FALSE ; + } + + drcSetupSerial (pinBase, pins, port, baud) ; + + return TRUE ; +} + + +/* + * doExtensionDrcNet: + * Interface to a DRC Network system + * drcn:base:pins:ipAddress:port:password + ********************************************************************************* + */ + +static int doExtensionDrcNet (char *progName, int pinBase, char *params) +{ + int pins ; + char *ipAddress, *port, *password ; + char pPort [1024] ; + + if ((params = extractInt (progName, params, &pins)) == NULL) + return FALSE ; + + if ((pins < 1) || (pins > 1000)) + { + verbError ("%s: pins (%d) out of range (2-1000)", progName, pins) ; + return FALSE ; + } + + if ((params = extractStr (progName, params, &ipAddress)) == NULL) + return FALSE ; + + if (strlen (ipAddress) == 0) + { + verbError ("%s: ipAddress required", progName) ; + return FALSE ; + } + + if ((params = extractStr (progName, params, &port)) == NULL) + return FALSE ; + + if (strlen (port) == 0) + { + sprintf (pPort, "%d", DEFAULT_SERVER_PORT) ; + port = pPort ; + } + + if ((params = extractStr (progName, params, &password)) == NULL) + return FALSE ; + + if (strlen (password) == 0) + { + verbError ("%s: password required", progName) ; + return FALSE ; + } + + return drcSetupNet (pinBase, pins, ipAddress, port, password) ; +} + + + +/* + * Function list + ********************************************************************************* + */ + +static struct extensionFunctionStruct extensionFunctions [] = +{ + { "mcp23008", &doExtensionMcp23008 }, + { "mcp23016", &doExtensionMcp23016 }, + { "mcp23017", &doExtensionMcp23017 }, + { "mcp23s08", &doExtensionMcp23s08 }, + { "mcp23s17", &doExtensionMcp23s17 }, + { "sr595", &doExtensionSr595 }, + { "pcf8574", &doExtensionPcf8574 }, + { "pcf8591", &doExtensionPcf8591 }, + { "bmp180", &doExtensionBmp180 }, + { "pseudoPins", &doExtensionPseudoPins }, + { "htu21d", &doExtensionHtu21d }, + { "ds18b20", &doExtensionDs18b20 }, + { "rht03", &doExtensionRht03 }, + { "mcp3002", &doExtensionMcp3002 }, + { "mcp3004", &doExtensionMcp3004 }, + { "mcp4802", &doExtensionMcp4802 }, + { "mcp3422", &doExtensionMcp3422 }, + { "max31855", &doExtensionMax31855 }, + { "ads1115", &doExtensionAds1115 }, + { "max5322", &doExtensionMax5322 }, + { "sn3218", &doExtensionSn3218 }, + { "drcs", &doExtensionDrcS }, + { "drcn", &doExtensionDrcNet }, + { NULL, NULL }, +} ; + + +/* + * loadWPiExtension: + * Load in a wiringPi extension + * The extensionData always starts with the name, a colon then the pinBase + * number. Other parameters after that are decoded by the module in question. + ********************************************************************************* + */ + +int loadWPiExtension (char *progName, char *extensionData, int printErrors) +{ + char *p ; + char *extension = extensionData ; + struct extensionFunctionStruct *extensionFn ; + int pinBase = 0 ; + + verbose = printErrors ; + +// Get the extension name by finding the first colon + + p = extension ; + while (*p != ':') + { + if (!*p) // ran out of characters + { + verbError ("%s: extension name not terminated by a colon", progName) ; + return FALSE ; + } + ++p ; + } + *p++ = 0 ; + +// Simple ATOI code + + if (!isdigit (*p)) + { + verbError ("%s: decimal pinBase number expected after extension name", progName) ; + return FALSE ; + } + + while (isdigit (*p)) + { + if (pinBase > 2147483647) // 2^31-1 ... Lets be realistic here... + { + verbError ("%s: pinBase too large", progName) ; + return FALSE ; + } + + pinBase = pinBase * 10 + (*p - '0') ; + ++p ; + } + + if (pinBase < 64) + { + verbError ("%s: pinBase (%d) too small. Minimum is 64.", progName, pinBase) ; + return FALSE ; + } + +// Search for extensions: + + for (extensionFn = extensionFunctions ; extensionFn->name != NULL ; ++extensionFn) + { + if (strcmp (extensionFn->name, extension) == 0) + return extensionFn->function (progName, pinBase, p) ; + } + + fprintf (stderr, "%s: extension %s not found", progName, extension) ; + return FALSE ; +} diff --git a/wiringPi/wpiExtensions.h b/wiringPi/wpiExtensions.h new file mode 100644 index 0000000..fcaec96 --- /dev/null +++ b/wiringPi/wpiExtensions.h @@ -0,0 +1,26 @@ +/* + * extensions.h: + * Part of the GPIO program to test, peek, poke and otherwise + * noodle with the GPIO hardware on the Raspberry Pi. + * Copyright (c) 2012-2015 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + + +extern int loadWPiExtension (char *progName, char *extensionData, int verbose) ; diff --git a/wiringPiD/Makefile b/wiringPiD/Makefile new file mode 100644 index 0000000..3df7695 --- /dev/null +++ b/wiringPiD/Makefile @@ -0,0 +1,100 @@ +# +# Makefile: +# The wiringPiD utility: +# https://projects.drogon.net/wiring-pi +# +# Copyright (c) 2012-2017 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# A "wiring" library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + +DESTDIR?=/usr +PREFIX?=/local + +ifneq ($V,1) +Q ?= @ +endif + +#DEBUG = -g -O0 +DEBUG = -O2 +CC = gcc +INCLUDE = -I$(DESTDIR)$(PREFIX)/include +CFLAGS = $(DEBUG) -Wall -Wextra $(INCLUDE) -Winline -pipe + +LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib +LIBS = -lwiringPi -lwiringPiDev -lpthread -lrt -lm -lcrypt + +# May not need to alter anything below this line +############################################################################### + +SRC = wiringpid.c network.c runRemote.c daemonise.c + +OBJ = $(SRC:.c=.o) + +all: wiringpid + +wiringpid: $(OBJ) + $Q echo [Link] + $Q $(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS) + +.c.o: + $Q echo [Compile] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ + +.PHONY: clean +clean: + $Q echo "[Clean]" + $Q rm -f $(OBJ) wiringpid *~ core tags *.bak + +.PHONY: tags +tags: $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) + +.PHONY: install +install: wiringpid + $Q echo "[Install]" + $Q mkdir -p $(DESTDIR)$(PREFIX)/sbin + $Q cp wiringpid $(DESTDIR)$(PREFIX)/sbin/ + $Q chown root.root $(DESTDIR)$(PREFIX)/sbin/wiringpid + +# $Q mkdir -p $(DESTDIR)$(PREFIX)/man/man8 +# $Q cp gpio.1 $(DESTDIR)$(PREFIX)/man/man8/ + +.PHONY: install-deb +install-deb: gpio + $Q echo "[Install: deb]" + $Q install -m 0755 -d $(CURDIR)/../debian-template/wiringPi/usr/bin + $Q install -m 0755 gpio $(CURDIR)/../debian-template/wiringPi/usr/bin + $Q install -m 0755 -d $(CURDIR)/../debian-template/wiringPi/man/man1 + $Q install -m 0644 gpio.1 $(CURDIR)/../debian-template/wiringPi/man/man1 + +.PHONY: uninstall +uninstall: + $Q echo "[UnInstall]" + $Q rm -f $(DESTDIR)$(PREFIX)/sbin/wiringpid + $Q rm -f $(DESTDIR)$(PREFIX)/man/man8/wiringpid.8 + +.PHONY: depend +depend: + makedepend -Y $(SRC) +# DO NOT DELETE + +wiringpid.o: drcNetCmd.h network.h runRemote.h daemonise.h +network.o: network.h +runRemote.o: drcNetCmd.h network.h runRemote.h +daemonise.o: daemonise.h diff --git a/wiringPiD/daemonise.c b/wiringPiD/daemonise.c new file mode 100644 index 0000000..134a6bb --- /dev/null +++ b/wiringPiD/daemonise.c @@ -0,0 +1,82 @@ +/* + * daemonise.c: + * Fairly generic "Turn the current process into a daemon" code. + * + * Copyright (c) 2016-2017 Gordon Henderson. + ********************************************************************************* + */ + +#include +#include +#include +#include +#include +#include + +#include "daemonise.h" + +void daemonise (const char *pidFile) +{ + pid_t pid ; + int i ; + FILE *fd ; + + syslog (LOG_DAEMON | LOG_INFO, "Becoming daemon") ; + +// Fork from the parent + + if ((pid = fork ()) < 0) + { + syslog (LOG_DAEMON | LOG_ALERT, "Fork no. 1 failed: %m") ; + exit (EXIT_FAILURE) ; + } + + if (pid > 0) // Parent - terminate + exit (EXIT_SUCCESS) ; + +// Now running on the child - become session leader + + if (setsid() < 0) + { + syslog (LOG_DAEMON | LOG_ALERT, "setsid failed: %m") ; + exit (EXIT_FAILURE) ; + } + +// Ignore a few signals + + signal (SIGCHLD, SIG_IGN) ; + signal (SIGHUP, SIG_IGN) ; + +// Fork again + + if ((pid = fork ()) < 0) + { + syslog (LOG_DAEMON | LOG_ALERT, "Fork no. 2 failed: %m") ; + exit (EXIT_FAILURE) ; + } + + if (pid > 0) // parent - terminate + exit (EXIT_SUCCESS) ; + +// Tidying up - reset umask, change to / and close all files + + umask (0) ; + chdir ("/") ; + + for (i = 0 ; i < sysconf (_SC_OPEN_MAX) ; ++i) + close (i) ; + +// Write PID into /var/run + + if (pidFile != NULL) + { + if ((fd = fopen (pidFile, "w")) == NULL) + { + syslog (LOG_DAEMON | LOG_ALERT, "Unable to write PID file: %m") ; + exit (EXIT_FAILURE) ; + } + + fprintf (fd, "%d\n", getpid ()) ; + fclose (fd) ; + } +} diff --git a/wiringPiD/daemonise.h b/wiringPiD/daemonise.h new file mode 100644 index 0000000..8d13319 --- /dev/null +++ b/wiringPiD/daemonise.h @@ -0,0 +1,9 @@ +/* + * daemonise.h: + * Fairly generic "Turn the current process into a daemon" code. + * + * Copyright (c) 2016-2017 Gordon Henderson. + ********************************************************************************* + */ + +extern void daemonise (const char *pidFile) ; diff --git a/wiringPiD/drcNetCmd.h b/wiringPiD/drcNetCmd.h new file mode 100644 index 0000000..70ef51b --- /dev/null +++ b/wiringPiD/drcNetCmd.h @@ -0,0 +1,44 @@ +/* + * drcNetCmd.c: + * Copyright (c) 2012-2017 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#define DEFAULT_SERVER_PORT 6124 + +#define DRCN_PIN_MODE 1 +#define DRCN_PULL_UP_DN 2 + +#define DRCN_DIGITAL_WRITE 3 +#define DRCN_DIGITAL_WRITE8 4 +#define DRCN_ANALOG_WRITE 5 +#define DRCN_PWM_WRITE 6 + +#define DRCN_DIGITAL_READ 7 +#define DRCN_DIGITAL_READ8 8 +#define DRCN_ANALOG_READ 9 + + +struct drcNetComStruct +{ + uint32_t pin ; + uint32_t cmd ; + uint32_t data ; +}; + diff --git a/wiringPiD/network.c b/wiringPiD/network.c new file mode 100644 index 0000000..9f6bb88 --- /dev/null +++ b/wiringPiD/network.c @@ -0,0 +1,330 @@ +/* + * network.c: + * Part of wiringPiD + * Copyright (c) 2012-2017 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "network.h" + +#define TRUE (1==1) +#define FALSE (!TRUE) + +// Local data + +#define SALT_LEN 16 + +static char salt [SALT_LEN + 1] ; +static char *returnedHash = NULL ; +static int serverFd = -1 ; + +// Union for the server Socket Address + +static union +{ + struct sockaddr_in sin ; + struct sockaddr_in6 sin6 ; +} serverSockAddr ; + +// and client address + +static union +{ + struct sockaddr_in sin ; + struct sockaddr_in6 sin6 ; +} clientSockAddr ; + + +/* + * getClientIP: + * Returns a pointer to a static string containing the clients IP address + ********************************************************************************* + */ + +char *getClientIP (void) +{ + char buf [INET6_ADDRSTRLEN] ; + static char ipAddress [1024] ; + + if (clientSockAddr.sin.sin_family == AF_INET) // IPv4 + { + if (snprintf (ipAddress, 1024, "IPv4: %s", + inet_ntop (clientSockAddr.sin.sin_family, (void *)&clientSockAddr.sin.sin_addr, buf, sizeof (buf))) == 1024) + strcpy (ipAddress, "Too long") ; + } + else // IPv6 + { + if (clientSockAddr.sin.sin_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED (&clientSockAddr.sin6.sin6_addr)) + { + if (snprintf (ipAddress, 1024, "IPv4in6: %s", + inet_ntop (clientSockAddr.sin.sin_family, (char *)&clientSockAddr.sin6.sin6_addr, buf, sizeof(buf))) == 1024) + strcpy (ipAddress, "Too long") ; + } + else + { + if (snprintf (ipAddress, 1024, "IPv6: %s", + inet_ntop (clientSockAddr.sin.sin_family, (char *)&clientSockAddr.sin6.sin6_addr, buf, sizeof(buf))) == 1024) + strcpy (ipAddress, "Too long") ; + } + } + + return ipAddress ; +} + + + +/* + * clientPstr: clientPrintf: + * Print over a network socket + ********************************************************************************* + */ + +static int clientPstr (int fd, char *s) +{ + int len = strlen (s) ; + return (write (fd, s, len) == len) ? 0 : -1 ; +} + +static int clientPrintf (const int fd, const char *message, ...) +{ + va_list argp ; + char buffer [1024] ; + + va_start (argp, message) ; + vsnprintf (buffer, 1023, message, argp) ; + va_end (argp) ; + + return clientPstr (fd, buffer) ; +} + + +/* + * sendGreeting: + * Send some text to the client device + ********************************************************************************* + */ + +int sendGreeting (int clientFd) +{ + if (clientPrintf (clientFd, "200 Welcome to wiringPiD - http://wiringpi.com/\n") < 0) + return -1 ; + + return clientPrintf (clientFd, "200 Connecting from: %s\n", getClientIP ()) ; +} + + +/* + * getSalt: + * Create a random 'salt' value for the password encryption process + ********************************************************************************* + */ + +static int getSalt (char drySalt []) +{ + static const char *seaDog = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789/." ; + + unsigned char wetSalt [SALT_LEN] ; + int i, fd ; + + if ((fd = open ("/dev/urandom", O_RDONLY)) < 0) + return fd ; + + if (read (fd, wetSalt, SALT_LEN) != SALT_LEN) + return -1 ; + + close (fd) ; + + for (i = 0 ; i < SALT_LEN ; ++i) + drySalt [i] = seaDog [wetSalt [i] & 63] ; + + drySalt [SALT_LEN] = 0 ; + + return 0 ; +} + + +/* + * sendChallenge: + * Create and send our salt (aka nonce) to the remote device + ********************************************************************************* + */ + +int sendChallenge (int clientFd) +{ + if (getSalt (salt) < 0) + return -1 ; + + return clientPrintf (clientFd, "Challenge %s\n", salt) ; +} + + +/* + * getResponse: + * Read the encrypted password from the remote device. + ********************************************************************************* + */ + + +int getResponse (int clientFd) +{ + char reply [1024] ; + int len ; + +// Being sort of lazy about this. I'm expecting an SHA-512 hash back and these +// are exactly 86 characters long, so no reason not to, I guess... + + len = 86 ; + + if (setsockopt (clientFd, SOL_SOCKET, SO_RCVLOWAT, (void *)&len, sizeof (len)) < 0) + return -1 ; + + len = recv (clientFd, reply, 86, 0) ; + if (len != 86) + return -1 ; + + reply [len] = 0 ; + + if ((returnedHash = malloc (len + 1)) == NULL) + return -1 ; + + strcpy (returnedHash, reply) ; + + return 0 ; +} + + +/* + * passwordMatch: + * See if there's a match. If not, we simply dump them. + ********************************************************************************* + */ + +int passwordMatch (const char *password) +{ + char *encrypted ; + char salted [1024] ; + + sprintf (salted, "$6$%s$", salt) ; + + encrypted = crypt (password, salted) ; + +// 20: $6$ then 16 characters of salt, then $ +// 86 is the length of an SHA-512 hash + + return strncmp (encrypted + 20, returnedHash, 86) == 0 ; +} + + +/* + * setupServer: + * Do what's needed to create a local server socket instance that can listen + * on both IPv4 and IPv6 interfaces. + ********************************************************************************* + */ + +int setupServer (int serverPort) +{ + socklen_t clientSockAddrSize = sizeof (clientSockAddr) ; + + int on = 1 ; + int family ; + socklen_t serverSockAddrSize ; + int clientFd ; + +// Try to create an IPv6 socket + + serverFd = socket (PF_INET6, SOCK_STREAM, 0) ; + +// If it didn't work, then fall-back to IPv4. + + if (serverFd < 0) + { + if ((serverFd = socket (PF_INET, SOCK_STREAM, 0)) < 0) + return -1 ; + + family = AF_INET ; + serverSockAddrSize = sizeof (struct sockaddr_in) ; + } + else // We got an IPv6 socket + { + family = AF_INET6 ; + serverSockAddrSize = sizeof (struct sockaddr_in6) ; + } + + if (setsockopt (serverFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0) + return -1 ; + +// Setup the servers socket address - cope with IPv4 and v6. + + memset (&serverSockAddr, 0, sizeof (serverSockAddr)) ; + switch (family) + { + case AF_INET: + serverSockAddr.sin.sin_family = AF_INET ; + serverSockAddr.sin.sin_addr.s_addr = htonl (INADDR_ANY) ; + serverSockAddr.sin.sin_port = htons (serverPort) ; + break; + + case AF_INET6: + serverSockAddr.sin6.sin6_family = AF_INET6 ; + serverSockAddr.sin6.sin6_addr = in6addr_any ; + serverSockAddr.sin6.sin6_port = htons (serverPort) ; + } + +// Bind, listen and accept + + if (bind (serverFd, (struct sockaddr *)&serverSockAddr, serverSockAddrSize) < 0) + return -1 ; + + if (listen (serverFd, 4) < 0) // Really only going to talk to one client at a time... + return -1 ; + + if ((clientFd = accept (serverFd, (struct sockaddr *)&clientSockAddr, &clientSockAddrSize)) < 0) + return -1 ; + + return clientFd ; +} + + +/* + * closeServer: + ********************************************************************************* + */ + +void closeServer (int clientFd) +{ + if (serverFd != -1) close (serverFd) ; + if (clientFd != -1) close (clientFd) ; + serverFd = clientFd = -1 ; +} diff --git a/wiringPiD/network.h b/wiringPiD/network.h new file mode 100644 index 0000000..94c3380 --- /dev/null +++ b/wiringPiD/network.h @@ -0,0 +1,31 @@ +/* + * network.h: + * Part of wiringPiD + * Copyright (c) 2012-2017 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +extern char *getClientIP (void) ; +extern int getResponce (int clientFd) ; +extern int setupServer (int serverPort) ; +extern int sendGreeting (int clientFd) ; +extern int sendChallenge (int clientFd) ; +extern int getResponse (int clientFd) ; +extern int passwordMatch (const char *password) ; +extern void closeServer (int clientFd) ; diff --git a/wiringPiD/runRemote.c b/wiringPiD/runRemote.c new file mode 100644 index 0000000..cd7432b --- /dev/null +++ b/wiringPiD/runRemote.c @@ -0,0 +1,126 @@ +/* + * runRemote.c: + * Run the remote commands passed over the network link. + * + * Copyright (c) 2012-2017 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +//#include + +#include +#include + +#include "drcNetCmd.h" +#include "network.h" +#include "runRemote.h" + + + +int noLocalPins = FALSE ; + + +void runRemoteCommands (int fd) +{ + register uint32_t pin ; + int len ; + struct drcNetComStruct cmd ; + + len = sizeof (struct drcNetComStruct) ; + + if (setsockopt (fd, SOL_SOCKET, SO_RCVLOWAT, (void *)&len, sizeof (len)) < 0) + return ; + + for (;;) + { + if (recv (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd)) // Probably remote hangup + return ; + + pin = cmd.pin ; + if (noLocalPins && ((pin & PI_GPIO_MASK) == 0)) + { + if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd)) + return ; + continue ; + } + + switch (cmd.cmd) + { + case DRCN_PIN_MODE: + pinMode (pin, cmd.data) ; + if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd)) + return ; + break ; + + case DRCN_PULL_UP_DN: + pullUpDnControl (pin, cmd.data) ; + break ; + + case DRCN_PWM_WRITE: + pwmWrite (pin, cmd.data) ; + if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd)) + return ; + break ; + + case DRCN_DIGITAL_WRITE: + digitalWrite (pin, cmd.data) ; + if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd)) + return ; + break ; + + case DRCN_DIGITAL_WRITE8: + //digitalWrite8 (pin, cmd.data) ; + if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd)) + return ; + break ; + + case DRCN_DIGITAL_READ: + cmd.data = digitalRead (pin) ; + if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd)) + return ; + break ; + + case DRCN_DIGITAL_READ8: + //cmd.data = digitalRead8 (pin) ; + if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd)) + return ; + break ; + + case DRCN_ANALOG_WRITE: + analogWrite (pin, cmd.data) ; + if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd)) + return ; + break ; + + case DRCN_ANALOG_READ: + cmd.data = analogRead (pin) ; + if (send (fd, &cmd, sizeof (cmd), 0) != sizeof (cmd)) + return ; + break ; + } + } + +} diff --git a/wiringPiD/runRemote.h b/wiringPiD/runRemote.h new file mode 100644 index 0000000..57d5018 --- /dev/null +++ b/wiringPiD/runRemote.h @@ -0,0 +1,29 @@ +/* + * runRemote.h: + * Run the remote commands passed over the network link. + * + * Copyright (c) 2012-2017 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +// Globals + +extern int noLocalPins ; + +extern void runRemoteCommands (int fd) ; diff --git a/wiringPiD/wiringpid.c b/wiringPiD/wiringpid.c new file mode 100644 index 0000000..8dde1cd --- /dev/null +++ b/wiringPiD/wiringpid.c @@ -0,0 +1,382 @@ +/* + * wiringPiD.c: + * Copyright (c) 2012-2017 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "drcNetCmd.h" +#include "network.h" +#include "runRemote.h" +#include "daemonise.h" + + +#define PIDFILE "/var/run/wiringPiD.pid" + + +// Globals + +static const char *usage = "[-h] [-d] [-g | -1 | -z] [[-x extension:pin:params] ...] password" ; +static int doDaemon = FALSE ; + +// + +static void logMsg (const char *message, ...) +{ + va_list argp ; + char buffer [1024] ; + + va_start (argp, message) ; + vsnprintf (buffer, 1023, message, argp) ; + va_end (argp) ; + + if (doDaemon) + syslog (LOG_DAEMON | LOG_INFO, "%s", buffer) ; + else + printf ("%s\n", buffer) ; +} + + +/* + * sigHandler: + * setupSigHandler: + * Somehing has happened that would normally terminate the program so try + * to close down nicely. + ********************************************************************************* + */ + +void sigHandler (int sig) +{ + logMsg ("Exiting on signal %d: %s", sig, strsignal (sig)) ; + (void)unlink (PIDFILE) ; + exit (EXIT_FAILURE) ; +} + +void setupSigHandler (void) +{ + struct sigaction action ; + + sigemptyset (&action.sa_mask) ; + action.sa_flags = 0 ; + +// Ignore what we can + + action.sa_handler = SIG_IGN ; + + sigaction (SIGHUP, &action, NULL) ; + sigaction (SIGTTIN, &action, NULL) ; + sigaction (SIGTTOU, &action, NULL) ; + +// Trap what we can to exit gracefully + + action.sa_handler = sigHandler ; + + sigaction (SIGINT, &action, NULL) ; + sigaction (SIGQUIT, &action, NULL) ; + sigaction (SIGILL, &action, NULL) ; + sigaction (SIGABRT, &action, NULL) ; + sigaction (SIGFPE, &action, NULL) ; + sigaction (SIGSEGV, &action, NULL) ; + sigaction (SIGPIPE, &action, NULL) ; + sigaction (SIGALRM, &action, NULL) ; + sigaction (SIGTERM, &action, NULL) ; + sigaction (SIGUSR1, &action, NULL) ; + sigaction (SIGUSR2, &action, NULL) ; + sigaction (SIGCHLD, &action, NULL) ; + sigaction (SIGTSTP, &action, NULL) ; + sigaction (SIGBUS, &action, NULL) ; +} + + +/* + * The works... + ********************************************************************************* + */ + +int main (int argc, char *argv []) +{ + int clientFd ; + char *p, *password ; + int i ; + int port = DEFAULT_SERVER_PORT ; + int wpiSetup = 0 ; + + if (argc < 2) + { + fprintf (stderr, "Usage: %s %s\n", argv [0], usage) ; + exit (EXIT_FAILURE) ; + } + +// Help? + + if (strcasecmp (argv [1], "-h") == 0) + { + printf ("Usage: %s %s\n", argv [0], usage) ; + return 0 ; + } + +// Daemonize? +// Must come before the other args as e.g. some extensions +// open files which get closed on daemonise... + + if (strcasecmp (argv [1], "-d") == 0) + { + if (geteuid () != 0) + { + fprintf (stderr, "%s: Must be root to run as a daemon.\n", argv [0]) ; + exit (EXIT_FAILURE) ; + } + + doDaemon = TRUE ; + daemonise (PIDFILE) ; + + for (i = 2 ; i < argc ; ++i) + argv [i - 1] = argv [i] ; + --argc ; + } + +// Scan all other arguments + + while (*argv [1] == '-') + { + +// Look for wiringPi setup arguments: +// Same as the gpio command and rtb. + +// -g - bcm_gpio + + if (strcasecmp (argv [1], "-g") == 0) + { + if (wpiSetup == 0) + { + logMsg ("BCM_GPIO mode selected") ; + wiringPiSetupGpio () ; + } + + for (i = 2 ; i < argc ; ++i) + argv [i - 1] = argv [i] ; + --argc ; + ++wpiSetup ; + continue ; + } + +// -1 - physical pins + + if (strcasecmp (argv [1], "-1") == 0) + { + if (wpiSetup == 0) + { + logMsg ("GPIO-PHYS mode selected") ; + wiringPiSetupPhys () ; + } + + for (i = 2 ; i < argc ; ++i) + argv [i - 1] = argv [i] ; + --argc ; + ++wpiSetup ; + continue ; + } + +// -z - no wiringPi - blocks remotes accessing local pins + + if (strcasecmp (argv [1], "-z") == 0) + { + if (wpiSetup == 0) + logMsg ("No GPIO mode selected") ; + + for (i = 2 ; i < argc ; ++i) + argv [i - 1] = argv [i] ; + --argc ; + noLocalPins = TRUE ; + ++wpiSetup ; + continue ; + } + +// -p to select the port + + if (strcasecmp (argv [1], "-p") == 0) + { + if (argc < 3) + { + logMsg ("-p missing extension port") ; + exit (EXIT_FAILURE) ; + } + + logMsg ("Setting port to: %s", argv [2]) ; + + port = atoi (argv [2]) ; + if ((port < 1) || (port > 65535)) + { + logMsg ("Invalid server port: %d", port) ; + exit (EXIT_FAILURE) ; + } + +// Shift args down by 2 + + for (i = 3 ; i < argc ; ++i) + argv [i - 2] = argv [i] ; + argc -= 2 ; + + continue ; + } + +// Check for -x argument to load in a new extension +// -x extension:base:args +// Can load many modules to extend the daemon. + + if (strcasecmp (argv [1], "-x") == 0) + { + if (argc < 3) + { + logMsg ("-x missing extension name:data:etc.") ; + exit (EXIT_FAILURE) ; + } + + logMsg ("Loading extension: %s", argv [2]) ; + + if (!loadWPiExtension (argv [0], argv [2], TRUE)) + { + logMsg ("Extension load failed: %s", strerror (errno)) ; + exit (EXIT_FAILURE) ; + } + +// Shift args down by 2 + + for (i = 3 ; i < argc ; ++i) + argv [i - 2] = argv [i] ; + argc -= 2 ; + + continue ; + } + + logMsg ("Invalid parameter: %s", argv [1]) ; + exit (EXIT_FAILURE) ; + } + +// Default to wiringPi mode + + if (wpiSetup == 0) + { + logMsg ("WiringPi GPIO mode selected") ; + wiringPiSetup () ; + } + +// Finally, should just be one arg left - the password... + + if (argc != 2) + { + logMsg ("No password supplied") ; + exit (EXIT_FAILURE) ; + } + + if (strlen (argv [1]) < 6) + { + logMsg ("Password too short - at least 6 chars, not %d", strlen (argv [1])) ; + exit (EXIT_FAILURE) ; + } + + if ((password = malloc (strlen (argv [1]) + 1)) == NULL) + { + logMsg ("Out of memory") ; + exit (EXIT_FAILURE) ; + } + strcpy (password, argv [1]) ; + +// Wipe out the password on the command-line in a vague attempt to try to +// hide it from snoopers + + for (p = argv [1] ; *p ; ++p) + *p = ' ' ; + + setupSigHandler () ; + +// Enter our big loop + + for (;;) + { + + if (!doDaemon) + printf ("-=-\nWaiting for a new connection...\n") ; + + if ((clientFd = setupServer (port)) < 0) + { + logMsg ("Unable to setup server: %s", strerror (errno)) ; + exit (EXIT_FAILURE) ; + } + + logMsg ("New connection from: %s.", getClientIP ()) ; + + if (!doDaemon) + printf ("Sending Greeting.\n") ; + + if (sendGreeting (clientFd) < 0) + { + logMsg ("Unable to send greeting message: %s", strerror (errno)) ; + closeServer (clientFd) ; + continue ; + } + + if (!doDaemon) + printf ("Sending Challenge.\n") ; + + if (sendChallenge (clientFd) < 0) + { + logMsg ("Unable to send challenge message: %s", strerror (errno)) ; + closeServer (clientFd) ; + continue ; + } + + if (!doDaemon) + printf ("Waiting for response.\n") ; + + if (getResponse (clientFd) < 0) + { + logMsg ("Connection closed waiting for response: %s", strerror (errno)) ; + closeServer (clientFd) ; + continue ; + } + + if (!passwordMatch (password)) + { + logMsg ("Password failure") ; + closeServer (clientFd) ; + continue ; + } + + logMsg ("Password OK - Starting") ; + + runRemoteCommands (clientFd) ; + closeServer (clientFd) ; + } + + return 0 ; +}