From 2fe3003e20162ccbc41197d0365e47ee51d6aad0 Mon Sep 17 00:00:00 2001 From: liuls2002 Date: Fri, 11 Aug 2023 15:53:17 +0800 Subject: [PATCH] first commit --- .gitignore | 9 + COPYING.LESSER | 165 ++ INSTALL | 29 + People | 37 + README.md | 390 +++++ VERSION | 1 + build | 300 ++++ debian/.gitignore | 9 + debian/changelog | 6 + debian/compat | 1 + debian/control | 29 + debian/copyright | 15 + debian/libwiringpi-dev.dirs | 2 + debian/libwiringpi-dev.install | 3 + debian/libwiringpi2.install | 1 + debian/libwiringpi2.shlibs | 2 + debian/rules | 49 + debian/wiringpi.dirs | 1 + debian/wiringpi.install | 4 + devLib/Makefile | 140 ++ devLib/ds1302.c | 240 +++ devLib/ds1302.h | 44 + devLib/font.h | 2577 ++++++++++++++++++++++++++++ devLib/gertboard.c | 164 ++ devLib/gertboard.h | 45 + devLib/lcd.c | 495 ++++++ devLib/lcd.h | 52 + devLib/lcd128x64.c | 673 ++++++++ devLib/lcd128x64.h | 39 + devLib/maxdetect.c | 238 +++ devLib/maxdetect.h | 40 + devLib/piFace.c | 112 ++ devLib/piFace.h | 32 + devLib/piFaceOld.c | 177 ++ devLib/piGlow.c | 118 ++ devLib/piGlow.h | 45 + devLib/piNes.c | 113 ++ devLib/piNes.h | 45 + devLib/scrollPhat.c | 430 +++++ devLib/scrollPhat.h | 39 + devLib/scrollPhatFont.h | 544 ++++++ examples/COPYING.LESSER | 165 ++ examples/Gertboard/7segments.c | 221 +++ examples/Gertboard/Makefile | 78 + examples/Gertboard/buttons.c | 83 + examples/Gertboard/gertboard.c | 96 ++ examples/Gertboard/record.c | 60 + examples/Gertboard/temperature.c | 78 + examples/Gertboard/voltmeter.c | 73 + examples/Gertboard/vumeter.c | 152 ++ examples/Makefile | 197 +++ examples/PiFace/Makefile | 88 + examples/PiFace/blink.c | 59 + examples/PiFace/buttons.c | 103 ++ examples/PiFace/ladder.c | 337 ++++ examples/PiFace/metro.c | 111 ++ examples/PiFace/motor.c | 120 ++ examples/PiFace/reaction.c | 194 +++ examples/PiGlow/Makefile | 82 + examples/PiGlow/piGlow0.c | 51 + examples/PiGlow/piGlow1.c | 258 +++ examples/PiGlow/piglow.c | 176 ++ examples/README.TXT | 18 + examples/blink-thread.c | 61 + examples/blink.c | 31 + examples/blink.rtb | 30 + examples/blink.sh | 37 + examples/blink12.c | 111 ++ examples/blink12drcs.c | 125 ++ examples/blink6drcs.c | 115 ++ examples/blink8-drcn.c | 61 + examples/blink8.c | 57 + examples/clock.c | 201 +++ examples/delayTest.c | 102 ++ examples/ds1302.c | 238 +++ examples/header.h | 23 + examples/isr-osc.c | 118 ++ examples/isr.c | 110 ++ examples/lcd-adafruit.c | 347 ++++ examples/lcd.c | 286 ++++ examples/lowPower.c | 68 + examples/max31855.c | 60 + examples/nes.c | 67 + examples/okLed.c | 82 + examples/oled_demo.c | 100 ++ examples/pwm.c | 44 + examples/q2w/Makefile | 84 + examples/q2w/binary.c | 79 + examples/q2w/blink-io.c | 61 + examples/q2w/blink.c | 50 + examples/q2w/blink.sh | 37 + examples/q2w/bright.c | 59 + examples/q2w/button.c | 63 + examples/q2w/volts.c | 62 + examples/rht03.c | 86 + examples/scrollPhat/Makefile | 79 + examples/scrollPhat/scphat.c | 230 +++ examples/scrollPhat/test.c | 115 ++ examples/serialRead.c | 48 + examples/serialTest.c | 75 + examples/servo.c | 57 + examples/softPwm.c | 89 + examples/softTone.c | 54 + examples/speed.c | 95 ++ examples/spiSpeed.c | 118 ++ examples/spidev_test.c | 480 ++++++ examples/spidev_test_linux3_4.c | 210 +++ examples/w25q64_test.c | 139 ++ examples/watchdog.c | 115 ++ examples/wfi.c | 161 ++ gpio/COPYING.LESSER | 165 ++ gpio/Makefile | 177 ++ gpio/OrangePi.c | 1373 +++++++++++++++ gpio/OrangePi.h | 11 + gpio/gpio.1 | 351 ++++ gpio/gpio.c | 1679 ++++++++++++++++++ gpio/pintest | 187 ++ gpio/readall.c | 401 +++++ gpio/test.sh | 44 + newVersion | 47 + pins/Makefile | 22 + pins/pins.pdf | Bin 0 -> 9833 bytes pins/pins.tex | 116 ++ update | 5 + version.h | 3 + wiringPi/COPYING.LESSER | 165 ++ wiringPi/Makefile | 244 +++ wiringPi/OrangePi.c | 2733 ++++++++++++++++++++++++++++++ wiringPi/OrangePi.h | 286 ++++ wiringPi/ads1115.c | 293 ++++ wiringPi/ads1115.h | 55 + wiringPi/bmp180.c | 237 +++ wiringPi/bmp180.h | 34 + wiringPi/drcNet.c | 405 +++++ wiringPi/drcNet.h | 42 + wiringPi/drcSerial.c | 196 +++ wiringPi/drcSerial.h | 33 + wiringPi/ds18b20.c | 146 ++ wiringPi/ds18b20.h | 34 + wiringPi/font.h | 1808 ++++++++++++++++++++ wiringPi/htu21d.c | 150 ++ wiringPi/htu21d.h | 34 + wiringPi/max31855.c | 99 ++ wiringPi/max31855.h | 33 + wiringPi/max5322.c | 84 + wiringPi/max5322.h | 33 + wiringPi/mcp23008.c | 149 ++ wiringPi/mcp23008.h | 33 + wiringPi/mcp23016.c | 164 ++ wiringPi/mcp23016.h | 33 + wiringPi/mcp23016reg.h | 48 + wiringPi/mcp23017.c | 195 +++ wiringPi/mcp23017.h | 33 + wiringPi/mcp23s08.c | 188 ++ wiringPi/mcp23s08.h | 33 + wiringPi/mcp23s17.c | 235 +++ wiringPi/mcp23s17.h | 33 + wiringPi/mcp23x08.h | 73 + wiringPi/mcp23x0817.h | 87 + wiringPi/mcp3002.c | 76 + wiringPi/mcp3002.h | 33 + wiringPi/mcp3004.c | 76 + wiringPi/mcp3004.h | 33 + wiringPi/mcp3422.c | 125 ++ wiringPi/mcp3422.h | 43 + wiringPi/mcp4802.c | 76 + wiringPi/mcp4802.h | 33 + wiringPi/noMoreStatic | 20 + wiringPi/oled.c | 163 ++ wiringPi/oled.h | 127 ++ wiringPi/pcf8574.c | 126 ++ wiringPi/pcf8574.h | 33 + wiringPi/pcf8591.c | 90 + wiringPi/pcf8591.h | 33 + wiringPi/piHiPri.c | 51 + wiringPi/piThread.c | 63 + wiringPi/pseudoPins.c | 95 ++ wiringPi/pseudoPins.h | 26 + wiringPi/rht03.c | 256 +++ wiringPi/rht03.h | 25 + wiringPi/sn3218.c | 75 + wiringPi/sn3218.h | 33 + wiringPi/softPwm.c | 183 ++ wiringPi/softPwm.h | 35 + wiringPi/softServo.c | 211 +++ wiringPi/softServo.h | 35 + wiringPi/softTone.c | 150 ++ wiringPi/softTone.h | 39 + wiringPi/sr595.c | 109 ++ wiringPi/sr595.h | 34 + wiringPi/w25q64.c | 362 ++++ wiringPi/w25q64.h | 36 + wiringPi/wiringPi.c | 2698 +++++++++++++++++++++++++++++ wiringPi/wiringPi.h | 283 ++++ wiringPi/wiringPiI2C.c | 233 +++ wiringPi/wiringPiI2C.h | 42 + wiringPi/wiringPiSPI.c | 145 ++ wiringPi/wiringPiSPI.h | 36 + wiringPi/wiringSerial.c | 231 +++ wiringPi/wiringSerial.h | 38 + wiringPi/wiringShift.c | 83 + wiringPi/wiringShift.h | 41 + wiringPi/wpiExtensions.c | 928 ++++++++++ wiringPi/wpiExtensions.h | 26 + wiringPiD/Makefile | 100 ++ wiringPiD/daemonise.c | 82 + wiringPiD/daemonise.h | 9 + wiringPiD/drcNetCmd.h | 44 + wiringPiD/network.c | 330 ++++ wiringPiD/network.h | 31 + wiringPiD/runRemote.c | 126 ++ wiringPiD/runRemote.h | 29 + wiringPiD/wiringpid.c | 382 +++++ 213 files changed, 37226 insertions(+) create mode 100644 .gitignore create mode 100644 COPYING.LESSER create mode 100644 INSTALL create mode 100644 People create mode 100644 README.md create mode 100644 VERSION create mode 100644 build create mode 100644 debian/.gitignore create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/libwiringpi-dev.dirs create mode 100644 debian/libwiringpi-dev.install create mode 100644 debian/libwiringpi2.install create mode 100644 debian/libwiringpi2.shlibs create mode 100644 debian/rules create mode 100644 debian/wiringpi.dirs create mode 100644 debian/wiringpi.install create mode 100644 devLib/Makefile create mode 100644 devLib/ds1302.c create mode 100644 devLib/ds1302.h create mode 100644 devLib/font.h create mode 100644 devLib/gertboard.c create mode 100644 devLib/gertboard.h create mode 100644 devLib/lcd.c create mode 100644 devLib/lcd.h create mode 100644 devLib/lcd128x64.c create mode 100644 devLib/lcd128x64.h create mode 100644 devLib/maxdetect.c create mode 100644 devLib/maxdetect.h create mode 100644 devLib/piFace.c create mode 100644 devLib/piFace.h create mode 100644 devLib/piFaceOld.c create mode 100644 devLib/piGlow.c create mode 100644 devLib/piGlow.h create mode 100644 devLib/piNes.c create mode 100644 devLib/piNes.h create mode 100644 devLib/scrollPhat.c create mode 100644 devLib/scrollPhat.h create mode 100644 devLib/scrollPhatFont.h create mode 100644 examples/COPYING.LESSER create mode 100644 examples/Gertboard/7segments.c create mode 100644 examples/Gertboard/Makefile create mode 100644 examples/Gertboard/buttons.c create mode 100644 examples/Gertboard/gertboard.c create mode 100644 examples/Gertboard/record.c create mode 100644 examples/Gertboard/temperature.c create mode 100644 examples/Gertboard/voltmeter.c create mode 100644 examples/Gertboard/vumeter.c create mode 100644 examples/Makefile create mode 100644 examples/PiFace/Makefile create mode 100644 examples/PiFace/blink.c create mode 100644 examples/PiFace/buttons.c create mode 100644 examples/PiFace/ladder.c create mode 100644 examples/PiFace/metro.c create mode 100644 examples/PiFace/motor.c create mode 100644 examples/PiFace/reaction.c create mode 100644 examples/PiGlow/Makefile create mode 100644 examples/PiGlow/piGlow0.c create mode 100644 examples/PiGlow/piGlow1.c create mode 100644 examples/PiGlow/piglow.c create mode 100644 examples/README.TXT create mode 100644 examples/blink-thread.c create mode 100644 examples/blink.c create mode 100644 examples/blink.rtb create mode 100644 examples/blink.sh create mode 100644 examples/blink12.c create mode 100644 examples/blink12drcs.c create mode 100644 examples/blink6drcs.c create mode 100644 examples/blink8-drcn.c create mode 100644 examples/blink8.c create mode 100644 examples/clock.c create mode 100644 examples/delayTest.c create mode 100644 examples/ds1302.c create mode 100644 examples/header.h create mode 100644 examples/isr-osc.c create mode 100644 examples/isr.c create mode 100644 examples/lcd-adafruit.c create mode 100644 examples/lcd.c create mode 100644 examples/lowPower.c create mode 100644 examples/max31855.c create mode 100644 examples/nes.c create mode 100644 examples/okLed.c create mode 100644 examples/oled_demo.c create mode 100644 examples/pwm.c create mode 100644 examples/q2w/Makefile create mode 100644 examples/q2w/binary.c create mode 100644 examples/q2w/blink-io.c create mode 100644 examples/q2w/blink.c create mode 100644 examples/q2w/blink.sh create mode 100644 examples/q2w/bright.c create mode 100644 examples/q2w/button.c create mode 100644 examples/q2w/volts.c create mode 100644 examples/rht03.c create mode 100644 examples/scrollPhat/Makefile create mode 100644 examples/scrollPhat/scphat.c create mode 100644 examples/scrollPhat/test.c create mode 100644 examples/serialRead.c create mode 100644 examples/serialTest.c create mode 100644 examples/servo.c create mode 100644 examples/softPwm.c create mode 100644 examples/softTone.c create mode 100644 examples/speed.c create mode 100644 examples/spiSpeed.c create mode 100644 examples/spidev_test.c create mode 100644 examples/spidev_test_linux3_4.c create mode 100644 examples/w25q64_test.c create mode 100644 examples/watchdog.c create mode 100644 examples/wfi.c create mode 100644 gpio/COPYING.LESSER create mode 100644 gpio/Makefile create mode 100644 gpio/OrangePi.c create mode 100644 gpio/OrangePi.h create mode 100644 gpio/gpio.1 create mode 100644 gpio/gpio.c create mode 100644 gpio/pintest create mode 100644 gpio/readall.c create mode 100644 gpio/test.sh create mode 100644 newVersion create mode 100644 pins/Makefile create mode 100644 pins/pins.pdf create mode 100644 pins/pins.tex create mode 100644 update create mode 100644 version.h create mode 100644 wiringPi/COPYING.LESSER create mode 100644 wiringPi/Makefile create mode 100644 wiringPi/OrangePi.c create mode 100644 wiringPi/OrangePi.h create mode 100644 wiringPi/ads1115.c create mode 100644 wiringPi/ads1115.h create mode 100644 wiringPi/bmp180.c create mode 100644 wiringPi/bmp180.h create mode 100644 wiringPi/drcNet.c create mode 100644 wiringPi/drcNet.h create mode 100644 wiringPi/drcSerial.c create mode 100644 wiringPi/drcSerial.h create mode 100644 wiringPi/ds18b20.c create mode 100644 wiringPi/ds18b20.h create mode 100644 wiringPi/font.h create mode 100644 wiringPi/htu21d.c create mode 100644 wiringPi/htu21d.h create mode 100644 wiringPi/max31855.c create mode 100644 wiringPi/max31855.h create mode 100644 wiringPi/max5322.c create mode 100644 wiringPi/max5322.h create mode 100644 wiringPi/mcp23008.c create mode 100644 wiringPi/mcp23008.h create mode 100644 wiringPi/mcp23016.c create mode 100644 wiringPi/mcp23016.h create mode 100644 wiringPi/mcp23016reg.h create mode 100644 wiringPi/mcp23017.c create mode 100644 wiringPi/mcp23017.h create mode 100644 wiringPi/mcp23s08.c create mode 100644 wiringPi/mcp23s08.h create mode 100644 wiringPi/mcp23s17.c create mode 100644 wiringPi/mcp23s17.h create mode 100644 wiringPi/mcp23x08.h create mode 100644 wiringPi/mcp23x0817.h create mode 100644 wiringPi/mcp3002.c create mode 100644 wiringPi/mcp3002.h create mode 100644 wiringPi/mcp3004.c create mode 100644 wiringPi/mcp3004.h create mode 100644 wiringPi/mcp3422.c create mode 100644 wiringPi/mcp3422.h create mode 100644 wiringPi/mcp4802.c create mode 100644 wiringPi/mcp4802.h create mode 100644 wiringPi/noMoreStatic create mode 100644 wiringPi/oled.c create mode 100644 wiringPi/oled.h create mode 100644 wiringPi/pcf8574.c create mode 100644 wiringPi/pcf8574.h create mode 100644 wiringPi/pcf8591.c create mode 100644 wiringPi/pcf8591.h create mode 100644 wiringPi/piHiPri.c create mode 100644 wiringPi/piThread.c create mode 100644 wiringPi/pseudoPins.c create mode 100644 wiringPi/pseudoPins.h create mode 100644 wiringPi/rht03.c create mode 100644 wiringPi/rht03.h create mode 100644 wiringPi/sn3218.c create mode 100644 wiringPi/sn3218.h create mode 100644 wiringPi/softPwm.c create mode 100644 wiringPi/softPwm.h create mode 100644 wiringPi/softServo.c create mode 100644 wiringPi/softServo.h create mode 100644 wiringPi/softTone.c create mode 100644 wiringPi/softTone.h create mode 100644 wiringPi/sr595.c create mode 100644 wiringPi/sr595.h create mode 100644 wiringPi/w25q64.c create mode 100644 wiringPi/w25q64.h create mode 100644 wiringPi/wiringPi.c create mode 100644 wiringPi/wiringPi.h create mode 100644 wiringPi/wiringPiI2C.c create mode 100644 wiringPi/wiringPiI2C.h create mode 100644 wiringPi/wiringPiSPI.c create mode 100644 wiringPi/wiringPiSPI.h create mode 100644 wiringPi/wiringSerial.c create mode 100644 wiringPi/wiringSerial.h create mode 100644 wiringPi/wiringShift.c create mode 100644 wiringPi/wiringShift.h create mode 100644 wiringPi/wpiExtensions.c create mode 100644 wiringPi/wpiExtensions.h create mode 100644 wiringPiD/Makefile create mode 100644 wiringPiD/daemonise.c create mode 100644 wiringPiD/daemonise.h create mode 100644 wiringPiD/drcNetCmd.h create mode 100644 wiringPiD/network.c create mode 100644 wiringPiD/network.h create mode 100644 wiringPiD/runRemote.c create mode 100644 wiringPiD/runRemote.h create mode 100644 wiringPiD/wiringpid.c 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 0000000000000000000000000000000000000000..bd9629d62044179a5532a68a0eb0dbd7b3ac2dd1 GIT binary patch literal 9833 zcmb_Cc_378*T_;MLM3a4VkqOzj4_PtJ0YQvbuhy)W|$dkk|% z*#n}Y0vO}TZgh7j285UcdPEW(PlW<{Bpe;DgLk30;?>k3G&&WJ^MV8<*WI#zAX3VE zE{_@*QrC|^a!e(%T5@JylXu>bWHlnu$mZl?UKGQuy>&wk9@W0?VRh*IEt^#Hh&z3U zf+T&_+tNE;I*N`OijJ;5S)Fa^@2y%!i#SwO9PA8NUW+UIPFwD{b$0`4HT#^B(#G*o zGgk(i&E2B@#G=DqQek44`&k~bZ0Yk_Q=fYD>5b)e6{3Rh$+gw*+w7ZJj<3cjpZltvFgXAlYnodLHi&PdDTlBufBm9nlBm)& zSK7-g90+^25%iryXgDIABx-+y9*{QWdQblR7~oES^5V8(PZM(Q6Pto2QgDUb5-_+L zTpqGx?ZcLD{@&}9&nv6F4h3QZtGmCR4t#c+<#x-{@B9THB7H}FRt8r3KFr9Pj0{#( zq>gEuDVsWo_4i_DpI_Z>>+nJK)!to~2L~+Lcd-q3$PSOd9Fq$!QN3h!1xrzrjiu5X z*3Wc0oo>j>`KbxmsG}0BHADh>t^yWYI#zqasZVbc?yfcFDJ25-Qf1|-VxSVJ7 zYd2-SPv(T7L_a&~3@knJq%oqtiNz&3`;y4kLrTY*B=)9|DatW*ttJG^BsN5n+9Rc; zjz&ul^i6buj9LEI@hlBw$Mu9H9yeXVYZb=WJ!uOK&EJ{Q7d;+j^_NH9MmgS%bzccx z?)=CRFm=`B24UCZ+QfVI=4z&xy6VGER=l3wP6_wLjv9S^M8~GyNJ{V!?j7cn#=knA z+4D%|oP)Hp(83_saO10I8lOa9YH5`O-oU^xso6u>9#|jhV0+{A1(de`jr56=t0%{0 z2;xhtb=2wb4%m*2!G`LAWaN+1NG38 zMQoJ{{U0 zvSQnWzimwUFP{s0-YWm~-Lj`0A71NjR-`zq>Gr!-;?FI$x(QK6`7BDMa907Nt}^@Z zD<$yj9$t#9XO4vL+R+M+i%2Wf=gVU?P)K?$=EJ9_0IT0|h&k$5;z-p1@;9M`wAsY}54i-54~7L8(`v?P(P0K0wX(Q>kb^}+|A=Dv*x zo{zs%O~~_FdlP^ANImDZHyf~+haVat%|eH*<=)_zD^Cb#t)QKD%T`+3#9|#$e1=*N zqG(g--N$61T|Y0&dc9E#vj5lt7xvivMD8nJSZ~{L80wCENM6N@FuVqNqU$nz zpmcd9L$&WpkAX$VF1uyAbI^qv!m|)`P^eXD@}djJk^3CPC>X;>UG^Qh@3YqF>ELpC zE0Le4)r`gTGV_qTqU{TUFCcb!Y_hwC+D#3|63VupTX8m$H`FnIKuVzyUP+3FM8Rbv z;Lwcw_%hZMh^;W)7x2UPP5Xx=yQD{2;hw| zPr@+tu>zBj8UV4e{mL%B-ICXwc+oT=`ym&fc2RcxV~jz2=*}_p?!}sS>un$0m4y~r zipsStVrx(JDX&K#C~=?G6?bDzs6U(A8XzSdm?HwwdPA7lDwJ$ro$tbVtTmqd#x7uu?C$*oMx>NV+H6n;|i$TegEai8tnVAfjwvp^LE z{nvt@ZHE;(U$}*YTa|vf)!RUs5^$zXdost>CN>Q=tX1!Koj%0E(<%$im=jLsf8PCd z+VRHZuwxY(#@EdvlyviBhwMOIs0&aQYQ=2l9Rv{_06jDL_Ik0)_E^OuILBV(r&Ik? z*^diT>vLQLnbZ@DimYqvc^y0*r7!V3-4Wd|?G!%0_k5GI1;>5fl`yfy7I$W#zGcSH zt;?wa(eN&DO_y)L&4md;lG|qUjh!iCYlyXh3#XF8YA@QL+`3ZEK<}X27Ve@TXxq%h zn6po;U#2zMvo6hmZ#y|TM2`RH1^a{ik9<-ODmqvjbqqy(cz9e}-+XfXfso-RH?5>u z{`p$YHw_N2MV46P8moHRNMj+gV=qSsZ;~5WM#A<_I6mhJKwjzcR18gZ{8afuWa0d7 z<~ZxOdf)Bd6fG&RjPpQ?qVTT`m6TypcUBZ&<8SNGPU-3^(^boHp{pb_&iEg zu_f6CyWvGOD(@+u5ck(?a9@uMY*Y@-%}ZzU~?tBUS8yO zaC^v$QoSQb;VSr!*G8Y6Q=C66yk!hjEqE4@; zq$>PRdg^lZwSA(e4CMh)vfIX=Un%pN8jpzdD?^%=`)F`SH+V6J7sn!u6NVl<+W}{f z;O(vvNo-PK1_;eFjf5H}H$RcU^qX$}7>16X%i{XiudHi9F1G zbDuNjntM7$lw%FIsFBgv)*{*C)GoG8=HI{VJH}M~ox5~x;cjBDl39WF{vsf>hn zUZ%@<{+9?_)fX4*YiDxb8l30c;vJ32L`vP{7M~!9-qWkdaJkxM{5nfJ^?)+@qFDl| z@N;W__mJ4Tr7xEqvU11q=9etOiSKfQ$7@ZYMaTEd-;}^jbWRYc4y{Fxqg#{(GSkw1 z%ugLKposC}$7hbUS{p?6mQ=pdN%IC0rf5HddE3Yt$LIN(>Q)30Utmm+57P2R`g^=8g-fek3Qo0xvxBn`y;rmqT(HA{Is#|fd zFT@)0((hiMsGmJ&jSN;)&W}tvJ7&#W#ByW(fqgj@)tyf16V}yW3nxsnK5X)~A9|7S zR_fY0US5d|UU5O$;X4x}Tu)nNKjIcMoX3i+mA?dhlK!50BRS_nzgDZC+_}uyNSSrg zn6vja)@0j?_U5|r$Mgys(mMC)$-LGeIXxJC_K|=@Oe1{$dfUhLr@nYy0$Iu`r=7+u5Ji^68O)Vv;tyXFM#U?{49(%SfYh>toIr%+Adb?kw6x zieCtMNkf(&sqvk#z|o@xKOi5Uzzkd?)F0pzd;G$udhe%*^Jp1-<%#I4M!RTtPrMQd zW?s8@-c%R$go!3vJPg+z8KXXLnKjv~`dnXU_pIcz%IKn36&&6x#+Z+Tun%ySgymOA z&$LU0nqU2wiI>`quJL4>$ho;skl**eI(bXF*sGT7l)c!8Tiw^Z15bu52s9O2AZCqc z&6n<+KkDPR)Nm}#rm>9^dPX>88}kOyW@qZ7jO7X zKiQajR)h+)jHZhoJTDh$wnlmk-KZo#<67dl5N24*0qdWA&zTg2Dex^YHR{w&`@}jh z?Fg(~wQ`)mz8Pt2{U!-q@wvYnzwOm(5)6%#>(CbQtg(K)Y;)V|I=abmPXgAFWkh5u zV6PL~l)~QrrMJgtreFHA9hT2}e`MXTfm}Uw&1tWDFx!Z{*6Gd2&i%|E*E{${{@K(X zKG8n2D%&ago}8;5Izf=OjYfF2jhz?AgNKXNQYm9A^ZUbOPw-_e<*F~0j8@&8@L6c= zroZwW343A|J!bd$?OmI^dJcEzMd}scxiiN$Zn5ca+dJB>aG}*^{hg!}2yzlphwoO8 zSDbp2hO)*_R6v)DLg@b z<>Q>?^?_+VsnS`n#1kp{1-nFIZclw15+mOzWxcEWJ@9ISy<_``71up#Dc}5=>cb=2 zb>}c&T|H(6x=MP>u4 z6;X_TVCFS{5dzavEZjdrt18t#)5OA(`~JYJu3n)BcF}yP{qS_s?pyP~sPl(zTR>_A ze<4(`hX0M1tl_qTg}aGORq`vsYgftg34UcORa~qfLyf$g64l-1r*$uO#qE*MBt9Tn z3Hi!t)*GxECSDbK^2j1AV8U{+l-mzwk2QmT9Lzy|QsqCaPgk(;>fyCNbnA3ljHA(| zYi1Ue0{T;uFZc>=lijktQlLUnYy9{EmFDO>`%!{+Z<5$0KYI*>HIvo~UcL@oD49@3 z^a^Lu<>EBiY&GgiJwL@kc6}&S?d9%#D(NNPo8iU2CqSWGlc`kZ!`E=`10yiXx4E8g z;oMR}2lsrsNX@z!fb^-o+!kN8|7=}e#=d9eGwB`^*6{1m%GjWd+18^?BeUr8I)`?V z;FX5U*SM1e$hmxm8e0+URkT&|*?j!hAdZ)ZO6t{i@1_hkK(# z7OByqu>jP0g$p%a2kjAMiWHsd@^(3v8To>V&nuZe%8gO$H93ad62*C`eD0j!7w27l zXpwRFrFm5cVea(XJCob=hquJ|9Vt;j^L6gnncu!I*O7bHNG5jw=l4nz(E$NM-Z8fd z-@cJiW-83z_x!4gR-gAVT#u}%@xsKy3v=qrn0V2f<`Z1O#RQEvrRmN#98ll9XviB= zj0dHlCstA5iHW&$GObe-#@No@}u`5 zn|(wJX7@g&6|M~X_s>OLxiWgoViVpIqA%?XU(7m+8~4k~7#ht9a6M_G?J>Cx;kO*2 zm==wi`N$1O9XQBWOHN*cw41Vr1(%;GWiD-Gsws}FX;T^l2I8_iTIbrwOb6JH&qJnX zot(>yu6;gIDWEzfN#`rXYxt3z?#*6QHhZ0w_wYU@=YrlS_m_;LY?VR*rYDQT<-5WM zTPlT*Tc3;7cO|iMVbs>V{D&@~o5$no1!V_1x@Z+x#r>U=B|go9g84^tB!sY0b(iJs zE0tb#9p*b)Y1AL+=+~y%f9!HVS0JQl!CKayFseO2mm@rFLOOk~xs!*)`DLY|W+0@R zEodg0M^E{oS8(-Y>%Gn~n`{I*uenU+!$fa|3b1;ek`~h~Y05=`nZ8U>%2kzb?HsL0 z`EKC3AZvSHvRKgYV|z|%Da8x_UFyLLC6CnzYum-rvnxk2Q;yg7+}YmLq&4|?EmlW; ze3i;5@Hq4JD=9|*?N zD85t|JPqswno%h(7I?ZX0QL%@fF(YF4$|oc(Df}gNs*`@BzhE(9QlJDYz_k2;62EZ z24yrA%^@J@r+f^QA5BJ(8z>-jQ$iXPI81b_Q!gXJHj$ls(tDYbEQ z9Esxgi^WgrP4IM_D>ws1ZniJ~V4(P~4F1{%1UO=50!6B+{S9|I+b(%&fl5M2vL!!xu67~n~McskJqx49dD0RuHl2HUGd zvKth+sW`yG*O|^RBSTf7e804~Ir~$DO*8+Z19XT40v*)j6`Aq zE21mion{MFK%yDH5C-Yre;9MWVgDB6_be3gAI|^9^XJN&68zxv2L$p1@6W$rBp}fY zZ~m!sa0_HjGL88A{(n(E!?=G}<8NcawJ0RlKQ;EhFxgb?pB7};|1Z^VTEZ0Pg$Mp= zAT2PGZQ)2L9EHL{6%dM03>IzA=+3**pz`t%K$GUe2xbrp#v#tz08eyt|9Q(;fHB7) zg#d^o;0@b-_>yXTG>M@{D6z%<+i@} zBt3BfjVAE1!fjc5CMIl0*4f?pC1=$t`^_&&4BCIwb~v`}tj%6F-lVkd{nsDmEIx+Q zwNKSvCuu)0xoA3+I6iyjLt=jDh34rPe51+C`Z~3F>{LtRvK@=T7A8%e`L5dGVKz>E zwXsVNw)*&meod@BK7UmV|`grW=eXKf8U@@io;lb82+ zo`RiMmniuo>e|_6D{J4%<9FJpI=!(sL@#wn?JKm-#<=ft`Bc;3P$U)JUE`^wn?^i; zPM(D+EK*9o!B!qss{Fk5^H!$La4x5P1}rz99>33*&phV@x8@+6aYF27{U*$A{xrPh zB31`GM+=p7(qPGqpyz$LD63VbN!YW4NR8%sSDT1 z*0-P4#;;VQzU^Y4>~8Tsy;{4iY2V~~C;bMw>n&O70rT&^%kPO$uDbHT?=e4eZYEt&I$-X(zq2LrtS)H}y{fla z>~{5==AAx3aO32n{Z428h`PFac0~(ISOQ6Ho#jl;De1vPR(yIC`UWas(a)EQZYiIT zq(5C6>p^rUsil(*Y|_#DbGzE+n_IP&2{WwUq-Gqy*9?g4+!y$*+km|FNrnDp*?GmQ zaMQG-?K(Wst7q0&%UmbKDK2U0!z-h18HdVmY@cnjulSs^uBb@rbkjV{J!D-dJ1oAa zrt(f1RZuL2mgSK{T1k+XXtt^$If1MPB=xb=A-L1+A-W17dO@-PZ; zS|Qeq4#8+C=1*s(2oIdwG14!DWYT=-bN@O3Gy^WOjbaHi=PWI!I_?06VnwRn_LqF{ ziM`k7I2ejgn79=!WS}7CQ|g$++4gzfHQzci{M_grjW44Y^|{jf?+3p1C>+q8a7g=b z{>rIrz%X{+^RWgSAd;JZms&itRuBvm_w^rG6+J?9Gu`w4_=gh{cXJwNye&2EHV>)z zxl*jIz)S5435#&$>}}?8dCvW%mY&gs;zv>y%={W&>5Vp5N%zTNhjJuicCJa?ocnrH z6U|W=7DPBCF>$p$<<+&5C##iC>t$Mo|Y!}m> zT<2D;?l}dW_9r9>^XR}&lFR%X8+Z|g-LjKpd~HmrxZzTt3K%d&{C$3yvY>lDR;!PV0cLEiJO z22rl8=Hf}L!7$UTir4q*WusrAN~V=NJ9_$`4dk_2&D5hB9#j@et!zm|b1jfRUQyDQ zAPa`vD#*W=f40=p!lAD}`D0}biv9G4TUb@C1IuB;D4M_gMl#p=yrk4HW#kg{goD1b z?LE8eQ#Wgj6MKx$#78{Ua2)VtT4VFt4iquUjDIaPH*2XsA6LJstiO`5wTbZ`8CdCe z23AoI@W#1#;^|Olyc?0M3Y)EX0)rA=Rbf^NCI}O6ZM-|tAc%^$2r{*F3G#Hoy28}e zAS&uOu*Sv1190AO!sZKT8WenZsY+;@8|z6h5CW6~yu7`@VhINXOSS)}*0Vot4#DLQR$#h%*oJ`vXuD2-&(fT(T znI^X>lbj313m{qpNI3-XYoT8cdm@DlWh{(yrufoTVa_hDNCaL%3GVEQz`&76yek|5 zUT~Z<##PY;O~7DX@xNB`{zJllSqhv0*OCWS0FIQw8s62{1y5Cl>6;lt_1!5n`i~M1 zswAg~gaJQy{$CIXw8+2TJ7~tAn^ysGluf`Qmk_7}9zN7i2&6n50e;YyNQ^QXp^QYI zPyzmi1X>%U(gweA0Dc4E|EBr_=?^Lj)e6aw8JJQDqoW0T`g1}Xr2k~X8l)dj$l@C=D)prMhVoUSg)1Pav)2l_P5+Z!x2 zadgnt0ni~~YAWC)ok%C))iz^JlSKb9AQ2fcq)ft*-Be)#a92D5=S!l))VztHdxOUN zp?(rk?Z;q~4)}}LzcJ1x2#jgaPQdSsp$38em#+UFqrcK5n0!@X{){B}k2K6UZU4-| zzk*u&-^H{HSco%%1yndAT%>iB8DWNyN1%}yGy;q;1Of(rKr}EC{~wH>?k~L=J9g5Z zb~4caG=4z-mJBOP|FWOV?;~~q6;A+9ct}MEBfI^$pcn-Oc?Bo|`V*#r0y`C(Q&93R z7#1lHp1&B^UoZufJb2Xq8w{cN4;TW$I5+=~^V8XZTaZyFaXk48WwC3TPJLH-B9#x3Fi literal 0 HcmV?d00001 diff --git a/pins/pins.tex b/pins/pins.tex new file mode 100644 index 0000000..c3753e9 --- /dev/null +++ b/pins/pins.tex @@ -0,0 +1,116 @@ +\documentclass[12pt,a4paper]{article} +\parskip 1ex +\parindent 0em +\thispagestyle{empty} +\pagestyle{plain} +\pagenumbering{arabic} +\setlength{\topmargin}{0pt} +\setlength{\headheight}{0pt} +\setlength{\headsep}{0pt} +\setlength{\topskip}{0pt} +\setlength{\textheight}{240mm} +\setlength{\footskip}{5ex} +\setlength{\oddsidemargin}{0pt} +\setlength{\evensidemargin}{0pt} +\setlength{\textwidth}{160mm} +\usepackage[dvips]{graphics,color} +\usepackage{helvet} +\renewcommand{\familydefault}{\sfdefault} +\begin{document} +\begin{sffamily} +\definecolor{rtb-black}{rgb} {0.0, 0.0, 0.0} +\definecolor{rtb-navy}{rgb} {0.0, 0.0, 0.5} +\definecolor{rtb-green}{rgb} {0.0, 0.5, 0.0} +\definecolor{rtb-teal}{rgb} {0.0, 0.5, 0.5} +\definecolor{rtb-maroon}{rgb} {0.5, 0.0, 0.0} +\definecolor{rtb-purple}{rgb} {0.5, 0.0, 0.5} +\definecolor{rtb-olive}{rgb} {0.5, 0.5, 0.0} +\definecolor{rtb-silver}{rgb} {0.7, 0.7, 0.7} +\definecolor{rtb-grey}{rgb} {0.5, 0.5, 0.5} +\definecolor{rtb-blue}{rgb} {0.0, 0.0, 1.0} +\definecolor{rtb-lime}{rgb} {0.0, 1.0, 0.0} +\definecolor{rtb-aqua}{rgb} {0.0, 1.0, 1.0} +\definecolor{rtb-red}{rgb} {1.0, 0.0, 0.0} +\definecolor{rtb-fuchsia}{rgb}{1.0, 0.0, 1.0} +\definecolor{rtb-yellow}{rgb} {1.0, 1.0, 0.0} +\definecolor{rtb-white}{rgb} {1.0, 1.0, 1.0} + +\begin{center} +\bfseries{WiringPi: GPIO Pin Numbering Tables}\\ +\tt{http://wiringpi.com/} +\end{center} + +\begin{center} +\begin{tabular}{|c|c|c||p{8mm}|p{8mm}||c|c|c|c|} +\hline +\multicolumn{8}{|c|}{\bfseries{P1: The Main GPIO connector}}\\ +\hline +\hline +WiringPi Pin & BCM GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & BCM GPIO & WiringPi Pin\\ +\hline +\hline + & & \textcolor{rtb-red}{3.3v} & \raggedleft{1} & 2 & \textcolor{rtb-maroon}{5v} & & \\ +\hline +8 & Rv1:0 - Rv2:2 & \textcolor{rtb-aqua}{SDA} & \raggedleft{3} & 4 & \textcolor{rtb-maroon}{5v} & & \\ +\hline +9 & Rv1:1 - Rv2:3 & \textcolor{rtb-aqua}{SCL} & \raggedleft{5} & 6 & \textcolor{rtb-black}{0v} & & \\ +\hline +7 & 4 & \textcolor{rtb-green}{GPIO7} & \raggedleft{7} & 8 & \textcolor{rtb-yellow}{TxD} & 14 & 15\\ +\hline + & & \textcolor{rtb-black}{0v} & \raggedleft{9} & 10 & \textcolor{rtb-yellow}{RxD} & 15 & 16\\ +\hline +0 & 17 & \textcolor{rtb-green}{GPIO0} & \raggedleft{11} & 12 & \textcolor{rtb-green}{GPIO1} & 18 & 1\\ +\hline +2 & Rv1:21 - Rv2:27 & \textcolor{rtb-green}{GPIO2} & \raggedleft{13} & 14 & \textcolor{rtb-black}{0v} & & \\ +\hline +3 & 22 & \textcolor{rtb-green}{GPIO3} & \raggedleft{15} & 16 & \textcolor{rtb-green}{GPIO4} & 23 & 4\\ +\hline + & & \textcolor{rtb-red}{3.3v} & \raggedleft{17} & 18 & \textcolor{rtb-green}{GPIO5} & 24 & 5\\ +\hline +12 & 10 & \textcolor{rtb-teal}{MOSI} & \raggedleft{19} & 20 & \textcolor{rtb-black}{0v} & & \\ +\hline +13 & 9 & \textcolor{rtb-teal}{MISO} & \raggedleft{21} & 22 & \textcolor{rtb-green}{GPIO6} & 25 & 6\\ +\hline +14 & 11 & \textcolor{rtb-teal}{SCLK} & \raggedleft{23} & 24 & \textcolor{rtb-teal}{CE0} & 8 & 10\\ +\hline + & & \textcolor{rtb-black}{0v} & \raggedleft{25} & 26 & \textcolor{rtb-teal}{CE1} & 7 & 11\\ +\hline +\hline +WiringPi Pin & BCM GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & BCM GPIO & WiringPi Pin\\ +\hline +\end{tabular} +\end{center} + +Note the differences between Revision 1 and Revision 2 Raspberry +Pi's. The Revision 2 is readily identifiable by the presence of the 2 +mounting holes. + +The revision 2 Raspberry Pi has an additional GPIO connector, P5, which is next to the main P1 GPIO +connector: + +\begin{center} +\begin{tabular}{|c|c|c||p{8mm}|p{8mm}||c|c|c|c|} +\hline +\multicolumn{8}{|c|}{\bfseries{P5: Secondary GPIO connector (Rev. 2 Pi only)}}\\ +\hline +\hline +WiringPi Pin & BCM GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & BCM GPIO & WiringPi Pin\\ +\hline +\hline + & & \textcolor{rtb-maroon}{5v} & \raggedleft{1} & 2 & \textcolor{rtb-red}{3.3v} & & \\ +\hline +17 & 28 & \textcolor{rtb-green}{GPIO8} & \raggedleft{3} & 4 & \textcolor{rtb-green}{GPIO9} & 29 & 18 \\ +\hline +19 & 30 & \textcolor{rtb-green}{GPIO10} & \raggedleft{5} & 6 & \textcolor{rtb-green}{GPIO11} & 31 & 20 \\ +\hline + & & \textcolor{rtb-black}{0v} & \raggedleft{7} & 8 & \textcolor{rtb-black}{0v} & & \\ +\hline +\hline +WiringPi Pin & BCM GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & BCM GPIO & WiringPi Pin\\ +\hline +\end{tabular} +\end{center} + + +\end{sffamily} +\end{document} diff --git a/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 ; +}