From 2c13e6148d78a8168c1c3e41d7e62670e0aca172 Mon Sep 17 00:00:00 2001 From: Gordon Henderson Date: Tue, 10 Jul 2012 13:37:06 +0100 Subject: [PATCH 01/29] Initial Commit --- README | 7 + examples/Makefile | 71 ++++ examples/speed.c | 103 ++++++ examples/test1 | Bin 0 -> 9835 bytes examples/test1.c | 91 +++++ examples/test2 | Bin 0 -> 9646 bytes examples/test2.c | 41 +++ gpio/COPYING | 674 +++++++++++++++++++++++++++++++++++++ gpio/Makefile | 73 +++++ gpio/gpio.1 | 145 ++++++++ gpio/gpio.c | 418 +++++++++++++++++++++++ gpio/test.sh | 23 ++ wiringPi/COPYING | 674 +++++++++++++++++++++++++++++++++++++ wiringPi/Makefile | 83 +++++ wiringPi/README | 7 + wiringPi/serial.c | 204 ++++++++++++ wiringPi/serial.h | 41 +++ wiringPi/wiringPi.c | 729 +++++++++++++++++++++++++++++++++++++++++ wiringPi/wiringPi.h | 69 ++++ wiringPi/wiringShift.c | 84 +++++ wiringPi/wiringShift.h | 41 +++ 21 files changed, 3578 insertions(+) create mode 100644 README create mode 100644 examples/Makefile create mode 100644 examples/speed.c create mode 100755 examples/test1 create mode 100644 examples/test1.c create mode 100755 examples/test2 create mode 100644 examples/test2.c create mode 100644 gpio/COPYING create mode 100644 gpio/Makefile create mode 100644 gpio/gpio.1 create mode 100644 gpio/gpio.c create mode 100755 gpio/test.sh create mode 100644 wiringPi/COPYING create mode 100644 wiringPi/Makefile create mode 100644 wiringPi/README create mode 100644 wiringPi/serial.c create mode 100644 wiringPi/serial.h create mode 100644 wiringPi/wiringPi.c create mode 100644 wiringPi/wiringPi.h create mode 100644 wiringPi/wiringShift.c create mode 100644 wiringPi/wiringShift.h diff --git a/README b/README new file mode 100644 index 0000000..781510a --- /dev/null +++ b/README @@ -0,0 +1,7 @@ + +WiringPi: An implementation of most of the Arduino Wiring + functions for the Raspberry Pi + +Full details at: + https://projects.drogon.net/raspberry-pi/wiringpi/ + diff --git a/examples/Makefile b/examples/Makefile new file mode 100644 index 0000000..72ce1eb --- /dev/null +++ b/examples/Makefile @@ -0,0 +1,71 @@ +# +# Makefile: +# wiringPi - Wiring Compatable library for the Raspberry Pi +# https://projects.drogon.net/wiring-pi +# +# Copyright (c) 2012 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# Wiring Compatable library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with wiringPi. If not, see . +################################################################################# + + +#DEBUG = -g -O0 +DEBUG = -O3 +CC = gcc +INCLUDE = -I/usr/local/include +CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe + +LDFLAGS = -L/usr/local/lib +LIBS = -lwiringPi + +# Should not alter anything below this line +############################################################################### + +SRC = test1.c test2.c speed.c + +OBJ = test1.o test2.o speed.o + +all: test1 test2 speed + +test1: test1.o + @echo [link] + $(CC) -o $@ test1.o $(LDFLAGS) $(LIBS) + +test2: test2.o + @echo [link] + $(CC) -o $@ test2.o $(LDFLAGS) $(LIBS) + +speed: speed.o + @echo [link] + $(CC) -o $@ speed.o $(LDFLAGS) $(LIBS) + + +.c.o: + @echo [CC] $< + @$(CC) -c $(CFLAGS) $< -o $@ + +clean: + rm -f $(OBJ) *~ core tags test1 test2 speed + +tags: $(SRC) + @echo [ctags] + @ctags $(SRC) + +depend: + makedepend -Y $(SRC) + +# DO NOT DELETE diff --git a/examples/speed.c b/examples/speed.c new file mode 100644 index 0000000..409c994 --- /dev/null +++ b/examples/speed.c @@ -0,0 +1,103 @@ + +/* + * speed.c: + * Simple program to measure the speed of the various GPIO + * access mechanisms. + */ + +#include + +#include +#include +#include + +#define FAST_COUNT 10000000 +#define SLOW_COUNT 1000000 + + +int main (void) +{ + int i ; + uint32_t start, end, count, sum, perSec ; + + printf ("Raspberry Pi wiringPi speed test program\n") ; + +// Start the standard way + + if (wiringPiSetup () == -1) + exit (1) ; + + printf ("Native wiringPi method: (%8d iterations)\n", FAST_COUNT) ; + + pinMode (0, OUTPUT) ; + + sum = 0 ; + for (i = 0 ; i < 3 ; ++i) + { + printf (" Pass: %d: ", i) ; + fflush (stdout) ; + + start = millis () ; + for (count = 0 ; count < FAST_COUNT ; ++count) + digitalWrite (0, 1) ; + end = millis () ; + printf (" %8dmS\n", end - start) ; + sum += (end - start) ; + } + digitalWrite (0, 0) ; + printf (" Average: %8dmS", sum / 3) ; + perSec = (int)(double)FAST_COUNT / (double)((double)sum / 3.0) * 1000.0 ; + printf (": %6d/sec\n", perSec) ; + + + printf ("Native GPIO method: (%8d iterations)\n", FAST_COUNT) ; + + wiringPiGpioMode (WPI_MODE_GPIO) ; + + pinMode (17, OUTPUT) ; + + sum = 0 ; + for (i = 0 ; i < 3 ; ++i) + { + printf (" Pass: %d: ", i) ; + fflush (stdout) ; + + start = millis () ; + for (count = 0 ; count < 10000000 ; ++count) + digitalWrite (17, 1) ; + end = millis () ; + printf (" %8dmS\n", end - start) ; + sum += (end - start) ; + } + digitalWrite (17, 0) ; + printf (" Average: %8dmS", sum / 3) ; + perSec = (int)(double)FAST_COUNT / (double)((double)sum / 3.0) * 1000.0 ; + printf (": %6d/sec\n", perSec) ; + + +// Switch to SYS mode: + + wiringPiSetupSys () ; + + printf ("/sys/class/gpio method: (%8d iterations)\n", SLOW_COUNT) ; + + sum = 0 ; + for (i = 0 ; i < 3 ; ++i) + { + printf (" Pass: %d: ", i) ; + fflush (stdout) ; + + start = millis () ; + for (count = 0 ; count < SLOW_COUNT ; ++count) + digitalWrite (17, 1) ; + end = millis () ; + printf (" %8dmS\n", end - start) ; + sum += (end - start) ; + } + digitalWrite (17, 0) ; + printf (" Average: %8dmS", sum / 3) ; + perSec = (int)(double)SLOW_COUNT / (double)((double)sum / 3.0) * 1000.0 ; + printf (": %6d/sec\n", perSec) ; + + return 0 ; +} diff --git a/examples/test1 b/examples/test1 new file mode 100755 index 0000000000000000000000000000000000000000..dfa08c8eb9d43394b2eaa3f315ef515b27abb4e8 GIT binary patch literal 9835 zcmbtaeQ;FQb-!xSR|uQ0Ngn~XxQ&(-QCyp$se~jx903C4k9ufUEA0XsuXZ=P zD-4Zl>kH!8P|QaI

Y3Qv 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 TU%{A-ZvO1W + +#include +#include +#include + + +// Simple sequencer data +// Triplets of LED, On/Off and delay + +uint8_t 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, 1, + 7, 0, 1, + + 0, 0, 1, // Extra delay + +// Back again + + 7, 1, 1, + 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 + + 9, 9, 9, // End marker + +} ; + + +int main (void) +{ + int pin ; + int dataPtr ; + int l, s, d ; + + printf ("Raspberry Pi wiringPi test program\n") ; + + if (wiringPiSetup () == -1) + exit (1) ; + + for (pin = 0 ; pin < 8 ; ++pin) + pinMode (pin, OUTPUT) ; + + pinMode (8, INPUT) ; // Pin 8 SDA0 - Has on-board 2k2 pull-up resistor + + dataPtr = 0 ; + + for (;;) + { + l = data [dataPtr++] ; // LED + s = data [dataPtr++] ; // State + d = data [dataPtr++] ; // Duration (10ths) + + if ((l + s + d) == 27) + { + dataPtr = 0 ; + continue ; + } + + digitalWrite (l, s) ; + + if (digitalRead (8) == 0) // Pressed as our switch shorts to ground + delay (d * 10) ; // Faster! + else + delay (d * 100) ; + } + + return 0 ; +} diff --git a/examples/test2 b/examples/test2 new file mode 100755 index 0000000000000000000000000000000000000000..d1f143ac2911dbd0e7fcee5779fc0b9c490e1dd1 GIT binary patch literal 9646 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 literal 0 HcmV?d00001 diff --git a/examples/test2.c b/examples/test2.c new file mode 100644 index 0000000..e34013c --- /dev/null +++ b/examples/test2.c @@ -0,0 +1,41 @@ + +/* + * test2.c: + * Simple test program to test the wiringPi functions + * PWM test + */ + +#include + +#include +#include +#include + +int main (void) +{ + int bright ; + + printf ("Raspberry Pi wiringPi PWM test program\n") ; + + if (wiringPiSetup () == -1) + exit (1) ; + + pinMode (1, PWM_OUTPUT) ; + + for (;;) + { + for (bright = 0 ; bright < 1024 ; ++bright) + { + pwmWrite (1, bright) ; + delay (1) ; + } + + for (bright = 1023 ; bright >= 0 ; --bright) + { + pwmWrite (1, bright) ; + delay (1) ; + } + } + + return 0 ; +} diff --git a/gpio/COPYING b/gpio/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/gpio/COPYING @@ -0,0 +1,674 @@ + GNU 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/gpio/Makefile b/gpio/Makefile new file mode 100644 index 0000000..043e329 --- /dev/null +++ b/gpio/Makefile @@ -0,0 +1,73 @@ +# +# Makefile: +# wiringPi - Wiring Compatable library for the Raspberry Pi +# https://projects.drogon.net/wiring-pi +# +# Copyright (c) 2012 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# Wiring Compatable library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with wiringPi. If not, see . +################################################################################# + + +#DEBUG = -g -O0 +DEBUG = -O3 +CC = gcc +INCLUDE = -I/usr/local/include +CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe + +LDFLAGS = -L/usr/local/lib +LIBS = -lwiringPi + +# Should not alter anything below this line +############################################################################### + +SRC = gpio.c + +OBJ = gpio.o + +all: gpio + +gpio: gpio.o + @echo [LD] + @$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS) + +.c.o: + @echo [CC] $< + @$(CC) -c $(CFLAGS) $< -o $@ + +clean: + rm -f $(OBJ) gpio *~ core tags + +tags: $(SRC) + @echo [ctags] + @ctags $(SRC) + +depend: + makedepend -Y $(SRC) + +install: + cp gpio /usr/local/bin + chown root.root /usr/local/bin/gpio + chmod 4755 /usr/local/bin/gpio + mkdir -p /usr/local/man/man1 + cp gpio.1 /usr/local/man/man1 + +uninstall: + rm -f /usr/local/bin/gpio + rm -f /usr/local/man/man1/gpio.1 + +# DO NOT DELETE diff --git a/gpio/gpio.1 b/gpio/gpio.1 new file mode 100644 index 0000000..25c8da5 --- /dev/null +++ b/gpio/gpio.1 @@ -0,0 +1,145 @@ +.TH "GPIO" "14 June 2012" "Command-Line access to Raspberry Pi GPIO" + +.SH NAME +gpio \- Command-line access to Raspberry Pi GPIO + +.SH SYNOPSIS +.B gpio +.RB [ \-g ] +.RB < read/write/pwm/mode ...> +.TP +.B gpio +.RB < export/unexport/exports ...> + +.SH DESCRIPTION + +.B GPIO +is a command line tool to allow the user easy access to the GPIO pins +on the Raspberry Pi. 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. + +Additionally, it can be used to set the exports in the /sys/class/gpio +system directory to allow subsequent programs to use the /sys/class/gpio +interface without needing to be run as root. + +.SH OPTIONS + +.TP +.B \-g +Use the BCM_GPIO pins numbers rather than WiringPi pin numbers. + +.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. + +.TP +.B pwm +Write a PWM value (0-1023) to the given pin. + +.TP +.B mode +Set a pin into input, output or pwm mode. Can also use the literals up, down or tri +to set the internal pull-up, pull-down or tristate controls. + +.TP +.B export +Export a GPIO pin in the /sys/class/gpio directory. Use like the mode command above +however only in and out are supported at this time. + +Once a GPIO pin has been exported, the +.B gpio +program changes the ownership of the /sys/class/gpio/gpioX/value pseudo file to +that of the user running the +.B gpio +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 unexport +Un-Export a GPIO pin in the /sys/class/gpio directory. + +.TP +.B exports +Print a list (if any) of all the exported GPIO pins and their current values. + +.SH "WiringPi vs. GPIO Pin numbering" + +.PP +.TS +r r l. +WiringPi GPIO Function +_ +0 17 +1 18 (PWM) +2 21 +3 22 +4 23 +5 24 +6 25 +7 4 +8 0 SDA0 +9 1 SCL0 +10 8 SPI CE0 +11 7 SPI CE1 +12 10 SPI MOSI +13 9 SPI MISO +14 11 SPI SCLK +15 14 TxD +16 15 RxD +.TE + +.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 export or unexport commands, the pin numbers are +.B always +native GPIO numbers and never wiringPi pin numbers. + +.SH "SEE ALSO" + +.LP +WiringPi's home page +.IP +https://projects.drogon.net/raspberry-pi/wiringpi/ + +.SH AUTHOR + +Gordon Henderson + +.SH "REPORTING BUGS" + +Report bugs to + +.SH COPYRIGHT + +Copyright (c) 2012 Gordon Henderson +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/gpio/gpio.c b/gpio/gpio.c new file mode 100644 index 0000000..7aa1d5f --- /dev/null +++ b/gpio/gpio.c @@ -0,0 +1,418 @@ +/* + * gpio.c: + * Set-UID command-line interface to the Raspberry Pi's GPIO + * 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 General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +//#include +#include + + +static int wpMode ; + + +char *usage = "Usage: gpio [-g] ..." ; + + +/* + * doExports: + * List all GPIO exports + ********************************************************************************* + */ + +void doExports (void) +{ + int fd ; + int i, l, first ; + char fName [128] ; + char dir, val ; + +// Rather crude, but who knows what others are up to... + + for (first = 0, i = 0 ; i < 64 ; ++i) + { + +// Try to read the direction + + 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: ", i) ; + + if ((l = read (fd, &dir, 1)) == 0) + { + printf ("Empty direction file (why?)\n") ; + close (fd) ; + continue ; + } + + /**/ if (dir == 'o') + printf ("Output ") ; + else if (dir == 'i') + printf ("Input ") ; + else + printf ("Wrong ") ; + + 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, &val, 1)) == 0) + { + printf ("Empty Value file (why?)\n") ; + close (fd) ; + continue ; + } + + /**/ if (val == '0' ) + printf ("(0)\n") ; + else if (val == '1') + printf ("(1)\n") ; + else + printf ("(?)\n") ; + + 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] ; + uid_t uid ; + gid_t gid ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + + 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) + fprintf (fd, "in\n") ; + else if (strcasecmp (mode, "out") == 0) + fprintf (fd, "out\n") ; + else + { + fprintf (stderr, "%s: Invalid mode: %s. Should be in or out\n", argv [1], mode) ; + exit (1) ; + } + + fclose (fd) ; + +// Change ownership so the current user can actually use it! + + uid = getuid () ; + gid = getgid () ; + + sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; + if (chown (fName, uid, gid) != 0) + { + fprintf (stderr, "%s: Unable to change ownership of the value file: %s\n", argv [1], strerror (errno)) ; + exit (1) ; + } + +} + + +/* + * 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]) ; + + 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) ; +} + +/* + * 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]) ; + + if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) + return ; + + mode = argv [3] ; + + /**/ if (strcasecmp (mode, "in") == 0) + pinMode (pin, INPUT) ; + else if (strcasecmp (mode, "out") == 0) + pinMode (pin, OUTPUT) ; + else if (strcasecmp (mode, "pwm") == 0) + pinMode (pin, PWM_OUTPUT) ; + else if (strcasecmp (mode, "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 + { + fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/up/down/tri\n", argv [1], mode) ; + exit (1) ; + } +} + +/* + * doWrite: + * gpio write pin value + ********************************************************************************* + */ + +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 ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) + return ; + + val = atoi (argv [3]) ; + + /**/ if (val == 0) + digitalWrite (pin, LOW) ; + else + digitalWrite (pin, HIGH) ; +} + + +/* + * 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]) ; + + if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) + { + printf ("0\n") ; + return ; + } + + val = digitalRead (pin) ; + + printf ("%s\n", val == 0 ? "0" : "1") ; +} + + +/* + * 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]) ; + + if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) + return ; + + val = atoi (argv [3]) ; + + pwmWrite (pin, val) ; +} + + +/* + * main: + * Start here + ********************************************************************************* + */ + +int main (int argc, char *argv []) +{ + int i ; + + if (argc == 1) + { + fprintf (stderr, "%s: %s\n", argv [0], usage) ; + return 1 ; + } + + if (geteuid () != 0) + { + fprintf (stderr, "%s: Must be root to run\n", argv [0]) ; + return 1 ; + } + +// Initial test for /sys/class/gpio operations: + + /**/ if (strcasecmp (argv [1], "exports" ) == 0) + { doExports () ; return 0 ; } + else if (strcasecmp (argv [1], "export" ) == 0) + { doExport (argc, argv) ; return 0 ; } + else if (strcasecmp (argv [1], "unexport") == 0) + { doUnexport (argc, argv) ; return 0 ; } + +// Check for -g argument + + if (strcasecmp (argv [1], "-g") == 0) + { + if (wiringPiSetupGpio () == -1) + { + fprintf (stderr, "%s: Unable to initialise GPIO in GPIO mode.\n", argv [0]) ; + exit (1) ; + } + + for (i = 2 ; i < argc ; ++i) + argv [i - 1] = argv [i] ; + --argc ; + wpMode = WPI_MODE_GPIO ; + } + else + { + if (wiringPiSetup () == -1) + { + fprintf (stderr, "%s: Unable to initialise GPIO in wiringPi mode\n", argv [0]) ; + exit (1) ; + } + wpMode = WPI_MODE_PINS ; + } + + /**/ if (strcasecmp (argv [1], "write" ) == 0) + doWrite (argc, argv) ; + else if (strcasecmp (argv [1], "read" ) == 0) + doRead (argc, argv) ; + else if (strcasecmp (argv [1], "mode" ) == 0) + doMode (argc, argv) ; + else if (strcasecmp (argv [1], "pwm" ) == 0) + doPwm (argc, argv) ; + else + { + fprintf (stderr, "%s: Unknown command: %s. (read/write/pwm/mode/export/unexport expected)\n", argv [0], argv [1]) ; + exit (1) ; + } + return 0 ; +} diff --git a/gpio/test.sh b/gpio/test.sh new file mode 100755 index 0000000..7127528 --- /dev/null +++ b/gpio/test.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# 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/wiringPi/COPYING b/wiringPi/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/wiringPi/COPYING @@ -0,0 +1,674 @@ + GNU 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/wiringPi/Makefile b/wiringPi/Makefile new file mode 100644 index 0000000..abcd35f --- /dev/null +++ b/wiringPi/Makefile @@ -0,0 +1,83 @@ +# +# Makefile: +# wiringPi - Wiring Compatable library for 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 General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with wiringPi. If not, see . +################################################################################# + + +TARGET=libwiringPi.a + +#DEBUG = -g -O0 +DEBUG = -O3 +CC = gcc +INCLUDE = -I. +CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe + +LIBS = + +# Should not alter anything below this line +############################################################################### + +SRC = wiringPi.c serial.c wiringShift.c + +OBJ = wiringPi.o serial.o wiringShift.o + +all: $(TARGET) + +$(TARGET): $(OBJ) + @echo [AR] $(OBJ) + @ar rcs $(TARGET) $(OBJ) + @size $(TARGET) + +.c.o: + @echo [CC] $< + @$(CC) -c $(CFLAGS) $< -o $@ + +clean: + rm -f $(OBJ) $(TARGET) *~ core tags Makefile.bak + +tags: $(SRC) + @echo [ctags] + @ctags $(SRC) + +depend: + makedepend -Y $(SRC) + +install: $(TARGET) + @echo [install] + install -m 0755 -d /usr/local/lib + install -m 0755 -d /usr/local/include + install -m 0644 wiringPi.h /usr/local/include + install -m 0644 serial.h /usr/local/include + install -m 0644 wiringShift.h /usr/local/include + install -m 0644 libwiringPi.a /usr/local/lib + +uninstall: + @echo [uninstall] + rm -f /usr/local/include/wiringPi.h + rm -f /usr/local/lib/libwiringPi.a + + + +# DO NOT DELETE + +wiringPi.o: wiringPi.h +serial.o: serial.h +wiringShift.o: wiringPi.h wiringShift.h diff --git a/wiringPi/README b/wiringPi/README new file mode 100644 index 0000000..781510a --- /dev/null +++ b/wiringPi/README @@ -0,0 +1,7 @@ + +WiringPi: An implementation of most of the Arduino Wiring + functions for the Raspberry Pi + +Full details at: + https://projects.drogon.net/raspberry-pi/wiringpi/ + diff --git a/wiringPi/serial.c b/wiringPi/serial.c new file mode 100644 index 0000000..abf9544 --- /dev/null +++ b/wiringPi/serial.c @@ -0,0 +1,204 @@ +/* + * serial.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 General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "serial.h" + +/* + * serialOpen: + * Open and initialise the serial port, setting all the right + * port parameters - or as many as are required - hopefully! + ********************************************************************************* + */ + +int serialOpen (char *device, int baud) +{ + struct termios options ; + speed_t myBaud ; + int status, fd ; + +#ifdef DEBUG + printf ("openSerialPort: <%s> baud: $d\n", device, baud) ; +#endif + + 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 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 ; + + 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 ; +} + + +/* + * serialClose: + * Release the serial port + ********************************************************************************* + */ + +void serialClose (int fd) +{ + close (fd) ; +} + + +/* + * serialPutchar: + * Send a single character to the serial port + ********************************************************************************* + */ + +void serialPutchar (int fd, uint8_t c) +{ + write (fd, &c, 1) ; +} + + +/* + * serialPuts: + * Send a string to the serial port + ********************************************************************************* + */ + +void serialPuts (int fd, char *s) +{ + write (fd, s, strlen (s)) ; +} + +/* + * serialPrintf: + * Printf over Serial + ********************************************************************************* + */ + +void serialPrintf (int fd, 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 (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 (int fd) +{ + uint8_t x ; + + if (read (fd, &x, 1) != 1) + return -1 ; + + return ((int)x) & 0xFF ; +} diff --git a/wiringPi/serial.h b/wiringPi/serial.h new file mode 100644 index 0000000..477a8a6 --- /dev/null +++ b/wiringPi/serial.h @@ -0,0 +1,41 @@ +/* + * serial.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 General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#ifndef _STDINT_H +# include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +extern int serialOpen (char *device, int baud) ; +extern void serialClose (int fd) ; +extern void serialPutchar (int fd, uint8_t c) ; +extern void serialPuts (int fd, char *s) ; +extern void serialPrintf (int fd, char *message, ...) ; +extern int serialDataAvail (int fd) ; +extern int serialGetchar (int fd) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c new file mode 100644 index 0000000..dcad15e --- /dev/null +++ b/wiringPi/wiringPi.c @@ -0,0 +1,729 @@ +/* + * wiringPi: + * Arduino compatable (ish) Wiring library for the Raspberry Pi + * Copyright (c) 2012 Gordon Henderson + * + * 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 General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +// Revisions: +// 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 + +// Pad drive current fiddling + +#undef DEBUG_PADS + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include "wiringPi.h" + +#ifndef TRUE +#define TRUE (1==1) +#define FALSE (1==2) +#endif + +// Port function select bits + +#define FSEL_INPT 0b000 +#define FSEL_OUTP 0b001 +#define FSEL_ALT0 0b100 +#define FSEL_ALT0 0b100 +#define FSEL_ALT1 0b101 +#define FSEL_ALT2 0b110 +#define FSEL_ALT3 0b111 +#define FSEL_ALT4 0b011 +#define FSEL_ALT5 0b010 + +// Access from ARM Running Linux +// Take from Gerts code. Some of this is not in the manual +// that I can find )-: + +#define BCM2708_PERI_BASE 0x20000000 +#define GPIO_PADS (BCM2708_PERI_BASE + 0x100000) +#define CLOCK_BASE (BCM2708_PERI_BASE + 0x101000) +#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) +#define GPIO_PWM (BCM2708_PERI_BASE + 0x20C000) + +#define PAGE_SIZE (4*1024) +#define BLOCK_SIZE (4*1024) + +// PWM + +#define PWM_CONTROL 0 +#define PWM_STATUS 1 +#define PWM0_RANGE 4 +#define PWM0_DATA 5 +#define PWM1_RANGE 8 +#define PWM1_DATA 9 + +#define PWMCLK_CNTL 40 +#define PWMCLK_DIV 41 + +#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 + +#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 + + +// Locals to hold pointers to the hardware + +static volatile uint32_t *gpio ; +static volatile uint32_t *pwm ; +static volatile uint32_t *clk ; + +// 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: +// +// 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) + +// sysFds: +// Map a file descriptor from the /sys/class/gpio/gpioX/value file + +static int sysFds [64] ; + +// Mode + +static int gpioPinMode ; + +// 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 + +static int pinToGpio [] = +{ + 17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7 + 0, 1, // I2C - SDA0, SCL0 + 8, 7, // SPI - CE1, CE0 + 10, 9, 11, // SPI - MOSI, MISO, SCLK + 14, 15, // UART - Tx, Rx +} ; + +// gpioToGPFSEL: +// Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5) + +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, +} ; + +// 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, +} ; + +// 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 +} ; + +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 + +} ; + + +// Time for easy calculations + +static unsigned long long epoch ; + +////////////////////////////////////////////////////////////////////////////////// + + +/* + * wiringPiGpioMode: + * Set the mode - use Pin numbers (0-16) or GPIO number (seemingly random) + ********************************************************************************* + */ + +void wiringPiGpioMode (int mode) +{ + gpioPinMode = mode ; +} + + +/* + * 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. + ********************************************************************************* + */ + +int wiringPiSetup (void) +{ + int fd ; + uint8_t *gpioMem, *pwmMem, *clkMem ; + struct timeval tv ; + +#ifdef DEBUG_PADS + uint8_t *gpioMem, *padsMem, *pwmMem, *clkMem ; + uint32_t *pads ; +#endif + +// Set Pin mode by default + + wiringPiGpioMode (WPI_MODE_PINS) ; + +// Open the master /dev/memory device + + if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0) + { + fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ; + return -1 ; + } + +// GPIO: + +// Allocate 2 pages - 1 ... + + if ((gpioMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) + { + fprintf (stderr, "wiringPiSetup: malloc failed: %s\n", strerror (errno)) ; + return -1 ; + } + +// ... presumably to make sure we can round it up to a whole page size + + if (((uint32_t)gpioMem % PAGE_SIZE) != 0) + gpioMem += PAGE_SIZE - ((uint32_t)gpioMem % PAGE_SIZE) ; + + gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_BASE) ; + + if ((int32_t)gpio < 0) + { + fprintf (stderr, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ; + return -1 ; + } + +// PWM + + if ((pwmMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) + { + fprintf (stderr, "wiringPiSetup: pwmMem malloc failed: %s\n", strerror (errno)) ; + return -1 ; + } + + if (((uint32_t)pwmMem % PAGE_SIZE) != 0) + pwmMem += PAGE_SIZE - ((uint32_t)pwmMem % PAGE_SIZE) ; + + pwm = (uint32_t *)mmap(pwmMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PWM) ; + + if ((int32_t)pwm < 0) + { + fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ; + return -1 ; + } + +// Clock control (needed for PWM) + + if ((clkMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) + { + fprintf (stderr, "wiringPiSetup: clkMem malloc failed: %s\n", strerror (errno)) ; + return -1 ; + } + + if (((uint32_t)clkMem % PAGE_SIZE) != 0) + clkMem += PAGE_SIZE - ((uint32_t)clkMem % PAGE_SIZE) ; + + clk = (uint32_t *)mmap(clkMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, CLOCK_BASE) ; + + if ((int32_t)clk < 0) + { + fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ; + return -1 ; + } + +#ifdef DEBUG_PADS + if ((padsMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) + { + fprintf (stderr, "wiringPiSetup: padsMem malloc failed: %s\n", strerror (errno)) ; + return -1 ; + } + + if (((uint32_t)padsMem % PAGE_SIZE) != 0) + padsMem += PAGE_SIZE - ((uint32_t)padsMem % PAGE_SIZE) ; + + pads = (uint32_t *)mmap(padsMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PADS) ; + + if ((int32_t)pads < 0) + { + fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ; + return -1 ; + } + + printf ("Checking pads @ 0x%08X\n", (unsigned int)pads) ; + + printf ("%08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ; +// *(pads + 11) = 0x1F ; + printf ("%08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ; +#endif + + gettimeofday (&tv, NULL) ; + epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ; + + 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) +{ + int x = wiringPiSetup () ; + + if (x != 0) + return x ; + + wiringPiGpioMode (WPI_MODE_GPIO) ; + 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 fd, pin ; + struct timeval tv ; + char fName [128] ; + +// Set GPIO_SYS mode by default + + wiringPiGpioMode (WPI_MODE_GPIO_SYS) ; + +// Open and scan the directory, looking for exported GPIOs, and pre-open +// the 'value' part to speed things up for later + + for (pin = 0 ; pin < 64 ; ++pin) + { + sysFds [pin] = -1 ; + sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; + if ((fd = open (fName, O_RDWR)) == -1) + continue ; + sysFds [pin] = fd ; + } + + gettimeofday (&tv, NULL) ; + epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ; + + return 0 ; +} + + +/* + * pinMode: + * Sets the mode of a pin to be input, output or PWM output + ********************************************************************************* + */ + +void pinMode (int pin, int mode) +{ + static int pwmRunning = FALSE ; + + int gpioPin, fSel, shift ; + int alt ; + +// We can't change the mode in GPIO_SYS mode + + if (gpioPinMode == WPI_MODE_GPIO_SYS) + return ; + + if (gpioPinMode == WPI_MODE_PINS) + { + if ((pin < 0) || (pin >= NUM_PINS)) + return ; + gpioPin = pinToGpio [pin] ; + } + else + gpioPin = pin ; + + fSel = gpioToGPFSEL [gpioPin] ; + shift = gpioToShift [gpioPin] ; + + /**/ if (mode == INPUT) + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input + else if (mode == OUTPUT) + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ; + else if (mode == PWM_OUTPUT) + { + if ((alt = gpioToPwmALT [gpioPin]) == 0) // Not a PWM pin + return ; + +// Set pin to PWM mode + + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; + +// We didn't initialise the PWM hardware at setup time - because it's possible that +// something else is using the PWM - e.g. the Audio systems! So if we use PWM +// here, then we're assuming that nothing else is, otherwise things are going +// to sound a bit funny... + + if (!pwmRunning) + { + +// Gert/Doms Values + *(clk + PWMCLK_DIV) = 0x5A000000 | (32<<12) ; // set pwm div to 32 (19.2/3 = 600KHz) + *(clk + PWMCLK_CNTL) = 0x5A000011 ; // Source=osc and enable + digitalWrite (pin, LOW) ; + *(pwm + PWM_CONTROL) = 0 ; // Disable PWM + delayMicroseconds (10) ; + *(pwm + PWM0_RANGE) = 0x400 ; + delayMicroseconds (10) ; + *(pwm + PWM1_RANGE) = 0x400 ; + delayMicroseconds (10) ; + +// Enable PWMs + + *(pwm + PWM0_DATA) = 512 ; + *(pwm + PWM1_DATA) = 512 ; + + *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ; + } + + } + +// When we change mode of any pin, we remove the pull up/downs + + pullUpDnControl (pin, PUD_OFF) ; +} + + +/* + * digitalWrite: + * Set an output bit + ********************************************************************************* + */ + +void digitalWrite (int pin, int value) +{ + int gpioPin ; + + if (gpioPinMode == WPI_MODE_PINS) + { + if ((pin < 0) || (pin >= NUM_PINS)) + return ; + gpioPin = pinToGpio [pin] ; + } + else + gpioPin = pin ; + + if (gpioPinMode == WPI_MODE_GPIO_SYS) + { + if (sysFds [gpioPin] != -1) + { + if (value == LOW) + write (sysFds [gpioPin], "0\n", 2) ; + else + write (sysFds [gpioPin], "1\n", 2) ; + } + } + else + { + if (value == LOW) + *(gpio + gpioToGPCLR [gpioPin]) = 1 << gpioPin ; + else + *(gpio + gpioToGPSET [gpioPin]) = 1 << gpioPin ; + } +} + + +/* + * pwnWrite: + * Set an output PWM value + ********************************************************************************* + */ + +void pwmWrite (int pin, int value) +{ + int port, gpioPin ; + +// We can't do this in GPIO_SYS mode + + if (gpioPinMode == WPI_MODE_GPIO_SYS) + return ; + + if (gpioPinMode == WPI_MODE_PINS) + { + if ((pin < 0) || (pin >= NUM_PINS)) + return ; + gpioPin = pinToGpio [pin] ; + } + else + gpioPin = pin ; + + port = gpioToPwmPort [gpioPin] ; + + *(pwm + port) = value & ~0x400 ; +} + + +/* + * digitalRead: + * Read the value of a given Pin, returning HIGH or LOW + ********************************************************************************* + */ + +int digitalRead (int pin) +{ + int gpioPin ; + char c ; + + if (gpioPinMode == WPI_MODE_PINS) + { + if ((pin < 0) || (pin >= NUM_PINS)) + return 0 ; + gpioPin = pinToGpio [pin] ; + } + else + gpioPin = pin ; + + if (gpioPinMode == WPI_MODE_GPIO_SYS) + { + if (sysFds [gpioPin] == -1) + return 0 ; + else + { + lseek (sysFds [gpioPin], 0L, SEEK_SET) ; + read (sysFds [gpioPin], &c, 1) ; + return (c == '0') ? 0 : 1 ; + } + } + else + { + if ((*(gpio + gpioToGPLEV [gpioPin]) & (1 << gpioPin)) != 0) + return HIGH ; + else + return LOW ; + } +} + +/* + * pullUpDownCtrl: + * Control the internal pull-up/down resistors on a GPIO pin + * The Arduino only has pull-ups and these are enabled by writing 1 + * to a port when in input mode - this paradigm doesn't quite apply + * here though. + ********************************************************************************* + */ + +void pullUpDnControl (int pin, int pud) +{ + int gpioPin ; + +// We can't do this in GPIO_SYS mode + + if (gpioPinMode == WPI_MODE_GPIO_SYS) + return ; + + if (gpioPinMode == WPI_MODE_PINS) + { + if ((pin < 0) || (pin >= NUM_PINS)) + return ; + gpioPin = pinToGpio [pin] ; + } + else + gpioPin = pin ; + + *(gpio + 37) = pud ; + delayMicroseconds (10) ; + *(gpio + gpioToPUDCLK [gpioPin]) = 1 << gpioPin ; + delayMicroseconds (10) ; + + *(gpio + 37) = 0 ; + *(gpio + gpioToPUDCLK [gpioPin]) = 0 ; +} + + +/* + * delay: delayMicroseconds + * Wait for some number of milli/micro seconds + ********************************************************************************* + */ + +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) ; +} + +void delayMicroseconds (unsigned int howLong) +{ + struct timespec sleeper, dummy ; + + sleeper.tv_sec = 0 ; + sleeper.tv_nsec = (long)(howLong * 1000) ; + + nanosleep (&sleeper, &dummy) ; +} + +/* + * millis: + * Return a number of milliseconds as an unsigned int. + ********************************************************************************* + */ + +unsigned int millis (void) +{ + struct timeval tv ; + unsigned long long t1 ; + + gettimeofday (&tv, NULL) ; + + t1 = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ; + + return (uint32_t)(t1 - epoch) ; +} diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h new file mode 100644 index 0000000..fcb7ae6 --- /dev/null +++ b/wiringPi/wiringPi.h @@ -0,0 +1,69 @@ +/* + * wiringPi: + * Arduino compatable (ish) Wiring library for 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 General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +// Handy defines + +#define NUM_PINS 17 + +#define WPI_MODE_PINS 0 +#define WPI_MODE_GPIO 1 +#define WPI_MODE_GPIO_SYS 2 + +#define INPUT 0 +#define OUTPUT 1 +#define PWM_OUTPUT 2 + +#define LOW 0 +#define HIGH 1 + +#define PUD_OFF 0 +#define PUD_DOWN 1 +#define PUD_UP 2 + +// Function prototypes +// c++ wrappers thanks to a commend by Nick Lott +// (and others on the Raspberry Pi forums) + +#ifdef __cplusplus +extern "C" { +#endif + +extern int wiringPiSetup (void) ; +extern int wiringPiSetupSys (void) ; +extern int wiringPiSetupGpio (void) ; + +extern void wiringPiGpioMode (int mode) ; + +extern void pullUpDnControl (int pin, int pud) ; +extern void pinMode (int pin, int mode) ; +extern void digitalWrite (int pin, int value) ; +extern void pwmWrite (int pin, int value) ; +extern int digitalRead (int pin) ; + +extern void delay (unsigned int howLong) ; +extern void delayMicroseconds (unsigned int howLong) ; +extern unsigned int millis (void) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/wiringShift.c b/wiringPi/wiringShift.c new file mode 100644 index 0000000..68c5faf --- /dev/null +++ b/wiringPi/wiringShift.c @@ -0,0 +1,84 @@ +/* + * 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 General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU 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..d723c5f --- /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 General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU 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 From 096ca1f1d401eaff9cee8e558b542d619310590e Mon Sep 17 00:00:00 2001 From: Philip Howard Date: Tue, 10 Jul 2012 22:43:28 +0100 Subject: [PATCH 02/29] experimental shiftOutWithDelay --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9eca6c8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.a +*.o From d677719d0ef0f8ad831a8859aceefc0c3dcb57e7 Mon Sep 17 00:00:00 2001 From: Philip Howard Date: Tue, 10 Jul 2012 22:43:51 +0100 Subject: [PATCH 03/29] Experimental shiftOutWithDelay --- wiringPi/wiringShift.c | 33 +++++++++++++++++++++++++++++++++ wiringPi/wiringShift.h | 1 + 2 files changed, 34 insertions(+) diff --git a/wiringPi/wiringShift.c b/wiringPi/wiringShift.c index 68c5faf..3682b22 100644 --- a/wiringPi/wiringShift.c +++ b/wiringPi/wiringShift.c @@ -82,3 +82,36 @@ void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) digitalWrite (cPin, LOW) ; } } + + +/* + * shiftOut: + * Shift data out to a clocked source + ********************************************************************************* + */ + +void shiftOutWithDelay (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val, uint8_t delay) +{ + int8_t i; + + if (order == MSBFIRST) + for (i = 7 ; i >= 0 ; --i) + { + digitalWrite (dPin, val & (1 << i)) ; + delayMicroseconds (delay) ; + digitalWrite (cPin, HIGH) ; + delayMicroseconds (delay) ; + digitalWrite (cPin, LOW) ; + delayMicroseconds (delay) ; + } + else + for (i = 0 ; i < 8 ; ++i) + { + digitalWrite (dPin, val & (1 << i)) ; + delayMicroseconds (delay) ; + digitalWrite (cPin, HIGH) ; + delayMicroseconds (delay) ; + digitalWrite (cPin, LOW) ; + delayMicroseconds (delay) ; + } +} diff --git a/wiringPi/wiringShift.h b/wiringPi/wiringShift.h index d723c5f..79c0fa6 100644 --- a/wiringPi/wiringShift.h +++ b/wiringPi/wiringShift.h @@ -35,6 +35,7 @@ extern "C" { extern uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) ; extern void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ; +extern void shiftOutWithDelay (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val, uint8_t delay) ; #ifdef __cplusplus } From d8e44ea3a6663f8eb2838f2fefdf8fddf7ef515a Mon Sep 17 00:00:00 2001 From: Philip Howard Date: Tue, 10 Jul 2012 23:36:07 +0100 Subject: [PATCH 04/29] Changed shiftOutWithDelay delay to int --- wiringPi/wiringShift.c | 2 +- wiringPi/wiringShift.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wiringPi/wiringShift.c b/wiringPi/wiringShift.c index 3682b22..c684dbb 100644 --- a/wiringPi/wiringShift.c +++ b/wiringPi/wiringShift.c @@ -90,7 +90,7 @@ void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ********************************************************************************* */ -void shiftOutWithDelay (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val, uint8_t delay) +void shiftOutWithDelay (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val, int delay) { int8_t i; diff --git a/wiringPi/wiringShift.h b/wiringPi/wiringShift.h index 79c0fa6..3d846e0 100644 --- a/wiringPi/wiringShift.h +++ b/wiringPi/wiringShift.h @@ -35,7 +35,7 @@ extern "C" { extern uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) ; extern void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ; -extern void shiftOutWithDelay (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val, uint8_t delay) ; +extern void shiftOutWithDelay (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val, int delay) ; #ifdef __cplusplus } From 43aa862e97c06b1383ee08590a96020723a43505 Mon Sep 17 00:00:00 2001 From: Gordon Drogon Date: Wed, 11 Jul 2012 22:42:56 +0100 Subject: [PATCH 05/29] New LCD library plus -v option for gpio binary --- examples/Makefile | 14 +- examples/lcd.c | 129 ++++++++++++++++ gpio/gpio.c | 17 ++- wiringPi/Makefile | 4 +- wiringPi/lcd.c | 365 ++++++++++++++++++++++++++++++++++++++++++++++ wiringPi/lcd.h | 37 +++++ 6 files changed, 556 insertions(+), 10 deletions(-) create mode 100644 examples/lcd.c create mode 100644 wiringPi/lcd.c create mode 100644 wiringPi/lcd.h diff --git a/examples/Makefile b/examples/Makefile index 72ce1eb..58a30cf 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -35,11 +35,11 @@ LIBS = -lwiringPi # Should not alter anything below this line ############################################################################### -SRC = test1.c test2.c speed.c +SRC = test1.c test2.c speed.c lcd.c -OBJ = test1.o test2.o speed.o +OBJ = test1.o test2.o speed.o lcd.o -all: test1 test2 speed +all: test1 test2 speed lcd test1: test1.o @echo [link] @@ -52,14 +52,18 @@ test2: test2.o speed: speed.o @echo [link] $(CC) -o $@ speed.o $(LDFLAGS) $(LIBS) - + +lcd: lcd.o + @echo [link] + $(CC) -o $@ lcd.o $(LDFLAGS) $(LIBS) + .c.o: @echo [CC] $< @$(CC) -c $(CFLAGS) $< -o $@ clean: - rm -f $(OBJ) *~ core tags test1 test2 speed + rm -f $(OBJ) *~ core tags test1 test2 speed lcd tags: $(SRC) @echo [ctags] diff --git a/examples/lcd.c b/examples/lcd.c new file mode 100644 index 0000000..2cabea7 --- /dev/null +++ b/examples/lcd.c @@ -0,0 +1,129 @@ +/* + * 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 General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include + +int main (void) +{ + int i, j ; + int fd1, fd2 ; + + char message1 [256] ; + char message2 [256] ; + char buf1 [30] ; + char buf2 [30] ; + + struct tm *t ; + time_t tim ; + + printf ("Raspberry Pi LCD test program\n") ; + + if (wiringPiSetup () == -1) + exit (1) ; + + fd1 = lcdInit (4, 20, 4, 8, 9, 4,5,6,7,0,0,0,0) ; + fd2 = lcdInit (2, 16, 4, 8, 10, 4,5,6,7,0,0,0,0) ; + +//fd1 = lcdInit (4, 20, 8, 8, 9, 0,1,2,3,4,5,6,7) ; +//fd2 = lcdInit (2, 16, 8, 8, 10, 0,1,2,3,4,5,6,7) ; + + if (fd1 == -1) + { + printf ("lcdInit 1 failed\n") ; + return 1 ; + } + + if (fd2 == -1) + { + printf ("lcdInit 2 failed\n") ; + return 1 ; + } + + sleep (1) ; + + lcdPosition (fd1, 0, 0) ; lcdPuts (fd1, " Gordon Henderson") ; + lcdPosition (fd1, 0, 1) ; lcdPuts (fd1, " --------------") ; +/* + lcdPosition (fd1, 0, 2) ; lcdPuts (fd1, " 00:00:00") ; + lcdPosition (fd1, 0, 3) ; lcdPuts (fd1, " DD:MM:YY") ; +*/ + + lcdPosition (fd2, 0, 0) ; lcdPuts (fd2, "Gordon Henderson") ; + lcdPosition (fd2, 0, 1) ; lcdPuts (fd2, "----------------") ; + + sleep (2) ; + + sprintf (message1, "%s", " http://projects.drogon.net/ ") ; + sprintf (message2, "%s", " This is a long message to go into the smaller display just for a demonstration of what we can do. ") ; + + for (;;) + { + i = 0 ; + j = 0 ; + for (;;) + { + strncpy (buf1, &message1 [i], 20) ; + buf1 [20] = 0 ; + lcdPosition (fd1, 0, 1) ; + lcdPuts (fd1, buf1) ; + ++i ; + if (i == strlen (message1) - 20) + i = 0 ; + + strncpy (buf2, &message2 [j], 16) ; + buf2 [16] = 0 ; + lcdPosition (fd2, 0, 1) ; + lcdPuts (fd2, buf2) ; + ++j ; + if (j == strlen (message2) - 16) + j = 0 ; + + tim = time (NULL) ; + t = localtime (&tim) ; + + sprintf (buf1, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ; + lcdPosition (fd1, 5, 2) ; + lcdPuts (fd1, buf1) ; + + sprintf (buf1, "%02d/%02d/%02d", t->tm_mday, t->tm_mon + 1, t->tm_year+1900) ; + lcdPosition (fd1, 4, 3) ; + lcdPuts (fd1, buf1) ; + + delay (250) ; + } + } + + return 0 ; +} diff --git a/gpio/gpio.c b/gpio/gpio.c index 7aa1d5f..bbc4e31 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -30,14 +30,17 @@ #include #include #include -//#include #include +#define VERSION "1.0" + static int wpMode ; -char *usage = "Usage: gpio [-g] ..." ; +char *usage = "Usage: gpio -v\n" + " gpio [-g] ...\n" + " gpio ..." ; /* @@ -367,6 +370,14 @@ int main (int argc, char *argv []) return 1 ; } + if (strcasecmp (argv [1], "-v") == 0) + { + printf ("gpio version: %s\n", VERSION) ; + printf ("Copyright (c) 2012 Gordon Henderson\n") ; + printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ; + return 0 ; + } + // Initial test for /sys/class/gpio operations: /**/ if (strcasecmp (argv [1], "exports" ) == 0) @@ -411,7 +422,7 @@ int main (int argc, char *argv []) doPwm (argc, argv) ; else { - fprintf (stderr, "%s: Unknown command: %s. (read/write/pwm/mode/export/unexport expected)\n", argv [0], argv [1]) ; + fprintf (stderr, "%s: Unknown command: %s. (read/write/pwm/mode expected)\n", argv [0], argv [1]) ; exit (1) ; } return 0 ; diff --git a/wiringPi/Makefile b/wiringPi/Makefile index abcd35f..c56a3cf 100644 --- a/wiringPi/Makefile +++ b/wiringPi/Makefile @@ -35,9 +35,9 @@ LIBS = # Should not alter anything below this line ############################################################################### -SRC = wiringPi.c serial.c wiringShift.c +SRC = wiringPi.c serial.c wiringShift.c lcd.c -OBJ = wiringPi.o serial.o wiringShift.o +OBJ = wiringPi.o serial.o wiringShift.o lcd.o all: $(TARGET) diff --git a/wiringPi/lcd.c b/wiringPi/lcd.c new file mode 100644 index 0000000..dc091bc --- /dev/null +++ b/wiringPi/lcd.c @@ -0,0 +1,365 @@ +/* + * 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 General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include + +#include "wiringPi.h" +#include "lcd.h" + +// Commands + +#define LCD_CLEAR 0x01 +#define LCD_HOME 0x02 +#define LCD_ENTRY 0x04 +#define LCD_ON_OFF 0x08 +#define LCD_CDSHIFT 0x10 +#define LCD_FUNC 0x20 +#define LCD_CGRAM 0x40 +#define LCD_DGRAM 0x80 + +#define LCD_ENTRY_SH 0x01 +#define LCD_ENTRY_ID 0x02 + +#define LCD_ON_OFF_B 0x01 +#define LCD_ON_OFF_C 0x02 +#define LCD_ON_OFF_D 0x04 + +#define LCD_FUNC_F 0x04 +#define LCD_FUNC_N 0x08 +#define LCD_FUNC_DL 0x10 + +#define LCD_CDSHIFT_RL 0x04 + +struct lcdDataStruct +{ + uint8_t bits, rows, cols ; + uint8_t rsPin, strbPin ; + uint8_t dataPins [8] ; +} ; + +struct lcdDataStruct *lcds [MAX_LCDS] ; + + +/* + * 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 (struct lcdDataStruct *lcd) +{ + digitalWrite (lcd->strbPin, 1) ; delayMicroseconds (1) ; + digitalWrite (lcd->strbPin, 0) ; delayMicroseconds (50) ; +} + + +/* + * sentDataCmd: + * Send an data or command byte to the display. + ********************************************************************************* + */ + +static void sendDataCmd (struct lcdDataStruct *lcd, uint8_t data) +{ + uint8_t i, d4 ; + + if (lcd->bits == 4) + { + d4 = (data >> 4) & 0x0F; + for (i = 0 ; i < 4 ; ++i) + { + digitalWrite (lcd->dataPins [i], (d4 & 1)) ; + d4 >>= 1 ; + } + strobe (lcd) ; + + d4 = data & 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], (data & 1)) ; + data >>= 1 ; + } + } + strobe (lcd) ; +} + + +/* + * putCommand: + * Send a command byte to the display + ********************************************************************************* + */ + +static void putCommand (struct lcdDataStruct *lcd, uint8_t command) +{ + digitalWrite (lcd->rsPin, 0) ; + sendDataCmd (lcd, command) ; +} + +static void put4Command (struct lcdDataStruct *lcd, uint8_t command) +{ + uint8_t i ; + + digitalWrite (lcd->rsPin, 0) ; + + for (i = 0 ; i < 4 ; ++i) + { + digitalWrite (lcd->dataPins [i], (command & 1)) ; + command >>= 1 ; + } + strobe (lcd) ; +} + + +/* + ********************************************************************************* + * User Code below here + ********************************************************************************* + */ + +/* + * lcdHome: lcdClear: + * Home the cursor or clear the screen. + ********************************************************************************* + */ + +void lcdHome (int fd) +{ + struct lcdDataStruct *lcd = lcds [fd] ; + putCommand (lcd, LCD_HOME) ; +} + +void lcdClear (int fd) +{ + struct lcdDataStruct *lcd = lcds [fd] ; + putCommand (lcd, LCD_CLEAR) ; +} + + +/* + * lcdPosition: + * Update the position of the cursor on the display + ********************************************************************************* + */ + + +void lcdPosition (int fd, int x, int y) +{ + static uint8_t rowOff [4] = { 0x00, 0x40, 0x14, 0x54 } ; + struct lcdDataStruct *lcd = lcds [fd] ; + + putCommand (lcd, x + (LCD_DGRAM | rowOff [y])) ; +} + + +/* + * lcdPutchar: + * Send a data byte to be displayed on the display + ********************************************************************************* + */ + +void lcdPutchar (int fd, uint8_t data) +{ + struct lcdDataStruct *lcd = lcds [fd] ; + + digitalWrite (lcd->rsPin, 1) ; + sendDataCmd (lcd, data) ; +} + + +/* + * lcdPuts: + * Send a string to be displayed on the display + ********************************************************************************* + */ + +void lcdPuts (int fd, char *string) +{ + while (*string) + lcdPutchar (fd, *string++) ; +} + + +/* + * lcdPrintf: + * Printf to an LCD display + ********************************************************************************* + */ + +void lcdPrintf (int fd, 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 (int rows, int cols, int bits, int rs, int strb, + int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) +{ + static int initialised = 0 ; + + uint8_t 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 = 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->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 + + putCommand (lcd, LCD_ON_OFF | LCD_ON_OFF_D) ; delay (2) ; + putCommand (lcd, LCD_ENTRY | LCD_ENTRY_ID) ; delay (2) ; + putCommand (lcd, LCD_CDSHIFT | LCD_CDSHIFT_RL) ; delay (2) ; + putCommand (lcd, LCD_CLEAR) ; delay (5) ; + + return lcdFd ; +} diff --git a/wiringPi/lcd.h b/wiringPi/lcd.h new file mode 100644 index 0000000..96744f6 --- /dev/null +++ b/wiringPi/lcd.h @@ -0,0 +1,37 @@ +/* + * 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 General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#define MAX_LCDS 8 + +extern void lcdHome (int fd) ; +extern void lcdClear (int fd) ; +extern void lcdPosition (int fd, int x, int y) ; +extern void lcdPutchar (int fd, uint8_t data) ; +extern void lcdPuts (int fd, char *string) ; +extern void lcdPrintf (int fd, char *message, ...) ; + +extern int lcdInit (int rows, int cols, int bits, int rs, int strb, + int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ; From d24a8fc4cbed187787e66dbe7c7488b177cdd58e Mon Sep 17 00:00:00 2001 From: Gordon Drogon Date: Fri, 17 Aug 2012 10:16:31 +0100 Subject: [PATCH 06/29] New timing methods --- COPYING.LESSER | 165 +++++++++++ examples/COPYING.LESSER | 165 +++++++++++ examples/Makefile | 22 +- examples/lcd.c | 6 +- examples/piface.c | 53 ++++ examples/speed.c | 6 +- examples/wfi.c | 158 ++++++++++ gpio/COPYING.LESSER | 165 +++++++++++ gpio/Makefile | 6 +- gpio/gpio.1 | 76 +++-- gpio/gpio.c | 232 ++++++++++++--- wiringPi/COPYING.LESSER | 165 +++++++++++ wiringPi/Makefile | 30 +- wiringPi/lcd.c | 6 +- wiringPi/lcd.h | 6 +- wiringPi/piHiPri.c | 50 ++++ wiringPi/piThread.c | 63 ++++ wiringPi/wiringPi.c | 635 ++++++++++++++++++++++++---------------- wiringPi/wiringPi.h | 47 ++- wiringPi/wiringPiFace.c | 355 ++++++++++++++++++++++ wiringPi/wiringSerial.c | 206 +++++++++++++ wiringPi/wiringSerial.h | 37 +++ wiringPi/wiringShift.c | 39 +-- wiringPi/wiringShift.h | 7 +- 24 files changed, 2308 insertions(+), 392 deletions(-) create mode 100644 COPYING.LESSER create mode 100644 examples/COPYING.LESSER create mode 100644 examples/piface.c create mode 100644 examples/wfi.c create mode 100644 gpio/COPYING.LESSER create mode 100644 wiringPi/COPYING.LESSER create mode 100644 wiringPi/piHiPri.c create mode 100644 wiringPi/piThread.c create mode 100644 wiringPi/wiringPiFace.c create mode 100644 wiringPi/wiringSerial.c create mode 100644 wiringPi/wiringSerial.h 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/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/Makefile b/examples/Makefile index 58a30cf..df00d79 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -9,16 +9,16 @@ # 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 General Public License as published by +# it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # wiringPi is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# GNU Lesser General Public License for more details. # -# You should have received a copy of the GNU General Public License +# You should have received a copy of the GNU Lesser General Public License # along with wiringPi. If not, see . ################################################################################# @@ -35,11 +35,11 @@ LIBS = -lwiringPi # Should not alter anything below this line ############################################################################### -SRC = test1.c test2.c speed.c lcd.c +SRC = test1.c test2.c speed.c lcd.c wfi.c piface.c -OBJ = test1.o test2.o speed.o lcd.o +OBJ = test1.o test2.o speed.o lcd.o wfi.o piface.o -all: test1 test2 speed lcd +all: test1 test2 speed lcd wfi piface test1: test1.o @echo [link] @@ -57,13 +57,21 @@ lcd: lcd.o @echo [link] $(CC) -o $@ lcd.o $(LDFLAGS) $(LIBS) +wfi: wfi.o + @echo [link] + $(CC) -o $@ wfi.o $(LDFLAGS) $(LIBS) -lpthread + +piface: piface.o + @echo [link] + $(CC) -o $@ piface.o $(LDFLAGS) $(LIBS) -lpthread + .c.o: @echo [CC] $< @$(CC) -c $(CFLAGS) $< -o $@ clean: - rm -f $(OBJ) *~ core tags test1 test2 speed lcd + rm -f $(OBJ) *~ core tags test1 test2 speed lcd wfi piface tags: $(SRC) @echo [ctags] diff --git a/examples/lcd.c b/examples/lcd.c index 2cabea7..6024917 100644 --- a/examples/lcd.c +++ b/examples/lcd.c @@ -10,16 +10,16 @@ * https://projects.drogon.net/raspberry-pi/wiringpi/ * * wiringPi is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * wiringPi is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License + * You should have received a copy of the GNU Lesser General Public License * along with wiringPi. If not, see . *********************************************************************** */ diff --git a/examples/piface.c b/examples/piface.c new file mode 100644 index 0000000..3305bf9 --- /dev/null +++ b/examples/piface.c @@ -0,0 +1,53 @@ + +/* + * piface.c: + * Simple test for the PiFace + * + * Read the buttons and output the same to the LEDs + */ + +#include + +#include +#include +#include + +int outputs [4] = { 0,0,0,0 } ; + +void scanButton (int button) +{ + if (digitalRead (button) == LOW) + { + outputs [button] ^= 1 ; + digitalWrite (button, outputs [button]) ; + } + + while (digitalRead (button) == LOW) + delay (1) ; +} + + +int main (void) +{ + int pin, button ; + + printf ("Raspberry Pi wiringPiFace test program\n") ; + + if (wiringPiSetupPiFace () == -1) + exit (1) ; + +// Enable internal pull-ups + + for (pin = 0 ; pin < 8 ; ++pin) + pullUpDnControl (pin, PUD_UP) ; + + + for (;;) + { + for (button = 0 ; button < 4 ; ++button) + scanButton (button) ; + delay (1) ; + } + + return 0 ; +} diff --git a/examples/speed.c b/examples/speed.c index 409c994..2f5d990 100644 --- a/examples/speed.c +++ b/examples/speed.c @@ -52,7 +52,8 @@ int main (void) printf ("Native GPIO method: (%8d iterations)\n", FAST_COUNT) ; - wiringPiGpioMode (WPI_MODE_GPIO) ; + if (wiringPiSetupGpio () == -1) + exit (1) ; pinMode (17, OUTPUT) ; @@ -77,7 +78,8 @@ int main (void) // Switch to SYS mode: - wiringPiSetupSys () ; + if (wiringPiSetupSys () == -1) + exit (1) ; printf ("/sys/class/gpio method: (%8d iterations)\n", SLOW_COUNT) ; diff --git a/examples/wfi.c b/examples/wfi.c new file mode 100644 index 0000000..9efcc2c --- /dev/null +++ b/examples/wfi.c @@ -0,0 +1,158 @@ +/* + * wfi.c: + * Wait for Interrupt test program + * + * 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 + +// 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? +// GPIO 0 is one of the I2C pins with an on-board pull-up + +#define BUTTON_PIN 0 + +// 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 + digitalWrite (18, 1) ; + + for (;;) + { + if (waitForInterrupt (BUTTON_PIN, -1) > 0) // Got it + { + +// Bouncing? + + if (millis () < debounceTime) + { + debounceTime = millis () + DEBOUNCE_TIME ; + continue ; + } + +// We have a valid one + + digitalWrite (17, state) ; + state ^= 1 ; + + piLock (COUNT_KEY) ; + ++globalCounter ; + piUnlock (COUNT_KEY) ; + +// Wait for key to be released + + while (digitalRead (0) == 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 bit) + + system ("gpio edge 0 falling") ; + system ("gpio export 17 out") ; + system ("gpio export 18 out") ; + +// Setup wiringPi + + wiringPiSetupSys () ; + +// Fire off our interrupt handler + + piThreadCreate (waitForIt) ; + + digitalWrite (17, 0) ; +} + + +/* + * 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 (5000) ; + } + + 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 index 043e329..c0740c9 100644 --- a/gpio/Makefile +++ b/gpio/Makefile @@ -9,16 +9,16 @@ # 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 General Public License as published by +# it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # wiringPi is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# GNU Lesser General Public License for more details. # -# You should have received a copy of the GNU General Public License +# You should have received a copy of the GNU Lesser General Public License # along with wiringPi. If not, see . ################################################################################# diff --git a/gpio/gpio.1 b/gpio/gpio.1 index 25c8da5..7da64b2 100644 --- a/gpio/gpio.1 +++ b/gpio/gpio.1 @@ -1,15 +1,23 @@ -.TH "GPIO" "14 June 2012" "Command-Line access to Raspberry Pi GPIO" +.TH "GPIO" "14 June 2012" "Command-Line access to Raspberry Pi and PiFace GPIO" .SH NAME -gpio \- Command-line access to Raspberry Pi GPIO +gpio \- Command-line access to Raspberry Pi and PiFace GPIO .SH SYNOPSIS +.TP +.B gpio +.RB [ \-v ] +.TP .B gpio .RB [ \-g ] .RB < read/write/pwm/mode ...> .TP .B gpio -.RB < export/unexport/exports ...> +.RB [ \-p ] +.RB < read/write/mode ...> +.TP +.B gpio +.RB < export/edge/unexport/unexportall/exports ...> .SH DESCRIPTION @@ -19,15 +27,23 @@ on the Raspberry Pi. 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. -Additionally, it can be used to set the exports in the /sys/class/gpio -system directory to allow subsequent programs to use the /sys/class/gpio +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 + .TP .B \-g -Use the BCM_GPIO pins numbers rather than WiringPi pin numbers. +Use the BCM_GPIO pins numbers rather than wiringPi pin numbers. + +.TP +.B \-p +Use the PiFace interface board and its corresponding pin numbers. .TP .B read @@ -44,27 +60,45 @@ Write a PWM value (0-1023) to the given pin. .TP .B mode -Set a pin into input, output or pwm mode. Can also use the literals up, down or tri -to set the internal pull-up, pull-down or tristate controls. +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. .TP .B export -Export a GPIO pin in the /sys/class/gpio directory. Use like the mode command above -however only in and out are supported at this time. +Export a GPIO pin in the \fI/sys/class/gpio\fR directory. Use like the +mode command above however only \fIin\fR and \fIout\fR are supported at +this time. Note that the pin number is the \fBBCM_GPIO\fR number and +not the wiringPi number. -Once a GPIO pin has been exported, the -.B gpio -program changes the ownership of the /sys/class/gpio/gpioX/value pseudo file to -that of the user running the -.B gpio -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. +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 abovem 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 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. @@ -119,9 +153,9 @@ gpio -g read 0 # Read GPIO Pin 0 (SDA0) .SH "NOTES" -When using the export or unexport commands, the pin numbers are -.B always -native GPIO numbers and never wiringPi pin numbers. +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. .SH "SEE ALSO" diff --git a/gpio/gpio.c b/gpio/gpio.c index bbc4e31..8467b3e 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -7,16 +7,16 @@ * https://projects.drogon.net/raspberry-pi/wiringpi/ * * wiringPi is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * wiringPi is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License + * You should have received a copy of the GNU Lesser General Public License * along with wiringPi. If not, see . *********************************************************************** */ @@ -37,10 +37,10 @@ static int wpMode ; - char *usage = "Usage: gpio -v\n" - " gpio [-g] ...\n" - " gpio ..." ; + " gpio [-g] ...\n" + " gpio [-p] ...\n" + " gpio ..." ; /* @@ -54,7 +54,7 @@ void doExports (void) int fd ; int i, l, first ; char fName [128] ; - char dir, val ; + char buf [16] ; // Rather crude, but who knows what others are up to... @@ -75,19 +75,14 @@ void doExports (void) printf ("%4d: ", i) ; - if ((l = read (fd, &dir, 1)) == 0) - { - printf ("Empty direction file (why?)\n") ; - close (fd) ; - 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 ; - /**/ if (dir == 'o') - printf ("Output ") ; - else if (dir == 'i') - printf ("Input ") ; - else - printf ("Wrong ") ; + printf ("%-3s", buf) ; close (fd) ; @@ -100,19 +95,32 @@ void doExports (void) continue ; } - if ((l = read (fd, &val, 1)) == 0) + 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 ("Empty Value file (why?)\n") ; - close (fd) ; + printf ("\n") ; continue ; } - /**/ if (val == '0' ) - printf ("(0)\n") ; - else if (val == '1') - printf ("(1)\n") ; - else - printf ("(?)\n") ; + 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) ; } @@ -161,9 +169,9 @@ void doExport (int argc, char *argv []) exit (1) ; } - /**/ if (strcasecmp (mode, "in") == 0) + /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0)) fprintf (fd, "in\n") ; - else if (strcasecmp (mode, "out") == 0) + else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0)) fprintf (fd, "out\n") ; else { @@ -184,7 +192,113 @@ void doExport (int argc, char *argv []) fprintf (stderr, "%s: Unable to change ownership of the value file: %s\n", argv [1], strerror (errno)) ; exit (1) ; } - + +// Also change ownership of the edge file - if it exists + + sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ; + if (chown (fName, uid, gid) != 0) + { + if (errno != ENOENT) // Silently ignore File not found - older kernel + { + fprintf (stderr, "%s: Unable to change ownership of the value file: %s\n", argv [1], strerror (errno)) ; + exit (1) ; + } + } + +} + + +/* + * 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] ; + uid_t uid ; + gid_t gid ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + + 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 so the current user can actually use it! + + uid = getuid () ; + gid = getgid () ; + + sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; + if (chown (fName, uid, gid) != 0) + { + fprintf (stderr, "%s: Unable to change ownership of the value file: %s\n", argv [1], strerror (errno)) ; + exit (1) ; + } + +// Also change ownership of the edge file + + sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ; + if (chown (fName, uid, gid) != 0) + { + fprintf (stderr, "%s: Unable to change ownership of the value file: %s\n", argv [1], strerror (errno)) ; + exit (1) ; + } + + fclose (fd) ; } @@ -218,6 +332,33 @@ void doUnexport (int argc, char *argv []) fclose (fd) ; } + +/* + * doUnexportAll: + * gpio unexportall + * Un-Export all the GPIO pins. + * This uses the /sys/class/gpio device interface. + ********************************************************************************* + */ + +void doUnexportall (int argc, char *argv []) +{ + FILE *fd ; + int pin ; + + for (pin = 0 ; pin < 63 ; ++pin) + { + 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) ; + } +} + + /* * doMode: * gpio mode pin mode ... @@ -381,11 +522,15 @@ int main (int argc, char *argv []) // Initial test for /sys/class/gpio operations: /**/ if (strcasecmp (argv [1], "exports" ) == 0) - { doExports () ; return 0 ; } + { doExports () ; return 0 ; } else if (strcasecmp (argv [1], "export" ) == 0) - { doExport (argc, argv) ; return 0 ; } + { doExport (argc, argv) ; return 0 ; } + else if (strcasecmp (argv [1], "edge" ) == 0) + { doEdge (argc, argv) ; return 0 ; } + else if (strcasecmp (argv [1], "unexportall") == 0) + { doUnexportall (argc, argv) ; return 0 ; } else if (strcasecmp (argv [1], "unexport") == 0) - { doUnexport (argc, argv) ; return 0 ; } + { doUnexport (argc, argv) ; return 0 ; } // Check for -g argument @@ -402,6 +547,25 @@ int main (int argc, char *argv []) --argc ; wpMode = WPI_MODE_GPIO ; } + +// Check for -p argument for PiFace + + else if (strcasecmp (argv [1], "-p") == 0) + { + if (wiringPiSetupPiFaceForGpioProg () == -1) + { + fprintf (stderr, "%s: Unable to initialise PiFace.\n", argv [0]) ; + exit (1) ; + } + + for (i = 2 ; i < argc ; ++i) + argv [i - 1] = argv [i] ; + --argc ; + wpMode = WPI_MODE_PIFACE ; + } + +// Default to wiringPi mode + else { if (wiringPiSetup () == -1) 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 index c56a3cf..3c23e96 100644 --- a/wiringPi/Makefile +++ b/wiringPi/Makefile @@ -8,16 +8,16 @@ # https://projects.drogon.net/raspberry-pi/wiringpi/ # # wiringPi is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by +# it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # wiringPi is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. +# GNU Lesser General Public License for more details. # -# You should have received a copy of the GNU General Public License +# You should have received a copy of the GNU Lesser General Public License # along with wiringPi. If not, see . ################################################################################# @@ -35,16 +35,17 @@ LIBS = # Should not alter anything below this line ############################################################################### -SRC = wiringPi.c serial.c wiringShift.c lcd.c +SRC = wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c lcd.c piHiPri.c piThread.c -OBJ = wiringPi.o serial.o wiringShift.o lcd.o +OBJ = wiringPi.o wiringPiFace.o wiringSerial.o wiringShift.o lcd.o piHiPri.o piThread.o all: $(TARGET) $(TARGET): $(OBJ) @echo [AR] $(OBJ) @ar rcs $(TARGET) $(OBJ) - @size $(TARGET) + @ranlib $(TARGET) + @size $(TARGET) .c.o: @echo [CC] $< @@ -64,13 +65,16 @@ install: $(TARGET) @echo [install] install -m 0755 -d /usr/local/lib install -m 0755 -d /usr/local/include - install -m 0644 wiringPi.h /usr/local/include - install -m 0644 serial.h /usr/local/include - install -m 0644 wiringShift.h /usr/local/include - install -m 0644 libwiringPi.a /usr/local/lib + install -m 0644 wiringPi.h /usr/local/include + install -m 0644 wiringSerial.h /usr/local/include + install -m 0644 wiringShift.h /usr/local/include + install -m 0644 lcd.h /usr/local/include + install -m 0644 libwiringPi.a /usr/local/lib uninstall: @echo [uninstall] + rm -f /usr/local/include/lcd.h + rm -f /usr/local/include/wiringShift.h rm -f /usr/local/include/wiringPi.h rm -f /usr/local/lib/libwiringPi.a @@ -79,5 +83,9 @@ uninstall: # DO NOT DELETE wiringPi.o: wiringPi.h -serial.o: serial.h +wiringPiFace.o: wiringPi.h +wiringSerial.o: wiringSerial.h wiringShift.o: wiringPi.h wiringShift.h +lcd.o: wiringPi.h lcd.h +piHiPri.o: wiringPi.h +piThread.o: wiringPi.h diff --git a/wiringPi/lcd.c b/wiringPi/lcd.c index dc091bc..6826a60 100644 --- a/wiringPi/lcd.c +++ b/wiringPi/lcd.c @@ -10,16 +10,16 @@ * https://projects.drogon.net/raspberry-pi/wiringpi/ * * wiringPi is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * wiringPi is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License + * You should have received a copy of the GNU Lesser General Public License * along with wiringPi. If not, see . *********************************************************************** */ diff --git a/wiringPi/lcd.h b/wiringPi/lcd.h index 96744f6..094f5f5 100644 --- a/wiringPi/lcd.h +++ b/wiringPi/lcd.h @@ -10,16 +10,16 @@ * https://projects.drogon.net/raspberry-pi/wiringpi/ * * wiringPi is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * wiringPi is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License + * You should have received a copy of the GNU Lesser General Public License * along with wiringPi. If not, see . *********************************************************************** */ diff --git a/wiringPi/piHiPri.c b/wiringPi/piHiPri.c new file mode 100644 index 0000000..e7e06b4 --- /dev/null +++ b/wiringPi/piHiPri.c @@ -0,0 +1,50 @@ +/* + * 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 (int pri) +{ + struct sched_param sched ; + + memset (&sched, 0, sizeof(sched)) ; + + if (pri > sched_get_priority_max (SCHED_RR)) + pri = sched_get_priority_max (SCHED_RR) ; + + sched.sched_priority = 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/wiringPi.c b/wiringPi/wiringPi.c index dcad15e..d99c863 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -11,21 +11,32 @@ * https://projects.drogon.net/raspberry-pi/wiringpi/ * * wiringPi 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 3 of the License, or - * (at your option) any later version. + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. * * wiringPi is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with wiringPi. If not, see . + * 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: @@ -45,6 +56,7 @@ #include #include +#include #include #include #include @@ -55,10 +67,18 @@ #include #include - - #include "wiringPi.h" +// Function stubs + +void (*pinMode) (int pin, int mode) ; +void (*pullUpDnControl) (int pin, int pud) ; +void (*digitalWrite) (int pin, int value) ; +void (*pwmWrite) (int pin, int value) ; +int (*digitalRead) (int pin) ; +int (*waitForInterrupt) (int pin, int mS) ; + + #ifndef TRUE #define TRUE (1==1) #define FALSE (1==2) @@ -77,7 +97,7 @@ #define FSEL_ALT5 0b010 // Access from ARM Running Linux -// Take from Gerts code. Some of this is not in the manual +// Take from Gert/Doms code. Some of this is not in the manual // that I can find )-: #define BCM2708_PERI_BASE 0x20000000 @@ -143,14 +163,10 @@ static volatile uint32_t *clk ; // X / 10 + ((X % 10) * 3) // sysFds: -// Map a file descriptor from the /sys/class/gpio/gpioX/value file +// Map a file descriptor from the /sys/class/gpio/gpioX/value static int sysFds [64] ; -// Mode - -static int gpioPinMode ; - // 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! @@ -158,13 +174,19 @@ static int gpioPinMode ; // pinToGpio: // Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin -static int pinToGpio [] = +static int pinToGpio [64] = { 17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7 0, 1, // I2C - SDA0, SCL0 8, 7, // SPI - CE1, CE0 10, 9, 11, // SPI - MOSI, MISO, SCLK 14, 15, // UART - Tx, Rx + +// 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 } ; // gpioToGPFSEL: @@ -219,6 +241,35 @@ static uint8_t gpioToGPLEV [] = 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 edgde 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 + // gpioToPUDCLK // (Word) offset to the Pull Up Down Clock regsiter @@ -265,16 +316,304 @@ static unsigned long long epoch ; /* - * wiringPiGpioMode: - * Set the mode - use Pin numbers (0-16) or GPIO number (seemingly random) + * pinMode: + * Sets the mode of a pin to be input, output or PWM output ********************************************************************************* */ -void wiringPiGpioMode (int mode) +void pinModeGpio (int pin, int mode) { - gpioPinMode = mode ; + static int pwmRunning = FALSE ; + int fSel, shift, alt ; + + pin &= 63 ; + + fSel = gpioToGPFSEL [pin] ; + shift = gpioToShift [pin] ; + + /**/ if (mode == INPUT) + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input + else if (mode == OUTPUT) + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ; + else if (mode == PWM_OUTPUT) + { + if ((alt = gpioToPwmALT [pin]) == 0) // Not a PWM pin + return ; + +// Set pin to PWM mode + + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; + +// We didn't initialise the PWM hardware at setup time - because it's possible that +// something else is using the PWM - e.g. the Audio systems! So if we use PWM +// here, then we're assuming that nothing else is, otherwise things are going +// to sound a bit funny... + + if (!pwmRunning) + { + +// Gert/Doms Values + *(clk + PWMCLK_DIV) = 0x5A000000 | (32<<12) ; // set pwm div to 32 (19.2/3 = 600KHz) + *(clk + PWMCLK_CNTL) = 0x5A000011 ; // Source=osc and enable + digitalWrite (pin, LOW) ; + *(pwm + PWM_CONTROL) = 0 ; // Disable PWM + delayMicroseconds (10) ; + *(pwm + PWM0_RANGE) = 0x400 ; + delayMicroseconds (10) ; + *(pwm + PWM1_RANGE) = 0x400 ; + delayMicroseconds (10) ; + +// Enable PWMs + + *(pwm + PWM0_DATA) = 512 ; + *(pwm + PWM1_DATA) = 512 ; + + *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ; + } + + } + +// When we change mode of any pin, we remove the pull up/downs + + pullUpDnControl (pin, PUD_OFF) ; } +void pinModeWPi (int pin, int mode) +{ + pinModeGpio (pinToGpio [pin & 63], mode) ; +} + +void pinModeSys (int pin, int mode) +{ + return ; +} + + +#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 + + + +/* + * digitalWrite: + * Set an output bit + ********************************************************************************* + */ + +void digitalWriteWPi (int pin, int value) +{ + int gpioPin = pinToGpio [pin & 63] ; + + if (value == LOW) + *(gpio + gpioToGPCLR [gpioPin]) = 1 << gpioPin ; + else + *(gpio + gpioToGPSET [gpioPin]) = 1 << gpioPin ; +} + +void digitalWriteGpio (int pin, int value) +{ + pin &= 63 ; + + if (value == LOW) + *(gpio + gpioToGPCLR [pin]) = 1 << pin ; + else + *(gpio + gpioToGPSET [pin]) = 1 << pin ; +} + +void digitalWriteSys (int pin, int value) +{ + pin &= 63 ; + + if (sysFds [pin] != -1) + { + if (value == LOW) + write (sysFds [pin], "0\n", 2) ; + else + write (sysFds [pin], "1\n", 2) ; + } +} + + +/* + * pwnWrite: + * Set an output PWM value + ********************************************************************************* + */ + +void pwmWriteWPi (int pin, int value) +{ + int port, gpioPin ; + + gpioPin = pinToGpio [pin & 63] ; + port = gpioToPwmPort [gpioPin] ; + + *(pwm + port) = value & 0x3FF ; +} + +void pwmWriteGpio (int pin, int value) +{ + int port, gpioPin ; + + gpioPin = pin & 63 ; + port = gpioToPwmPort [gpioPin] ; + + *(pwm + port) = value & 0x3FF ; +} + + +void pwmWriteSys (int pin, int value) +{ + return ; +} + + +/* + * digitalRead: + * Read the value of a given Pin, returning HIGH or LOW + ********************************************************************************* + */ + +int digitalReadWPi (int pin) +{ + int gpioPin ; + + pin &= 63 ; + + gpioPin = pinToGpio [pin] ; + + if ((*(gpio + gpioToGPLEV [gpioPin]) & (1 << gpioPin)) != 0) + return HIGH ; + else + return LOW ; +} + +int digitalReadGpio (int pin) +{ + pin &= 63 ; + + if ((*(gpio + gpioToGPLEV [pin]) & (1 << pin)) != 0) + return HIGH ; + else + return LOW ; +} + +int digitalReadSys (int pin) +{ + char c ; + + pin &= 63 ; + + if (sysFds [pin] == -1) + return 0 ; + + lseek (sysFds [pin], 0L, SEEK_SET) ; + read (sysFds [pin], &c, 1) ; + return (c == '0') ? 0 : 1 ; +} + + +/* + * pullUpDownCtrl: + * Control the internal pull-up/down resistors on a GPIO pin + * The Arduino only has pull-ups and these are enabled by writing 1 + * to a port when in input mode - this paradigm doesn't quite apply + * here though. + ********************************************************************************* + */ + +void pullUpDnControlWPi (int pin, int pud) +{ + pin = pinToGpio [pin & 63] ; + + *(gpio + 37) = pud ; + delayMicroseconds (10) ; + *(gpio + gpioToPUDCLK [pin]) = 1 << pin ; + delayMicroseconds (10) ; + + *(gpio + 37) = 0 ; + *(gpio + gpioToPUDCLK [pin]) = 0 ; +} + +void pullUpDnControlGpio (int pin, int pud) +{ + pin &= 63 ; + + *(gpio + 37) = pud ; + delayMicroseconds (10) ; + *(gpio + gpioToPUDCLK [pin]) = 1 << pin ; + delayMicroseconds (10) ; + + *(gpio + 37) = 0 ; + *(gpio + gpioToPUDCLK [pin]) = 0 ; +} + +void pullUpDnControlSys (int pin, int pud) +{ + return ; +} + + +/* + * waitForInterrupt: + * 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 waitForInterruptSys (int pin, int mS) +{ + int fd, x ; + char buf [8] ; + struct pollfd polls ; + + if ((fd = sysFds [pin & 63]) == -1) + return -2 ; + +// Do a dummy read + + x = read (fd, buf, 6) ; + if (x < 0) + return x ; + +// And seek + + lseek (fd, 0, SEEK_SET) ; + +// Setup poll structure + + polls.fd = fd ; + polls.events = POLLPRI ; // Urgent data! + +// Wait for it ... + + return poll (&polls, 1, mS) ; +} + +int waitForInterruptWPi (int pin, int mS) +{ + return waitForInterruptSys (pinToGpio [pin & 63], mS) ; +} + +int waitForInterruptGpio (int pin, int mS) +{ + return waitForInterruptSys (pin, mS) ; +} + + /* * wiringPiSetup: @@ -296,9 +635,12 @@ int wiringPiSetup (void) uint32_t *pads ; #endif -// Set Pin mode by default - - wiringPiGpioMode (WPI_MODE_PINS) ; + pinMode = pinModeWPi ; + pullUpDnControl = pullUpDnControlWPi ; + digitalWrite = digitalWriteWPi ; + pwmWrite = pwmWriteWPi ; + digitalRead = digitalReadWPi ; + waitForInterrupt = waitForInterruptWPi ; // Open the master /dev/memory device @@ -417,7 +759,13 @@ int wiringPiSetupGpio (void) if (x != 0) return x ; - wiringPiGpioMode (WPI_MODE_GPIO) ; + pinMode = pinModeGpio ; + pullUpDnControl = pullUpDnControlGpio ; + digitalWrite = digitalWriteGpio ; + pwmWrite = pwmWriteGpio ; + digitalRead = digitalReadGpio ; + waitForInterrupt = waitForInterruptGpio ; + return 0 ; } @@ -433,26 +781,28 @@ int wiringPiSetupGpio (void) int wiringPiSetupSys (void) { - int fd, pin ; + int pin ; struct timeval tv ; char fName [128] ; -// Set GPIO_SYS mode by default - - wiringPiGpioMode (WPI_MODE_GPIO_SYS) ; + pinMode = pinModeSys ; + pullUpDnControl = pullUpDnControlSys ; + digitalWrite = digitalWriteSys ; + pwmWrite = pwmWriteSys ; + digitalRead = digitalReadSys ; + waitForInterrupt = waitForInterruptSys ; // Open and scan the directory, looking for exported GPIOs, and pre-open -// the 'value' part to speed things up for later +// the 'value' interface to speed things up for later for (pin = 0 ; pin < 64 ; ++pin) { - sysFds [pin] = -1 ; sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; - if ((fd = open (fName, O_RDWR)) == -1) - continue ; - sysFds [pin] = fd ; + sysFds [pin] = open (fName, O_RDWR) ; } +// Initialise the epoch for mills() ... + gettimeofday (&tv, NULL) ; epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ; @@ -460,228 +810,7 @@ int wiringPiSetupSys (void) } -/* - * pinMode: - * Sets the mode of a pin to be input, output or PWM output - ********************************************************************************* - */ -void pinMode (int pin, int mode) -{ - static int pwmRunning = FALSE ; - - int gpioPin, fSel, shift ; - int alt ; - -// We can't change the mode in GPIO_SYS mode - - if (gpioPinMode == WPI_MODE_GPIO_SYS) - return ; - - if (gpioPinMode == WPI_MODE_PINS) - { - if ((pin < 0) || (pin >= NUM_PINS)) - return ; - gpioPin = pinToGpio [pin] ; - } - else - gpioPin = pin ; - - fSel = gpioToGPFSEL [gpioPin] ; - shift = gpioToShift [gpioPin] ; - - /**/ if (mode == INPUT) - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input - else if (mode == OUTPUT) - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ; - else if (mode == PWM_OUTPUT) - { - if ((alt = gpioToPwmALT [gpioPin]) == 0) // Not a PWM pin - return ; - -// Set pin to PWM mode - - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; - -// We didn't initialise the PWM hardware at setup time - because it's possible that -// something else is using the PWM - e.g. the Audio systems! So if we use PWM -// here, then we're assuming that nothing else is, otherwise things are going -// to sound a bit funny... - - if (!pwmRunning) - { - -// Gert/Doms Values - *(clk + PWMCLK_DIV) = 0x5A000000 | (32<<12) ; // set pwm div to 32 (19.2/3 = 600KHz) - *(clk + PWMCLK_CNTL) = 0x5A000011 ; // Source=osc and enable - digitalWrite (pin, LOW) ; - *(pwm + PWM_CONTROL) = 0 ; // Disable PWM - delayMicroseconds (10) ; - *(pwm + PWM0_RANGE) = 0x400 ; - delayMicroseconds (10) ; - *(pwm + PWM1_RANGE) = 0x400 ; - delayMicroseconds (10) ; - -// Enable PWMs - - *(pwm + PWM0_DATA) = 512 ; - *(pwm + PWM1_DATA) = 512 ; - - *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ; - } - - } - -// When we change mode of any pin, we remove the pull up/downs - - pullUpDnControl (pin, PUD_OFF) ; -} - - -/* - * digitalWrite: - * Set an output bit - ********************************************************************************* - */ - -void digitalWrite (int pin, int value) -{ - int gpioPin ; - - if (gpioPinMode == WPI_MODE_PINS) - { - if ((pin < 0) || (pin >= NUM_PINS)) - return ; - gpioPin = pinToGpio [pin] ; - } - else - gpioPin = pin ; - - if (gpioPinMode == WPI_MODE_GPIO_SYS) - { - if (sysFds [gpioPin] != -1) - { - if (value == LOW) - write (sysFds [gpioPin], "0\n", 2) ; - else - write (sysFds [gpioPin], "1\n", 2) ; - } - } - else - { - if (value == LOW) - *(gpio + gpioToGPCLR [gpioPin]) = 1 << gpioPin ; - else - *(gpio + gpioToGPSET [gpioPin]) = 1 << gpioPin ; - } -} - - -/* - * pwnWrite: - * Set an output PWM value - ********************************************************************************* - */ - -void pwmWrite (int pin, int value) -{ - int port, gpioPin ; - -// We can't do this in GPIO_SYS mode - - if (gpioPinMode == WPI_MODE_GPIO_SYS) - return ; - - if (gpioPinMode == WPI_MODE_PINS) - { - if ((pin < 0) || (pin >= NUM_PINS)) - return ; - gpioPin = pinToGpio [pin] ; - } - else - gpioPin = pin ; - - port = gpioToPwmPort [gpioPin] ; - - *(pwm + port) = value & ~0x400 ; -} - - -/* - * digitalRead: - * Read the value of a given Pin, returning HIGH or LOW - ********************************************************************************* - */ - -int digitalRead (int pin) -{ - int gpioPin ; - char c ; - - if (gpioPinMode == WPI_MODE_PINS) - { - if ((pin < 0) || (pin >= NUM_PINS)) - return 0 ; - gpioPin = pinToGpio [pin] ; - } - else - gpioPin = pin ; - - if (gpioPinMode == WPI_MODE_GPIO_SYS) - { - if (sysFds [gpioPin] == -1) - return 0 ; - else - { - lseek (sysFds [gpioPin], 0L, SEEK_SET) ; - read (sysFds [gpioPin], &c, 1) ; - return (c == '0') ? 0 : 1 ; - } - } - else - { - if ((*(gpio + gpioToGPLEV [gpioPin]) & (1 << gpioPin)) != 0) - return HIGH ; - else - return LOW ; - } -} - -/* - * pullUpDownCtrl: - * Control the internal pull-up/down resistors on a GPIO pin - * The Arduino only has pull-ups and these are enabled by writing 1 - * to a port when in input mode - this paradigm doesn't quite apply - * here though. - ********************************************************************************* - */ - -void pullUpDnControl (int pin, int pud) -{ - int gpioPin ; - -// We can't do this in GPIO_SYS mode - - if (gpioPinMode == WPI_MODE_GPIO_SYS) - return ; - - if (gpioPinMode == WPI_MODE_PINS) - { - if ((pin < 0) || (pin >= NUM_PINS)) - return ; - gpioPin = pinToGpio [pin] ; - } - else - gpioPin = pin ; - - *(gpio + 37) = pud ; - delayMicroseconds (10) ; - *(gpio + gpioToPUDCLK [gpioPin]) = 1 << gpioPin ; - delayMicroseconds (10) ; - - *(gpio + 37) = 0 ; - *(gpio + gpioToPUDCLK [gpioPin]) = 0 ; -} /* diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index fcb7ae6..a81511a 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -7,16 +7,16 @@ * https://projects.drogon.net/raspberry-pi/wiringpi/ * * wiringPi is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * wiringPi is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License + * You should have received a copy of the GNU Lesser General Public License * along with wiringPi. If not, see . *********************************************************************** */ @@ -28,6 +28,7 @@ #define WPI_MODE_PINS 0 #define WPI_MODE_GPIO 1 #define WPI_MODE_GPIO_SYS 2 +#define WPI_MODE_PIFACE 3 #define INPUT 0 #define OUTPUT 1 @@ -48,17 +49,39 @@ extern "C" { #endif -extern int wiringPiSetup (void) ; -extern int wiringPiSetupSys (void) ; -extern int wiringPiSetupGpio (void) ; +// Basic wiringPi functions -extern void wiringPiGpioMode (int mode) ; +extern int wiringPiSetup (void) ; +extern int wiringPiSetupSys (void) ; +extern int wiringPiSetupGpio (void) ; +extern int wiringPiSetupPiFace (void) ; -extern void pullUpDnControl (int pin, int pud) ; -extern void pinMode (int pin, int mode) ; -extern void digitalWrite (int pin, int value) ; -extern void pwmWrite (int pin, int value) ; -extern int digitalRead (int pin) ; +extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only + +extern void (*pinMode) (int pin, int mode) ; +extern void (*pullUpDnControl) (int pin, int pud) ; +extern void (*digitalWrite) (int pin, int value) ; +extern void (*pwmWrite) (int pin, int value) ; +extern int (*digitalRead) (int pin) ; + +// Interrupts + +extern int (*waitForInterrupt) (int pin, int mS) ; + +// Threads + +#define PI_THREAD(X) void *X (void *dummy) + +extern int piThreadCreate (void *(*fn)(void *)) ; +extern void piLock (int key) ; +extern void piUnlock (int key) ; + +// Schedulling priority + +extern int piHiPri (int pri) ; + + +// Extras from arduino land extern void delay (unsigned int howLong) ; extern void delayMicroseconds (unsigned int howLong) ; diff --git a/wiringPi/wiringPiFace.c b/wiringPi/wiringPiFace.c new file mode 100644 index 0000000..2425413 --- /dev/null +++ b/wiringPi/wiringPiFace.c @@ -0,0 +1,355 @@ +/* + * wiringPiFace: + * Arduino compatable (ish) Wiring library for the Raspberry Pi + * Copyright (c) 2012 Gordon Henderson + * + * This file to interface with the PiFace peripheral device which + * has an MCP23S17 GPIO device connected via the SPI bus. + * + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + + +#include +#include +#include +#include +#include +#include + +#include "wiringPi.h" + + +// The SPI bus parameters +// Variables as they need to be passed as pointers later on + +static char *spiDevice = "/dev/spidev0.0" ; +static uint8_t spiMode = 0 ; +static uint8_t spiBPW = 8 ; +static uint32_t spiSpeed = 5000000 ; +static uint16_t spiDelay = 0; + +// Locals here to keep track of everything + +static int spiFd ; + +// The MCP23S17 doesn't have bit-set operations, so it's +// cheaper to keep a copy here than to read/modify/write it + +uint8_t dataOutRegister = 0 ; +uint8_t pudRegister = 0 ; + +// MCP23S17 Registers + +#define IOCON 0x0A + +#define IODIRA 0x00 +#define IPOLA 0x02 +#define GPINTENA 0x04 +#define DEFVALA 0x06 +#define INTCONA 0x08 +#define GPPUA 0x0C +#define INTFA 0x0E +#define INTCAPA 0x10 +#define GPIOA 0x12 +#define OLATA 0x14 + +#define IODIRB 0x01 +#define IPOLB 0x03 +#define GPINTENB 0x05 +#define DEFVALB 0x07 +#define INTCONB 0x09 +#define GPPUB 0x0D +#define INTFB 0x0F +#define INTCAPB 0x11 +#define GPIOB 0x13 +#define OLATB 0x15 + +// Bits in the IOCON register + +#define IOCON_BANK_MODE 0x80 +#define IOCON_MIRROR 0x40 +#define IOCON_SEQOP 0x20 +#define IOCON_DISSLW 0x10 +#define IOCON_HAEN 0x08 +#define IOCON_ODR 0x04 +#define IOCON_INTPOL 0x02 +#define IOCON_UNUSED 0x01 + +// Default initialisation mode + +#define IOCON_INIT (IOCON_SEQOP) + +// Command codes + +#define CMD_WRITE 0x40 +#define CMD_READ 0x41 + + +/* + * writeByte: + * Write a byte to a register on the MCP23S17 on the SPI bus. + * This is using the synchronous access mechanism. + ********************************************************************************* + */ + +static void writeByte (uint8_t reg, uint8_t data) +{ + uint8_t spiBufTx [3] ; + uint8_t spiBufRx [3] ; + struct spi_ioc_transfer spi ; + + spiBufTx [0] = CMD_WRITE ; + spiBufTx [1] = reg ; + spiBufTx [2] = data ; + + spi.tx_buf = (unsigned long)spiBufTx ; + spi.rx_buf = (unsigned long)spiBufRx ; + spi.len = 3 ; + spi.delay_usecs = spiDelay ; + spi.speed_hz = spiSpeed ; + spi.bits_per_word = spiBPW ; + + ioctl (spiFd, SPI_IOC_MESSAGE(1), &spi) ; +} + +/* + * readByte: + * Read a byte from a register on the MCP23S17 on the SPI bus. + * This is the synchronous access mechanism. + * What appears to happen is that the data returned is at + * the same offset as the number of bytes written to the device. So if we + * write 2 bytes (e.g. command then register number), then the data returned + * will by at the 3rd byte... + ********************************************************************************* + */ + +static uint8_t readByte (uint8_t reg) +{ + uint8_t tx [4] ; + uint8_t rx [4] ; + struct spi_ioc_transfer spi ; + + tx [0] = CMD_READ ; + tx [1] = reg ; + tx [2] = 0 ; + + spi.tx_buf = (unsigned long)tx ; + spi.rx_buf = (unsigned long)rx ; + spi.len = 3 ; + spi.delay_usecs = spiDelay ; + spi.speed_hz = spiSpeed ; + spi.bits_per_word = spiBPW ; + + ioctl (spiFd, SPI_IOC_MESSAGE(1), &spi) ; + + return rx [2] ; +} + + +/* + * digitalWritePiFace: + * Perform the digitalWrite function on the PiFace board + ********************************************************************************* + */ + +void digitalWritePiFace (int pin, int value) +{ + uint8_t mask = 1 << pin ; + + if (value == 0) + dataOutRegister &= (~mask) ; + else + dataOutRegister |= mask ; + + writeByte (GPIOA, dataOutRegister) ; +} + + +void digitalWritePiFaceSpecial (int pin, int value) +{ + uint8_t mask = 1 << pin ; + uint8_t old ; + + old = readByte (GPIOA) ; + + if (value == 0) + old &= (~mask) ; + else + old |= mask ; + + writeByte (GPIOA, old) ; +} + + +/* + * digitalReadPiFace: + * Perform the digitalRead function on the PiFace board + ********************************************************************************* + */ + +int digitalReadPiFace (int pin) +{ + uint8_t mask = 1 << pin ; + + if ((readByte (GPIOB) & mask) != 0) + return HIGH ; + else + return LOW ; +} + + +/* + * pullUpDnControlPiFace: + * Perform the pullUpDnControl function on the PiFace board + ********************************************************************************* + */ + +void pullUpDnControlPiFace (int pin, int pud) +{ + uint8_t mask = 1 << pin ; + + if (pud == PUD_UP) + pudRegister |= mask ; + else + pudRegister &= (~mask) ; + + writeByte (GPPUB, pudRegister) ; + +} + + +void pullUpDnControlPiFaceSpecial (int pin, int pud) +{ + uint8_t mask = 1 << pin ; + uint8_t old ; + + old = readByte (GPPUB) ; + + if (pud == PUD_UP) + old |= mask ; + else + old &= (~mask) ; + + writeByte (GPPUB, old) ; + +} + + + +/* + * Dummy functions that are not used in this mode + ********************************************************************************* + */ + +void pinModePiFace (int pin, int mode) {} +void pwmWritePiFace (int pin, int value) {} +int waitForInterruptPiFace (int pin, int mS) { return 0 ; } + + +/* + * wiringPiSetupPiFace + * Setup the SPI interface and initialise the MCP23S17 chip + ********************************************************************************* + */ + +static int _wiringPiSetupPiFace (void) +{ + if ((spiFd = open (spiDevice, O_RDWR)) < 0) + return -1 ; + +// Set SPI parameters +// Why are we doing a read after write? +// I don't know - just blindliy copying an example elsewhere... -GH- + + if (ioctl (spiFd, SPI_IOC_WR_MODE, &spiMode) < 0) + return -1 ; + + if (ioctl (spiFd, SPI_IOC_RD_MODE, &spiMode) < 0) + return -1 ; + + if (ioctl (spiFd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0) + return -1 ; + + if (ioctl (spiFd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0) + return -1 ; + + if (ioctl (spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed) < 0) + return -1 ; + + if (ioctl (spiFd, SPI_IOC_RD_MAX_SPEED_HZ, &spiSpeed) < 0) + return -1 ; + +// Setup the MCP23S17 + + writeByte (IOCON, IOCON_INIT) ; + + writeByte (IODIRA, 0x00) ; // Port A -> Outputs + writeByte (IODIRB, 0xFF) ; // Port B -> Inputs + + return 0 ; +} + + +int wiringPiSetupPiFace (void) +{ + int x = _wiringPiSetupPiFace () ; + + if (x != 0) + return x ; + + writeByte (GPIOA, 0x00) ; // Set all outptus off + writeByte (GPPUB, 0x00) ; // Disable any pull-ups on port B + + pinMode = pinModePiFace ; + pullUpDnControl = pullUpDnControlPiFace ; + digitalWrite = digitalWritePiFace ; + pwmWrite = pwmWritePiFace ; + digitalRead = digitalReadPiFace ; + waitForInterrupt = waitForInterruptPiFace ; + + return 0 ; +} + + +/* + * wiringPiSetupPiFaceForGpioProg: + * Setup the SPI interface and initialise the MCP23S17 chip + * Special version for the gpio program + ********************************************************************************* + */ + + +int wiringPiSetupPiFaceForGpioProg (void) +{ + int x = _wiringPiSetupPiFace () ; + + if (x != 0) + return x ; + + pinMode = pinModePiFace ; + pullUpDnControl = pullUpDnControlPiFaceSpecial ; + digitalWrite = digitalWritePiFaceSpecial ; + pwmWrite = pwmWritePiFace ; + digitalRead = digitalReadPiFace ; + waitForInterrupt = waitForInterruptPiFace ; + + return 0 ; +} diff --git a/wiringPi/wiringSerial.c b/wiringPi/wiringSerial.c new file mode 100644 index 0000000..c3dae67 --- /dev/null +++ b/wiringPi/wiringSerial.c @@ -0,0 +1,206 @@ +/* + * 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 . + *********************************************************************** + */ + +#undef DEBUG + +#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 (char *device, int baud) +{ + struct termios options ; + speed_t myBaud ; + int status, fd ; + +#ifdef DEBUG + printf ("openSerialPort: <%s> baud: $d\n", device, baud) ; +#endif + + 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 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 ; + + 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 ; +} + + +/* + * serialClose: + * Release the serial port + ********************************************************************************* + */ + +void serialClose (int fd) +{ + close (fd) ; +} + + +/* + * serialPutchar: + * Send a single character to the serial port + ********************************************************************************* + */ + +void serialPutchar (int fd, unsigned char c) +{ + write (fd, &c, 1) ; +} + + +/* + * serialPuts: + * Send a string to the serial port + ********************************************************************************* + */ + +void serialPuts (int fd, char *s) +{ + write (fd, s, strlen (s)) ; +} + +/* + * serialPrintf: + * Printf over Serial + ********************************************************************************* + */ + +void serialPrintf (int fd, 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 (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 (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..609838d --- /dev/null +++ b/wiringPi/wiringSerial.h @@ -0,0 +1,37 @@ +/* + * 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 (char *device, int baud) ; +extern void serialClose (int fd) ; +extern void serialPutchar (int fd, unsigned char c) ; +extern void serialPuts (int fd, char *s) ; +extern void serialPrintf (int fd, char *message, ...) ; +extern int serialDataAvail (int fd) ; +extern int serialGetchar (int fd) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/wiringShift.c b/wiringPi/wiringShift.c index c684dbb..b9b7a44 100644 --- a/wiringPi/wiringShift.c +++ b/wiringPi/wiringShift.c @@ -8,16 +8,16 @@ * https://projects.drogon.net/raspberry-pi/wiringpi/ * * wiringPi is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * wiringPi is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License + * You should have received a copy of the GNU Lesser General Public License * along with wiringPi. If not, see . *********************************************************************** */ @@ -82,36 +82,3 @@ void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) digitalWrite (cPin, LOW) ; } } - - -/* - * shiftOut: - * Shift data out to a clocked source - ********************************************************************************* - */ - -void shiftOutWithDelay (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val, int delay) -{ - int8_t i; - - if (order == MSBFIRST) - for (i = 7 ; i >= 0 ; --i) - { - digitalWrite (dPin, val & (1 << i)) ; - delayMicroseconds (delay) ; - digitalWrite (cPin, HIGH) ; - delayMicroseconds (delay) ; - digitalWrite (cPin, LOW) ; - delayMicroseconds (delay) ; - } - else - for (i = 0 ; i < 8 ; ++i) - { - digitalWrite (dPin, val & (1 << i)) ; - delayMicroseconds (delay) ; - digitalWrite (cPin, HIGH) ; - delayMicroseconds (delay) ; - digitalWrite (cPin, LOW) ; - delayMicroseconds (delay) ; - } -} diff --git a/wiringPi/wiringShift.h b/wiringPi/wiringShift.h index 3d846e0..a3f4581 100644 --- a/wiringPi/wiringShift.h +++ b/wiringPi/wiringShift.h @@ -8,16 +8,16 @@ * https://projects.drogon.net/raspberry-pi/wiringpi/ * * wiringPi is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * wiringPi is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License + * You should have received a copy of the GNU Lesser General Public License * along with wiringPi. If not, see . *********************************************************************** */ @@ -35,7 +35,6 @@ extern "C" { extern uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) ; extern void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ; -extern void shiftOutWithDelay (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val, int delay) ; #ifdef __cplusplus } From 21f0472265d9e96a4f4d601afaaf7a04155530df Mon Sep 17 00:00:00 2001 From: Philip Howard Date: Sat, 18 Aug 2012 09:58:23 +0100 Subject: [PATCH 07/29] Cleanup, removed redundant COPYING and serial.* files --- wiringPi/COPYING | 674 ---------------------------------------------- wiringPi/serial.c | 204 -------------- wiringPi/serial.h | 41 --- 3 files changed, 919 deletions(-) delete mode 100644 wiringPi/COPYING delete mode 100644 wiringPi/serial.c delete mode 100644 wiringPi/serial.h diff --git a/wiringPi/COPYING b/wiringPi/COPYING deleted file mode 100644 index 94a9ed0..0000000 --- a/wiringPi/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU 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. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU 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 -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/wiringPi/serial.c b/wiringPi/serial.c deleted file mode 100644 index abf9544..0000000 --- a/wiringPi/serial.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * serial.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 General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * wiringPi is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with wiringPi. If not, see . - *********************************************************************** - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "serial.h" - -/* - * serialOpen: - * Open and initialise the serial port, setting all the right - * port parameters - or as many as are required - hopefully! - ********************************************************************************* - */ - -int serialOpen (char *device, int baud) -{ - struct termios options ; - speed_t myBaud ; - int status, fd ; - -#ifdef DEBUG - printf ("openSerialPort: <%s> baud: $d\n", device, baud) ; -#endif - - 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 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 ; - - 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 ; -} - - -/* - * serialClose: - * Release the serial port - ********************************************************************************* - */ - -void serialClose (int fd) -{ - close (fd) ; -} - - -/* - * serialPutchar: - * Send a single character to the serial port - ********************************************************************************* - */ - -void serialPutchar (int fd, uint8_t c) -{ - write (fd, &c, 1) ; -} - - -/* - * serialPuts: - * Send a string to the serial port - ********************************************************************************* - */ - -void serialPuts (int fd, char *s) -{ - write (fd, s, strlen (s)) ; -} - -/* - * serialPrintf: - * Printf over Serial - ********************************************************************************* - */ - -void serialPrintf (int fd, 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 (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 (int fd) -{ - uint8_t x ; - - if (read (fd, &x, 1) != 1) - return -1 ; - - return ((int)x) & 0xFF ; -} diff --git a/wiringPi/serial.h b/wiringPi/serial.h deleted file mode 100644 index 477a8a6..0000000 --- a/wiringPi/serial.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * serial.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 General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * wiringPi is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with wiringPi. If not, see . - *********************************************************************** - */ - -#ifndef _STDINT_H -# include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -extern int serialOpen (char *device, int baud) ; -extern void serialClose (int fd) ; -extern void serialPutchar (int fd, uint8_t c) ; -extern void serialPuts (int fd, char *s) ; -extern void serialPrintf (int fd, char *message, ...) ; -extern int serialDataAvail (int fd) ; -extern int serialGetchar (int fd) ; - -#ifdef __cplusplus -} -#endif From ae40bdaf6a1b0267737365c2e1c5be17dda122b0 Mon Sep 17 00:00:00 2001 From: Gordon Henderson Date: Tue, 28 Aug 2012 18:37:54 +0100 Subject: [PATCH 08/29] Merged from git.drogon.net, SPI driver helpers, C++ wrappers, softPwm, piNes, gertboard, SPI --- examples/Makefile | 25 ++- examples/delayTest.c | 68 ++++++ examples/gertboard.c | 77 +++++++ examples/gertboard.png | Bin 0 -> 4834 bytes examples/nes.c | 44 ++++ examples/softPwm.c | 69 ++++++ gpio/Makefile | 2 +- gpio/gpio.1 | 102 +++++++-- gpio/gpio.c | 450 ++++++++++++++++++++++++++++++++-------- wiringPi/gertboard.c | 122 +++++++++++ wiringPi/gertboard.h | 39 ++++ wiringPi/lcd.h | 8 + wiringPi/piNes.c | 113 ++++++++++ wiringPi/piNes.h | 45 ++++ wiringPi/softPwm.c | 130 ++++++++++++ wiringPi/softPwm.h | 34 +++ wiringPi/wiringPi.c | 441 ++++++++++++++++++++++++++------------- wiringPi/wiringPi.h | 21 +- wiringPi/wiringPiSPI.c | 117 +++++++++++ wiringPi/wiringPiSPI.h | 35 ++++ wiringPi/wiringSerial.c | 44 ++-- wiringPi/wiringSerial.h | 1 + 22 files changed, 1708 insertions(+), 279 deletions(-) create mode 100644 examples/delayTest.c create mode 100644 examples/gertboard.c create mode 100644 examples/gertboard.png create mode 100644 examples/nes.c create mode 100644 examples/softPwm.c create mode 100644 wiringPi/gertboard.c create mode 100644 wiringPi/gertboard.h create mode 100644 wiringPi/piNes.c create mode 100644 wiringPi/piNes.h create mode 100644 wiringPi/softPwm.c create mode 100644 wiringPi/softPwm.h create mode 100644 wiringPi/wiringPiSPI.c create mode 100644 wiringPi/wiringPiSPI.h diff --git a/examples/Makefile b/examples/Makefile index df00d79..450e0dc 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -35,11 +35,11 @@ LIBS = -lwiringPi # Should not alter anything below this line ############################################################################### -SRC = test1.c test2.c speed.c lcd.c wfi.c piface.c +SRC = test1.c test2.c speed.c lcd.c wfi.c piface.c gertboard.c nes.c delayTest.c softPwm.c -OBJ = test1.o test2.o speed.o lcd.o wfi.o piface.o +OBJ = test1.o test2.o speed.o lcd.o wfi.o piface.o gertboard.o nes.o delayTest.o softPwm.o -all: test1 test2 speed lcd wfi piface +all: test1 test2 speed lcd wfi piface gertboard nes softPwm test1: test1.o @echo [link] @@ -65,13 +65,30 @@ piface: piface.o @echo [link] $(CC) -o $@ piface.o $(LDFLAGS) $(LIBS) -lpthread +gertboard: gertboard.o + @echo [link] + $(CC) -o $@ gertboard.o $(LDFLAGS) $(LIBS) -lm + +nes: nes.o + @echo [link] + $(CC) -o $@ nes.o $(LDFLAGS) $(LIBS) -lm + +softPwm: softPwm.o + @echo [link] + $(CC) -o $@ softPwm.o $(LDFLAGS) $(LIBS) -lm -lpthread + + +delayTest: delayTest.o + @echo [link] + $(CC) -o $@ delayTest.o $(LDFLAGS) $(LIBS) + .c.o: @echo [CC] $< @$(CC) -c $(CFLAGS) $< -o $@ clean: - rm -f $(OBJ) *~ core tags test1 test2 speed lcd wfi piface + rm -f $(OBJ) *~ core tags test1 test2 speed lcd wfi piface gertboard nes delayTest softPwm tags: $(SRC) @echo [ctags] diff --git a/examples/delayTest.c b/examples/delayTest.c new file mode 100644 index 0000000..8c95522 --- /dev/null +++ b/examples/delayTest.c @@ -0,0 +1,68 @@ + +#include +#include +#include + +#include +#include +#include + +#define CYCLES 1000 +#define DELAY 99 + +int main() +{ + int x ; + struct timeval t1, t2 ; + long long t ; + unsigned int max, min ; + + unsigned int values [CYCLES] ; + + max = 0 ; + min = 1000000 ; + + if (wiringPiSetup () == -1) + return 1 ; + + piHiPri (10) ; + sleep (1) ; + +// Baseline test + + gettimeofday (&t1, NULL) ; + gettimeofday (&t2, NULL) ; + + t = t2.tv_usec - t1.tv_usec ; + printf ("Baseline test: %lld\n", t); + + for (x = 0 ; x < CYCLES ; ++x) + { + gettimeofday (&t1, NULL) ; + delayMicroseconds (DELAY) ; + gettimeofday (&t2, NULL) ; + + t = t2.tv_usec - t1.tv_usec ; + if (t > max) max = t ; + if (t < min) min = t ; + values [x] = t ; + } + + printf ("Done: Max: %d, min: %d\n", max, min) ; + + for (x = 0 ; x < CYCLES ; ++x) + { + printf ("%4d", values [x]) ; + if (values [x] > DELAY) + printf (".") ; + else if (values [x] < DELAY) + printf ("-") ; + else + printf (" ") ; + if (((x + 1) % 20) == 0) + printf ("\n") ; + } + printf ("\n") ; + + return 0 ; +} diff --git a/examples/gertboard.c b/examples/gertboard.c new file mode 100644 index 0000000..8f26dd4 --- /dev/null +++ b/examples/gertboard.c @@ -0,0 +1,77 @@ + +/* + * 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 + * copy this value to D/A port 1 and use a 'scope on both D/A ports + * to check all's well. + * + */ + +#include +#include +#include + +#define B_SIZE 200 +#undef DO_TIMING + +#include +#include + +int main (void) +{ + double angle ; + int i ; + uint32_t x1 ; + int buffer [B_SIZE] ; + +#ifdef DO_TIMING + unsigned int now, then ; +#endif + + printf ("Raspberry Pi Gertboard SPI test program\n") ; + + if (wiringPiSetupSys () < 0) + return -1 ; + + if (gertboardSPISetup () < 0) + return 1 ; + +// Generate a Sine Wave + + 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) ; + } + + + for (;;) + { +#ifdef DO_TIMING + then = millis () ; +#endif + + for (i = 0 ; i < B_SIZE ; ++i) + { + gertboardAnalogWrite (0, buffer [i]) ; + +#ifndef DO_TIMING + x1 = gertboardAnalogRead (0) ; + gertboardAnalogWrite (1, x1 >> 2) ; // 10-bit A/D, 8-bit D/A +#endif + } + +#ifdef DO_TIMING + now = millis () ; + printf ("%4d mS, %9.7f S/sample", now - then, ((double)(now - then) / 1000.0) / (double)B_SIZE) ; + printf (" -> %9.4f samples/sec \n", 1 / (((double)(now - then) / 1000.0) / (double)B_SIZE)) ; +#endif + } + + return 0 ; +} diff --git a/examples/gertboard.png b/examples/gertboard.png new file mode 100644 index 0000000000000000000000000000000000000000..03c5cdd63dbb163330d19400cb9d896211e86ae7 GIT binary patch literal 4834 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 IM6N<$f;V*&MF0Q* literal 0 HcmV?d00001 diff --git a/examples/nes.c b/examples/nes.c new file mode 100644 index 0000000..1a485bd --- /dev/null +++ b/examples/nes.c @@ -0,0 +1,44 @@ + +#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/softPwm.c b/examples/softPwm.c new file mode 100644 index 0000000..09b4ae0 --- /dev/null +++ b/examples/softPwm.c @@ -0,0 +1,69 @@ + +#include +#include +#include + +#include +#include + +#define RANGE 100 +#define NUM_LEDS 12 + +int ledMap [NUM_LEDS] = { 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13 } ; + +int values [NUM_LEDS] = { 0, 17, 32, 50, 67, 85, 100, 85, 67, 50, 32, 17 } ; + +int main () +{ + int i, j ; + char buf [80] ; + + if (wiringPiSetup () == -1) + { + fprintf (stdout, "oops: %s\n", strerror (errno)) ; + return 1 ; + } + + for (i = 0 ; i < NUM_LEDS ; ++i) + { + softPwmCreate (ledMap [i], 0, RANGE) ; + printf ("%3d, %3d, %3d\n", i, ledMap [i], values [i]) ; + } + + fgets (buf, 80, stdin) ; + +// Bring all up one by one: + + for (i = 0 ; i < NUM_LEDS ; ++i) + for (j = 0 ; j <= 100 ; ++j) + { + softPwmWrite (ledMap [i], j) ; + delay (10) ; + } + + fgets (buf, 80, stdin) ; + +// Down fast + + for (i = 100 ; i > 0 ; --i) + { + for (j = 0 ; j < NUM_LEDS ; ++j) + softPwmWrite (ledMap [j], i) ; + delay (10) ; + } + + fgets (buf, 80, stdin) ; + + 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/gpio/Makefile b/gpio/Makefile index c0740c9..a92dd5f 100644 --- a/gpio/Makefile +++ b/gpio/Makefile @@ -41,7 +41,7 @@ OBJ = gpio.o all: gpio -gpio: gpio.o +gpio: gpio.o /usr/local/lib/libwiringPi.a @echo [LD] @$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS) diff --git a/gpio/gpio.1 b/gpio/gpio.1 index 7da64b2..bc8e36e 100644 --- a/gpio/gpio.1 +++ b/gpio/gpio.1 @@ -4,28 +4,55 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO .SH SYNOPSIS -.TP .B gpio -.RB [ \-v ] -.TP +.B \-v +.PP .B gpio -.RB [ \-g ] -.RB < read/write/pwm/mode ...> -.TP +.B [ \-g ] +.B read/write/pwm/mode ... +.PP .B gpio -.RB [ \-p ] -.RB < read/write/mode ...> -.TP +.B [ \-p ] +.B read/write/mode +.B ... +.PP .B gpio -.RB < export/edge/unexport/unexportall/exports ...> +.B unexportall/exports +.PP +.B gpio +.B export/edge/unexport +.B ... +.PP +.B gpio +.B drive +group value +.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 command line tool to allow the user easy access to the GPIO pins -on the Raspberry Pi. 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. +is a swiss army knofe 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 +convertors 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. 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 @@ -64,6 +91,14 @@ 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. +.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 @@ -96,12 +131,41 @@ requiring root/sudo. Un-Export a GPIO pin in the /sys/class/gpio directory. .TP -.B unexportall -Un-Export all the GPIO pins in the /sys/class/gpio directory. +.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 exports -Print a list (if any) of all the exported GPIO pins and their current values. +.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 load i2c/spi +This loads the i2c or the spi drivers into the system and changes the permissions on +the associated /dev/ entries so that the current user has access to them. + +.TP +.B gbr +channel + +This reads the analog to digital convertor 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 convertor. +The board jumpers need to be in-place to do this operation. + .SH "WiringPi vs. GPIO Pin numbering" @@ -170,7 +234,7 @@ Gordon Henderson .SH "REPORTING BUGS" -Report bugs to +Report bugs to .SH COPYRIGHT diff --git a/gpio/gpio.c b/gpio/gpio.c index 8467b3e..b696542 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -1,6 +1,7 @@ /* * gpio.c: - * Set-UID command-line interface to the Raspberry Pi's GPIO + * Swiss-Army-Knife, Set-UID command-line interface to the Raspberry + * Pi's GPIO. * Copyright (c) 2012 Gordon Henderson *********************************************************************** * This file is part of wiringPi: @@ -21,7 +22,6 @@ *********************************************************************** */ -#include #include #include @@ -32,15 +32,144 @@ #include #include +#include +#include -#define VERSION "1.0" +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==2) +#endif + +#define VERSION "1.2" static int wpMode ; char *usage = "Usage: gpio -v\n" + " gpio -h\n" " gpio [-g] ...\n" " gpio [-p] ...\n" - " gpio ..." ; + " gpio export/edge/unexport/unexportall/exports ...\n" + " gpio drive \n" + " gpio pwm-bal/pwm-ms \n" + " gpio pwmr \n" + " gpio load spi/i2c\n" + " gpio gbr \n" + " gpio gbw \n" ; + + +/* + * 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) + { + if (errno == ENOENT) // Warn that it's not there + fprintf (stderr, "%s: Warning: File not present: %s\n", cmd, file) ; + else + { + fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ; + exit (1) ; + } + } +} + + +/* + * 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 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 _doLoadUsage (char *argv []) +{ + fprintf (stderr, "Usage: %s load \n", argv [0]) ; + exit (1) ; +} + +static void doLoad (int argc, char *argv []) +{ + char *module ; + char cmd [80] ; + char *file1, *file2 ; + + if (argc != 3) + _doLoadUsage (argv) ; + + /**/ if (strcasecmp (argv [2], "spi") == 0) + { + module = "spi_bcm2708" ; + file1 = "/dev/spidev0.0" ; + file2 = "/dev/spidev0.1" ; + } + else if (strcasecmp (argv [2], "i2c") == 0) + { + module = "i2c_bcm2708" ; + file1 = "/dev/i2c-0" ; + file2 = "/dev/i2c-1" ; + } + else + _doLoadUsage (argv) ; + + if (!moduleLoaded (module)) + { + sprintf (cmd, "modprobe %s", module) ; + system (cmd) ; + } + + if (!moduleLoaded (module)) + { + fprintf (stderr, "%s: Unable to load %s\n", argv [0], module) ; + exit (1) ; + } + + sleep (1) ; // To let things get settled + + changeOwner (argv [0], file1) ; + changeOwner (argv [0], file2) ; +} + /* @@ -49,7 +178,7 @@ char *usage = "Usage: gpio -v\n" ********************************************************************************* */ -void doExports (void) +static void doExports (int argc, char *argv []) { int fd ; int i, l, first ; @@ -140,8 +269,6 @@ void doExport (int argc, char *argv []) int pin ; char *mode ; char fName [128] ; - uid_t uid ; - gid_t gid ; if (argc != 4) { @@ -183,27 +310,11 @@ void doExport (int argc, char *argv []) // Change ownership so the current user can actually use it! - uid = getuid () ; - gid = getgid () ; - sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; - if (chown (fName, uid, gid) != 0) - { - fprintf (stderr, "%s: Unable to change ownership of the value file: %s\n", argv [1], strerror (errno)) ; - exit (1) ; - } - -// Also change ownership of the edge file - if it exists + changeOwner (argv [0], fName) ; sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ; - if (chown (fName, uid, gid) != 0) - { - if (errno != ENOENT) // Silently ignore File not found - older kernel - { - fprintf (stderr, "%s: Unable to change ownership of the value file: %s\n", argv [1], strerror (errno)) ; - exit (1) ; - } - } + changeOwner (argv [0], fName) ; } @@ -222,8 +333,6 @@ void doEdge (int argc, char *argv []) int pin ; char *mode ; char fName [128] ; - uid_t uid ; - gid_t gid ; if (argc != 4) { @@ -231,8 +340,7 @@ void doEdge (int argc, char *argv []) exit (1) ; } - pin = atoi (argv [2]) ; - + pin = atoi (argv [2]) ; mode = argv [3] ; // Export the pin and set direction to input @@ -263,40 +371,23 @@ void doEdge (int argc, char *argv []) 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") ; + /**/ 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 so the current user can actually use it! - - uid = getuid () ; - gid = getgid () ; +// 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) ; - if (chown (fName, uid, gid) != 0) - { - fprintf (stderr, "%s: Unable to change ownership of the value file: %s\n", argv [1], strerror (errno)) ; - exit (1) ; - } - -// Also change ownership of the edge file + changeOwner (argv [0], fName) ; sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ; - if (chown (fName, uid, gid) != 0) - { - fprintf (stderr, "%s: Unable to change ownership of the value file: %s\n", argv [1], strerror (errno)) ; - exit (1) ; - } + changeOwner (argv [0], fName) ; fclose (fd) ; } @@ -383,18 +474,12 @@ void doMode (int argc, char *argv []) mode = argv [3] ; - /**/ if (strcasecmp (mode, "in") == 0) - pinMode (pin, INPUT) ; - else if (strcasecmp (mode, "out") == 0) - pinMode (pin, OUTPUT) ; - else if (strcasecmp (mode, "pwm") == 0) - pinMode (pin, PWM_OUTPUT) ; - else if (strcasecmp (mode, "up") == 0) - pullUpDnControl (pin, PUD_UP) ; - else if (strcasecmp (mode, "down") == 0) - pullUpDnControl (pin, PUD_DOWN) ; - else if (strcasecmp (mode, "tri") == 0) - pullUpDnControl (pin, PUD_OFF) ; + /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ; + else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ; + else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ; + 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 { fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/up/down/tri\n", argv [1], mode) ; @@ -402,13 +487,125 @@ void doMode (int argc, char *argv []) } } + +/* + * 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) ; +} + + +/* + * doGbw: + * gpio gbw channel value + ********************************************************************************* + */ + +static void doGbw (int argc, char *argv []) +{ + int channel, value ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s gbr \n", argv [0]) ; + exit (1) ; + } + + channel = atoi (argv [2]) ; + value = atoi (argv [3]) ; + + if ((channel < 0) || (channel > 1)) + { + fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ; + exit (1) ; + } + + if ((value < 0) || (value > 1023)) + { + fprintf (stderr, "%s: value must be from 0 to 255\n", argv [0]) ; + exit (1) ; + } + + if (gertboardSPISetup () == -1) + { + fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ; + exit (1) ; + } + + gertboardAnalogWrite (channel, value) ; +} + + +/* + * doGbr: + * gpio gbr channel + ********************************************************************************* + */ + +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: channel must be 0 or 1\n", argv [0]) ; + exit (1) ; + } + + if (gertboardSPISetup () == -1) + { + fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ; + exit (1) ; + } + + printf ("%d\n",gertboardAnalogRead (channel)) ; +} + + + /* * doWrite: * gpio write pin value ********************************************************************************* */ -void doWrite (int argc, char *argv []) +static void doWrite (int argc, char *argv []) { int pin, val ; @@ -489,6 +686,39 @@ void doPwm (int argc, char *argv []) } +/* + * doPwmMode: doPwmRange: + * Change the PWM mode and Range 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) ; +} + + /* * main: * Start here @@ -505,10 +735,10 @@ int main (int argc, char *argv []) return 1 ; } - if (geteuid () != 0) + if (strcasecmp (argv [1], "-h") == 0) { - fprintf (stderr, "%s: Must be root to run\n", argv [0]) ; - return 1 ; + printf ("%s: %s\n", argv [0], usage) ; + return 0 ; } if (strcasecmp (argv [1], "-v") == 0) @@ -516,21 +746,54 @@ int main (int argc, char *argv []) printf ("gpio version: %s\n", VERSION) ; printf ("Copyright (c) 2012 Gordon Henderson\n") ; printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ; + printf ("For details type: %s -warranty\n", argv [0]) ; return 0 ; } + if (strcasecmp (argv [1], "-warranty") == 0) + { + printf ("gpio version: %s\n", VERSION) ; + printf ("Copyright (c) 2012 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") ; + return 0 ; + } + + if (geteuid () != 0) + { + fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ; + return 1 ; + } + // Initial test for /sys/class/gpio operations: - /**/ if (strcasecmp (argv [1], "exports" ) == 0) - { doExports () ; return 0 ; } - else if (strcasecmp (argv [1], "export" ) == 0) - { doExport (argc, argv) ; return 0 ; } - else if (strcasecmp (argv [1], "edge" ) == 0) - { doEdge (argc, argv) ; return 0 ; } - else if (strcasecmp (argv [1], "unexportall") == 0) - { doUnexportall (argc, argv) ; return 0 ; } - else if (strcasecmp (argv [1], "unexport") == 0) - { doUnexport (argc, argv) ; return 0 ; } + /**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; } + else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; } + else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; } + else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argc, argv) ; return 0 ; } + else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; } + +// Check for drive or load commands: + + if (strcasecmp (argv [1], "drive") == 0) { doPadDrive (argc, argv) ; return 0 ; } + if (strcasecmp (argv [1], "load" ) == 0) { doLoad (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 -g argument @@ -538,7 +801,7 @@ int main (int argc, char *argv []) { if (wiringPiSetupGpio () == -1) { - fprintf (stderr, "%s: Unable to initialise GPIO in GPIO mode.\n", argv [0]) ; + fprintf (stderr, "%s: Unable to initialise GPIO mode.\n", argv [0]) ; exit (1) ; } @@ -570,23 +833,30 @@ int main (int argc, char *argv []) { if (wiringPiSetup () == -1) { - fprintf (stderr, "%s: Unable to initialise GPIO in wiringPi mode\n", argv [0]) ; + fprintf (stderr, "%s: Unable to initialise wiringPi mode\n", argv [0]) ; exit (1) ; } wpMode = WPI_MODE_PINS ; } - /**/ if (strcasecmp (argv [1], "write" ) == 0) - doWrite (argc, argv) ; - else if (strcasecmp (argv [1], "read" ) == 0) - doRead (argc, argv) ; - else if (strcasecmp (argv [1], "mode" ) == 0) - doMode (argc, argv) ; - else if (strcasecmp (argv [1], "pwm" ) == 0) - doPwm (argc, argv) ; +// Check for PWM operations + + if (wpMode != WPI_MODE_PIFACE) + { + if (strcasecmp (argv [1], "pwm-bal") == 0) { doPwmMode (PWM_MODE_BAL) ; return 0 ; } + if (strcasecmp (argv [1], "pwm-ms") == 0) { doPwmMode (PWM_MODE_MS) ; return 0 ; } + if (strcasecmp (argv [1], "pwmr") == 0) { doPwmRange (argc, argv) ; return 0 ; } + } + +// Check for wiring commands + + /**/ 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], "mode" ) == 0) doMode (argc, argv) ; else { - fprintf (stderr, "%s: Unknown command: %s. (read/write/pwm/mode expected)\n", argv [0], argv [1]) ; + fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ; exit (1) ; } return 0 ; diff --git a/wiringPi/gertboard.c b/wiringPi/gertboard.c new file mode 100644 index 0000000..a8795d3 --- /dev/null +++ b/wiringPi/gertboard.c @@ -0,0 +1,122 @@ +/* + * 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 "wiringPiSPI.h" + +#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 (int chan, 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 (int chan) +{ + uint8_t spiData [2] ; + + uint8_t chanBits ; + + if (chan == 0) + chanBits = 0b11010000 ; + else + chanBits = 0b11110000 ; + + spiData [0] = chanBits ; + spiData [1] = 0 ; + + wiringPiSPIDataRW (SPI_A2D, spiData, 2) ; + + return ((spiData [0] << 7) | (spiData [1] >> 1)) & 0x3FF ; +} + + +/* + * gertboardSPISetup: + * Initialise the SPI bus, etc. + ********************************************************************************* + */ + +int gertboardSPISetup (void) +{ + if (wiringPiSPISetup (SPI_A2D, SPI_ADC_SPEED) < 0) + return -1 ; + + if (wiringPiSPISetup (SPI_D2A, SPI_DAC_SPEED) < 0) + return -1 ; + + return 0 ; +} diff --git a/wiringPi/gertboard.h b/wiringPi/gertboard.h new file mode 100644 index 0000000..98fd1e7 --- /dev/null +++ b/wiringPi/gertboard.h @@ -0,0 +1,39 @@ +/* + * 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 + +extern void gertboardAnalogWrite (int chan, int value) ; +extern int gertboardAnalogRead (int chan) ; +extern int gertboardSPISetup (void) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/lcd.h b/wiringPi/lcd.h index 094f5f5..d4c724c 100644 --- a/wiringPi/lcd.h +++ b/wiringPi/lcd.h @@ -33,5 +33,13 @@ extern void lcdPutchar (int fd, uint8_t data) ; extern void lcdPuts (int fd, char *string) ; extern void lcdPrintf (int fd, char *message, ...) ; +#ifdef __cplusplus +extern "C" { +#endif + extern int lcdInit (int rows, int cols, int bits, int rs, int strb, int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/piNes.c b/wiringPi/piNes.c new file mode 100644 index 0000000..a115050 --- /dev/null +++ b/wiringPi/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/wiringPi/piNes.h b/wiringPi/piNes.h new file mode 100644 index 0000000..897f181 --- /dev/null +++ b/wiringPi/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/wiringPi/softPwm.c b/wiringPi/softPwm.c new file mode 100644 index 0000000..b568dfb --- /dev/null +++ b/wiringPi/softPwm.c @@ -0,0 +1,130 @@ +/* + * softPwm.c: + * 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 . + *********************************************************************** + */ + +#include +#include + +#include "wiringPi.h" +#include "softPwm.h" + +#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 uS, so a pulse time +// of 100 and a range of 100 gives a period of 100 * 100 = 10,000 uS +// which is a frequency of 100Hz. +// +// It's possible to get a higher frequency by lowering the pulse time, +// however CPU uage will skyrocket as wiringPi uses a hard-loop to time +// periods under 100uS - this is because the Linux timer calls are just +// 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 int marks [MAX_PINS] ; +static int range [MAX_PINS] ; + +int newPin = -1 ; + + +/* + * softPwmThread: + * Thread to do the actual PWM output + ********************************************************************************* + */ + +static PI_THREAD (softPwmThread) +{ + int pin, mark, space ; + + pin = newPin ; + newPin = -1 ; + + piHiPri (50) ; + + 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) +{ + pin &= 63 ; + + /**/ if (value < 0) + value = 0 ; + else if (value > range [pin]) + value = range [pin] ; + + marks [pin] = value ; +} + + +/* + * softPwmCreate: + * Create a new PWM thread. + ********************************************************************************* + */ + +int softPwmCreate (int pin, int initialValue, int pwmRange) +{ + int res ; + + pinMode (pin, OUTPUT) ; + digitalWrite (pin, LOW) ; + + marks [pin] = initialValue ; + range [pin] = pwmRange ; + + newPin = pin ; + res = piThreadCreate (softPwmThread) ; + + while (newPin != -1) + delay (1) ; + + return res ; +} diff --git a/wiringPi/softPwm.h b/wiringPi/softPwm.h new file mode 100644 index 0000000..28ad299 --- /dev/null +++ b/wiringPi/softPwm.h @@ -0,0 +1,34 @@ +/* + * 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) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index d99c863..39c34da 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -71,12 +71,16 @@ // Function stubs -void (*pinMode) (int pin, int mode) ; -void (*pullUpDnControl) (int pin, int pud) ; -void (*digitalWrite) (int pin, int value) ; -void (*pwmWrite) (int pin, int value) ; -int (*digitalRead) (int pin) ; -int (*waitForInterrupt) (int pin, int mS) ; +void (*pinMode) (int pin, int mode) ; +void (*pullUpDnControl) (int pin, int pud) ; +void (*digitalWrite) (int pin, int value) ; +void (*pwmWrite) (int pin, int value) ; +void (*setPadDrive) (int group, int value) ; +int (*digitalRead) (int pin) ; +int (*waitForInterrupt) (int pin, int mS) ; +void (*delayMicroseconds) (unsigned int howLong) ; +void (*pwmSetMode) (int mode) ; +void (*pwmSetRange) (unsigned int range) ; #ifndef TRUE @@ -84,6 +88,11 @@ int (*waitForInterrupt) (int pin, int mS) ; #define FALSE (1==2) #endif +// BCM Magic + +#define BCM_PASSWORD 0x5A000000 + + // Port function select bits #define FSEL_INPT 0b000 @@ -100,10 +109,11 @@ int (*waitForInterrupt) (int pin, int mS) ; // Take from Gert/Doms code. Some of this is not in the manual // that I can find )-: -#define BCM2708_PERI_BASE 0x20000000 +#define BCM2708_PERI_BASE 0x20000000 #define GPIO_PADS (BCM2708_PERI_BASE + 0x100000) #define CLOCK_BASE (BCM2708_PERI_BASE + 0x101000) #define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) +#define GPIO_TIMER (BCM2708_PERI_BASE + 0x00B000) #define GPIO_PWM (BCM2708_PERI_BASE + 0x20C000) #define PAGE_SIZE (4*1024) @@ -137,12 +147,27 @@ int (*waitForInterrupt) (int pin, int mS) ; #define PWM0_SERIAL 0x0002 // Run in serial mode #define PWM0_ENABLE 0x0001 // Channel Enable +// Timer + +#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 uint32_t *gpio ; static volatile uint32_t *pwm ; static volatile uint32_t *clk ; +static volatile uint32_t *pads ; +static volatile uint32_t *timer ; + +static volatile uint32_t *timerIrqRaw ; // The BCM2835 has 54 GPIO pins. // BCM2835 data sheet, Page 90 onwards. @@ -273,6 +298,8 @@ static uint8_t gpioToFEN [] = // gpioToPUDCLK // (Word) offset to the Pull Up Down Clock regsiter +#define GPPUD 37 + 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, @@ -352,30 +379,42 @@ void pinModeGpio (int pin, int mode) if (!pwmRunning) { + *(pwm + PWM_CONTROL) = 0 ; // Stop PWM + delayMicroseconds (10) ; + // Gert/Doms Values - *(clk + PWMCLK_DIV) = 0x5A000000 | (32<<12) ; // set pwm div to 32 (19.2/3 = 600KHz) - *(clk + PWMCLK_CNTL) = 0x5A000011 ; // Source=osc and enable - digitalWrite (pin, LOW) ; - *(pwm + PWM_CONTROL) = 0 ; // Disable PWM - delayMicroseconds (10) ; - *(pwm + PWM0_RANGE) = 0x400 ; - delayMicroseconds (10) ; - *(pwm + PWM1_RANGE) = 0x400 ; + *(clk + PWMCLK_DIV) = BCM_PASSWORD | (32<<12) ; // set pwm div to 32 (19.2/32 = 600KHz) + *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Source=osc and enable + delayMicroseconds (10) ; + *(pwm + PWM0_RANGE) = 0x400 ; delayMicroseconds (10) ; + *(pwm + PWM1_RANGE) = 0x400 ; delayMicroseconds (10) ; + // Enable PWMs *(pwm + PWM0_DATA) = 512 ; *(pwm + PWM1_DATA) = 512 ; +// Balanced mode (default) + *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ; + + pwmRunning = TRUE ; } } // When we change mode of any pin, we remove the pull up/downs +// Or we used to... Hm. Commented out now because for some wieird reason, +// it seems to block subsequent attempts to set the pull up/downs and I've +// not quite gotten to the bottom of why this happens +// The down-side is that the pull up/downs are rememberd in the SoC between +// power cycles, so it's going to be a good idea to explicitly set them in +// any new code. +// +// pullUpDnControl (pin, PUD_OFF) ; - pullUpDnControl (pin, PUD_OFF) ; } void pinModeWPi (int pin, int mode) @@ -389,6 +428,38 @@ void pinModeSys (int pin, int mode) } +/* + * pwmControl: + * Allow the user to control some of the PWM functions + ********************************************************************************* + */ + +void pwmSetModeWPi (int mode) +{ + if (mode == PWM_MODE_MS) + *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ; + else + *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ; +} + +void pwmSetModeSys (int mode) +{ + return ; +} + + +void pwmSetRangeWPi (unsigned int range) +{ + *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ; + *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ; +} + +void pwmSetRangeSys (unsigned int range) +{ + return ; +} + + #ifdef notYetReady /* * pinED01: @@ -414,12 +485,12 @@ void pinEnableED01Pi (int pin) void digitalWriteWPi (int pin, int value) { - int gpioPin = pinToGpio [pin & 63] ; + pin = pinToGpio [pin & 63] ; if (value == LOW) - *(gpio + gpioToGPCLR [gpioPin]) = 1 << gpioPin ; + *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ; else - *(gpio + gpioToGPSET [gpioPin]) = 1 << gpioPin ; + *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ; } void digitalWriteGpio (int pin, int value) @@ -427,9 +498,9 @@ void digitalWriteGpio (int pin, int value) pin &= 63 ; if (value == LOW) - *(gpio + gpioToGPCLR [pin]) = 1 << pin ; + *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ; else - *(gpio + gpioToGPSET [pin]) = 1 << pin ; + *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ; } void digitalWriteSys (int pin, int value) @@ -452,28 +523,55 @@ void digitalWriteSys (int pin, int value) ********************************************************************************* */ -void pwmWriteWPi (int pin, int value) -{ - int port, gpioPin ; - - gpioPin = pinToGpio [pin & 63] ; - port = gpioToPwmPort [gpioPin] ; - - *(pwm + port) = value & 0x3FF ; -} - void pwmWriteGpio (int pin, int value) { - int port, gpioPin ; + int port ; - gpioPin = pin & 63 ; - port = gpioToPwmPort [gpioPin] ; + pin = pin & 63 ; + port = gpioToPwmPort [pin] ; - *(pwm + port) = value & 0x3FF ; + *(pwm + port) = value ; +} + +void pwmWriteWPi (int pin, int value) +{ + pwmWriteGpio (pinToGpio [pin & 63], value) ; +} + +void pwmWriteSys (int pin, int value) +{ + return ; } -void pwmWriteSys (int pin, int value) +/* + * setPadDrive: + * Set the PAD driver value + ********************************************************************************* + */ + +void setPadDriveWPi (int group, int value) +{ + uint32_t wrVal ; + + if ((group < 0) || (group > 2)) + return ; + + wrVal = BCM_PASSWORD | 0x18 | (value & 7) ; + *(pads + group + 11) = wrVal ; + +#ifdef DEBUG_PADS + printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ; + printf ("Read : %08X\n", *(pads + group + 11)) ; +#endif +} + +void setPadDriveGpio (int group, int value) +{ + setPadDriveWPi (group, value) ; +} + +void setPadDriveSys (int group, int value) { return ; } @@ -487,13 +585,9 @@ void pwmWriteSys (int pin, int value) int digitalReadWPi (int pin) { - int gpioPin ; + pin = pinToGpio [pin & 63] ; - pin &= 63 ; - - gpioPin = pinToGpio [pin] ; - - if ((*(gpio + gpioToGPLEV [gpioPin]) & (1 << gpioPin)) != 0) + if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0) return HIGH ; else return LOW ; @@ -503,7 +597,7 @@ int digitalReadGpio (int pin) { pin &= 63 ; - if ((*(gpio + gpioToGPLEV [pin]) & (1 << pin)) != 0) + if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0) return HIGH ; else return LOW ; @@ -533,30 +627,21 @@ int digitalReadSys (int pin) ********************************************************************************* */ -void pullUpDnControlWPi (int pin, int pud) -{ - pin = pinToGpio [pin & 63] ; - - *(gpio + 37) = pud ; - delayMicroseconds (10) ; - *(gpio + gpioToPUDCLK [pin]) = 1 << pin ; - delayMicroseconds (10) ; - - *(gpio + 37) = 0 ; - *(gpio + gpioToPUDCLK [pin]) = 0 ; -} - void pullUpDnControlGpio (int pin, int pud) { pin &= 63 ; + pud &= 3 ; - *(gpio + 37) = pud ; - delayMicroseconds (10) ; - *(gpio + gpioToPUDCLK [pin]) = 1 << pin ; - delayMicroseconds (10) ; + *(gpio + GPPUD) = pud ; delayMicroseconds (5) ; + *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ; - *(gpio + 37) = 0 ; - *(gpio + gpioToPUDCLK [pin]) = 0 ; + *(gpio + GPPUD) = 0 ; delayMicroseconds (5) ; + *(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ; +} + +void pullUpDnControlWPi (int pin, int pud) +{ + pullUpDnControlGpio (pinToGpio [pin & 63], pud) ; } void pullUpDnControlSys (int pin, int pud) @@ -615,6 +700,94 @@ int waitForInterruptGpio (int pin, int mS) + +/* + * delay: + * Wait for some number of milli seconds + ********************************************************************************* + */ + +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 )-: + ********************************************************************************* + */ + +void delayMicrosecondsSys (unsigned int howLong) +{ + struct timespec sleeper, dummy ; + + sleeper.tv_sec = 0 ; + sleeper.tv_nsec = (long)(howLong * 1000) ; + + nanosleep (&sleeper, &dummy) ; +} + +void delayMicrosecondsHard (unsigned int howLong) +{ + *(timer + TIMER_LOAD) = howLong ; + *(timer + TIMER_IRQ_CLR) = 0 ; + + while (*timerIrqRaw == 0) + ; +} + +void delayMicrosecondsWPi (unsigned int howLong) +{ + struct timespec sleeper, dummy ; + + /**/ if (howLong == 0) + return ; + else if (howLong < 100) + delayMicrosecondsHard (howLong) ; + else + { + sleeper.tv_sec = 0 ; + sleeper.tv_nsec = (long)(howLong * 1000) ; + nanosleep (&sleeper, &dummy) ; + } +} + + +/* + * millis: + * Return a number of milliseconds as an unsigned int. + ********************************************************************************* + */ + +unsigned int millis (void) +{ + struct timeval tv ; + unsigned long long t1 ; + + gettimeofday (&tv, NULL) ; + + t1 = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ; + + return (uint32_t)(t1 - epoch) ; +} + + /* * wiringPiSetup: * Must be called once at the start of your program execution. @@ -627,20 +800,19 @@ int waitForInterruptGpio (int pin, int mS) int wiringPiSetup (void) { int fd ; - uint8_t *gpioMem, *pwmMem, *clkMem ; + uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ; struct timeval tv ; -#ifdef DEBUG_PADS - uint8_t *gpioMem, *padsMem, *pwmMem, *clkMem ; - uint32_t *pads ; -#endif - - pinMode = pinModeWPi ; - pullUpDnControl = pullUpDnControlWPi ; - digitalWrite = digitalWriteWPi ; - pwmWrite = pwmWriteWPi ; - digitalRead = digitalReadWPi ; - waitForInterrupt = waitForInterruptWPi ; + pinMode = pinModeWPi ; + pullUpDnControl = pullUpDnControlWPi ; + digitalWrite = digitalWriteWPi ; + pwmWrite = pwmWriteWPi ; + setPadDrive = setPadDriveWPi ; + digitalRead = digitalReadWPi ; + waitForInterrupt = waitForInterruptWPi ; + delayMicroseconds = delayMicrosecondsWPi ; + pwmSetMode = pwmSetModeWPi ; + pwmSetRange = pwmSetRangeWPi ; // Open the master /dev/memory device @@ -711,7 +883,8 @@ int wiringPiSetup (void) return -1 ; } -#ifdef DEBUG_PADS +// The drive pads + if ((padsMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) { fprintf (stderr, "wiringPiSetup: padsMem malloc failed: %s\n", strerror (errno)) ; @@ -728,14 +901,41 @@ int wiringPiSetup (void) fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ; return -1 ; } - - printf ("Checking pads @ 0x%08X\n", (unsigned int)pads) ; - printf ("%08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ; -// *(pads + 11) = 0x1F ; - printf ("%08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ; +#ifdef DEBUG_PADS + printf ("Checking pads @ 0x%08X\n", (unsigned int)pads) ; + printf (" -> %08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ; #endif +// The system timer + + if ((timerMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) + { + fprintf (stderr, "wiringPiSetup: timerMem malloc failed: %s\n", strerror (errno)) ; + return -1 ; + } + + if (((uint32_t)timerMem % PAGE_SIZE) != 0) + timerMem += PAGE_SIZE - ((uint32_t)timerMem % PAGE_SIZE) ; + + timer = (uint32_t *)mmap(timerMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_TIMER) ; + + if ((int32_t)timer < 0) + { + fprintf (stderr, "wiringPiSetup: mmap failed (timer): %s\n", strerror (errno)) ; + return -1 ; + } + +// 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 ; + +// Initialise our epoch for millis() + gettimeofday (&tv, NULL) ; epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ; @@ -759,12 +959,16 @@ int wiringPiSetupGpio (void) if (x != 0) return x ; - pinMode = pinModeGpio ; - pullUpDnControl = pullUpDnControlGpio ; - digitalWrite = digitalWriteGpio ; - pwmWrite = pwmWriteGpio ; - digitalRead = digitalReadGpio ; - waitForInterrupt = waitForInterruptGpio ; + pinMode = pinModeGpio ; + pullUpDnControl = pullUpDnControlGpio ; + digitalWrite = digitalWriteGpio ; + pwmWrite = pwmWriteGpio ; + setPadDrive = setPadDriveGpio ; + digitalRead = digitalReadGpio ; + waitForInterrupt = waitForInterruptGpio ; + delayMicroseconds = delayMicrosecondsWPi ; // Same + pwmSetMode = pwmSetModeWPi ; + pwmSetRange = pwmSetRangeWPi ; return 0 ; } @@ -785,12 +989,17 @@ int wiringPiSetupSys (void) struct timeval tv ; char fName [128] ; - pinMode = pinModeSys ; - pullUpDnControl = pullUpDnControlSys ; - digitalWrite = digitalWriteSys ; - pwmWrite = pwmWriteSys ; - digitalRead = digitalReadSys ; - waitForInterrupt = waitForInterruptSys ; + pinMode = pinModeSys ; + pullUpDnControl = pullUpDnControlSys ; + digitalWrite = digitalWriteSys ; + pwmWrite = pwmWriteSys ; + setPadDrive = setPadDriveSys ; + digitalRead = digitalReadSys ; + waitForInterrupt = waitForInterruptSys ; + delayMicroseconds = delayMicrosecondsSys ; + pwmSetMode = pwmSetModeSys ; + pwmSetRange = pwmSetRangeSys ; + // Open and scan the directory, looking for exported GPIOs, and pre-open // the 'value' interface to speed things up for later @@ -808,51 +1017,3 @@ int wiringPiSetupSys (void) return 0 ; } - - - - - -/* - * delay: delayMicroseconds - * Wait for some number of milli/micro seconds - ********************************************************************************* - */ - -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) ; -} - -void delayMicroseconds (unsigned int howLong) -{ - struct timespec sleeper, dummy ; - - sleeper.tv_sec = 0 ; - sleeper.tv_nsec = (long)(howLong * 1000) ; - - nanosleep (&sleeper, &dummy) ; -} - -/* - * millis: - * Return a number of milliseconds as an unsigned int. - ********************************************************************************* - */ - -unsigned int millis (void) -{ - struct timeval tv ; - unsigned long long t1 ; - - gettimeofday (&tv, NULL) ; - - t1 = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ; - - return (uint32_t)(t1 - epoch) ; -} diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index a81511a..1d21fa0 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -41,6 +41,12 @@ #define PUD_DOWN 1 #define PUD_UP 2 +// PWM + +#define PWM_MODE_MS 0 +#define PWM_MODE_BAL 1 + + // Function prototypes // c++ wrappers thanks to a commend by Nick Lott // (and others on the Raspberry Pi forums) @@ -58,11 +64,15 @@ extern int wiringPiSetupPiFace (void) ; extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only -extern void (*pinMode) (int pin, int mode) ; -extern void (*pullUpDnControl) (int pin, int pud) ; -extern void (*digitalWrite) (int pin, int value) ; -extern void (*pwmWrite) (int pin, int value) ; -extern int (*digitalRead) (int pin) ; +extern void (*pinMode) (int pin, int mode) ; +extern void (*pullUpDnControl) (int pin, int pud) ; +extern void (*digitalWrite) (int pin, int value) ; +extern void (*pwmWrite) (int pin, int value) ; +extern void (*setPadDrive) (int group, int value) ; +extern int (*digitalRead) (int pin) ; +extern void (*delayMicroseconds) (unsigned int howLong) ; +extern void (*pwmSetMode) (int mode) ; +extern void (*pwmSetRange) (unsigned int range) ; // Interrupts @@ -84,7 +94,6 @@ extern int piHiPri (int pri) ; // Extras from arduino land extern void delay (unsigned int howLong) ; -extern void delayMicroseconds (unsigned int howLong) ; extern unsigned int millis (void) ; #ifdef __cplusplus diff --git a/wiringPi/wiringPiSPI.c b/wiringPi/wiringPiSPI.c new file mode 100644 index 0000000..f2e3000 --- /dev/null +++ b/wiringPi/wiringPiSPI.c @@ -0,0 +1,117 @@ +/* + * wiringPiSPI.c: + * Simplified SPI access routines + * 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 "wiringPiSPI.h" + + +// The SPI bus parameters +// Variables as they need to be passed as pointers later on + +static char *spiDev0 = "/dev/spidev0.0" ; +static char *spiDev1 = "/dev/spidev0.1" ; +static uint8_t spiMode = 0 ; +static uint8_t spiBPW = 8 ; +static uint16_t spiDelay = 0; + +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 ; + + 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) ; +} + + +/* + * wiringPiSPISetup: + * Open the SPI device, and set it up, etc. + ********************************************************************************* + */ + +int wiringPiSPISetup (int channel, int speed) +{ + int fd ; + + channel &= 1 ; + + if ((fd = open (channel == 0 ? spiDev0 : spiDev1, O_RDWR)) < 0) + return -1 ; + + spiSpeeds [channel] = speed ; + spiFds [channel] = fd ; + +// Set SPI parameters. +// Why are we reading it afterwriting it? I've no idea, but for now I'm blindly +// copying example code I've seen online... + + if (ioctl (fd, SPI_IOC_WR_MODE, &spiMode) < 0) return -1 ; + if (ioctl (fd, SPI_IOC_RD_MODE, &spiMode) < 0) return -1 ; + + if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0) return -1 ; + if (ioctl (fd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0) return -1 ; + + if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) return -1 ; + if (ioctl (fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) return -1 ; + + return fd ; +} diff --git a/wiringPi/wiringPiSPI.h b/wiringPi/wiringPiSPI.h new file mode 100644 index 0000000..f53697d --- /dev/null +++ b/wiringPi/wiringPiSPI.h @@ -0,0 +1,35 @@ +/* + * wiringPiSPI.h: + * Simplified SPI access routines + * 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 + +int wiringPiSPIGetFd (int channel) ; +int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ; +int wiringPiSPISetup (int channel, int speed) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/wiringSerial.c b/wiringPi/wiringSerial.c index c3dae67..28ec598 100644 --- a/wiringPi/wiringSerial.c +++ b/wiringPi/wiringSerial.c @@ -20,8 +20,6 @@ *********************************************************************** */ -#undef DEBUG - #include #include #include @@ -49,10 +47,6 @@ int serialOpen (char *device, int baud) speed_t myBaud ; int status, fd ; -#ifdef DEBUG - printf ("openSerialPort: <%s> baud: $d\n", device, baud) ; -#endif - switch (baud) { case 50: myBaud = B50 ; break ; @@ -86,22 +80,22 @@ int serialOpen (char *device, int baud) tcgetattr (fd, &options) ; - cfmakeraw (&options) ; - cfsetispeed (&options, myBaud) ; - cfsetospeed (&options, myBaud) ; + 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_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) + options.c_cc [VMIN] = 0 ; + options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds) - tcsetattr (fd, TCSANOW, &options) ; + tcsetattr (fd, TCSANOW | TCSAFLUSH, &options) ; ioctl (fd, TIOCMGET, &status); @@ -116,6 +110,18 @@ int serialOpen (char *device, int baud) } +/* + * serialFlush: + * Flush the serial buffers (both tx & rx) + ********************************************************************************* + */ + +void serialFlush (int fd) +{ + tcflush (fd, TCIOFLUSH) ; +} + + /* * serialClose: * Release the serial port diff --git a/wiringPi/wiringSerial.h b/wiringPi/wiringSerial.h index 609838d..1a4198c 100644 --- a/wiringPi/wiringSerial.h +++ b/wiringPi/wiringSerial.h @@ -26,6 +26,7 @@ extern "C" { extern int serialOpen (char *device, int baud) ; extern void serialClose (int fd) ; +extern void serialFlush (int fd) ; extern void serialPutchar (int fd, unsigned char c) ; extern void serialPuts (int fd, char *s) ; extern void serialPrintf (int fd, char *message, ...) ; From 8b30932c8bf00277b69aed277040959d9a2e18bf Mon Sep 17 00:00:00 2001 From: Tom Wardill Date: Thu, 20 Sep 2012 22:21:06 +0200 Subject: [PATCH 09/29] Update wiringPi/piNes.c Use other style import, for successful local build. --- wiringPi/piNes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiringPi/piNes.c b/wiringPi/piNes.c index a115050..5c32798 100644 --- a/wiringPi/piNes.c +++ b/wiringPi/piNes.c @@ -22,7 +22,7 @@ *********************************************************************** */ -#include +#include ""wiringPi.h"" #include "piNes.h" From a6513231393c70cf7d9b6dc3c3df6f22aa0bba4c Mon Sep 17 00:00:00 2001 From: Gordon Henderson Date: Tue, 23 Oct 2012 21:15:08 +0100 Subject: [PATCH 10/29] Latest changes from master repository --- People | 10 ++ examples/Makefile | 8 +- examples/README.TXT | 14 +++ gpio/Makefile | 37 +++--- gpio/gpio.1 | 79 ++++++++----- gpio/gpio.c | 119 ++++++++++++++++--- gpio/test.sh | 21 ++++ wiringPi/Makefile | 97 ++++++++++----- wiringPi/README | 4 +- wiringPi/lcd.c | 5 +- wiringPi/lcd.h | 8 +- wiringPi/wiringPi.c | 279 ++++++++++++++++++++++++++++++++++++++------ wiringPi/wiringPi.h | 4 + 13 files changed, 548 insertions(+), 137 deletions(-) create mode 100644 People create mode 100644 examples/README.TXT diff --git a/People b/People new file mode 100644 index 0000000..2c5fa92 --- /dev/null +++ b/People @@ -0,0 +1,10 @@ + +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 + diff --git a/examples/Makefile b/examples/Makefile index 450e0dc..16bf7e2 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -39,7 +39,12 @@ SRC = test1.c test2.c speed.c lcd.c wfi.c piface.c gertboard.c nes.c delayTest.c OBJ = test1.o test2.o speed.o lcd.o wfi.o piface.o gertboard.o nes.o delayTest.o softPwm.o -all: test1 test2 speed lcd wfi piface gertboard nes softPwm +BINS = test1 test2 speed lcd wfi piface gertboard nes delayTest softPwm + +all: + @cat README.TXT + @echo " $(BINS)" | fmt + @echo "" test1: test1.o @echo [link] @@ -77,7 +82,6 @@ softPwm: softPwm.o @echo [link] $(CC) -o $@ softPwm.o $(LDFLAGS) $(LIBS) -lm -lpthread - delayTest: delayTest.o @echo [link] $(CC) -o $@ delayTest.o $(LDFLAGS) $(LIBS) diff --git a/examples/README.TXT b/examples/README.TXT new file mode 100644 index 0000000..2bf6f1e --- /dev/null +++ b/examples/README.TXT @@ -0,0 +1,14 @@ + +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 + +Where exampleName is one of: + diff --git a/gpio/Makefile b/gpio/Makefile index a92dd5f..5693c44 100644 --- a/gpio/Makefile +++ b/gpio/Makefile @@ -24,7 +24,7 @@ #DEBUG = -g -O0 -DEBUG = -O3 +DEBUG = -O2 CC = gcc INCLUDE = -I/usr/local/include CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe @@ -32,42 +32,49 @@ CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe LDFLAGS = -L/usr/local/lib LIBS = -lwiringPi -# Should not alter anything below this line +# May not need to alter anything below this line ############################################################################### SRC = gpio.c -OBJ = gpio.o +OBJ = $(SRC:.c=.o) all: gpio -gpio: gpio.o /usr/local/lib/libwiringPi.a - @echo [LD] +gpio: gpio.o + @echo [Link] @$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS) .c.o: - @echo [CC] $< + @echo [Compile] $< @$(CC) -c $(CFLAGS) $< -o $@ +.PHONEY: clean clean: - rm -f $(OBJ) gpio *~ core tags + rm -f $(OBJ) gpio *~ core tags *.bak +.PHONEY: tags tags: $(SRC) @echo [ctags] @ctags $(SRC) -depend: - makedepend -Y $(SRC) - +.PHONEY: install install: - cp gpio /usr/local/bin - chown root.root /usr/local/bin/gpio - chmod 4755 /usr/local/bin/gpio - mkdir -p /usr/local/man/man1 - cp gpio.1 /usr/local/man/man1 + @echo "[Install]" + @cp gpio /usr/local/bin + @chown root.root /usr/local/bin/gpio + @chmod 4755 /usr/local/bin/gpio + @mkdir -p /usr/local/man/man1 + @cp gpio.1 /usr/local/man/man1 +.PHONEY: uninstall uninstall: + @echo "[UnInstall]" rm -f /usr/local/bin/gpio rm -f /usr/local/man/man1/gpio.1 +.PHONEY: depend +depend: + makedepend -Y $(SRC) + # DO NOT DELETE diff --git a/gpio/gpio.1 b/gpio/gpio.1 index bc8e36e..be38791 100644 --- a/gpio/gpio.1 +++ b/gpio/gpio.1 @@ -1,4 +1,4 @@ -.TH "GPIO" "14 June 2012" "Command-Line access to Raspberry Pi and PiFace GPIO" +.TH "GPIO" "21st October 2012" "Command-Line access to Raspberry Pi and PiFace GPIO" .SH NAME gpio \- Command-line access to Raspberry Pi and PiFace GPIO @@ -17,6 +17,9 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO .B ... .PP .B gpio +.B readall +.PP +.B gpio .B unexportall/exports .PP .B gpio @@ -48,9 +51,9 @@ channel value .SH DESCRIPTION .B GPIO -is a swiss army knofe of a command line tool to allow the user easy +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 -convertors on the Gertboard. It's designed for simple testing and +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. @@ -62,7 +65,7 @@ interface without needing to be run as root. .TP .B \-v -Output the current version +Output the current version including the board revision of the Raspberry Pi. .TP .B \-g @@ -73,20 +76,26 @@ Use the BCM_GPIO pins numbers rather than wiringPi pin numbers. Use the PiFace interface board and its corresponding pin numbers. .TP -.B read +.B read Read the digital value of the given pin and print 0 or 1 to represent the respective logic levels. .TP -.B write +.B write Write the given value (0 or 1) to the pin. .TP -.B pwm +.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. + +.TP +.B pwm Write a PWM value (0-1023) to the given pin. .TP -.B mode +.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. @@ -122,7 +131,7 @@ the direction to input and set the edge interrupt method to \fInone\fR, above and note that \fBBCM_GPIO\fR pin number is used not not wiringPi pin numbering. -Like the export commands abovem ownership is set to that of the +Like the export commands above, ownership is set to that of the calling user, allowing subsequent access from user programs without requiring root/sudo. @@ -155,7 +164,7 @@ the associated /dev/ entries so that the current user has access to them. .B gbr channel -This reads the analog to digital convertor on the Gertboard on the given +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 @@ -163,7 +172,7 @@ channel. The board jumpers need to be in-place to do this operation. channel value This writes the supplied value to the output channel on the Gertboards -SPI digital to analogue convertor. +SPI digital to analogue converter. The board jumpers need to be in-place to do this operation. @@ -171,26 +180,30 @@ The board jumpers need to be in-place to do this operation. .PP .TS -r r l. -WiringPi GPIO Function +r r r l. +WiringPi GPIO-r1 GPIO-r2 Function _ -0 17 -1 18 (PWM) -2 21 -3 22 -4 23 -5 24 -6 25 -7 4 -8 0 SDA0 -9 1 SCL0 -10 8 SPI CE0 -11 7 SPI CE1 -12 10 SPI MOSI -13 9 SPI MISO -14 11 SPI SCLK -15 14 TxD -16 15 RxD +0 17 17 +1 18 18 (PWM) +2 21 27 +3 22 22 +4 23 23 +5 24 24 +6 25 25 +7 4 4 +8 0 2 I2C: SDA0 +9 1 3 I2C: SCL0 +10 8 8 SPI: CE0 +11 7 7 SPI: CE1 +12 10 10 SPI: MOSI +13 9 9 SPI: MISO +14 11 11 SPI: SCLK +15 14 14 TxD +16 15 16 RxD +17 - 28 +18 - 29 +19 - 30 +20 - 31 .TE .SH FILES @@ -234,10 +247,14 @@ Gordon Henderson .SH "REPORTING BUGS" -Report bugs to +Please report bugs to .SH COPYRIGHT Copyright (c) 2012 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. diff --git a/gpio/gpio.c b/gpio/gpio.c index b696542..f019c1f 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -40,7 +40,7 @@ # define FALSE (1==2) #endif -#define VERSION "1.2" +#define VERSION "1.4" static int wpMode ; @@ -48,13 +48,16 @@ char *usage = "Usage: gpio -v\n" " gpio -h\n" " gpio [-g] ...\n" " gpio [-p] ...\n" - " gpio export/edge/unexport/unexportall/exports ...\n" + " gpio readall\n" + " gpio unexportall/exports ...\n" + " gpio export/edge/unexport ...\n" " gpio drive \n" " gpio pwm-bal/pwm-ms \n" " gpio pwmr \n" + " gpio pwmc \n" " gpio load spi/i2c\n" " gpio gbr \n" - " gpio gbw \n" ; + " gpio gbw " ; // No trailing newline needed here. /* @@ -171,6 +174,65 @@ static void doLoad (int argc, char *argv []) } +/* + * doReadall: + * Read all the GPIO pins + ********************************************************************************* + */ + +static char *pinNames [] = +{ + "GPIO 0", + "GPIO 1", + "GPIO 2", + "GPIO 3", + "GPIO 4", + "GPIO 5", + "GPIO 6", + "GPIO 7", + "SDA ", + "SCL ", + "CE0 ", + "CE1 ", + "MOSI ", + "MISO ", + "SCLK ", + "TxD ", + "RxD ", + "GPIO 8", + "GPIO 9", + "GPIO10", + "GPIO11", +} ; + +static void doReadall (void) +{ + int pin ; + + printf ("+----------+------+--------+-------+\n") ; + printf ("| wiringPi | GPIO | Name | Value |\n") ; + printf ("+----------+------+--------+-------+\n") ; + + for (pin = 0 ; pin < NUM_PINS ; ++pin) + printf ("| %6d | %3d | %s | %s |\n", + pin, wpiPinToGpio (pin), + pinNames [pin], + digitalRead (pin) == HIGH ? "High" : "Low ") ; + + printf ("+----------+------+--------+-------+\n") ; + + if (piBoardRev () == 1) + return ; + + for (pin = 17 ; pin <= 20 ; ++pin) + printf ("| %6d | %3d | %s | %s |\n", + pin, wpiPinToGpio (pin), + pinNames [pin], + digitalRead (pin) == HIGH ? "High" : "Low ") ; + + printf ("+----------+------+--------+-------+\n") ; +} + /* * doExports: @@ -687,8 +749,8 @@ void doPwm (int argc, char *argv []) /* - * doPwmMode: doPwmRange: - * Change the PWM mode and Range values + * doPwmMode: doPwmRange: doPwmClock: + * Change the PWM mode, range and clock divider values ********************************************************************************* */ @@ -718,6 +780,27 @@ static void doPwmRange (int argc, char *argv []) 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) ; +} + /* * main: @@ -731,7 +814,7 @@ int main (int argc, char *argv []) if (argc == 1) { - fprintf (stderr, "%s: %s\n", argv [0], usage) ; + fprintf (stderr, "%s\n", usage) ; return 1 ; } @@ -747,6 +830,8 @@ int main (int argc, char *argv []) printf ("Copyright (c) 2012 Gordon Henderson\n") ; printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ; printf ("For details type: %s -warranty\n", argv [0]) ; + printf ("\n") ; + printf ("This Raspberry Pi is a revision %d board.\n", piBoardRev ()) ; return 0 ; } @@ -785,9 +870,8 @@ int main (int argc, char *argv []) else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argc, argv) ; return 0 ; } else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; } -// Check for drive or load commands: +// Check for load command: - if (strcasecmp (argv [1], "drive") == 0) { doPadDrive (argc, argv) ; return 0 ; } if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; } // Gertboard commands @@ -839,21 +923,24 @@ int main (int argc, char *argv []) wpMode = WPI_MODE_PINS ; } -// Check for PWM operations +// Check for PWM or Pad Drive operations if (wpMode != WPI_MODE_PIFACE) { - if (strcasecmp (argv [1], "pwm-bal") == 0) { doPwmMode (PWM_MODE_BAL) ; return 0 ; } - if (strcasecmp (argv [1], "pwm-ms") == 0) { doPwmMode (PWM_MODE_MS) ; return 0 ; } - if (strcasecmp (argv [1], "pwmr") == 0) { doPwmRange (argc, argv) ; return 0 ; } + if (strcasecmp (argv [1], "pwm-bal") == 0) { doPwmMode (PWM_MODE_BAL) ; return 0 ; } + if (strcasecmp (argv [1], "pwm-ms") == 0) { doPwmMode (PWM_MODE_MS) ; return 0 ; } + if (strcasecmp (argv [1], "pwmr") == 0) { doPwmRange (argc, argv) ; return 0 ; } + if (strcasecmp (argv [1], "pwmc") == 0) { doPwmClock (argc, argv) ; return 0 ; } + if (strcasecmp (argv [1], "drive") == 0) { doPadDrive (argc, argv) ; return 0 ; } } // Check for wiring commands - /**/ 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], "mode" ) == 0) doMode (argc, argv) ; + /**/ if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ; + else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ; + else if (strcasecmp (argv [1], "write") == 0) doWrite (argc, argv) ; + else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ; + else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ; else { fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ; diff --git a/gpio/test.sh b/gpio/test.sh index 7127528..a7c2bb2 100755 --- a/gpio/test.sh +++ b/gpio/test.sh @@ -1,4 +1,25 @@ #!/bin/bash +# +# test.sh: +# Simple test: Assumes LEDs on Pins 0-7 and lights them +# in-turn. +################################################################################# +# 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 . +################################################################################# # Simple test - assumes LEDs on Pins 0-7. diff --git a/wiringPi/Makefile b/wiringPi/Makefile index 3c23e96..c0a39f9 100644 --- a/wiringPi/Makefile +++ b/wiringPi/Makefile @@ -21,71 +21,104 @@ # along with wiringPi. If not, see . ################################################################################# +DYN_VERS_MAJ=1 +DYN_VERS_MIN=0 -TARGET=libwiringPi.a +STATIC=libwiringPi.a +DYNAMIC=libwiringPi.so.$(DYN_VERS_MAJ).$(DYN_VERS_MIN) #DEBUG = -g -O0 -DEBUG = -O3 +DEBUG = -O2 CC = gcc INCLUDE = -I. -CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe +CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe -fPIC LIBS = # Should not alter anything below this line ############################################################################### -SRC = wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c lcd.c piHiPri.c piThread.c +SRC = wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c \ + gertboard.c \ + piNes.c \ + lcd.c piHiPri.c piThread.c softPwm.c wiringPiSPI.c -OBJ = wiringPi.o wiringPiFace.o wiringSerial.o wiringShift.o lcd.o piHiPri.o piThread.o +OBJ = $(SRC:.c=.o) -all: $(TARGET) +#all: $(STATIC) $(DYNAMIC) +all: $(DYNAMIC) -$(TARGET): $(OBJ) - @echo [AR] $(OBJ) - @ar rcs $(TARGET) $(OBJ) - @ranlib $(TARGET) - @size $(TARGET) +$(STATIC): $(OBJ) + @echo [Link (Static)] + @ar rcs $(STATIC) $(OBJ) + @ranlib $(STATIC) + @size $(STATIC) + +$(DYNAMIC): $(OBJ) + @echo [Link] + @$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ) .c.o: - @echo [CC] $< + @echo [Compile] $< @$(CC) -c $(CFLAGS) $< -o $@ +.PHONEY: clean clean: - rm -f $(OBJ) $(TARGET) *~ core tags Makefile.bak + rm -f $(OBJ) *~ core tags Makefile.bak libwiringPi.* +.PHONEY: tags tags: $(SRC) @echo [ctags] @ctags $(SRC) +.PHONEY: install +install: $(TARGET) + @echo "[Install]" + @install -m 0755 -d /usr/local/lib + @install -m 0755 -d /usr/local/include + @install -m 0644 wiringPi.h /usr/local/include + @install -m 0644 wiringSerial.h /usr/local/include + @install -m 0644 wiringShift.h /usr/local/include + @install -m 0644 gertboard.h /usr/local/include + @install -m 0644 piNes.h /usr/local/include + @install -m 0644 softPwm.h /usr/local/include + @install -m 0644 lcd.h /usr/local/include + @install -m 0644 wiringPiSPI.h /usr/local/include +# @install -m 0644 libwiringPi.a /usr/local/lib + @install -m 0755 libwiringPi.so.1.0 /usr/local/lib + @ln -sf /usr/local/lib/libwiringPi.so.1.0 /usr/local/lib/libwiringPi.so + @ln -sf /usr/local/lib/libwiringPi.so.1.0 /usr/local/lib/libwiringPi.so.1 + @ldconfig + +.PHONEY: uninstall +uninstall: + @echo "[UnInstall]" + @rm -f /usr/local/include/wiringPi.h + @rm -f /usr/local/include/wiringSerial.h + @rm -f /usr/local/include/wiringShift.h + @rm -f /usr/local/include/gertboard.h + @rm -f /usr/local/include/piNes.h + @rm -f /usr/local/include/softPwm.h + @rm -f /usr/local/include/lcd.h + @rm -f /usr/local/include/wiringPiSPI.h + @rm -f /usr/local/lib/libwiringPi.* + @ldconfig + + +.PHONEY: depend depend: makedepend -Y $(SRC) -install: $(TARGET) - @echo [install] - install -m 0755 -d /usr/local/lib - install -m 0755 -d /usr/local/include - install -m 0644 wiringPi.h /usr/local/include - install -m 0644 wiringSerial.h /usr/local/include - install -m 0644 wiringShift.h /usr/local/include - install -m 0644 lcd.h /usr/local/include - install -m 0644 libwiringPi.a /usr/local/lib - -uninstall: - @echo [uninstall] - rm -f /usr/local/include/lcd.h - rm -f /usr/local/include/wiringShift.h - rm -f /usr/local/include/wiringPi.h - rm -f /usr/local/lib/libwiringPi.a - - - # DO NOT DELETE wiringPi.o: wiringPi.h wiringPiFace.o: wiringPi.h wiringSerial.o: wiringSerial.h wiringShift.o: wiringPi.h wiringShift.h +gertboard.o: wiringPiSPI.h gertboard.h +piNes.o: wiringPi.h piNes.h lcd.o: wiringPi.h lcd.h piHiPri.o: wiringPi.h piThread.o: wiringPi.h +softPwm.o: wiringPi.h softPwm.h +wiringPiSPI.o: wiringPiSPI.h diff --git a/wiringPi/README b/wiringPi/README index 781510a..c79754e 100644 --- a/wiringPi/README +++ b/wiringPi/README @@ -1,6 +1,8 @@ WiringPi: An implementation of most of the Arduino Wiring - functions for the Raspberry Pi + functions for the Raspberry Pi, + along with many more features and libraries to support + hardware, etc. on the Raspberry Pi Full details at: https://projects.drogon.net/raspberry-pi/wiringpi/ diff --git a/wiringPi/lcd.c b/wiringPi/lcd.c index 6826a60..aa58cab 100644 --- a/wiringPi/lcd.c +++ b/wiringPi/lcd.c @@ -75,7 +75,10 @@ struct lcdDataStruct *lcds [MAX_LCDS] ; static void strobe (struct lcdDataStruct *lcd) { - digitalWrite (lcd->strbPin, 1) ; delayMicroseconds (1) ; + +// Note timing changes for new version of delayMicroseconds () + + digitalWrite (lcd->strbPin, 1) ; delayMicroseconds (50) ; digitalWrite (lcd->strbPin, 0) ; delayMicroseconds (50) ; } diff --git a/wiringPi/lcd.h b/wiringPi/lcd.h index d4c724c..ecd1d25 100644 --- a/wiringPi/lcd.h +++ b/wiringPi/lcd.h @@ -26,6 +26,10 @@ #define MAX_LCDS 8 +#ifdef __cplusplus +extern "C" { +#endif + extern void lcdHome (int fd) ; extern void lcdClear (int fd) ; extern void lcdPosition (int fd, int x, int y) ; @@ -33,10 +37,6 @@ extern void lcdPutchar (int fd, uint8_t data) ; extern void lcdPuts (int fd, char *string) ; extern void lcdPrintf (int fd, char *message, ...) ; -#ifdef __cplusplus -extern "C" { -#endif - extern int lcdInit (int rows, int cols, int bits, int rs, int strb, int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ; diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 39c34da..9fe3ab1 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -2,6 +2,7 @@ * wiringPi: * Arduino compatable (ish) Wiring library for the Raspberry Pi * Copyright (c) 2012 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 @@ -56,6 +57,8 @@ #include #include +#include +#include #include #include #include @@ -81,6 +84,7 @@ int (*waitForInterrupt) (int pin, int mS) ; void (*delayMicroseconds) (unsigned int howLong) ; void (*pwmSetMode) (int mode) ; void (*pwmSetRange) (unsigned int range) ; +void (*pwmSetClock) (int divisor) ; #ifndef TRUE @@ -166,9 +170,12 @@ static volatile uint32_t *pwm ; static volatile uint32_t *clk ; static volatile uint32_t *pads ; static volatile uint32_t *timer ; - static volatile uint32_t *timerIrqRaw ; +// Debugging + +static int wiringPiDebug = FALSE ; + // The BCM2835 has 54 GPIO pins. // BCM2835 data sheet, Page 90 onwards. // There are 6 control registers, each control the functions of a block @@ -198,8 +205,11 @@ static int sysFds [64] ; // pinToGpio: // Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin +// Cope for 2 different board revieions here -static int pinToGpio [64] = +static int *pinToGpio ; + +static int pinToGpioR1 [64] = { 17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7 0, 1, // I2C - SDA0, SCL0 @@ -209,11 +219,28 @@ static int pinToGpio [64] = // 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, // ... 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 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, // New GPIOs 8 though 11 wpi 17 - 20 + +// Padding: + + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 31 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 +} ; + + // gpioToGPFSEL: // Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5) @@ -227,6 +254,7 @@ static uint8_t gpioToGPFSEL [] = 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 @@ -239,6 +267,7 @@ static uint8_t gpioToShift [] = 0,3,6,9,12,15,18,21,24,27, } ; + // gpioToGPSET: // (Word) offset to the GPIO Set registers for each GPIO pin @@ -248,6 +277,7 @@ static uint8_t gpioToGPSET [] = 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, } ; + // gpioToGPCLR: // (Word) offset to the GPIO Clear registers for each GPIO pin @@ -257,6 +287,7 @@ static uint8_t gpioToGPCLR [] = 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 @@ -266,6 +297,7 @@ static uint8_t gpioToGPLEV [] = 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 @@ -295,6 +327,7 @@ static uint8_t gpioToFEN [] = } ; #endif + // gpioToPUDCLK // (Word) offset to the Pull Up Down Clock regsiter @@ -306,6 +339,7 @@ static uint8_t gpioToPUDCLK [] = 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 @@ -339,7 +373,122 @@ static uint8_t gpioToPwmPort [] = static unsigned long long epoch ; -////////////////////////////////////////////////////////////////////////////////// +/* + * Functions + ********************************************************************************* + */ + + +/* + * wpiPinToGpio: + * Translate a wiringPi Pin number to native GPIO pin number. + * (We don't use this here, prefering to just do the lookup directly, + * but it's been requested!) + ********************************************************************************* + */ + +int wpiPinToGpio (int wpiPin) +{ + return pinToGpio [wpiPin & 63] ; +} + + +/* + * piBoardRev: + * Return a number representing the hardware revision of the board. + * Revision is currently 1 or 2. -1 is returned on error. + * + * Much confusion here )-: + * Seems there ar esome boards with 0000 in them (mistake in manufacture) + * and some board with 0005 in them (another mistake in manufacture). + * So the distinction between boards that I can see is: + * 0000 - Error + * 0001 - Not used + * 0002 - Rev 1 + * 0003 - Rev 1 + * 0004 - Rev 2 + * 0005 - Rev 2 + * 0006 - Rev 2 + * 000f - Rev 2 + 512MB + * + * A small thorn is the olde style overvolting - that will add in + * 1000000 + * + ********************************************************************************* + */ + +int piBoardRev (void) +{ + FILE *cpuFd ; + char line [120] ; + char *c, lastChar ; + static int boardRev = -1 ; + +// No point checking twice... + + if (boardRev != -1) + return boardRev ; + + if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL) + return -1 ; + + while (fgets (line, 120, cpuFd) != NULL) + if (strncmp (line, "Revision", 8) == 0) + break ; + + fclose (cpuFd) ; + + if (line == NULL) + { + fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ; + fprintf (stderr, " (No \"Revision\" line)\n") ; + errno = 0 ; + return -1 ; + } + + for (c = line ; *c ; ++c) + if (isdigit (*c)) + break ; + + if (!isdigit (*c)) + { + fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ; + fprintf (stderr, " (No numeric revision string in: \"%s\"\n", line) ; + errno = 0 ; + return -1 ; + } + +// If you have overvolted the Pi, then it appears that the revision +// has 100000 added to it! + + if (wiringPiDebug) + if (strlen (c) != 4) + printf ("piboardRev: This Pi has/is overvolted!\n") ; + + lastChar = c [strlen (c) - 2] ; + + /**/ if ((lastChar == '2') || (lastChar == '3')) + boardRev = 1 ; + else + boardRev = 2 ; + +#ifdef DO_WE_CARE_ABOUT_THIS_NOW + else + { + fprintf (stderr, "WARNING: wiringPi: Unable to determine board revision from \"%d\"\n", r) ; + fprintf (stderr, " -> You may want to check:\n") ; + fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ; + fprintf (stderr, " -> Assuming a Rev 1 board\n") ; + boardRev = 1 ; + } +#endif + + if (wiringPiDebug) + printf ("piboardRev: Revision string: %s, board revision: %d\n", c, boardRev) ; + + return boardRev ; +} + /* @@ -350,7 +499,6 @@ static unsigned long long epoch ; void pinModeGpio (int pin, int mode) { - static int pwmRunning = FALSE ; int fSel, shift, alt ; pin &= 63 ; @@ -371,38 +519,28 @@ void pinModeGpio (int pin, int mode) *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; -// We didn't initialise the PWM hardware at setup time - because it's possible that -// something else is using the PWM - e.g. the Audio systems! So if we use PWM -// here, then we're assuming that nothing else is, otherwise things are going -// to sound a bit funny... +// Page 107 of the BCM Peripherals manual talks about the GPIO clocks, +// but I'm assuming (hoping!) that this applies to other clocks too. - if (!pwmRunning) - { + *(pwm + PWM_CONTROL) = 0 ; // Stop PWM + *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock + delayMicroseconds (110) ; // See comments in pwmSetClockWPi - *(pwm + PWM_CONTROL) = 0 ; // Stop PWM - delayMicroseconds (10) ; - -// Gert/Doms Values - *(clk + PWMCLK_DIV) = BCM_PASSWORD | (32<<12) ; // set pwm div to 32 (19.2/32 = 600KHz) - *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Source=osc and enable + (void)*(pwm + PWM_CONTROL) ; + while ((*(pwm + PWM_CONTROL) & 0x80) != 0) // Wait for clock to be !BUSY + delayMicroseconds (1) ; - delayMicroseconds (10) ; + *(clk + PWMCLK_DIV) = BCM_PASSWORD | (32 << 12) ; // set pwm div to 32 (19.2/32 = 600KHz) + *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // enable clk - *(pwm + PWM0_RANGE) = 0x400 ; delayMicroseconds (10) ; - *(pwm + PWM1_RANGE) = 0x400 ; delayMicroseconds (10) ; +// Default range regsiter of 1024 -// Enable PWMs + *(pwm + PWM0_DATA) = 0 ; *(pwm + PWM0_RANGE) = 1024 ; + *(pwm + PWM1_DATA) = 0 ; *(pwm + PWM1_RANGE) = 1024 ; - *(pwm + PWM0_DATA) = 512 ; - *(pwm + PWM1_DATA) = 512 ; - -// Balanced mode (default) - - *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ; - - pwmRunning = TRUE ; - } +// Enable PWMs in balanced mode (default) + *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ; } // When we change mode of any pin, we remove the pull up/downs @@ -459,6 +597,55 @@ void pwmSetRangeSys (unsigned int range) return ; } +/* + * pwmSetClockWPi: + * Set/Change the PWM clock. Originally my code, but changed + * (for the better!) by Chris Hall, + * after further study of the manual and testing with a 'scope + ********************************************************************************* + */ + +void pwmSetClockWPi (int divisor) +{ + unsigned int pwm_control ; + divisor &= 4095 ; + + if (wiringPiDebug) + printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ; + + pwm_control = *(pwm + PWM_CONTROL) ; // preserve PWM_CONTROL + +// We need to stop PWM prior to stopping PWM clock in MS mode otherwise BUSY +// stays high. + + *(pwm + PWM_CONTROL) = 0 ; // Stop PWM + +// Stop PWM clock before changing divisor. The delay after this does need to +// this big (95uS occasionally fails, 100uS OK), it's almost as though the BUSY +// flag is not working properly in balanced mode. Without the delay when DIV is +// adjusted the clock sometimes switches to very slow, once slow further DIV +// adjustments do nothing and it's difficult to get out of this mode. + + *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock + delayMicroseconds (110) ; // prevents clock going sloooow + + while ((*(pwm + PWM_CONTROL) & 0x80) != 0) // Wait for clock to be !BUSY + delayMicroseconds (1) ; + + *(clk + PWMCLK_DIV) = BCM_PASSWORD | (divisor << 12) ; + + *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Start PWM clock + *(pwm + PWM_CONTROL) = pwm_control ; // restore PWM_CONTROL + + if (wiringPiDebug) + printf ("Set to: %d. Now : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ; +} + +void pwmSetClockSys (int divisor) +{ + return ; +} + #ifdef notYetReady /* @@ -518,7 +705,7 @@ void digitalWriteSys (int pin, int value) /* - * pwnWrite: + * pwmWrite: * Set an output PWM value ********************************************************************************* */ @@ -699,8 +886,6 @@ int waitForInterruptGpio (int pin, int mS) } - - /* * delay: * Wait for some number of milli seconds @@ -800,9 +985,16 @@ unsigned int millis (void) int wiringPiSetup (void) { int fd ; + int boardRev ; uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ; struct timeval tv ; + if (getenv ("WIRINGPI_DEBUG") != NULL) + wiringPiDebug = TRUE ; + + if (wiringPiDebug) + printf ("wiringPi: wiringPiSetup called\n") ; + pinMode = pinModeWPi ; pullUpDnControl = pullUpDnControlWPi ; digitalWrite = digitalWriteWPi ; @@ -813,7 +1005,16 @@ int wiringPiSetup (void) delayMicroseconds = delayMicrosecondsWPi ; pwmSetMode = pwmSetModeWPi ; pwmSetRange = pwmSetRangeWPi ; + pwmSetClock = pwmSetClockWPi ; + if ((boardRev = piBoardRev ()) < 0) + return -1 ; + + if (boardRev == 1) + pinToGpio = pinToGpioR1 ; + else + pinToGpio = pinToGpioR2 ; + // Open the master /dev/memory device if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0) @@ -954,9 +1155,12 @@ int wiringPiSetup (void) int wiringPiSetupGpio (void) { - int x = wiringPiSetup () ; + int x ; - if (x != 0) + if (wiringPiDebug) + printf ("wiringPi: wiringPiSetupGpio called\n") ; + + if ((x = wiringPiSetup ()) < 0) return x ; pinMode = pinModeGpio ; @@ -969,6 +1173,7 @@ int wiringPiSetupGpio (void) delayMicroseconds = delayMicrosecondsWPi ; // Same pwmSetMode = pwmSetModeWPi ; pwmSetRange = pwmSetRangeWPi ; + pwmSetClock = pwmSetClockWPi ; return 0 ; } @@ -989,6 +1194,9 @@ int wiringPiSetupSys (void) struct timeval tv ; char fName [128] ; + if (wiringPiDebug) + printf ("wiringPi: wiringPiSetupSys called\n") ; + pinMode = pinModeSys ; pullUpDnControl = pullUpDnControlSys ; digitalWrite = digitalWriteSys ; @@ -999,6 +1207,7 @@ int wiringPiSetupSys (void) delayMicroseconds = delayMicrosecondsSys ; pwmSetMode = pwmSetModeSys ; pwmSetRange = pwmSetRangeSys ; + pwmSetClock = pwmSetClockSys ; // Open and scan the directory, looking for exported GPIOs, and pre-open diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 1d21fa0..cab3080 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -62,6 +62,9 @@ extern int wiringPiSetupSys (void) ; extern int wiringPiSetupGpio (void) ; extern int wiringPiSetupPiFace (void) ; +extern int piBoardRev (void) ; +extern int wpiPinToGpio (int wpiPin) ; + extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only extern void (*pinMode) (int pin, int mode) ; @@ -73,6 +76,7 @@ extern int (*digitalRead) (int pin) ; extern void (*delayMicroseconds) (unsigned int howLong) ; extern void (*pwmSetMode) (int mode) ; extern void (*pwmSetRange) (unsigned int range) ; +extern void (*pwmSetClock) (int divisor) ; // Interrupts From 89bbe97856407979fa75c4c793fabf4db839a0ee Mon Sep 17 00:00:00 2001 From: Steven Osborn Date: Tue, 30 Oct 2012 01:18:21 -0700 Subject: [PATCH 11/29] Update wiringPi/piNes.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix double-double quote issue.  Fixes https://github.com/WiringPi/WiringPi/issues/4 --- wiringPi/piNes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiringPi/piNes.c b/wiringPi/piNes.c index 5c32798..3b54d76 100644 --- a/wiringPi/piNes.c +++ b/wiringPi/piNes.c @@ -22,7 +22,7 @@ *********************************************************************** */ -#include ""wiringPi.h"" +#include "wiringPi.h" #include "piNes.h" From dda3305ce14a750e7529ff20b0acf9e53bd8eb7a Mon Sep 17 00:00:00 2001 From: Gordon Drogon Date: Tue, 11 Dec 2012 20:59:52 +0000 Subject: [PATCH 12/29] Updated with latest changes --- People | 5 + build | 44 +++ examples/Makefile | 51 ++- examples/delayTest.c | 87 +++-- examples/okLed.c | 65 ++++ examples/{softPwm.c => pwm.c} | 0 examples/serialRead.c | 31 ++ examples/servo.c | 33 ++ examples/test1 | Bin 9835 -> 0 bytes examples/test2 | Bin 9646 -> 0 bytes examples/tone.c | 37 ++ gpio/COPYING | 674 ---------------------------------- gpio/gpio.1 | 13 +- gpio/gpio.c | 69 +++- wiringPi/Makefile | 69 ++-- wiringPi/piNes.c | 2 +- wiringPi/softServo.c | 202 ++++++++++ wiringPi/softServo.h | 35 ++ wiringPi/softTone.c | 119 ++++++ wiringPi/softTone.h | 38 ++ wiringPi/wiringPi.c | 117 +++++- wiringPi/wiringPi.h | 1 + wiringPi/wiringPiFace.c | 27 +- wiringPi/wiringPiSPI.c | 2 +- 24 files changed, 919 insertions(+), 802 deletions(-) create mode 100755 build create mode 100644 examples/okLed.c rename examples/{softPwm.c => pwm.c} (100%) create mode 100644 examples/serialRead.c create mode 100644 examples/servo.c delete mode 100755 examples/test1 delete mode 100755 examples/test2 create mode 100644 examples/tone.c delete mode 100644 gpio/COPYING create mode 100644 wiringPi/softServo.c create mode 100644 wiringPi/softServo.h create mode 100644 wiringPi/softTone.c create mode 100644 wiringPi/softTone.h diff --git a/People b/People index 2c5fa92..e0c262c 100644 --- a/People +++ b/People @@ -8,3 +8,8 @@ Nick Lott: (And others) 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. diff --git a/build b/build new file mode 100755 index 0000000..740b512 --- /dev/null +++ b/build @@ -0,0 +1,44 @@ +#!/bin/bash + +if [ x$1 = "xclean" ]; then + echo Cleaning + echo + cd wiringPi + make clean + cd ../gpio + make clean + cd ../examples + make clean + cd .. +elif [ x$1 = "xuninstall" ]; then + echo Uninstalling + echo + echo "WiringPi library" + cd wiringPi + sudo make uninstall + echo + echo "GPIO Utility" + cd ../gpio + sudo make uninstall + cd .. +else + echo wiringPi Build script - please wait... + echo + echo "WiringPi library" + cd wiringPi + make + sudo make install + echo + echo "GPIO Utility" + cd ../gpio + make + sudo make install + echo + echo "Examples" + cd ../examples + make + cd .. +fi + +echo +echo All Done. diff --git a/examples/Makefile b/examples/Makefile index 16bf7e2..738d36c 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -30,16 +30,19 @@ INCLUDE = -I/usr/local/include CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe LDFLAGS = -L/usr/local/lib -LIBS = -lwiringPi +LDLIBS = -lwiringPi # Should not alter anything below this line ############################################################################### -SRC = test1.c test2.c speed.c lcd.c wfi.c piface.c gertboard.c nes.c delayTest.c softPwm.c +SRC = test1.c test2.c speed.c lcd.c wfi.c \ + piface.c gertboard.c nes.c \ + pwm.c tone.c servo.c \ + delayTest.c serialRead.c okLed.c -OBJ = test1.o test2.o speed.o lcd.o wfi.o piface.o gertboard.o nes.o delayTest.o softPwm.o +OBJ = $(SRC:.c=.o) -BINS = test1 test2 speed lcd wfi piface gertboard nes delayTest softPwm +BINS = $(SRC:.c=) all: @cat README.TXT @@ -48,43 +51,59 @@ all: test1: test1.o @echo [link] - $(CC) -o $@ test1.o $(LDFLAGS) $(LIBS) + @$(CC) -o $@ test1.o $(LDFLAGS) $(LDLIBS) test2: test2.o @echo [link] - $(CC) -o $@ test2.o $(LDFLAGS) $(LIBS) + @$(CC) -o $@ test2.o $(LDFLAGS) $(LDLIBS) speed: speed.o @echo [link] - $(CC) -o $@ speed.o $(LDFLAGS) $(LIBS) + @$(CC) -o $@ speed.o $(LDFLAGS) $(LDLIBS) lcd: lcd.o @echo [link] - $(CC) -o $@ lcd.o $(LDFLAGS) $(LIBS) + @$(CC) -o $@ lcd.o $(LDFLAGS) $(LDLIBS) wfi: wfi.o @echo [link] - $(CC) -o $@ wfi.o $(LDFLAGS) $(LIBS) -lpthread + @$(CC) -o $@ wfi.o $(LDFLAGS) $(LDLIBS) piface: piface.o @echo [link] - $(CC) -o $@ piface.o $(LDFLAGS) $(LIBS) -lpthread + @$(CC) -o $@ piface.o $(LDFLAGS) $(LDLIBS) -lpthread gertboard: gertboard.o @echo [link] - $(CC) -o $@ gertboard.o $(LDFLAGS) $(LIBS) -lm + @$(CC) -o $@ gertboard.o $(LDFLAGS) $(LDLIBS) -lm nes: nes.o @echo [link] - $(CC) -o $@ nes.o $(LDFLAGS) $(LIBS) -lm + @$(CC) -o $@ nes.o $(LDFLAGS) $(LDLIBS) -lm -softPwm: softPwm.o +pwm: pwm.o @echo [link] - $(CC) -o $@ softPwm.o $(LDFLAGS) $(LIBS) -lm -lpthread + @$(CC) -o $@ pwm.o $(LDFLAGS) $(LDLIBS) -lm -lpthread delayTest: delayTest.o @echo [link] - $(CC) -o $@ delayTest.o $(LDFLAGS) $(LIBS) + @$(CC) -o $@ delayTest.o $(LDFLAGS) $(LDLIBS) + +serialRead: serialRead.o + @echo [link] + @$(CC) -o $@ serialRead.o $(LDFLAGS) $(LDLIBS) + +okLed: okLed.o + @echo [link] + @$(CC) -o $@ okLed.o $(LDFLAGS) $(LDLIBS) + +tone: tone.o + @echo [link] + @$(CC) -o $@ tone.o $(LDFLAGS) $(LDLIBS) + +servo: servo.o + @echo [link] + @$(CC) -o $@ servo.o $(LDFLAGS) $(LDLIBS) .c.o: @@ -92,7 +111,7 @@ delayTest: delayTest.o @$(CC) -c $(CFLAGS) $< -o $@ clean: - rm -f $(OBJ) *~ core tags test1 test2 speed lcd wfi piface gertboard nes delayTest softPwm + rm -f $(OBJ) *~ core tags $(BINS) tags: $(SRC) @echo [ctags] diff --git a/examples/delayTest.c b/examples/delayTest.c index 8c95522..d05f3ff 100644 --- a/examples/delayTest.c +++ b/examples/delayTest.c @@ -3,30 +3,24 @@ #include #include -#include -#include #include #define CYCLES 1000 -#define DELAY 99 int main() { int x ; struct timeval t1, t2 ; - long long t ; - unsigned int max, min ; - - unsigned int values [CYCLES] ; - - max = 0 ; - min = 1000000 ; + int t ; + int max, min ; + int del ; + int underRuns, overRuns, exactRuns, total ; + int descheds ; if (wiringPiSetup () == -1) return 1 ; - piHiPri (10) ; - sleep (1) ; + piHiPri (10) ; sleep (1) ; // Baseline test @@ -34,35 +28,56 @@ int main() gettimeofday (&t2, NULL) ; t = t2.tv_usec - t1.tv_usec ; - printf ("Baseline test: %lld\n", t); + printf ("Baseline test: %d\n", t); - for (x = 0 ; x < CYCLES ; ++x) + for (del = 1 ; del < 200 ; ++del) { - gettimeofday (&t1, NULL) ; - delayMicroseconds (DELAY) ; - gettimeofday (&t2, NULL) ; - - t = t2.tv_usec - t1.tv_usec ; - if (t > max) max = t ; - if (t < min) min = t ; - values [x] = t ; - } + underRuns = overRuns = exactRuns = total = 0 ; + descheds = 0 ; + max = del ; + min = del ; - printf ("Done: Max: %d, min: %d\n", max, min) ; + 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) ; + delayMicroseconds (del) ; + gettimeofday (&t2, NULL) ; - for (x = 0 ; x < CYCLES ; ++x) - { - printf ("%4d", values [x]) ; - if (values [x] > DELAY) - printf (".") ; - else if (values [x] < DELAY) - printf ("-") ; - else - printf (" ") ; - if (((x + 1) % 20) == 0) - printf ("\n") ; + if (t2.tv_usec < t1.tv_usec) // Counter wrapped + t = (1000000 + t2.tv_usec) - t1.tv_usec; + else + t = t2.tv_usec - t1.tv_usec ; + if (t > 999) + { + ++descheds ; + continue ; + } + else + break ; + } + + if (t > max) + { + max = t ; + ++overRuns ; + } + else if (t < min) + { + min = t ; + ++underRuns ; + } + else + ++exactRuns ; + + 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) ; + delay (1) ; } - printf ("\n") ; return 0 ; } diff --git a/examples/okLed.c b/examples/okLed.c new file mode 100644 index 0000000..3bf21e2 --- /dev/null +++ b/examples/okLed.c @@ -0,0 +1,65 @@ +/* + * okLed: + * Make the OK LED on the Pi Pulsate... + * Copyright (c) 2012 gordon Henderson, but please Share and Enjoy! + * + * 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 & + * + */ + +#include +#include +#include +#include +#include + +#include +#include + +#define OK_LED 16 + +int main () +{ + int fd, i ; + + if ((fd = open ("/sys/class/leds/led0/trigger", O_RDWR)) < 0) + { + fprintf (stderr, "Unable to change LED trigger: %s\n", strerror (errno)) ; + return 1 ; + } + + write (fd, "none\n", 5) ; + close (fd) ; + + if (wiringPiSetupGpio () < 0) + { + fprintf (stderr, "Unable to setup GPIO: %s\n", strerror (errno)) ; + return 1 ; + } + + softPwmCreate (OK_LED, 0, 100) ; + + for (;;) + { + 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/softPwm.c b/examples/pwm.c similarity index 100% rename from examples/softPwm.c rename to examples/pwm.c diff --git a/examples/serialRead.c b/examples/serialRead.c new file mode 100644 index 0000000..34b9bad --- /dev/null +++ b/examples/serialRead.c @@ -0,0 +1,31 @@ + +/* + * serialRead.c: + * Example program to read bytes from the Serial line + * + */ + +#include +#include +#include + +#include + +int main () +{ + int fd ; + + if ((fd = serialOpen ("/dev/ttyAMA0", 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/servo.c b/examples/servo.c new file mode 100644 index 0000000..0237832 --- /dev/null +++ b/examples/servo.c @@ -0,0 +1,33 @@ + +#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/test1 b/examples/test1 deleted file mode 100755 index dfa08c8eb9d43394b2eaa3f315ef515b27abb4e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9835 zcmbtaeQ;FQb-!xSR|uQ0Ngn~XxQ&(-QCyp$se~jx903C4k9ufUEA0XsuXZ=P zD-4Zl>kH!8P|QaI

Y3Qv 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 diff --git a/examples/tone.c b/examples/tone.c new file mode 100644 index 0000000..8b1fcd7 --- /dev/null +++ b/examples/tone.c @@ -0,0 +1,37 @@ + +#include +#include +#include + +#include +#include + +#define RANGE 100 +#define NUM_LEDS 12 + +int scale [8] = { 262, 294, 330, 349, 392, 440, 494, 525 } ; + +int main () +{ + int i, j ; + char buf [80] ; + + if (wiringPiSetup () == -1) + { + fprintf (stdout, "oops: %s\n", strerror (errno)) ; + return 1 ; + } + + softToneCreate (3) ; + + for (;;) + { + for (i = 0 ; i < 8 ; ++i) + { + printf ("%3d\n", i) ; + softToneWrite (3, scale [i]) ; + delay (500) ; + } + } + +} diff --git a/gpio/COPYING b/gpio/COPYING deleted file mode 100644 index 94a9ed0..0000000 --- a/gpio/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU 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. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU 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 -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/gpio/gpio.1 b/gpio/gpio.1 index be38791..c39e5dc 100644 --- a/gpio/gpio.1 +++ b/gpio/gpio.1 @@ -9,11 +9,11 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO .PP .B gpio .B [ \-g ] -.B read/write/pwm/mode ... +.B read/write/wb/pwm/mode ... .PP .B gpio .B [ \-p ] -.B read/write/mode +.B read/write/wb .B ... .PP .B gpio @@ -82,7 +82,14 @@ respective logic levels. .TP .B write -Write the given value (0 or 1) to the pin. +Write the given value (0 or 1) to the pin. You need to set the pin +to output mode first. + +.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 diff --git a/gpio/gpio.c b/gpio/gpio.c index f019c1f..52fcb6f 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -40,14 +40,14 @@ # define FALSE (1==2) #endif -#define VERSION "1.4" +#define VERSION "1.5" static int wpMode ; char *usage = "Usage: gpio -v\n" " gpio -h\n" - " gpio [-g] ...\n" - " gpio [-p] ...\n" + " gpio [-g] ...\n" + " gpio [-p] ...\n" " gpio readall\n" " gpio unexportall/exports ...\n" " gpio export/edge/unexport ...\n" @@ -133,7 +133,7 @@ static void _doLoadUsage (char *argv []) static void doLoad (int argc, char *argv []) { - char *module ; + char *module1, *module2 ; char cmd [80] ; char *file1, *file2 ; @@ -142,28 +142,36 @@ static void doLoad (int argc, char *argv []) /**/ if (strcasecmp (argv [2], "spi") == 0) { - module = "spi_bcm2708" ; + module1 = "spidev" ; + module2 = "spi_bcm2708" ; file1 = "/dev/spidev0.0" ; file2 = "/dev/spidev0.1" ; } else if (strcasecmp (argv [2], "i2c") == 0) { - module = "i2c_bcm2708" ; + module1 = "i2c_dev" ; + module2 = "i2c_bcm2708" ; file1 = "/dev/i2c-0" ; file2 = "/dev/i2c-1" ; } else _doLoadUsage (argv) ; - if (!moduleLoaded (module)) + if (!moduleLoaded (module1)) { - sprintf (cmd, "modprobe %s", module) ; + sprintf (cmd, "modprobe %s", module1) ; system (cmd) ; } - if (!moduleLoaded (module)) + if (!moduleLoaded (module2)) { - fprintf (stderr, "%s: Unable to load %s\n", argv [0], module) ; + sprintf (cmd, "modprobe %s", module2) ; + system (cmd) ; + } + + if (!moduleLoaded (module2)) + { + fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ; exit (1) ; } @@ -588,6 +596,7 @@ static void doPadDrive (int argc, char *argv []) /* * doGbw: * gpio gbw channel value + * Gertboard Write - To the Analog output ********************************************************************************* */ @@ -629,6 +638,7 @@ static void doGbw (int argc, char *argv []) /* * doGbr: * gpio gbr channel + * From the analog input ********************************************************************************* */ @@ -682,7 +692,12 @@ static void doWrite (int argc, char *argv []) if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) return ; - val = atoi (argv [3]) ; + /**/ 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) ; @@ -690,6 +705,27 @@ static void doWrite (int argc, char *argv []) digitalWrite (pin, HIGH) ; } +/* + * doWriteByte: + * gpio write 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) ; +} + /* * doRead: @@ -936,11 +972,12 @@ int main (int argc, char *argv []) // Check for wiring commands - /**/ if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ; - else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ; - else if (strcasecmp (argv [1], "write") == 0) doWrite (argc, argv) ; - else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ; - else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ; + /**/ if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ; + else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ; + else if (strcasecmp (argv [1], "write") == 0) doWrite (argc, argv) ; + else if (strcasecmp (argv [1], "wb") == 0) doWriteByte (argc, argv) ; + else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ; + else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ; else { fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ; diff --git a/wiringPi/Makefile b/wiringPi/Makefile index c0a39f9..e18a654 100644 --- a/wiringPi/Makefile +++ b/wiringPi/Makefile @@ -24,8 +24,12 @@ DYN_VERS_MAJ=1 DYN_VERS_MIN=0 +VERSION=$(DYN_VERS_MAJ).$(DYN_VERS_MIN) +DESTDIR=/usr +PREFIX=/local + STATIC=libwiringPi.a -DYNAMIC=libwiringPi.so.$(DYN_VERS_MAJ).$(DYN_VERS_MIN) +DYNAMIC=libwiringPi.so.$(VERSION) #DEBUG = -g -O0 DEBUG = -O2 @@ -41,21 +45,22 @@ LIBS = SRC = wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c \ gertboard.c \ piNes.c \ - lcd.c piHiPri.c piThread.c softPwm.c wiringPiSPI.c + lcd.c piHiPri.c piThread.c wiringPiSPI.c \ + softPwm.c softServo.c softTone.c OBJ = $(SRC:.c=.o) -#all: $(STATIC) $(DYNAMIC) -all: $(DYNAMIC) +all: $(STATIC) $(DYNAMIC) +#all: $(DYNAMIC) $(STATIC): $(OBJ) - @echo [Link (Static)] + @echo "[Link (Static)]" @ar rcs $(STATIC) $(OBJ) @ranlib $(STATIC) - @size $(STATIC) +# @size $(STATIC) $(DYNAMIC): $(OBJ) - @echo [Link] + @echo "[Link (Dynamic)]" @$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ) .c.o: @@ -74,34 +79,38 @@ tags: $(SRC) .PHONEY: install install: $(TARGET) @echo "[Install]" - @install -m 0755 -d /usr/local/lib - @install -m 0755 -d /usr/local/include - @install -m 0644 wiringPi.h /usr/local/include - @install -m 0644 wiringSerial.h /usr/local/include - @install -m 0644 wiringShift.h /usr/local/include - @install -m 0644 gertboard.h /usr/local/include - @install -m 0644 piNes.h /usr/local/include - @install -m 0644 softPwm.h /usr/local/include - @install -m 0644 lcd.h /usr/local/include - @install -m 0644 wiringPiSPI.h /usr/local/include -# @install -m 0644 libwiringPi.a /usr/local/lib - @install -m 0755 libwiringPi.so.1.0 /usr/local/lib - @ln -sf /usr/local/lib/libwiringPi.so.1.0 /usr/local/lib/libwiringPi.so - @ln -sf /usr/local/lib/libwiringPi.so.1.0 /usr/local/lib/libwiringPi.so.1 + @install -m 0755 -d $(DESTDIR)$(PREFIX)/lib + @install -m 0755 -d $(DESTDIR)$(PREFIX)/include + @install -m 0644 wiringPi.h $(DESTDIR)$(PREFIX)/include + @install -m 0644 wiringSerial.h $(DESTDIR)$(PREFIX)/include + @install -m 0644 wiringShift.h $(DESTDIR)$(PREFIX)/include + @install -m 0644 gertboard.h $(DESTDIR)$(PREFIX)/include + @install -m 0644 piNes.h $(DESTDIR)$(PREFIX)/include + @install -m 0644 softPwm.h $(DESTDIR)$(PREFIX)/include + @install -m 0644 softServo.h $(DESTDIR)$(PREFIX)/include + @install -m 0644 softTone.h $(DESTDIR)$(PREFIX)/include + @install -m 0644 lcd.h $(DESTDIR)$(PREFIX)/include + @install -m 0644 wiringPiSPI.h $(DESTDIR)$(PREFIX)/include + @install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib + @install -m 0755 libwiringPi.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib + @ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so + @ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so.1 @ldconfig .PHONEY: uninstall uninstall: @echo "[UnInstall]" - @rm -f /usr/local/include/wiringPi.h - @rm -f /usr/local/include/wiringSerial.h - @rm -f /usr/local/include/wiringShift.h - @rm -f /usr/local/include/gertboard.h - @rm -f /usr/local/include/piNes.h - @rm -f /usr/local/include/softPwm.h - @rm -f /usr/local/include/lcd.h - @rm -f /usr/local/include/wiringPiSPI.h - @rm -f /usr/local/lib/libwiringPi.* + @rm -f $(DESTDIR)$(PREFIX)/include/wiringPi.h + @rm -f $(DESTDIR)$(PREFIX)/include/wiringSerial.h + @rm -f $(DESTDIR)$(PREFIX)/include/wiringShift.h + @rm -f $(DESTDIR)$(PREFIX)/include/gertboard.h + @rm -f $(DESTDIR)$(PREFIX)/include/piNes.h + @rm -f $(DESTDIR)$(PREFIX)/include/softPwm.h + @rm -f $(DESTDIR)$(PREFIX)/include/softServo.h + @rm -f $(DESTDIR)$(PREFIX)/include/softTone.h + @rm -f $(DESTDIR)$(PREFIX)/include/lcd.h + @rm -f $(DESTDIR)$(PREFIX)/include/wiringPiSPI.h + @rm -f $(DESTDIR)$(PREFIX)/lib/libwiringPi.* @ldconfig diff --git a/wiringPi/piNes.c b/wiringPi/piNes.c index 3b54d76..a115050 100644 --- a/wiringPi/piNes.c +++ b/wiringPi/piNes.c @@ -22,7 +22,7 @@ *********************************************************************** */ -#include "wiringPi.h" +#include #include "piNes.h" diff --git a/wiringPi/softServo.c b/wiringPi/softServo.c new file mode 100644 index 0000000..a6ff1fb --- /dev/null +++ b/wiringPi/softServo.c @@ -0,0 +1,202 @@ +/* + * 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. + + +#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..d14c2a2 --- /dev/null +++ b/wiringPi/softTone.c @@ -0,0 +1,119 @@ +/* + * 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 frewqs [MAX_PINS] ; + +static int newPin = -1 ; + + +/* + * softToneThread: + * Thread to do the actual PWM output + ********************************************************************************* + */ + +static PI_THREAD (softToneThread) +{ + int pin, frewq, halfPeriod ; + + pin = newPin ; + newPin = -1 ; + + piHiPri (50) ; + + for (;;) + { + frewq = frewqs [pin] ; + if (frewq != 0) + { + halfPeriod = 500000 / frewq ; + + 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 frewq) +{ + pin &= 63 ; + + /**/ if (frewq < 0) + frewq = 0 ; + else if (frewq > 5000) // Max 5KHz + frewq = 5000 ; + + frewqs [pin] = frewq ; +} + + +/* + * softToneCreate: + * Create a new tone thread. + ********************************************************************************* + */ + +int softToneCreate (int pin) +{ + int res ; + + pinMode (pin, OUTPUT) ; + digitalWrite (pin, LOW) ; + + frewqs [pin] = 0 ; + + newPin = pin ; + res = piThreadCreate (softToneThread) ; + + while (newPin != -1) + delay (1) ; + + return res ; +} diff --git a/wiringPi/softTone.h b/wiringPi/softTone.h new file mode 100644 index 0000000..80c64fe --- /dev/null +++ b/wiringPi/softTone.h @@ -0,0 +1,38 @@ +/* + * 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 softToneWrite (int pin, int frewq) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 9fe3ab1..df4d969 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -77,6 +77,7 @@ void (*pinMode) (int pin, int mode) ; void (*pullUpDnControl) (int pin, int pud) ; void (*digitalWrite) (int pin, int value) ; +void (*digitalWriteByte) (int value) ; void (*pwmWrite) (int pin, int value) ; void (*setPadDrive) (int group, int value) ; int (*digitalRead) (int pin) ; @@ -399,15 +400,15 @@ int wpiPinToGpio (int wpiPin) * Revision is currently 1 or 2. -1 is returned on error. * * Much confusion here )-: - * Seems there ar esome boards with 0000 in them (mistake in manufacture) - * and some board with 0005 in them (another mistake in manufacture). + * Seems there are some boards with 0000 in them (mistake in manufacture) + * and some board with 0005 in them (another mistake in manufacture?) * So the distinction between boards that I can see is: * 0000 - Error * 0001 - Not used * 0002 - Rev 1 * 0003 - Rev 1 * 0004 - Rev 2 - * 0005 - Rev 2 + * 0005 - Rev 2 (but error) * 0006 - Rev 2 * 000f - Rev 2 + 512MB * @@ -499,6 +500,8 @@ int piBoardRev (void) void pinModeGpio (int pin, int mode) { +// register int barrier ; + int fSel, shift, alt ; pin &= 63 ; @@ -519,30 +522,40 @@ void pinModeGpio (int pin, int mode) *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; + delayMicroseconds (110) ; // See comments in pwmSetClockWPi + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; + // Page 107 of the BCM Peripherals manual talks about the GPIO clocks, // but I'm assuming (hoping!) that this applies to other clocks too. *(pwm + PWM_CONTROL) = 0 ; // Stop PWM - *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock - delayMicroseconds (110) ; // See comments in pwmSetClockWPi - (void)*(pwm + PWM_CONTROL) ; - while ((*(pwm + PWM_CONTROL) & 0x80) != 0) // Wait for clock to be !BUSY + *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock + delayMicroseconds (110) ; // See comments in pwmSetClockWPi + + while ((*(clk + PWMCLK_CNTL) & 0x80) != 0) // Wait for clock to be !BUSY delayMicroseconds (1) ; *(clk + PWMCLK_DIV) = BCM_PASSWORD | (32 << 12) ; // set pwm div to 32 (19.2/32 = 600KHz) *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // enable clk -// Default range regsiter of 1024 + delayMicroseconds (110) ; // See comments in pwmSetClockWPi - *(pwm + PWM0_DATA) = 0 ; *(pwm + PWM0_RANGE) = 1024 ; - *(pwm + PWM1_DATA) = 0 ; *(pwm + PWM1_RANGE) = 1024 ; +// Default range register of 1024 + + *(pwm + PWM0_RANGE) = 1024 ; delayMicroseconds (10) ; + *(pwm + PWM1_RANGE) = 1024 ; delayMicroseconds (10) ; + *(pwm + PWM0_DATA) = 0 ; delayMicroseconds (10) ; + *(pwm + PWM1_DATA) = 0 ; delayMicroseconds (10) ; // Enable PWMs in balanced mode (default) *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ; + + delay (100) ; } + // When we change mode of any pin, we remove the pull up/downs // Or we used to... Hm. Commented out now because for some wieird reason, // it seems to block subsequent attempts to set the pull up/downs and I've @@ -629,7 +642,7 @@ void pwmSetClockWPi (int divisor) *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock delayMicroseconds (110) ; // prevents clock going sloooow - while ((*(pwm + PWM_CONTROL) & 0x80) != 0) // Wait for clock to be !BUSY + while ((*(clk + PWMCLK_CNTL) & 0x80) != 0) // Wait for clock to be !BUSY delayMicroseconds (1) ; *(clk + PWMCLK_DIV) = BCM_PASSWORD | (divisor << 12) ; @@ -704,6 +717,50 @@ void digitalWriteSys (int pin, int value) } +/* + * digitalWriteByte: + * Write an 8-bit byte to the first 8 GPIO pins - try to do it as + * fast as possible. + * However it still needs 2 operations to set the bits, so any external + * hardware must not rely on seeing a change as there will be a change + * to set the outputs bits to zero, then another change to set the 1's + ********************************************************************************* + */ + +void digitalWriteByteGpio (int value) +{ + uint32_t pinSet = 0 ; + uint32_t pinClr = 0 ; + int mask = 1 ; + int pin ; + + for (pin = 0 ; pin < 8 ; ++pin) + { + if ((value & mask) == 0) + pinClr |= (1 << pinToGpio [pin]) ; + else + pinSet |= (1 << pinToGpio [pin]) ; + + *(gpio + gpioToGPCLR [0]) = pinClr ; + *(gpio + gpioToGPSET [0]) = pinSet ; + + mask <<= 1 ; + } +} + +void digitalWriteByteSys (int value) +{ + int mask = 1 ; + int pin ; + + for (pin = 0 ; pin < 8 ; ++pin) + { + digitalWriteSys (pinToGpio [pin], value & mask) ; + mask <<= 1 ; + } +} + + /* * pwmWrite: * Set an output PWM value @@ -915,6 +972,9 @@ void delay (unsigned int howLong) * 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... ********************************************************************************* */ @@ -930,16 +990,31 @@ void delayMicrosecondsSys (unsigned int howLong) void delayMicrosecondsHard (unsigned int howLong) { +#ifdef HARD_TIMER + volatile unsigned int dummy ; + *(timer + TIMER_LOAD) = howLong ; *(timer + TIMER_IRQ_CLR) = 0 ; - while (*timerIrqRaw == 0) - ; + dummy = *timerIrqRaw ; + while (dummy == 0) + dummy = *timerIrqRaw ; +#else + 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) ; +#endif } void delayMicrosecondsWPi (unsigned int howLong) { - struct timespec sleeper, dummy ; + struct timespec sleeper ; /**/ if (howLong == 0) return ; @@ -949,7 +1024,7 @@ void delayMicrosecondsWPi (unsigned int howLong) { sleeper.tv_sec = 0 ; sleeper.tv_nsec = (long)(howLong * 1000) ; - nanosleep (&sleeper, &dummy) ; + nanosleep (&sleeper, NULL) ; } } @@ -998,6 +1073,7 @@ int wiringPiSetup (void) pinMode = pinModeWPi ; pullUpDnControl = pullUpDnControlWPi ; digitalWrite = digitalWriteWPi ; + digitalWriteByte = digitalWriteByteGpio ; // Same code pwmWrite = pwmWriteWPi ; setPadDrive = setPadDriveWPi ; digitalRead = digitalReadWPi ; @@ -1166,6 +1242,7 @@ int wiringPiSetupGpio (void) pinMode = pinModeGpio ; pullUpDnControl = pullUpDnControlGpio ; digitalWrite = digitalWriteGpio ; + digitalWriteByte = digitalWriteByteGpio ; pwmWrite = pwmWriteGpio ; setPadDrive = setPadDriveGpio ; digitalRead = digitalReadGpio ; @@ -1190,6 +1267,7 @@ int wiringPiSetupGpio (void) int wiringPiSetupSys (void) { + int boardRev ; int pin ; struct timeval tv ; char fName [128] ; @@ -1200,6 +1278,7 @@ int wiringPiSetupSys (void) pinMode = pinModeSys ; pullUpDnControl = pullUpDnControlSys ; digitalWrite = digitalWriteSys ; + digitalWriteByte = digitalWriteByteSys ; pwmWrite = pwmWriteSys ; setPadDrive = setPadDriveSys ; digitalRead = digitalReadSys ; @@ -1209,6 +1288,14 @@ int wiringPiSetupSys (void) pwmSetRange = pwmSetRangeSys ; pwmSetClock = pwmSetClockSys ; + if ((boardRev = piBoardRev ()) < 0) + return -1 ; + + if (boardRev == 1) + pinToGpio = pinToGpioR1 ; + else + pinToGpio = pinToGpioR2 ; + // Open and scan the directory, looking for exported GPIOs, and pre-open // the 'value' interface to speed things up for later diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index cab3080..6a7278e 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -70,6 +70,7 @@ extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio extern void (*pinMode) (int pin, int mode) ; extern void (*pullUpDnControl) (int pin, int pud) ; extern void (*digitalWrite) (int pin, int value) ; +extern void (*digitalWriteByte) (int value) ; extern void (*pwmWrite) (int pin, int value) ; extern void (*setPadDrive) (int group, int value) ; extern int (*digitalRead) (int pin) ; diff --git a/wiringPi/wiringPiFace.c b/wiringPi/wiringPiFace.c index 2425413..ac3c6fa 100644 --- a/wiringPi/wiringPiFace.c +++ b/wiringPi/wiringPiFace.c @@ -182,6 +182,11 @@ void digitalWritePiFace (int pin, int value) writeByte (GPIOA, dataOutRegister) ; } +void digitalWriteBytePiFace (int value) +{ + writeByte (GPIOA, value) ; +} + void digitalWritePiFaceSpecial (int pin, int value) { @@ -318,12 +323,13 @@ int wiringPiSetupPiFace (void) writeByte (GPIOA, 0x00) ; // Set all outptus off writeByte (GPPUB, 0x00) ; // Disable any pull-ups on port B - pinMode = pinModePiFace ; - pullUpDnControl = pullUpDnControlPiFace ; - digitalWrite = digitalWritePiFace ; - pwmWrite = pwmWritePiFace ; - digitalRead = digitalReadPiFace ; - waitForInterrupt = waitForInterruptPiFace ; + pinMode = pinModePiFace ; + pullUpDnControl = pullUpDnControlPiFace ; + digitalWrite = digitalWritePiFace ; + digitalWriteByte = digitalWriteBytePiFace ; + pwmWrite = pwmWritePiFace ; + digitalRead = digitalReadPiFace ; + waitForInterrupt = waitForInterruptPiFace ; return 0 ; } @@ -344,12 +350,13 @@ int wiringPiSetupPiFaceForGpioProg (void) if (x != 0) return x ; - pinMode = pinModePiFace ; + pinMode = pinModePiFace ; pullUpDnControl = pullUpDnControlPiFaceSpecial ; digitalWrite = digitalWritePiFaceSpecial ; - pwmWrite = pwmWritePiFace ; - digitalRead = digitalReadPiFace ; - waitForInterrupt = waitForInterruptPiFace ; + digitalWriteByte = digitalWriteBytePiFace ; + pwmWrite = pwmWritePiFace ; + digitalRead = digitalReadPiFace ; + waitForInterrupt = waitForInterruptPiFace ; return 0 ; } diff --git a/wiringPi/wiringPiSPI.c b/wiringPi/wiringPiSPI.c index f2e3000..4441498 100644 --- a/wiringPi/wiringPiSPI.c +++ b/wiringPi/wiringPiSPI.c @@ -52,7 +52,7 @@ static int spiFds [2] ; int wiringPiSPIGetFd (int channel) { - return spiFds [channel &1] ; + return spiFds [channel & 1] ; } From 234e34450b768375cf5936cb150ee541eace7fc2 Mon Sep 17 00:00:00 2001 From: Philip Howard Date: Sun, 24 Mar 2013 20:04:07 +0000 Subject: [PATCH 13/29] Synced to git.drogon.net --- INSTALL | 48 +++ People | 12 + README.TXT | 26 ++ build | 63 ++- examples/Makefile | 36 +- examples/README.TXT | 6 +- examples/blink.c | 50 +++ examples/blink.rtb | 30 ++ examples/blink.sh | 37 ++ examples/delayTest.c | 24 ++ examples/gertboard.c | 19 +- examples/header.h | 23 ++ examples/isr-osc.c | 118 ++++++ examples/isr.c | 99 +++++ examples/nes.c | 23 ++ examples/okLed.c | 22 +- examples/piface.c | 24 +- examples/pwm.c | 24 ++ examples/serialRead.c | 21 +- examples/serialTest.c | 75 ++++ examples/servo.c | 24 ++ examples/speed.c | 20 +- examples/test1.c | 22 +- examples/test2.c | 23 +- examples/tone.c | 34 +- examples/wfi.c | 31 +- gpio/Makefile | 6 +- gpio/gpio | Bin 0 -> 21304 bytes gpio/gpio.1 | 43 +- gpio/gpio.c | 134 ++++--- wiringPi/Makefile | 37 +- wiringPi/lcd.c | 12 + wiringPi/lcd.h | 13 +- wiringPi/libwiringPi.so.1.0 | Bin 0 -> 43311 bytes wiringPi/q2w.c | 89 +++++ wiringPi/softServo.c | 9 + wiringPi/softTone.c | 4 +- wiringPi/wiringPi.c | 762 +++++++++++++++++++++++------------- wiringPi/wiringPi.h | 48 ++- wiringPi/wiringPiI2C.c | 122 ++++++ wiringPi/wiringPiI2C.h | 41 ++ 41 files changed, 1829 insertions(+), 425 deletions(-) create mode 100644 INSTALL create mode 100644 README.TXT create mode 100644 examples/blink.c create mode 100644 examples/blink.rtb create mode 100644 examples/blink.sh create mode 100644 examples/header.h create mode 100644 examples/isr-osc.c create mode 100644 examples/isr.c create mode 100644 examples/serialTest.c create mode 100755 gpio/gpio create mode 100755 wiringPi/libwiringPi.so.1.0 create mode 100644 wiringPi/q2w.c create mode 100644 wiringPi/wiringPiI2C.c create mode 100644 wiringPi/wiringPiI2C.h diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..8a6d38e --- /dev/null +++ b/INSTALL @@ -0,0 +1,48 @@ + +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 + +If you want to install a static library, you may need to do this manually: + + cd wiringPi + make static + sudo make install-static + + +To un-install wiringPi: + + ./build uninstall + + +I2C: + +If your system has the correct i2c-dev libraries and headers installed, +then the I2C helpers will be compiled into wiringPi. If you want to +use the I2C helpers and don't have them installed, then under Raspbian, +issue the command: + + sudo apt-get install libi2c-dev + +Consult the documentation for your system if you are not running Raspbian. + +Gordon Henderson + +projects@drogon.net +https://projects.drogon.net/ diff --git a/People b/People index e0c262c..8be8b6d 100644 --- a/People +++ b/People @@ -13,3 +13,15 @@ Chris McSweeny 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! diff --git a/README.TXT b/README.TXT new file mode 100644 index 0000000..0fce86a --- /dev/null +++ b/README.TXT @@ -0,0 +1,26 @@ + +wiringPi README +=============== + +Please note that the official way to get wiringPi is via git from +git.drogon.net and not GitHub. + +ie. + + git clone git://git.drogon.net/wiringPi + +The version of wiringPi held on GitHub by "Gadgetoid" is used to build the +wiringPython, Ruby, Perl, etc. wrappers for these other languages. This +version may lag the official Drogon release. Pull requests may not be +accepted to Github.... + +Please see + + https://projects.drogon.net/raspberry-pi/wiringpi/ + +for the official documentation, etc. and the best way to submit bug reports, etc. +is by sending an email to projects@drogon.net + +Thanks! + + -Gordon diff --git a/build b/build index 740b512..cbb1a4f 100755 --- a/build +++ b/build @@ -1,5 +1,18 @@ #!/bin/bash +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 +} + if [ x$1 = "xclean" ]; then echo Cleaning echo @@ -9,8 +22,10 @@ if [ x$1 = "xclean" ]; then make clean cd ../examples make clean - cd .. -elif [ x$1 = "xuninstall" ]; then + exit +fi + +if [ x$1 = "xuninstall" ]; then echo Uninstalling echo echo "WiringPi library" @@ -21,24 +36,50 @@ elif [ x$1 = "xuninstall" ]; then cd ../gpio sudo make uninstall cd .. -else - echo wiringPi Build script - please wait... + exit +fi + + + echo "wiringPi Build script" + echo "=====================" + echo + +# Check for I2C being installed... +# ... and if-so, then automatically make the I2C helpers + + if [ -f /usr/include/linux/i2c-dev.h ]; then + grep -q i2c_smbus_read_byte /usr/include/linux/i2c-dev.h + if [ $? = 0 ]; then + target=i2c + echo "Building wiringPi with the I2C helper libraries." + else + target=all + echo "The wiringPi I2C helper libraries will not be built." + fi + fi + echo echo "WiringPi library" cd wiringPi - make + sudo make uninstall + make $target + check-make-ok sudo make install + check-make-ok + echo echo "GPIO Utility" cd ../gpio make + check-make-ok sudo make install - echo - echo "Examples" - cd ../examples - make - cd .. -fi + check-make-ok + +# echo +# echo "Examples" +# cd ../examples +# make +# cd .. echo echo All Done. diff --git a/examples/Makefile b/examples/Makefile index 738d36c..defd510 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -30,15 +30,15 @@ INCLUDE = -I/usr/local/include CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe LDFLAGS = -L/usr/local/lib -LDLIBS = -lwiringPi +LDLIBS = -lwiringPi -lpthread -lm # Should not alter anything below this line ############################################################################### -SRC = test1.c test2.c speed.c lcd.c wfi.c \ - piface.c gertboard.c nes.c \ - pwm.c tone.c servo.c \ - delayTest.c serialRead.c okLed.c +SRC = blink.c test1.c test2.c speed.c lcd.c wfi.c isr.c isr-osc.c \ + piface.c gertboard.c nes.c \ + pwm.c tone.c servo.c \ + delayTest.c serialRead.c serialTest.c okLed.c OBJ = $(SRC:.c=.o) @@ -49,6 +49,12 @@ all: @echo " $(BINS)" | fmt @echo "" +really-all: $(BINS) + +blink: blink.o + @echo [link] + @$(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS) + test1: test1.o @echo [link] @$(CC) -o $@ test1.o $(LDFLAGS) $(LDLIBS) @@ -69,21 +75,29 @@ wfi: wfi.o @echo [link] @$(CC) -o $@ wfi.o $(LDFLAGS) $(LDLIBS) +isr: isr.o + @echo [link] + @$(CC) -o $@ isr.o $(LDFLAGS) $(LDLIBS) + +isr-osc: isr-osc.o + @echo [link] + @$(CC) -o $@ isr-osc.o $(LDFLAGS) $(LDLIBS) + piface: piface.o @echo [link] - @$(CC) -o $@ piface.o $(LDFLAGS) $(LDLIBS) -lpthread + @$(CC) -o $@ piface.o $(LDFLAGS) $(LDLIBS) gertboard: gertboard.o @echo [link] - @$(CC) -o $@ gertboard.o $(LDFLAGS) $(LDLIBS) -lm + @$(CC) -o $@ gertboard.o $(LDFLAGS) $(LDLIBS) nes: nes.o @echo [link] - @$(CC) -o $@ nes.o $(LDFLAGS) $(LDLIBS) -lm + @$(CC) -o $@ nes.o $(LDFLAGS) $(LDLIBS) pwm: pwm.o @echo [link] - @$(CC) -o $@ pwm.o $(LDFLAGS) $(LDLIBS) -lm -lpthread + @$(CC) -o $@ pwm.o $(LDFLAGS) $(LDLIBS) delayTest: delayTest.o @echo [link] @@ -93,6 +107,10 @@ serialRead: serialRead.o @echo [link] @$(CC) -o $@ serialRead.o $(LDFLAGS) $(LDLIBS) +serialTest: serialTest.o + @echo [link] + @$(CC) -o $@ serialTest.o $(LDFLAGS) $(LDLIBS) + okLed: okLed.o @echo [link] @$(CC) -o $@ okLed.o $(LDFLAGS) $(LDLIBS) diff --git a/examples/README.TXT b/examples/README.TXT index 2bf6f1e..33263b1 100644 --- a/examples/README.TXT +++ b/examples/README.TXT @@ -10,5 +10,9 @@ To compile an individual example, just type make exampleName -Where exampleName is one of: +To really compile everything: + + make really-all + +The individual tests are: diff --git a/examples/blink.c b/examples/blink.c new file mode 100644 index 0000000..bb9f856 --- /dev/null +++ b/examples/blink.c @@ -0,0 +1,50 @@ +/* + * blink.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 + +int main (void) +{ + printf ("Raspberry Pi blink\n") ; + + if (wiringPiSetup () == -1) + return 1 ; + + pinMode (LED, OUTPUT) ; + + for (;;) + { + digitalWrite (LED, 1) ; // On + delay (500) ; // mS + digitalWrite (LED, 0) ; // Off + delay (500) ; + } + 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..2aa378a --- /dev/null +++ b/examples/blink.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# +# 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. + +LED=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/delayTest.c b/examples/delayTest.c index d05f3ff..4c8b6ca 100644 --- a/examples/delayTest.c +++ b/examples/delayTest.c @@ -1,3 +1,27 @@ +/* + * 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 diff --git a/examples/gertboard.c b/examples/gertboard.c index 8f26dd4..f02e27d 100644 --- a/examples/gertboard.c +++ b/examples/gertboard.c @@ -1,4 +1,3 @@ - /* * gertboard.c: * Simple test for the SPI bus on the Gertboard @@ -10,6 +9,24 @@ * copy this value to D/A port 1 and use a 'scope on both D/A ports * to check all's well. * + * 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 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..2bef54a --- /dev/null +++ b/examples/isr.c @@ -0,0 +1,99 @@ +/* + * 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 + + +// What GPIO input are we using? +// This is a wiringPi pin number + +#define BUTTON_PIN 0 + +// globalCounter: +// Global variable to count interrupts +// Should be declared volatile to make sure the compiler doesn't cache it. + +static volatile int globalCounter = 0 ; + + +/* + * myInterrupt: + ********************************************************************************* + */ + +void myInterrupt (void) +{ + ++globalCounter ; +} + + +/* + ********************************************************************************* + * main + ********************************************************************************* + */ + +int main (void) +{ + int myCounter = 0 ; + + if (wiringPiSetup () < 0) + { + fprintf (stderr, "Unable to setup wiringPi: %s\n", strerror (errno)) ; + return 1 ; + } + + if (wiringPiISR (BUTTON_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 (100) ; + + printf (" Done. counter: %5d\n", globalCounter) ; + myCounter = globalCounter ; + } + + return 0 ; +} diff --git a/examples/nes.c b/examples/nes.c index 1a485bd..31908e8 100644 --- a/examples/nes.c +++ b/examples/nes.c @@ -1,3 +1,26 @@ +/* + * 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 diff --git a/examples/okLed.c b/examples/okLed.c index 3bf21e2..9b3a170 100644 --- a/examples/okLed.c +++ b/examples/okLed.c @@ -1,7 +1,6 @@ /* - * okLed: + * okLed.c: * Make the OK LED on the Pi Pulsate... - * Copyright (c) 2012 gordon Henderson, but please Share and Enjoy! * * Originally posted to the Raspberry Pi forums: * http://www.raspberrypi.org/phpBB3/viewtopic.php?p=162581#p162581 @@ -10,6 +9,24 @@ * 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 @@ -17,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/examples/piface.c b/examples/piface.c index 3305bf9..0f00960 100644 --- a/examples/piface.c +++ b/examples/piface.c @@ -1,9 +1,27 @@ - /* - * piface.c: - * Simple test for the PiFace + * piFace.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 diff --git a/examples/pwm.c b/examples/pwm.c index 09b4ae0..c1fc331 100644 --- a/examples/pwm.c +++ b/examples/pwm.c @@ -1,3 +1,27 @@ +/* + * pwm.c: + * Test of the software PWM driver. Needs 12 LEDs 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 diff --git a/examples/serialRead.c b/examples/serialRead.c index 34b9bad..9ee11ac 100644 --- a/examples/serialRead.c +++ b/examples/serialRead.c @@ -1,8 +1,25 @@ - /* - * serialRead.c: + * 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 diff --git a/examples/serialTest.c b/examples/serialTest.c new file mode 100644 index 0000000..0d6da5f --- /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/ttyAMA0", 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 index 0237832..aa1ab05 100644 --- a/examples/servo.c +++ b/examples/servo.c @@ -1,3 +1,27 @@ +/* + * 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 diff --git a/examples/speed.c b/examples/speed.c index 2f5d990..863317e 100644 --- a/examples/speed.c +++ b/examples/speed.c @@ -1,8 +1,26 @@ - /* * 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 diff --git a/examples/test1.c b/examples/test1.c index 7eb0abd..4c75711 100644 --- a/examples/test1.c +++ b/examples/test1.c @@ -1,7 +1,27 @@ - /* * test1.c: * Simple test program to test the wiringPi functions + * This is a sequencer to make a patter appear on 8 LEDs + * connected to the GPIO pins. + * + * 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 diff --git a/examples/test2.c b/examples/test2.c index e34013c..580591e 100644 --- a/examples/test2.c +++ b/examples/test2.c @@ -1,8 +1,25 @@ - /* * test2.c: - * Simple test program to test the wiringPi functions - * PWM test + * 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 diff --git a/examples/tone.c b/examples/tone.c index 8b1fcd7..0e8a47d 100644 --- a/examples/tone.c +++ b/examples/tone.c @@ -1,3 +1,27 @@ +/* + * tone.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 @@ -6,15 +30,13 @@ #include #include -#define RANGE 100 -#define NUM_LEDS 12 +#define PIN 3 int scale [8] = { 262, 294, 330, 349, 392, 440, 494, 525 } ; int main () { - int i, j ; - char buf [80] ; + int i ; if (wiringPiSetup () == -1) { @@ -22,14 +44,14 @@ int main () return 1 ; } - softToneCreate (3) ; + softToneCreate (PIN) ; for (;;) { for (i = 0 ; i < 8 ; ++i) { printf ("%3d\n", i) ; - softToneWrite (3, scale [i]) ; + softToneWrite (PIN, scale [i]) ; delay (500) ; } } diff --git a/examples/wfi.c b/examples/wfi.c index 9efcc2c..6bb6892 100644 --- a/examples/wfi.c +++ b/examples/wfi.c @@ -2,7 +2,17 @@ * wfi.c: * Wait for Interrupt test program * - * Copyright (c) 2012 Gordon Henderson. + * 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/ @@ -33,9 +43,8 @@ #define COUNT_KEY 0 // What BCM_GPIO input are we using? -// GPIO 0 is one of the I2C pins with an on-board pull-up -#define BUTTON_PIN 0 +#define BUTTON_PIN 17 // Debounce time in mS @@ -63,13 +72,11 @@ PI_THREAD (waitForIt) int debounceTime = 0 ; (void)piHiPri (10) ; // Set this thread to be high priority - digitalWrite (18, 1) ; for (;;) { if (waitForInterrupt (BUTTON_PIN, -1) > 0) // Got it { - // Bouncing? if (millis () < debounceTime) @@ -80,7 +87,6 @@ PI_THREAD (waitForIt) // We have a valid one - digitalWrite (17, state) ; state ^= 1 ; piLock (COUNT_KEY) ; @@ -89,7 +95,7 @@ PI_THREAD (waitForIt) // Wait for key to be released - while (digitalRead (0) == LOW) + while (digitalRead (BUTTON_PIN) == LOW) delay (1) ; debounceTime = millis () + DEBOUNCE_TIME ; @@ -108,11 +114,9 @@ void setup (void) { // Use the gpio program to initialise the hardware -// (This is the crude, but effective bit) +// (This is the crude, but effective) - system ("gpio edge 0 falling") ; - system ("gpio export 17 out") ; - system ("gpio export 18 out") ; + system ("gpio edge 17 falling") ; // Setup wiringPi @@ -120,9 +124,8 @@ void setup (void) // Fire off our interrupt handler - piThreadCreate (waitForIt) ; + piThreadCreate (waitForIt) ; - digitalWrite (17, 0) ; } @@ -147,7 +150,7 @@ int main (void) piLock (COUNT_KEY) ; myCounter = globalCounter ; piUnlock (COUNT_KEY) ; - delay (5000) ; + delay (500) ; } printf (" Done. myCounter: %5d\n", myCounter) ; diff --git a/gpio/Makefile b/gpio/Makefile index 5693c44..a043962 100644 --- a/gpio/Makefile +++ b/gpio/Makefile @@ -30,7 +30,7 @@ INCLUDE = -I/usr/local/include CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe LDFLAGS = -L/usr/local/lib -LIBS = -lwiringPi +LIBS = -lwiringPi -lpthread -lm # May not need to alter anything below this line ############################################################################### @@ -70,8 +70,8 @@ install: .PHONEY: uninstall uninstall: @echo "[UnInstall]" - rm -f /usr/local/bin/gpio - rm -f /usr/local/man/man1/gpio.1 + @rm -f /usr/local/bin/gpio + @rm -f /usr/local/man/man1/gpio.1 .PHONEY: depend depend: diff --git a/gpio/gpio b/gpio/gpio new file mode 100755 index 0000000000000000000000000000000000000000..54df96acc4db421f20e155f5ca8ab5a32637ea97 GIT binary patch literal 21304 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 literal 0 HcmV?d00001 diff --git a/gpio/gpio.1 b/gpio/gpio.1 index c39e5dc..ec65519 100644 --- a/gpio/gpio.1 +++ b/gpio/gpio.1 @@ -9,7 +9,7 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO .PP .B gpio .B [ \-g ] -.B read/write/wb/pwm/mode ... +.B read/write/wb/pwm/clock/mode ... .PP .B gpio .B [ \-p ] @@ -38,7 +38,7 @@ group value range .PP .B gpio -.B load \ i2c/spi +.B load \ i2c/spi ... .PP .B gpio .B gbr @@ -57,6 +57,9 @@ 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. @@ -70,6 +73,8 @@ 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 \-p @@ -99,7 +104,13 @@ mode. .TP .B pwm -Write a PWM value (0-1023) to the given pin. +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 @@ -163,9 +174,18 @@ Change the PWM mode to balanced (the default) or mark:space ratio (traditional) Change the PWM range register. The default is 1024. .TP -.B load i2c/spi -This loads the i2c or the spi drivers into the system and changes the permissions on -the associated /dev/ entries so that the current user has access to them. +.B load i2c [baudrate] +This loads the i2c or drivers into the kernel and changes the permissions +on the associated /dev/ entries so that the current user has access to +them. Optionally it will set the I2C baudrate to that supplied (or as +close as the Pi can manage) The default speed is 100Kb/sec. + +.TP +.B load spi [buffer size in KB] +This loads the spi drivers into the kernel and changes the permissions +on the associated /dev/ entries so that the current user has access to +them. Optionally it will set the SPI buffer size to that supplied. The +default is 4KB. .TP .B gbr @@ -183,7 +203,7 @@ SPI digital to analogue converter. The board jumpers need to be in-place to do this operation. -.SH "WiringPi vs. GPIO Pin numbering" +.SH "WiringPi vs. BCM_GPIO Pin numbering" .PP .TS @@ -213,6 +233,12 @@ _ 20 - 31 .TE +Note that "r1" and "r2" above refers to the board revision. Normally +wiringPi detects the correct board revision with use for it's own +numbering scheme, but if you are using a Revision 2 board with some +of the pins which change numbers between revisions you will need +to alter your software. + .SH FILES .TP 2.2i @@ -264,4 +290,5 @@ 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. +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 index 52fcb6f..e71e432 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -35,18 +35,20 @@ #include #include +extern int wiringPiDebug ; + #ifndef TRUE # define TRUE (1==1) # define FALSE (1==2) #endif -#define VERSION "1.5" +#define VERSION "1.12" static int wpMode ; char *usage = "Usage: gpio -v\n" " gpio -h\n" - " gpio [-g] ...\n" + " gpio [-g] ...\n" " gpio [-p] ...\n" " gpio readall\n" " gpio unexportall/exports ...\n" @@ -127,7 +129,7 @@ static int moduleLoaded (char *modName) static void _doLoadUsage (char *argv []) { - fprintf (stderr, "Usage: %s load \n", argv [0]) ; + fprintf (stderr, "Usage: %s load [SPI bufferSize in KB | I2C baudrate in Kb/sec]\n", argv [0]) ; exit (1) ; } @@ -136,16 +138,23 @@ static void doLoad (int argc, char *argv []) char *module1, *module2 ; char cmd [80] ; char *file1, *file2 ; + char args1 [32], args2 [32] ; - if (argc != 3) + 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) + sprintf (args1, " bufsiz=%d", atoi (argv [3]) * 1024) ; + else if (argc > 4) + _doLoadUsage (argv) ; } else if (strcasecmp (argv [2], "i2c") == 0) { @@ -153,19 +162,23 @@ static void doLoad (int argc, char *argv []) 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 (!moduleLoaded (module1)) { - sprintf (cmd, "modprobe %s", module1) ; + sprintf (cmd, "modprobe %s%s", module1, args1) ; system (cmd) ; } if (!moduleLoaded (module2)) { - sprintf (cmd, "modprobe %s", module2) ; + sprintf (cmd, "modprobe %s%s", module2, args2) ; system (cmd) ; } @@ -190,55 +203,39 @@ static void doLoad (int argc, char *argv []) static char *pinNames [] = { - "GPIO 0", - "GPIO 1", - "GPIO 2", - "GPIO 3", - "GPIO 4", - "GPIO 5", - "GPIO 6", - "GPIO 7", - "SDA ", - "SCL ", - "CE0 ", - "CE1 ", - "MOSI ", - "MISO ", - "SCLK ", - "TxD ", - "RxD ", - "GPIO 8", - "GPIO 9", - "GPIO10", - "GPIO11", + "GPIO 0", "GPIO 1", "GPIO 2", "GPIO 3", "GPIO 4", "GPIO 5", "GPIO 6", "GPIO 7", + "SDA ", "SCL ", + "CE0 ", "CE1 ", "MOSI ", "MISO ", "SCLK ", + "TxD ", "RxD ", + "GPIO 8", "GPIO 9", "GPIO10", "GPIO11", +} ; + +static char *alts [] = +{ + "IN ", "OUT ", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3" } ; static void doReadall (void) { int pin ; - printf ("+----------+------+--------+-------+\n") ; - printf ("| wiringPi | GPIO | Name | Value |\n") ; - printf ("+----------+------+--------+-------+\n") ; + printf ("+----------+------+--------+------+-------+\n") ; + printf ("| wiringPi | GPIO | Name | Mode | Value |\n") ; + printf ("+----------+------+--------+------+-------+\n") ; - for (pin = 0 ; pin < NUM_PINS ; ++pin) - printf ("| %6d | %3d | %s | %s |\n", + for (pin = 0 ; pin < 64 ; ++pin) + { + if (wpiPinToGpio (pin) == -1) + continue ; + + printf ("| %6d | %3d | %s | %s | %s |\n", pin, wpiPinToGpio (pin), pinNames [pin], + alts [getAlt (pin)], digitalRead (pin) == HIGH ? "High" : "Low ") ; + } - printf ("+----------+------+--------+-------+\n") ; - - if (piBoardRev () == 1) - return ; - - for (pin = 17 ; pin <= 20 ; ++pin) - printf ("| %6d | %3d | %s | %s |\n", - pin, wpiPinToGpio (pin), - pinNames [pin], - digitalRead (pin) == HIGH ? "High" : "Low ") ; - - printf ("+----------+------+--------+-------+\n") ; + printf ("+----------+------+--------+------+-------+\n") ; } @@ -544,15 +541,16 @@ void doMode (int argc, char *argv []) mode = argv [3] ; - /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ; - else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ; - else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ; - else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ; - else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ; - else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ; + /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ; + else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ; + else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ; + else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ; + else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ; + else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ; + else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ; else { - fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/up/down/tri\n", argv [1], mode) ; + fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/clock/up/down/tri\n", argv [1], mode) ; exit (1) ; } } @@ -757,6 +755,33 @@ void doRead (int argc, char *argv []) } +/* + * 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]) ; + + if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) + return ; + + freq = atoi (argv [3]) ; + + gpioClockSet (pin, freq) ; +} + + /* * doPwm: * Output a PWM value on a pin @@ -848,6 +873,12 @@ 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\n", usage) ; @@ -977,6 +1008,7 @@ int main (int argc, char *argv []) else if (strcasecmp (argv [1], "write") == 0) doWrite (argc, argv) ; else if (strcasecmp (argv [1], "wb") == 0) doWriteByte (argc, argv) ; else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ; + else if (strcasecmp (argv [1], "clock") == 0) doClock (argc, argv) ; else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ; else { diff --git a/wiringPi/Makefile b/wiringPi/Makefile index e18a654..c6a4555 100644 --- a/wiringPi/Makefile +++ b/wiringPi/Makefile @@ -1,4 +1,4 @@ -# +# ; # Makefile: # wiringPi - Wiring Compatable library for the Raspberry Pi # @@ -45,13 +45,19 @@ LIBS = SRC = wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c \ gertboard.c \ piNes.c \ - lcd.c piHiPri.c piThread.c wiringPiSPI.c \ + lcd.c piHiPri.c piThread.c \ + wiringPiSPI.c \ softPwm.c softServo.c softTone.c +SRC_I2C = wiringPiI2C.c + OBJ = $(SRC:.c=.o) -all: $(STATIC) $(DYNAMIC) -#all: $(DYNAMIC) +OBJ_I2C = $(SRC_I2C:.c=.o) + +all: $(DYNAMIC) + +static: $(STATIC) $(STATIC): $(OBJ) @echo "[Link (Static)]" @@ -63,13 +69,17 @@ $(DYNAMIC): $(OBJ) @echo "[Link (Dynamic)]" @$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ) +i2c: $(OBJ) $(OBJ_I2C) + @echo "[Link (Dynamic + I2C)]" + @$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ) $(OBJ_I2C) + .c.o: @echo [Compile] $< @$(CC) -c $(CFLAGS) $< -o $@ .PHONEY: clean clean: - rm -f $(OBJ) *~ core tags Makefile.bak libwiringPi.* + rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPi.* .PHONEY: tags tags: $(SRC) @@ -77,7 +87,7 @@ tags: $(SRC) @ctags $(SRC) .PHONEY: install -install: $(TARGET) +install: $(DYNAMIC) @echo "[Install]" @install -m 0755 -d $(DESTDIR)$(PREFIX)/lib @install -m 0755 -d $(DESTDIR)$(PREFIX)/include @@ -91,12 +101,17 @@ install: $(TARGET) @install -m 0644 softTone.h $(DESTDIR)$(PREFIX)/include @install -m 0644 lcd.h $(DESTDIR)$(PREFIX)/include @install -m 0644 wiringPiSPI.h $(DESTDIR)$(PREFIX)/include - @install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib + @install -m 0644 wiringPiI2C.h $(DESTDIR)$(PREFIX)/include @install -m 0755 libwiringPi.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib @ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so @ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so.1 @ldconfig +.PHONEY: install-static +install-static: $(STATIC) + @echo "[Install Static]" + @install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib + .PHONEY: uninstall uninstall: @echo "[UnInstall]" @@ -110,13 +125,14 @@ uninstall: @rm -f $(DESTDIR)$(PREFIX)/include/softTone.h @rm -f $(DESTDIR)$(PREFIX)/include/lcd.h @rm -f $(DESTDIR)$(PREFIX)/include/wiringPiSPI.h + @rm -f $(DESTDIR)$(PREFIX)/include/wiringPiI2C.h @rm -f $(DESTDIR)$(PREFIX)/lib/libwiringPi.* @ldconfig .PHONEY: depend depend: - makedepend -Y $(SRC) + makedepend -Y $(SRC) $(SRC_I2C) # DO NOT DELETE @@ -129,5 +145,8 @@ piNes.o: wiringPi.h piNes.h lcd.o: wiringPi.h lcd.h piHiPri.o: wiringPi.h piThread.o: wiringPi.h -softPwm.o: wiringPi.h softPwm.h wiringPiSPI.o: wiringPiSPI.h +softPwm.o: wiringPi.h softPwm.h +softServo.o: wiringPi.h softServo.h +softTone.o: wiringPi.h softTone.h +wiringPiI2C.o: wiringPi.h wiringPiI2C.h diff --git a/wiringPi/lcd.c b/wiringPi/lcd.c index aa58cab..f123db2 100644 --- a/wiringPi/lcd.c +++ b/wiringPi/lcd.c @@ -174,6 +174,18 @@ void lcdClear (int fd) } +/* + * lcdSendCommand: + * Send any arbitary command to the display + ********************************************************************************* + */ + +void lcdSendCommand (int fd, uint8_t command) +{ + struct lcdDataStruct *lcd = lcds [fd] ; + putCommand (lcd, command) ; +} + /* * lcdPosition: * Update the position of the cursor on the display diff --git a/wiringPi/lcd.h b/wiringPi/lcd.h index ecd1d25..beebb75 100644 --- a/wiringPi/lcd.h +++ b/wiringPi/lcd.h @@ -30,12 +30,13 @@ extern "C" { #endif -extern void lcdHome (int fd) ; -extern void lcdClear (int fd) ; -extern void lcdPosition (int fd, int x, int y) ; -extern void lcdPutchar (int fd, uint8_t data) ; -extern void lcdPuts (int fd, char *string) ; -extern void lcdPrintf (int fd, char *message, ...) ; +extern void lcdHome (int fd) ; +extern void lcdClear (int fd) ; +extern void lcdSendCommand (int fd, uint8_t command) ; +extern void lcdPosition (int fd, int x, int y) ; +extern void lcdPutchar (int fd, uint8_t data) ; +extern void lcdPuts (int fd, char *string) ; +extern void lcdPrintf (int fd, char *message, ...) ; extern int lcdInit (int rows, int cols, int bits, int rs, int strb, int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ; diff --git a/wiringPi/libwiringPi.so.1.0 b/wiringPi/libwiringPi.so.1.0 new file mode 100755 index 0000000000000000000000000000000000000000..7c87ee9e0b6a1975bca211971d0a94605bef164a GIT binary patch literal 43311 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 literal 0 HcmV?d00001 diff --git a/wiringPi/q2w.c b/wiringPi/q2w.c new file mode 100644 index 0000000..31486da --- /dev/null +++ b/wiringPi/q2w.c @@ -0,0 +1,89 @@ +/* + * q2w.c: + *********************************************************************** + */ + +#include +#include +#include +#include +#include + +#include +#include + +// MCP23S17 Registers + +#define IOCON 0x0A + +#define IODIRA 0x00 +#define IPOLA 0x02 +#define GPINTENA 0x04 +#define DEFVALA 0x06 +#define INTCONA 0x08 +#define GPPUA 0x0C +#define INTFA 0x0E +#define INTCAPA 0x10 +#define GPIOA 0x12 +#define OLATA 0x14 + +#define IODIRB 0x01 +#define IPOLB 0x03 +#define GPINTENB 0x05 +#define DEFVALB 0x07 +#define INTCONB 0x09 +#define GPPUB 0x0D +#define INTFB 0x0F +#define INTCAPB 0x11 +#define GPIOB 0x13 +#define OLATB 0x15 + +// Bits in the IOCON register + +#define IOCON_BANK_MODE 0x80 +#define IOCON_MIRROR 0x40 +#define IOCON_SEQOP 0x20 +#define IOCON_DISSLW 0x10 +#define IOCON_HAEN 0x08 +#define IOCON_ODR 0x04 +#define IOCON_INTPOL 0x02 +#define IOCON_UNUSED 0x01 + +// Default initialisation mode + +#define IOCON_INIT (IOCON_SEQOP) + + + +/* + ********************************************************************************* + * The works + ********************************************************************************* + */ + +int main (int argc, char *argv []) +{ + int q2w ; + +// if (wiringPiSetup () == -1) +// { fprintf (stderr, "q2w: Unable to initialise wiringPi: %s\n", strerror (errno)) ; return 1 ; } + + if ((q2w = wiringPiI2CSetup (0x20)) == -1) + { fprintf (stderr, "q2w: Unable to initialise I2C: %s\n", strerror (errno)) ; return 1 ; } + +// Very simple direct control of the MCP23017: + + wiringPiI2CWriteReg8 (q2w, IOCON, IOCON_INIT) ; + wiringPiI2CWriteReg8 (q2w, IODIRA, 0x00) ; // Port A -> Outputs + wiringPiI2CWriteReg8 (q2w, IODIRB, 0x00) ; // Port B -> Outputs + + for (;;) + { + wiringPiI2CWriteReg8 (q2w, GPIOA, 0x00) ; // All Off + delay (500) ; + wiringPiI2CWriteReg8 (q2w, GPIOA, 0xFF) ; // All On + delay (500) ; + } + + return 0 ; +} diff --git a/wiringPi/softServo.c b/wiringPi/softServo.c index a6ff1fb..9de9f4f 100644 --- a/wiringPi/softServo.c +++ b/wiringPi/softServo.c @@ -54,6 +54,15 @@ // 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 diff --git a/wiringPi/softTone.c b/wiringPi/softTone.c index d14c2a2..8463627 100644 --- a/wiringPi/softTone.c +++ b/wiringPi/softTone.c @@ -59,7 +59,9 @@ static PI_THREAD (softToneThread) for (;;) { frewq = frewqs [pin] ; - if (frewq != 0) + if (frewq == 0) + delay (1) ; + else { halfPeriod = 500000 / frewq ; diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index df4d969..a68ae33 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -51,9 +51,6 @@ // Added in the 2 UART pins // Change maxPins to numPins to more accurately reflect purpose -// Pad drive current fiddling - -#undef DEBUG_PADS #include #include @@ -65,24 +62,27 @@ #include #include #include +#include #include #include -#include #include +#include +#include #include "wiringPi.h" // Function stubs void (*pinMode) (int pin, int mode) ; +int (*getAlt) (int pin) ; void (*pullUpDnControl) (int pin, int pud) ; void (*digitalWrite) (int pin, int value) ; void (*digitalWriteByte) (int value) ; void (*pwmWrite) (int pin, int value) ; +void (*gpioClockSet) (int pin, int value) ; void (*setPadDrive) (int group, int value) ; int (*digitalRead) (int pin) ; int (*waitForInterrupt) (int pin, int mS) ; -void (*delayMicroseconds) (unsigned int howLong) ; void (*pwmSetMode) (int mode) ; void (*pwmSetRange) (unsigned int range) ; void (*pwmSetClock) (int divisor) ; @@ -98,6 +98,24 @@ void (*pwmSetClock) (int divisor) ; #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 @@ -111,20 +129,21 @@ void (*pwmSetClock) (int divisor) ; #define FSEL_ALT5 0b010 // Access from ARM Running Linux -// Take from Gert/Doms code. Some of this is not in the manual +// Taken from Gert/Doms code. Some of this is not in the manual // that I can find )-: -#define BCM2708_PERI_BASE 0x20000000 -#define GPIO_PADS (BCM2708_PERI_BASE + 0x100000) -#define CLOCK_BASE (BCM2708_PERI_BASE + 0x101000) -#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) -#define GPIO_TIMER (BCM2708_PERI_BASE + 0x00B000) -#define GPIO_PWM (BCM2708_PERI_BASE + 0x20C000) +#define BCM2708_PERI_BASE 0x20000000 +#define GPIO_PADS (BCM2708_PERI_BASE + 0x00100000) +#define CLOCK_BASE (BCM2708_PERI_BASE + 0x00101000) +#define GPIO_BASE (BCM2708_PERI_BASE + 0x00200000) +#define GPIO_TIMER (BCM2708_PERI_BASE + 0x0000B000) +#define GPIO_PWM (BCM2708_PERI_BASE + 0x0020C000) #define PAGE_SIZE (4*1024) #define BLOCK_SIZE (4*1024) // PWM +// Word offsets into the PWM control region #define PWM_CONTROL 0 #define PWM_STATUS 1 @@ -133,17 +152,11 @@ void (*pwmSetClock) (int divisor) ; #define PWM1_RANGE 8 #define PWM1_DATA 9 +// Clock regsiter offsets + #define PWMCLK_CNTL 40 #define PWMCLK_DIV 41 -#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 - #define PWM0_MS_MODE 0x0080 // Run in MS mode #define PWM0_USEFIFO 0x0020 // Data from FIFO #define PWM0_REVPOLAR 0x0010 // Reverse polarity @@ -152,7 +165,16 @@ void (*pwmSetClock) (int divisor) ; #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) @@ -173,33 +195,28 @@ static volatile uint32_t *pads ; static volatile uint32_t *timer ; static volatile uint32_t *timerIrqRaw ; +// Time for easy calculations + +static uint64_t epochMilli, epochMicro ; + +// Misc + +static int wiringPiMode = WPI_MODE_UNINITIALISED ; + // Debugging -static int wiringPiDebug = FALSE ; - -// 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: -// -// 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) +int wiringPiDebug = FALSE ; // sysFds: // Map a file descriptor from the /sys/class/gpio/gpioX/value static int sysFds [64] ; +// 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! @@ -329,11 +346,14 @@ static uint8_t gpioToFEN [] = #endif -// gpioToPUDCLK -// (Word) offset to the Pull Up Down Clock regsiter +// 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, @@ -356,6 +376,9 @@ static uint8_t gpioToPwmALT [] = 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63 } ; +// gpioToPwmPort +// The port value to put a GPIO pin into PWM mode + static uint8_t gpioToPwmPort [] = { 0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7 @@ -369,10 +392,55 @@ static uint8_t gpioToPwmPort [] = } ; +// gpioToGpClkALT: +// ALT value to put a GPIO pin into GP Clock mode. +// On the Pi we can really only use BCM_GPIO_4 and BCM_GPIO_21 +// for clocks 0 and 1 respectivey, however I'll include the full +// list for completeness - maybe one day... -// Time for easy calculations +#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 +} ; -static unsigned long long epoch ; /* * Functions @@ -407,9 +475,11 @@ int wpiPinToGpio (int wpiPin) * 0001 - Not used * 0002 - Rev 1 * 0003 - Rev 1 - * 0004 - Rev 2 - * 0005 - Rev 2 (but error) + * 0004 - Rev 2 (Early reports? + * 0005 - Rev 2 (but error?) * 0006 - Rev 2 + * 0008 - Rev 2 - Model A + * 000e - Rev 2 + 512MB * 000f - Rev 2 + 512MB * * A small thorn is the olde style overvolting - that will add in @@ -418,6 +488,15 @@ int wpiPinToGpio (int wpiPin) ********************************************************************************* */ +static void piBoardRevOops (char *why) +{ + fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ; + fprintf (stderr, " -> %s\n", why) ; + fprintf (stderr, " -> You may want to check:\n") ; + fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ; + exit (EXIT_FAILURE) ; +} + int piBoardRev (void) { FILE *cpuFd ; @@ -425,13 +504,11 @@ int piBoardRev (void) char *c, lastChar ; static int boardRev = -1 ; -// No point checking twice... - - if (boardRev != -1) + if (boardRev != -1) // No point checking twice return boardRev ; if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL) - return -1 ; + piBoardRevOops ("Unable to open /proc/cpuinfo") ; while (fgets (line, 120, cpuFd) != NULL) if (strncmp (line, "Revision", 8) == 0) @@ -439,25 +516,21 @@ int piBoardRev (void) fclose (cpuFd) ; - if (line == NULL) - { - fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ; - fprintf (stderr, " (No \"Revision\" line)\n") ; - errno = 0 ; - return -1 ; - } + if (strncmp (line, "Revision", 8) != 0) + piBoardRevOops ("No \"Revision\" line") ; + + for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c) + *c = 0 ; + if (wiringPiDebug) + printf ("piboardRev: Revision string: %s\n", line) ; + for (c = line ; *c ; ++c) if (isdigit (*c)) break ; if (!isdigit (*c)) - { - fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ; - fprintf (stderr, " (No numeric revision string in: \"%s\"\n", line) ; - errno = 0 ; - return -1 ; - } + piBoardRevOops ("No numeric revision string") ; // If you have overvolted the Pi, then it appears that the revision // has 100000 added to it! @@ -466,26 +539,18 @@ int piBoardRev (void) if (strlen (c) != 4) printf ("piboardRev: This Pi has/is overvolted!\n") ; - lastChar = c [strlen (c) - 2] ; + lastChar = line [strlen (line) - 1] ; + + if (wiringPiDebug) + printf ("piboardRev: lastChar is: '%c' (%d, 0x%02X)\n", lastChar, lastChar, lastChar) ; /**/ if ((lastChar == '2') || (lastChar == '3')) boardRev = 1 ; else boardRev = 2 ; -#ifdef DO_WE_CARE_ABOUT_THIS_NOW - else - { - fprintf (stderr, "WARNING: wiringPi: Unable to determine board revision from \"%d\"\n", r) ; - fprintf (stderr, " -> You may want to check:\n") ; - fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ; - fprintf (stderr, " -> Assuming a Rev 1 board\n") ; - boardRev = 1 ; - } -#endif - if (wiringPiDebug) - printf ("piboardRev: Revision string: %s, board revision: %d\n", c, boardRev) ; + printf ("piBoardRev: Returning revision: %d\n", boardRev) ; return boardRev ; } @@ -493,15 +558,14 @@ int piBoardRev (void) /* - * pinMode: - * Sets the mode of a pin to be input, output or PWM output + * getAlt: + * Returns the ALT bits for a given port. Only really of-use + * for the gpio readall command (I think) ********************************************************************************* */ -void pinModeGpio (int pin, int mode) +int getAltGpio (int pin) { -// register int barrier ; - int fSel, shift, alt ; pin &= 63 ; @@ -509,73 +573,19 @@ void pinModeGpio (int pin, int mode) fSel = gpioToGPFSEL [pin] ; shift = gpioToShift [pin] ; - /**/ if (mode == INPUT) - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input - else if (mode == OUTPUT) - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ; - else if (mode == PWM_OUTPUT) - { - if ((alt = gpioToPwmALT [pin]) == 0) // Not a PWM pin - return ; - -// Set pin to PWM mode - - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; - - delayMicroseconds (110) ; // See comments in pwmSetClockWPi - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; - -// Page 107 of the BCM Peripherals manual talks about the GPIO clocks, -// but I'm assuming (hoping!) that this applies to other clocks too. - - *(pwm + PWM_CONTROL) = 0 ; // Stop PWM - - *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock - delayMicroseconds (110) ; // See comments in pwmSetClockWPi - - while ((*(clk + PWMCLK_CNTL) & 0x80) != 0) // Wait for clock to be !BUSY - delayMicroseconds (1) ; - - *(clk + PWMCLK_DIV) = BCM_PASSWORD | (32 << 12) ; // set pwm div to 32 (19.2/32 = 600KHz) - *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // enable clk - - delayMicroseconds (110) ; // See comments in pwmSetClockWPi - -// Default range register of 1024 - - *(pwm + PWM0_RANGE) = 1024 ; delayMicroseconds (10) ; - *(pwm + PWM1_RANGE) = 1024 ; delayMicroseconds (10) ; - *(pwm + PWM0_DATA) = 0 ; delayMicroseconds (10) ; - *(pwm + PWM1_DATA) = 0 ; delayMicroseconds (10) ; - -// Enable PWMs in balanced mode (default) - - *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ; - - delay (100) ; - } - - -// When we change mode of any pin, we remove the pull up/downs -// Or we used to... Hm. Commented out now because for some wieird reason, -// it seems to block subsequent attempts to set the pull up/downs and I've -// not quite gotten to the bottom of why this happens -// The down-side is that the pull up/downs are rememberd in the SoC between -// power cycles, so it's going to be a good idea to explicitly set them in -// any new code. -// -// pullUpDnControl (pin, PUD_OFF) ; + alt = (*(gpio + fSel) >> shift) & 7 ; + return alt ; } -void pinModeWPi (int pin, int mode) +int getAltWPi (int pin) { - pinModeGpio (pinToGpio [pin & 63], mode) ; + return getAltGpio (pinToGpio [pin & 63]) ; } -void pinModeSys (int pin, int mode) +int getAltSys (int pin) { - return ; + return 0 ; } @@ -620,7 +630,7 @@ void pwmSetRangeSys (unsigned int range) void pwmSetClockWPi (int divisor) { - unsigned int pwm_control ; + uint32_t pwm_control ; divisor &= 4095 ; if (wiringPiDebug) @@ -741,11 +751,11 @@ void digitalWriteByteGpio (int value) else pinSet |= (1 << pinToGpio [pin]) ; - *(gpio + gpioToGPCLR [0]) = pinClr ; - *(gpio + gpioToGPSET [0]) = pinSet ; - mask <<= 1 ; } + + *(gpio + gpioToGPCLR [0]) = pinClr ; + *(gpio + gpioToGPSET [0]) = pinSet ; } void digitalWriteByteSys (int value) @@ -788,6 +798,44 @@ void pwmWriteSys (int pin, int value) } +/* + * gpioClockSet: + * Set the freuency on a GPIO clock pin + ********************************************************************************* + */ + +void gpioClockSetGpio (int pin, int freq) +{ + int divi, divr, divf ; + + pin &= 63 ; + + divi = 19200000 / freq ; + divr = 19200000 % freq ; + divf = (int)((double)divr * 4096.0 / 19200000.0) ; + + if (divi > 4095) + divi = 4095 ; + + *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | GPIO_CLOCK_SOURCE ; // Stop GPIO Clock + while ((*(clk + gpioToClkCon [pin]) & 0x80) != 0) // ... and wait + ; + + *(clk + gpioToClkDiv [pin]) = BCM_PASSWORD | (divi << 12) | divf ; // Set dividers + *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | 0x10 | GPIO_CLOCK_SOURCE ; // Start Clock +} + +void gpioClockSetWPi (int pin, int freq) +{ + gpioClockSetGpio (pinToGpio [pin & 63], freq) ; +} + +void gpioClockSetSys (int pin, int freq) +{ + return ; +} + + /* * setPadDrive: * Set the PAD driver value @@ -804,10 +852,11 @@ void setPadDriveWPi (int group, int value) wrVal = BCM_PASSWORD | 0x18 | (value & 7) ; *(pads + group + 11) = wrVal ; -#ifdef DEBUG_PADS - printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ; - printf ("Read : %08X\n", *(pads + group + 11)) ; -#endif + if (wiringPiDebug) + { + printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ; + printf ("Read : %08X\n", *(pads + group + 11)) ; + } } void setPadDriveGpio (int group, int value) @@ -894,6 +943,65 @@ void pullUpDnControlSys (int pin, int pud) } +/* + * pinMode: + * Sets the mode of a pin to be input, output or PWM output + ********************************************************************************* + */ + +void pinModeGpio (int pin, int mode) +{ +// register int barrier ; + + int fSel, shift, alt ; + + pin &= 63 ; + + fSel = gpioToGPFSEL [pin] ; + shift = gpioToShift [pin] ; + + /**/ if (mode == INPUT) + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input + else if (mode == OUTPUT) + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ; + else if (mode == PWM_OUTPUT) + { + if ((alt = gpioToPwmALT [pin]) == 0) // Not a PWM pin + return ; + +// Set pin to PWM mode + + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; + delayMicroseconds (110) ; // See comments in pwmSetClockWPi + + pwmSetModeWPi (PWM_MODE_BAL) ; // Pi default mode + pwmSetRangeWPi (1024) ; // Default range of 1024 + pwmSetClockWPi (32) ; // 19.2 / 32 = 600KHz - Also starts the PWM + } + else if (mode == GPIO_CLOCK) + { + if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin + return ; + +// Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz + + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; + delayMicroseconds (110) ; + gpioClockSetGpio (pin, 100000) ; + } +} + +void pinModeWPi (int pin, int mode) +{ + pinModeGpio (pinToGpio [pin & 63], mode) ; +} + +void pinModeSys (int pin, int mode) +{ + return ; +} + + /* * waitForInterrupt: * Wait for Interrupt on a GPIO pin. @@ -906,22 +1014,12 @@ void pullUpDnControlSys (int pin, int pud) int waitForInterruptSys (int pin, int mS) { int fd, x ; - char buf [8] ; + uint8_t c ; struct pollfd polls ; if ((fd = sysFds [pin & 63]) == -1) return -2 ; -// Do a dummy read - - x = read (fd, buf, 6) ; - if (x < 0) - return x ; - -// And seek - - lseek (fd, 0, SEEK_SET) ; - // Setup poll structure polls.fd = fd ; @@ -929,7 +1027,14 @@ int waitForInterruptSys (int pin, int mS) // Wait for it ... - return poll (&polls, 1, mS) ; + x = poll (&polls, 1, mS) ; + +// Do a dummy read to clear the interrupt +// A one character read appars to be enough. + + (void)read (fd, &c, 1) ; + + return x ; } int waitForInterruptWPi (int pin, int mS) @@ -943,6 +1048,123 @@ int waitForInterruptGpio (int pin, int mS) } +/* + * 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 (void *arg) +{ + int myPin = *(int *)arg ; + + (void)piHiPri (55) ; // Only effective if we run as root + + for (;;) + if (waitForInterruptSys (myPin, -1) > 0) + isrFunctions [myPin] () ; + + return NULL ; +} + + +/* + * wiringPiISR: + * 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 ; + char fName [64] ; + char *modeS ; + char pinS [8] ; + pid_t pid ; + int count, i ; + uint8_t c ; + + pin &= 63 ; + + if (wiringPiMode == WPI_MODE_UNINITIALISED) + { + fprintf (stderr, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ; + exit (EXIT_FAILURE) ; + } + else if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [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 pid ; + + if (pid == 0) // Child, exec + { + execl ("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ; + return -1 ; // Failure ... + } + else // Parent, wait + wait (NULL) ; + } + +// Now pre-open the /sys/class node - it may already be open if +// we are in Sys mode, but this will do no harm. + + sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; + if ((sysFds [pin] = open (fName, O_RDWR)) < 0) + return -1 ; + +// Clear any initial pending interrupt + + ioctl (sysFds [pin], FIONREAD, &count) ; + for (i = 0 ; i < count ; ++i) + read (sysFds [pin], &c, 1) ; + + isrFunctions [pin] = function ; + + pthread_create (&threadId, NULL, interruptHandler, &pin) ; + + delay (1) ; + + return 0 ; +} + + +/* + * initialiseEpoch: + * Initialise our start-of-time variable to be the current unix + * time in milliseconds. + ********************************************************************************* + */ + +static void initialiseEpoch (void) +{ + 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) ; +} + /* * delay: * Wait for some number of milli seconds @@ -978,28 +1200,8 @@ void delay (unsigned int howLong) ********************************************************************************* */ -void delayMicrosecondsSys (unsigned int howLong) -{ - struct timespec sleeper, dummy ; - - sleeper.tv_sec = 0 ; - sleeper.tv_nsec = (long)(howLong * 1000) ; - - nanosleep (&sleeper, &dummy) ; -} - void delayMicrosecondsHard (unsigned int howLong) { -#ifdef HARD_TIMER - volatile unsigned int dummy ; - - *(timer + TIMER_LOAD) = howLong ; - *(timer + TIMER_IRQ_CLR) = 0 ; - - dummy = *timerIrqRaw ; - while (dummy == 0) - dummy = *timerIrqRaw ; -#else struct timeval tNow, tLong, tEnd ; gettimeofday (&tNow, NULL) ; @@ -1009,10 +1211,9 @@ void delayMicrosecondsHard (unsigned int howLong) while (timercmp (&tNow, &tEnd, <)) gettimeofday (&tNow, NULL) ; -#endif } -void delayMicrosecondsWPi (unsigned int howLong) +void delayMicroseconds (unsigned int howLong) { struct timespec sleeper ; @@ -1038,13 +1239,30 @@ void delayMicrosecondsWPi (unsigned int howLong) unsigned int millis (void) { struct timeval tv ; - unsigned long long t1 ; + uint64_t now ; gettimeofday (&tv, NULL) ; + now = (uint64_t)tv.tv_sec * (uint64_t)1000 + (uint64_t)(tv.tv_usec / 1000) ; - t1 = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ; + return (uint32_t)(now - epochMilli) ; +} - return (uint32_t)(t1 - epoch) ; + +/* + * micros: + * Return a number of microseconds as an unsigned int. + ********************************************************************************* + */ + +unsigned int micros (void) +{ + struct timeval tv ; + uint64_t now ; + + gettimeofday (&tv, NULL) ; + now = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)tv.tv_usec ; + + return (uint32_t)(now - epochMicro) ; } @@ -1061,30 +1279,37 @@ int wiringPiSetup (void) { int fd ; int boardRev ; - uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ; - struct timeval tv ; + + if (geteuid () != 0) + { + fprintf (stderr, "wiringPi:\n Must be root to call wiringPiSetup().\n (Did you forget sudo?)\n") ; + exit (EXIT_FAILURE) ; + } if (getenv ("WIRINGPI_DEBUG") != NULL) + { + printf ("wiringPi: Debug mode enabled\n") ; wiringPiDebug = TRUE ; + } if (wiringPiDebug) printf ("wiringPi: wiringPiSetup called\n") ; pinMode = pinModeWPi ; + getAlt = getAltWPi ; pullUpDnControl = pullUpDnControlWPi ; digitalWrite = digitalWriteWPi ; digitalWriteByte = digitalWriteByteGpio ; // Same code + gpioClockSet = gpioClockSetWPi ; pwmWrite = pwmWriteWPi ; setPadDrive = setPadDriveWPi ; digitalRead = digitalReadWPi ; waitForInterrupt = waitForInterruptWPi ; - delayMicroseconds = delayMicrosecondsWPi ; pwmSetMode = pwmSetModeWPi ; pwmSetRange = pwmSetRangeWPi ; pwmSetClock = pwmSetClockWPi ; - if ((boardRev = piBoardRev ()) < 0) - return -1 ; + boardRev = piBoardRev () ; if (boardRev == 1) pinToGpio = pinToGpioR1 ; @@ -1095,111 +1320,82 @@ int wiringPiSetup (void) if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0) { - fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ; + if (wiringPiDebug) + { + int serr = errno ; + fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ; + errno = serr ; + } return -1 ; } // GPIO: -// Allocate 2 pages - 1 ... - - if ((gpioMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) + gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ; + if ((int32_t)gpio == -1) { - fprintf (stderr, "wiringPiSetup: malloc failed: %s\n", strerror (errno)) ; - return -1 ; - } - -// ... presumably to make sure we can round it up to a whole page size - - if (((uint32_t)gpioMem % PAGE_SIZE) != 0) - gpioMem += PAGE_SIZE - ((uint32_t)gpioMem % PAGE_SIZE) ; - - gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_BASE) ; - - if ((int32_t)gpio < 0) - { - fprintf (stderr, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ; + if (wiringPiDebug) + { + int serr = errno ; + fprintf (stderr, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ; + errno = serr ; + } return -1 ; } // PWM - if ((pwmMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) + pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ; + if ((int32_t)pwm == -1) { - fprintf (stderr, "wiringPiSetup: pwmMem malloc failed: %s\n", strerror (errno)) ; - return -1 ; - } - - if (((uint32_t)pwmMem % PAGE_SIZE) != 0) - pwmMem += PAGE_SIZE - ((uint32_t)pwmMem % PAGE_SIZE) ; - - pwm = (uint32_t *)mmap(pwmMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PWM) ; - - if ((int32_t)pwm < 0) - { - fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ; + if (wiringPiDebug) + { + int serr = errno ; + fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ; + errno = serr ; + } return -1 ; } // Clock control (needed for PWM) - if ((clkMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) + clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, CLOCK_BASE) ; + if ((int32_t)clk == -1) { - fprintf (stderr, "wiringPiSetup: clkMem malloc failed: %s\n", strerror (errno)) ; - return -1 ; - } - - if (((uint32_t)clkMem % PAGE_SIZE) != 0) - clkMem += PAGE_SIZE - ((uint32_t)clkMem % PAGE_SIZE) ; - - clk = (uint32_t *)mmap(clkMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, CLOCK_BASE) ; - - if ((int32_t)clk < 0) - { - fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ; + if (wiringPiDebug) + { + int serr = errno ; + fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ; + errno = serr ; + } return -1 ; } // The drive pads - if ((padsMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) + pads = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PADS) ; + if ((int32_t)pads == -1) { - fprintf (stderr, "wiringPiSetup: padsMem malloc failed: %s\n", strerror (errno)) ; + if (wiringPiDebug) + { + int serr = errno ; + fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ; + errno = serr ; + } return -1 ; } - if (((uint32_t)padsMem % PAGE_SIZE) != 0) - padsMem += PAGE_SIZE - ((uint32_t)padsMem % PAGE_SIZE) ; - - pads = (uint32_t *)mmap(padsMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PADS) ; - - if ((int32_t)pads < 0) - { - fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ; - return -1 ; - } - -#ifdef DEBUG_PADS - printf ("Checking pads @ 0x%08X\n", (unsigned int)pads) ; - printf (" -> %08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ; -#endif - // The system timer - if ((timerMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) + timer = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_TIMER) ; + if ((int32_t)timer == -1) { - fprintf (stderr, "wiringPiSetup: timerMem malloc failed: %s\n", strerror (errno)) ; - return -1 ; - } - - if (((uint32_t)timerMem % PAGE_SIZE) != 0) - timerMem += PAGE_SIZE - ((uint32_t)timerMem % PAGE_SIZE) ; - - timer = (uint32_t *)mmap(timerMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_TIMER) ; - - if ((int32_t)timer < 0) - { - fprintf (stderr, "wiringPiSetup: mmap failed (timer): %s\n", strerror (errno)) ; + if (wiringPiDebug) + { + int serr = errno ; + fprintf (stderr, "wiringPiSetup: mmap failed (timer): %s\n", strerror (errno)) ; + errno = serr ; + } return -1 ; } @@ -1211,10 +1407,9 @@ int wiringPiSetup (void) *(timer + TIMER_PRE_DIV) = 0x00000F9 ; timerIrqRaw = timer + TIMER_IRQ_RAW ; -// Initialise our epoch for millis() + initialiseEpoch () ; - gettimeofday (&tv, NULL) ; - epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ; + wiringPiMode = WPI_MODE_PINS ; return 0 ; } @@ -1233,25 +1428,34 @@ int wiringPiSetupGpio (void) { int x ; - if (wiringPiDebug) - printf ("wiringPi: wiringPiSetupGpio called\n") ; + if (geteuid () != 0) + { + fprintf (stderr, "Must be root to call wiringPiSetupGpio(). (Did you forget sudo?)\n") ; + exit (EXIT_FAILURE) ; + } if ((x = wiringPiSetup ()) < 0) return x ; + if (wiringPiDebug) + printf ("wiringPi: wiringPiSetupGpio called\n") ; + pinMode = pinModeGpio ; + getAlt = getAltGpio ; pullUpDnControl = pullUpDnControlGpio ; digitalWrite = digitalWriteGpio ; digitalWriteByte = digitalWriteByteGpio ; + gpioClockSet = gpioClockSetGpio ; pwmWrite = pwmWriteGpio ; setPadDrive = setPadDriveGpio ; digitalRead = digitalReadGpio ; waitForInterrupt = waitForInterruptGpio ; - delayMicroseconds = delayMicrosecondsWPi ; // Same pwmSetMode = pwmSetModeWPi ; pwmSetRange = pwmSetRangeWPi ; pwmSetClock = pwmSetClockWPi ; + wiringPiMode = WPI_MODE_GPIO ; + return 0 ; } @@ -1269,34 +1473,35 @@ int wiringPiSetupSys (void) { int boardRev ; int pin ; - struct timeval tv ; char fName [128] ; + if (getenv ("WIRINGPI_DEBUG") != NULL) + wiringPiDebug = TRUE ; + if (wiringPiDebug) printf ("wiringPi: wiringPiSetupSys called\n") ; pinMode = pinModeSys ; + getAlt = getAltSys ; pullUpDnControl = pullUpDnControlSys ; digitalWrite = digitalWriteSys ; digitalWriteByte = digitalWriteByteSys ; + gpioClockSet = gpioClockSetSys ; pwmWrite = pwmWriteSys ; setPadDrive = setPadDriveSys ; digitalRead = digitalReadSys ; waitForInterrupt = waitForInterruptSys ; - delayMicroseconds = delayMicrosecondsSys ; pwmSetMode = pwmSetModeSys ; pwmSetRange = pwmSetRangeSys ; pwmSetClock = pwmSetClockSys ; - if ((boardRev = piBoardRev ()) < 0) - return -1 ; + boardRev = piBoardRev () ; if (boardRev == 1) pinToGpio = pinToGpioR1 ; else pinToGpio = pinToGpioR2 ; - // Open and scan the directory, looking for exported GPIOs, and pre-open // the 'value' interface to speed things up for later @@ -1306,10 +1511,9 @@ int wiringPiSetupSys (void) sysFds [pin] = open (fName, O_RDWR) ; } -// Initialise the epoch for mills() ... + initialiseEpoch () ; - gettimeofday (&tv, NULL) ; - epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ; + wiringPiMode = WPI_MODE_GPIO_SYS ; return 0 ; } diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 6a7278e..18c6da5 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -23,32 +23,50 @@ // Handy defines +// Deprecated #define NUM_PINS 17 #define WPI_MODE_PINS 0 #define WPI_MODE_GPIO 1 #define WPI_MODE_GPIO_SYS 2 #define WPI_MODE_PIFACE 3 +#define WPI_MODE_UNINITIALISED -1 -#define INPUT 0 -#define OUTPUT 1 -#define PWM_OUTPUT 2 +// Pin modes -#define LOW 0 -#define HIGH 1 +#define INPUT 0 +#define OUTPUT 1 +#define PWM_OUTPUT 2 +#define GPIO_CLOCK 3 -#define PUD_OFF 0 -#define PUD_DOWN 1 -#define PUD_UP 2 +#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 +#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 + +// Threads + +#define PI_THREAD(X) void *X (void *dummy) // Function prototypes -// c++ wrappers thanks to a commend by Nick Lott +// c++ wrappers thanks to a comment by Nick Lott // (and others on the Raspberry Pi forums) #ifdef __cplusplus @@ -68,13 +86,14 @@ extern int wpiPinToGpio (int wpiPin) ; extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only extern void (*pinMode) (int pin, int mode) ; +extern int (*getAlt) (int pin) ; extern void (*pullUpDnControl) (int pin, int pud) ; extern void (*digitalWrite) (int pin, int value) ; extern void (*digitalWriteByte) (int value) ; +extern void (*gpioClockSet) (int pin, int freq) ; extern void (*pwmWrite) (int pin, int value) ; extern void (*setPadDrive) (int group, int value) ; extern int (*digitalRead) (int pin) ; -extern void (*delayMicroseconds) (unsigned int howLong) ; extern void (*pwmSetMode) (int mode) ; extern void (*pwmSetRange) (unsigned int range) ; extern void (*pwmSetClock) (int divisor) ; @@ -82,11 +101,10 @@ extern void (*pwmSetClock) (int divisor) ; // Interrupts extern int (*waitForInterrupt) (int pin, int mS) ; +extern int wiringPiISR (int pin, int mode, void (*function)(void)) ; // Threads -#define PI_THREAD(X) void *X (void *dummy) - extern int piThreadCreate (void *(*fn)(void *)) ; extern void piLock (int key) ; extern void piUnlock (int key) ; @@ -99,7 +117,9 @@ extern int piHiPri (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 } diff --git a/wiringPi/wiringPiI2C.c b/wiringPi/wiringPiI2C.c new file mode 100644 index 0000000..93fe1d3 --- /dev/null +++ b/wiringPi/wiringPiI2C.c @@ -0,0 +1,122 @@ +/* + * 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 . + *********************************************************************** + */ + +#include +#include +#include +#include +#include + +#include "wiringPi.h" +#include "wiringPiI2C.h" + + +/* + * wiringPiI2CRead: + * Simple device read + ********************************************************************************* + */ + +int wiringPiI2CRead (int fd) +{ + return i2c_smbus_read_byte (fd) ; +} + + +/* + * wiringPiI2CReadReg8: wiringPiI2CReadReg16: + * Read an 8 or 16-bit value from a regsiter on the device + ********************************************************************************* + */ + +int wiringPiI2CReadReg8 (int fd, int reg) +{ + return i2c_smbus_read_byte_data (fd, reg) ; +} + +int wiringPiI2CReadReg16 (int fd, int reg) +{ + return i2c_smbus_read_word_data (fd, reg) ; +} + + +/* + * wiringPiI2CWrite: + * Simple device write + ********************************************************************************* + */ + +int wiringPiI2CWrite (int fd, int data) +{ + return i2c_smbus_write_byte (fd, data) ; +} + + +/* + * wiringPiI2CWriteReg8: wiringPiI2CWriteReg16: + * Write an 8 or 16-bit value to the given register + ********************************************************************************* + */ + +int wiringPiI2CWriteReg8 (int fd, int reg, int data) +{ + return i2c_smbus_write_byte_data (fd, reg, data) ; +} + +int wiringPiI2CWriteReg16 (int fd, int reg, int data) +{ + return i2c_smbus_write_word_data (fd, reg, data) ; +} + + +/* + * wiringPiI2CSetup: + * Open the I2C device, and regsiter the target device + ********************************************************************************* + */ + +int wiringPiI2CSetup (int devId) +{ + int rev, fd ; + char *device ; + + if ((rev = piBoardRev ()) < 0) + { + fprintf (stderr, "wiringPiI2CSetup: Unable to determine Pi board revision\n") ; + exit (1) ; + } + + if (rev == 1) + device = "/dev/i2c-0" ; + else + device = "/dev/i2c-1" ; + + if ((fd = open (device, O_RDWR)) < 0) + return -1 ; + + if (ioctl (fd, I2C_SLAVE, devId) < 0) + return -1 ; + + return fd ; +} diff --git a/wiringPi/wiringPiI2C.h b/wiringPi/wiringPiI2C.h new file mode 100644 index 0000000..6710ff4 --- /dev/null +++ b/wiringPi/wiringPiI2C.h @@ -0,0 +1,41 @@ +/* + * 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) ; + +int wiringPiI2CSetup (int devId) ; + +#ifdef __cplusplus +} +#endif From 3fbc564d00b4e8fa5dc6772190575f7d1d12d12d Mon Sep 17 00:00:00 2001 From: Gordon Henderson Date: Sun, 24 Mar 2013 20:04:07 +0000 Subject: [PATCH 14/29] Synced to git.drogon.net --- INSTALL | 48 +++ People | 12 + README.TXT | 26 ++ build | 63 ++- examples/Makefile | 36 +- examples/README.TXT | 6 +- examples/blink.c | 50 +++ examples/blink.rtb | 30 ++ examples/blink.sh | 37 ++ examples/delayTest.c | 24 ++ examples/gertboard.c | 19 +- examples/header.h | 23 ++ examples/isr-osc.c | 118 ++++++ examples/isr.c | 99 +++++ examples/nes.c | 23 ++ examples/okLed.c | 22 +- examples/piface.c | 24 +- examples/pwm.c | 24 ++ examples/serialRead.c | 21 +- examples/serialTest.c | 75 ++++ examples/servo.c | 24 ++ examples/speed.c | 20 +- examples/test1.c | 22 +- examples/test2.c | 23 +- examples/tone.c | 34 +- examples/wfi.c | 31 +- gpio/Makefile | 6 +- gpio/gpio | Bin 0 -> 21304 bytes gpio/gpio.1 | 43 +- gpio/gpio.c | 134 ++++--- wiringPi/Makefile | 37 +- wiringPi/lcd.c | 12 + wiringPi/lcd.h | 13 +- wiringPi/libwiringPi.so.1.0 | Bin 0 -> 43311 bytes wiringPi/q2w.c | 89 +++++ wiringPi/softServo.c | 9 + wiringPi/softTone.c | 4 +- wiringPi/wiringPi.c | 762 +++++++++++++++++++++++------------- wiringPi/wiringPi.h | 48 ++- wiringPi/wiringPiI2C.c | 122 ++++++ wiringPi/wiringPiI2C.h | 41 ++ 41 files changed, 1829 insertions(+), 425 deletions(-) create mode 100644 INSTALL create mode 100644 README.TXT create mode 100644 examples/blink.c create mode 100644 examples/blink.rtb create mode 100644 examples/blink.sh create mode 100644 examples/header.h create mode 100644 examples/isr-osc.c create mode 100644 examples/isr.c create mode 100644 examples/serialTest.c create mode 100755 gpio/gpio create mode 100755 wiringPi/libwiringPi.so.1.0 create mode 100644 wiringPi/q2w.c create mode 100644 wiringPi/wiringPiI2C.c create mode 100644 wiringPi/wiringPiI2C.h diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..8a6d38e --- /dev/null +++ b/INSTALL @@ -0,0 +1,48 @@ + +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 + +If you want to install a static library, you may need to do this manually: + + cd wiringPi + make static + sudo make install-static + + +To un-install wiringPi: + + ./build uninstall + + +I2C: + +If your system has the correct i2c-dev libraries and headers installed, +then the I2C helpers will be compiled into wiringPi. If you want to +use the I2C helpers and don't have them installed, then under Raspbian, +issue the command: + + sudo apt-get install libi2c-dev + +Consult the documentation for your system if you are not running Raspbian. + +Gordon Henderson + +projects@drogon.net +https://projects.drogon.net/ diff --git a/People b/People index e0c262c..8be8b6d 100644 --- a/People +++ b/People @@ -13,3 +13,15 @@ Chris McSweeny 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! diff --git a/README.TXT b/README.TXT new file mode 100644 index 0000000..0fce86a --- /dev/null +++ b/README.TXT @@ -0,0 +1,26 @@ + +wiringPi README +=============== + +Please note that the official way to get wiringPi is via git from +git.drogon.net and not GitHub. + +ie. + + git clone git://git.drogon.net/wiringPi + +The version of wiringPi held on GitHub by "Gadgetoid" is used to build the +wiringPython, Ruby, Perl, etc. wrappers for these other languages. This +version may lag the official Drogon release. Pull requests may not be +accepted to Github.... + +Please see + + https://projects.drogon.net/raspberry-pi/wiringpi/ + +for the official documentation, etc. and the best way to submit bug reports, etc. +is by sending an email to projects@drogon.net + +Thanks! + + -Gordon diff --git a/build b/build index 740b512..cbb1a4f 100755 --- a/build +++ b/build @@ -1,5 +1,18 @@ #!/bin/bash +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 +} + if [ x$1 = "xclean" ]; then echo Cleaning echo @@ -9,8 +22,10 @@ if [ x$1 = "xclean" ]; then make clean cd ../examples make clean - cd .. -elif [ x$1 = "xuninstall" ]; then + exit +fi + +if [ x$1 = "xuninstall" ]; then echo Uninstalling echo echo "WiringPi library" @@ -21,24 +36,50 @@ elif [ x$1 = "xuninstall" ]; then cd ../gpio sudo make uninstall cd .. -else - echo wiringPi Build script - please wait... + exit +fi + + + echo "wiringPi Build script" + echo "=====================" + echo + +# Check for I2C being installed... +# ... and if-so, then automatically make the I2C helpers + + if [ -f /usr/include/linux/i2c-dev.h ]; then + grep -q i2c_smbus_read_byte /usr/include/linux/i2c-dev.h + if [ $? = 0 ]; then + target=i2c + echo "Building wiringPi with the I2C helper libraries." + else + target=all + echo "The wiringPi I2C helper libraries will not be built." + fi + fi + echo echo "WiringPi library" cd wiringPi - make + sudo make uninstall + make $target + check-make-ok sudo make install + check-make-ok + echo echo "GPIO Utility" cd ../gpio make + check-make-ok sudo make install - echo - echo "Examples" - cd ../examples - make - cd .. -fi + check-make-ok + +# echo +# echo "Examples" +# cd ../examples +# make +# cd .. echo echo All Done. diff --git a/examples/Makefile b/examples/Makefile index 738d36c..defd510 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -30,15 +30,15 @@ INCLUDE = -I/usr/local/include CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe LDFLAGS = -L/usr/local/lib -LDLIBS = -lwiringPi +LDLIBS = -lwiringPi -lpthread -lm # Should not alter anything below this line ############################################################################### -SRC = test1.c test2.c speed.c lcd.c wfi.c \ - piface.c gertboard.c nes.c \ - pwm.c tone.c servo.c \ - delayTest.c serialRead.c okLed.c +SRC = blink.c test1.c test2.c speed.c lcd.c wfi.c isr.c isr-osc.c \ + piface.c gertboard.c nes.c \ + pwm.c tone.c servo.c \ + delayTest.c serialRead.c serialTest.c okLed.c OBJ = $(SRC:.c=.o) @@ -49,6 +49,12 @@ all: @echo " $(BINS)" | fmt @echo "" +really-all: $(BINS) + +blink: blink.o + @echo [link] + @$(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS) + test1: test1.o @echo [link] @$(CC) -o $@ test1.o $(LDFLAGS) $(LDLIBS) @@ -69,21 +75,29 @@ wfi: wfi.o @echo [link] @$(CC) -o $@ wfi.o $(LDFLAGS) $(LDLIBS) +isr: isr.o + @echo [link] + @$(CC) -o $@ isr.o $(LDFLAGS) $(LDLIBS) + +isr-osc: isr-osc.o + @echo [link] + @$(CC) -o $@ isr-osc.o $(LDFLAGS) $(LDLIBS) + piface: piface.o @echo [link] - @$(CC) -o $@ piface.o $(LDFLAGS) $(LDLIBS) -lpthread + @$(CC) -o $@ piface.o $(LDFLAGS) $(LDLIBS) gertboard: gertboard.o @echo [link] - @$(CC) -o $@ gertboard.o $(LDFLAGS) $(LDLIBS) -lm + @$(CC) -o $@ gertboard.o $(LDFLAGS) $(LDLIBS) nes: nes.o @echo [link] - @$(CC) -o $@ nes.o $(LDFLAGS) $(LDLIBS) -lm + @$(CC) -o $@ nes.o $(LDFLAGS) $(LDLIBS) pwm: pwm.o @echo [link] - @$(CC) -o $@ pwm.o $(LDFLAGS) $(LDLIBS) -lm -lpthread + @$(CC) -o $@ pwm.o $(LDFLAGS) $(LDLIBS) delayTest: delayTest.o @echo [link] @@ -93,6 +107,10 @@ serialRead: serialRead.o @echo [link] @$(CC) -o $@ serialRead.o $(LDFLAGS) $(LDLIBS) +serialTest: serialTest.o + @echo [link] + @$(CC) -o $@ serialTest.o $(LDFLAGS) $(LDLIBS) + okLed: okLed.o @echo [link] @$(CC) -o $@ okLed.o $(LDFLAGS) $(LDLIBS) diff --git a/examples/README.TXT b/examples/README.TXT index 2bf6f1e..33263b1 100644 --- a/examples/README.TXT +++ b/examples/README.TXT @@ -10,5 +10,9 @@ To compile an individual example, just type make exampleName -Where exampleName is one of: +To really compile everything: + + make really-all + +The individual tests are: diff --git a/examples/blink.c b/examples/blink.c new file mode 100644 index 0000000..bb9f856 --- /dev/null +++ b/examples/blink.c @@ -0,0 +1,50 @@ +/* + * blink.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 + +int main (void) +{ + printf ("Raspberry Pi blink\n") ; + + if (wiringPiSetup () == -1) + return 1 ; + + pinMode (LED, OUTPUT) ; + + for (;;) + { + digitalWrite (LED, 1) ; // On + delay (500) ; // mS + digitalWrite (LED, 0) ; // Off + delay (500) ; + } + 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..2aa378a --- /dev/null +++ b/examples/blink.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# +# 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. + +LED=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/delayTest.c b/examples/delayTest.c index d05f3ff..4c8b6ca 100644 --- a/examples/delayTest.c +++ b/examples/delayTest.c @@ -1,3 +1,27 @@ +/* + * 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 diff --git a/examples/gertboard.c b/examples/gertboard.c index 8f26dd4..f02e27d 100644 --- a/examples/gertboard.c +++ b/examples/gertboard.c @@ -1,4 +1,3 @@ - /* * gertboard.c: * Simple test for the SPI bus on the Gertboard @@ -10,6 +9,24 @@ * copy this value to D/A port 1 and use a 'scope on both D/A ports * to check all's well. * + * 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 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..2bef54a --- /dev/null +++ b/examples/isr.c @@ -0,0 +1,99 @@ +/* + * 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 + + +// What GPIO input are we using? +// This is a wiringPi pin number + +#define BUTTON_PIN 0 + +// globalCounter: +// Global variable to count interrupts +// Should be declared volatile to make sure the compiler doesn't cache it. + +static volatile int globalCounter = 0 ; + + +/* + * myInterrupt: + ********************************************************************************* + */ + +void myInterrupt (void) +{ + ++globalCounter ; +} + + +/* + ********************************************************************************* + * main + ********************************************************************************* + */ + +int main (void) +{ + int myCounter = 0 ; + + if (wiringPiSetup () < 0) + { + fprintf (stderr, "Unable to setup wiringPi: %s\n", strerror (errno)) ; + return 1 ; + } + + if (wiringPiISR (BUTTON_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 (100) ; + + printf (" Done. counter: %5d\n", globalCounter) ; + myCounter = globalCounter ; + } + + return 0 ; +} diff --git a/examples/nes.c b/examples/nes.c index 1a485bd..31908e8 100644 --- a/examples/nes.c +++ b/examples/nes.c @@ -1,3 +1,26 @@ +/* + * 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 diff --git a/examples/okLed.c b/examples/okLed.c index 3bf21e2..9b3a170 100644 --- a/examples/okLed.c +++ b/examples/okLed.c @@ -1,7 +1,6 @@ /* - * okLed: + * okLed.c: * Make the OK LED on the Pi Pulsate... - * Copyright (c) 2012 gordon Henderson, but please Share and Enjoy! * * Originally posted to the Raspberry Pi forums: * http://www.raspberrypi.org/phpBB3/viewtopic.php?p=162581#p162581 @@ -10,6 +9,24 @@ * 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 @@ -17,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/examples/piface.c b/examples/piface.c index 3305bf9..0f00960 100644 --- a/examples/piface.c +++ b/examples/piface.c @@ -1,9 +1,27 @@ - /* - * piface.c: - * Simple test for the PiFace + * piFace.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 diff --git a/examples/pwm.c b/examples/pwm.c index 09b4ae0..c1fc331 100644 --- a/examples/pwm.c +++ b/examples/pwm.c @@ -1,3 +1,27 @@ +/* + * pwm.c: + * Test of the software PWM driver. Needs 12 LEDs 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 diff --git a/examples/serialRead.c b/examples/serialRead.c index 34b9bad..9ee11ac 100644 --- a/examples/serialRead.c +++ b/examples/serialRead.c @@ -1,8 +1,25 @@ - /* - * serialRead.c: + * 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 diff --git a/examples/serialTest.c b/examples/serialTest.c new file mode 100644 index 0000000..0d6da5f --- /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/ttyAMA0", 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 index 0237832..aa1ab05 100644 --- a/examples/servo.c +++ b/examples/servo.c @@ -1,3 +1,27 @@ +/* + * 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 diff --git a/examples/speed.c b/examples/speed.c index 2f5d990..863317e 100644 --- a/examples/speed.c +++ b/examples/speed.c @@ -1,8 +1,26 @@ - /* * 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 diff --git a/examples/test1.c b/examples/test1.c index 7eb0abd..4c75711 100644 --- a/examples/test1.c +++ b/examples/test1.c @@ -1,7 +1,27 @@ - /* * test1.c: * Simple test program to test the wiringPi functions + * This is a sequencer to make a patter appear on 8 LEDs + * connected to the GPIO pins. + * + * 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 diff --git a/examples/test2.c b/examples/test2.c index e34013c..580591e 100644 --- a/examples/test2.c +++ b/examples/test2.c @@ -1,8 +1,25 @@ - /* * test2.c: - * Simple test program to test the wiringPi functions - * PWM test + * 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 diff --git a/examples/tone.c b/examples/tone.c index 8b1fcd7..0e8a47d 100644 --- a/examples/tone.c +++ b/examples/tone.c @@ -1,3 +1,27 @@ +/* + * tone.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 @@ -6,15 +30,13 @@ #include #include -#define RANGE 100 -#define NUM_LEDS 12 +#define PIN 3 int scale [8] = { 262, 294, 330, 349, 392, 440, 494, 525 } ; int main () { - int i, j ; - char buf [80] ; + int i ; if (wiringPiSetup () == -1) { @@ -22,14 +44,14 @@ int main () return 1 ; } - softToneCreate (3) ; + softToneCreate (PIN) ; for (;;) { for (i = 0 ; i < 8 ; ++i) { printf ("%3d\n", i) ; - softToneWrite (3, scale [i]) ; + softToneWrite (PIN, scale [i]) ; delay (500) ; } } diff --git a/examples/wfi.c b/examples/wfi.c index 9efcc2c..6bb6892 100644 --- a/examples/wfi.c +++ b/examples/wfi.c @@ -2,7 +2,17 @@ * wfi.c: * Wait for Interrupt test program * - * Copyright (c) 2012 Gordon Henderson. + * 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/ @@ -33,9 +43,8 @@ #define COUNT_KEY 0 // What BCM_GPIO input are we using? -// GPIO 0 is one of the I2C pins with an on-board pull-up -#define BUTTON_PIN 0 +#define BUTTON_PIN 17 // Debounce time in mS @@ -63,13 +72,11 @@ PI_THREAD (waitForIt) int debounceTime = 0 ; (void)piHiPri (10) ; // Set this thread to be high priority - digitalWrite (18, 1) ; for (;;) { if (waitForInterrupt (BUTTON_PIN, -1) > 0) // Got it { - // Bouncing? if (millis () < debounceTime) @@ -80,7 +87,6 @@ PI_THREAD (waitForIt) // We have a valid one - digitalWrite (17, state) ; state ^= 1 ; piLock (COUNT_KEY) ; @@ -89,7 +95,7 @@ PI_THREAD (waitForIt) // Wait for key to be released - while (digitalRead (0) == LOW) + while (digitalRead (BUTTON_PIN) == LOW) delay (1) ; debounceTime = millis () + DEBOUNCE_TIME ; @@ -108,11 +114,9 @@ void setup (void) { // Use the gpio program to initialise the hardware -// (This is the crude, but effective bit) +// (This is the crude, but effective) - system ("gpio edge 0 falling") ; - system ("gpio export 17 out") ; - system ("gpio export 18 out") ; + system ("gpio edge 17 falling") ; // Setup wiringPi @@ -120,9 +124,8 @@ void setup (void) // Fire off our interrupt handler - piThreadCreate (waitForIt) ; + piThreadCreate (waitForIt) ; - digitalWrite (17, 0) ; } @@ -147,7 +150,7 @@ int main (void) piLock (COUNT_KEY) ; myCounter = globalCounter ; piUnlock (COUNT_KEY) ; - delay (5000) ; + delay (500) ; } printf (" Done. myCounter: %5d\n", myCounter) ; diff --git a/gpio/Makefile b/gpio/Makefile index 5693c44..a043962 100644 --- a/gpio/Makefile +++ b/gpio/Makefile @@ -30,7 +30,7 @@ INCLUDE = -I/usr/local/include CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe LDFLAGS = -L/usr/local/lib -LIBS = -lwiringPi +LIBS = -lwiringPi -lpthread -lm # May not need to alter anything below this line ############################################################################### @@ -70,8 +70,8 @@ install: .PHONEY: uninstall uninstall: @echo "[UnInstall]" - rm -f /usr/local/bin/gpio - rm -f /usr/local/man/man1/gpio.1 + @rm -f /usr/local/bin/gpio + @rm -f /usr/local/man/man1/gpio.1 .PHONEY: depend depend: diff --git a/gpio/gpio b/gpio/gpio new file mode 100755 index 0000000000000000000000000000000000000000..54df96acc4db421f20e155f5ca8ab5a32637ea97 GIT binary patch literal 21304 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 literal 0 HcmV?d00001 diff --git a/gpio/gpio.1 b/gpio/gpio.1 index c39e5dc..ec65519 100644 --- a/gpio/gpio.1 +++ b/gpio/gpio.1 @@ -9,7 +9,7 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO .PP .B gpio .B [ \-g ] -.B read/write/wb/pwm/mode ... +.B read/write/wb/pwm/clock/mode ... .PP .B gpio .B [ \-p ] @@ -38,7 +38,7 @@ group value range .PP .B gpio -.B load \ i2c/spi +.B load \ i2c/spi ... .PP .B gpio .B gbr @@ -57,6 +57,9 @@ 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. @@ -70,6 +73,8 @@ 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 \-p @@ -99,7 +104,13 @@ mode. .TP .B pwm -Write a PWM value (0-1023) to the given pin. +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 @@ -163,9 +174,18 @@ Change the PWM mode to balanced (the default) or mark:space ratio (traditional) Change the PWM range register. The default is 1024. .TP -.B load i2c/spi -This loads the i2c or the spi drivers into the system and changes the permissions on -the associated /dev/ entries so that the current user has access to them. +.B load i2c [baudrate] +This loads the i2c or drivers into the kernel and changes the permissions +on the associated /dev/ entries so that the current user has access to +them. Optionally it will set the I2C baudrate to that supplied (or as +close as the Pi can manage) The default speed is 100Kb/sec. + +.TP +.B load spi [buffer size in KB] +This loads the spi drivers into the kernel and changes the permissions +on the associated /dev/ entries so that the current user has access to +them. Optionally it will set the SPI buffer size to that supplied. The +default is 4KB. .TP .B gbr @@ -183,7 +203,7 @@ SPI digital to analogue converter. The board jumpers need to be in-place to do this operation. -.SH "WiringPi vs. GPIO Pin numbering" +.SH "WiringPi vs. BCM_GPIO Pin numbering" .PP .TS @@ -213,6 +233,12 @@ _ 20 - 31 .TE +Note that "r1" and "r2" above refers to the board revision. Normally +wiringPi detects the correct board revision with use for it's own +numbering scheme, but if you are using a Revision 2 board with some +of the pins which change numbers between revisions you will need +to alter your software. + .SH FILES .TP 2.2i @@ -264,4 +290,5 @@ 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. +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 index 52fcb6f..e71e432 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -35,18 +35,20 @@ #include #include +extern int wiringPiDebug ; + #ifndef TRUE # define TRUE (1==1) # define FALSE (1==2) #endif -#define VERSION "1.5" +#define VERSION "1.12" static int wpMode ; char *usage = "Usage: gpio -v\n" " gpio -h\n" - " gpio [-g] ...\n" + " gpio [-g] ...\n" " gpio [-p] ...\n" " gpio readall\n" " gpio unexportall/exports ...\n" @@ -127,7 +129,7 @@ static int moduleLoaded (char *modName) static void _doLoadUsage (char *argv []) { - fprintf (stderr, "Usage: %s load \n", argv [0]) ; + fprintf (stderr, "Usage: %s load [SPI bufferSize in KB | I2C baudrate in Kb/sec]\n", argv [0]) ; exit (1) ; } @@ -136,16 +138,23 @@ static void doLoad (int argc, char *argv []) char *module1, *module2 ; char cmd [80] ; char *file1, *file2 ; + char args1 [32], args2 [32] ; - if (argc != 3) + 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) + sprintf (args1, " bufsiz=%d", atoi (argv [3]) * 1024) ; + else if (argc > 4) + _doLoadUsage (argv) ; } else if (strcasecmp (argv [2], "i2c") == 0) { @@ -153,19 +162,23 @@ static void doLoad (int argc, char *argv []) 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 (!moduleLoaded (module1)) { - sprintf (cmd, "modprobe %s", module1) ; + sprintf (cmd, "modprobe %s%s", module1, args1) ; system (cmd) ; } if (!moduleLoaded (module2)) { - sprintf (cmd, "modprobe %s", module2) ; + sprintf (cmd, "modprobe %s%s", module2, args2) ; system (cmd) ; } @@ -190,55 +203,39 @@ static void doLoad (int argc, char *argv []) static char *pinNames [] = { - "GPIO 0", - "GPIO 1", - "GPIO 2", - "GPIO 3", - "GPIO 4", - "GPIO 5", - "GPIO 6", - "GPIO 7", - "SDA ", - "SCL ", - "CE0 ", - "CE1 ", - "MOSI ", - "MISO ", - "SCLK ", - "TxD ", - "RxD ", - "GPIO 8", - "GPIO 9", - "GPIO10", - "GPIO11", + "GPIO 0", "GPIO 1", "GPIO 2", "GPIO 3", "GPIO 4", "GPIO 5", "GPIO 6", "GPIO 7", + "SDA ", "SCL ", + "CE0 ", "CE1 ", "MOSI ", "MISO ", "SCLK ", + "TxD ", "RxD ", + "GPIO 8", "GPIO 9", "GPIO10", "GPIO11", +} ; + +static char *alts [] = +{ + "IN ", "OUT ", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3" } ; static void doReadall (void) { int pin ; - printf ("+----------+------+--------+-------+\n") ; - printf ("| wiringPi | GPIO | Name | Value |\n") ; - printf ("+----------+------+--------+-------+\n") ; + printf ("+----------+------+--------+------+-------+\n") ; + printf ("| wiringPi | GPIO | Name | Mode | Value |\n") ; + printf ("+----------+------+--------+------+-------+\n") ; - for (pin = 0 ; pin < NUM_PINS ; ++pin) - printf ("| %6d | %3d | %s | %s |\n", + for (pin = 0 ; pin < 64 ; ++pin) + { + if (wpiPinToGpio (pin) == -1) + continue ; + + printf ("| %6d | %3d | %s | %s | %s |\n", pin, wpiPinToGpio (pin), pinNames [pin], + alts [getAlt (pin)], digitalRead (pin) == HIGH ? "High" : "Low ") ; + } - printf ("+----------+------+--------+-------+\n") ; - - if (piBoardRev () == 1) - return ; - - for (pin = 17 ; pin <= 20 ; ++pin) - printf ("| %6d | %3d | %s | %s |\n", - pin, wpiPinToGpio (pin), - pinNames [pin], - digitalRead (pin) == HIGH ? "High" : "Low ") ; - - printf ("+----------+------+--------+-------+\n") ; + printf ("+----------+------+--------+------+-------+\n") ; } @@ -544,15 +541,16 @@ void doMode (int argc, char *argv []) mode = argv [3] ; - /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ; - else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ; - else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ; - else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ; - else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ; - else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ; + /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ; + else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ; + else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ; + else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ; + else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ; + else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ; + else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ; else { - fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/up/down/tri\n", argv [1], mode) ; + fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/clock/up/down/tri\n", argv [1], mode) ; exit (1) ; } } @@ -757,6 +755,33 @@ void doRead (int argc, char *argv []) } +/* + * 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]) ; + + if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) + return ; + + freq = atoi (argv [3]) ; + + gpioClockSet (pin, freq) ; +} + + /* * doPwm: * Output a PWM value on a pin @@ -848,6 +873,12 @@ 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\n", usage) ; @@ -977,6 +1008,7 @@ int main (int argc, char *argv []) else if (strcasecmp (argv [1], "write") == 0) doWrite (argc, argv) ; else if (strcasecmp (argv [1], "wb") == 0) doWriteByte (argc, argv) ; else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ; + else if (strcasecmp (argv [1], "clock") == 0) doClock (argc, argv) ; else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ; else { diff --git a/wiringPi/Makefile b/wiringPi/Makefile index e18a654..c6a4555 100644 --- a/wiringPi/Makefile +++ b/wiringPi/Makefile @@ -1,4 +1,4 @@ -# +# ; # Makefile: # wiringPi - Wiring Compatable library for the Raspberry Pi # @@ -45,13 +45,19 @@ LIBS = SRC = wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c \ gertboard.c \ piNes.c \ - lcd.c piHiPri.c piThread.c wiringPiSPI.c \ + lcd.c piHiPri.c piThread.c \ + wiringPiSPI.c \ softPwm.c softServo.c softTone.c +SRC_I2C = wiringPiI2C.c + OBJ = $(SRC:.c=.o) -all: $(STATIC) $(DYNAMIC) -#all: $(DYNAMIC) +OBJ_I2C = $(SRC_I2C:.c=.o) + +all: $(DYNAMIC) + +static: $(STATIC) $(STATIC): $(OBJ) @echo "[Link (Static)]" @@ -63,13 +69,17 @@ $(DYNAMIC): $(OBJ) @echo "[Link (Dynamic)]" @$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ) +i2c: $(OBJ) $(OBJ_I2C) + @echo "[Link (Dynamic + I2C)]" + @$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ) $(OBJ_I2C) + .c.o: @echo [Compile] $< @$(CC) -c $(CFLAGS) $< -o $@ .PHONEY: clean clean: - rm -f $(OBJ) *~ core tags Makefile.bak libwiringPi.* + rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPi.* .PHONEY: tags tags: $(SRC) @@ -77,7 +87,7 @@ tags: $(SRC) @ctags $(SRC) .PHONEY: install -install: $(TARGET) +install: $(DYNAMIC) @echo "[Install]" @install -m 0755 -d $(DESTDIR)$(PREFIX)/lib @install -m 0755 -d $(DESTDIR)$(PREFIX)/include @@ -91,12 +101,17 @@ install: $(TARGET) @install -m 0644 softTone.h $(DESTDIR)$(PREFIX)/include @install -m 0644 lcd.h $(DESTDIR)$(PREFIX)/include @install -m 0644 wiringPiSPI.h $(DESTDIR)$(PREFIX)/include - @install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib + @install -m 0644 wiringPiI2C.h $(DESTDIR)$(PREFIX)/include @install -m 0755 libwiringPi.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib @ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so @ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so.1 @ldconfig +.PHONEY: install-static +install-static: $(STATIC) + @echo "[Install Static]" + @install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib + .PHONEY: uninstall uninstall: @echo "[UnInstall]" @@ -110,13 +125,14 @@ uninstall: @rm -f $(DESTDIR)$(PREFIX)/include/softTone.h @rm -f $(DESTDIR)$(PREFIX)/include/lcd.h @rm -f $(DESTDIR)$(PREFIX)/include/wiringPiSPI.h + @rm -f $(DESTDIR)$(PREFIX)/include/wiringPiI2C.h @rm -f $(DESTDIR)$(PREFIX)/lib/libwiringPi.* @ldconfig .PHONEY: depend depend: - makedepend -Y $(SRC) + makedepend -Y $(SRC) $(SRC_I2C) # DO NOT DELETE @@ -129,5 +145,8 @@ piNes.o: wiringPi.h piNes.h lcd.o: wiringPi.h lcd.h piHiPri.o: wiringPi.h piThread.o: wiringPi.h -softPwm.o: wiringPi.h softPwm.h wiringPiSPI.o: wiringPiSPI.h +softPwm.o: wiringPi.h softPwm.h +softServo.o: wiringPi.h softServo.h +softTone.o: wiringPi.h softTone.h +wiringPiI2C.o: wiringPi.h wiringPiI2C.h diff --git a/wiringPi/lcd.c b/wiringPi/lcd.c index aa58cab..f123db2 100644 --- a/wiringPi/lcd.c +++ b/wiringPi/lcd.c @@ -174,6 +174,18 @@ void lcdClear (int fd) } +/* + * lcdSendCommand: + * Send any arbitary command to the display + ********************************************************************************* + */ + +void lcdSendCommand (int fd, uint8_t command) +{ + struct lcdDataStruct *lcd = lcds [fd] ; + putCommand (lcd, command) ; +} + /* * lcdPosition: * Update the position of the cursor on the display diff --git a/wiringPi/lcd.h b/wiringPi/lcd.h index ecd1d25..beebb75 100644 --- a/wiringPi/lcd.h +++ b/wiringPi/lcd.h @@ -30,12 +30,13 @@ extern "C" { #endif -extern void lcdHome (int fd) ; -extern void lcdClear (int fd) ; -extern void lcdPosition (int fd, int x, int y) ; -extern void lcdPutchar (int fd, uint8_t data) ; -extern void lcdPuts (int fd, char *string) ; -extern void lcdPrintf (int fd, char *message, ...) ; +extern void lcdHome (int fd) ; +extern void lcdClear (int fd) ; +extern void lcdSendCommand (int fd, uint8_t command) ; +extern void lcdPosition (int fd, int x, int y) ; +extern void lcdPutchar (int fd, uint8_t data) ; +extern void lcdPuts (int fd, char *string) ; +extern void lcdPrintf (int fd, char *message, ...) ; extern int lcdInit (int rows, int cols, int bits, int rs, int strb, int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ; diff --git a/wiringPi/libwiringPi.so.1.0 b/wiringPi/libwiringPi.so.1.0 new file mode 100755 index 0000000000000000000000000000000000000000..7c87ee9e0b6a1975bca211971d0a94605bef164a GIT binary patch literal 43311 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 literal 0 HcmV?d00001 diff --git a/wiringPi/q2w.c b/wiringPi/q2w.c new file mode 100644 index 0000000..31486da --- /dev/null +++ b/wiringPi/q2w.c @@ -0,0 +1,89 @@ +/* + * q2w.c: + *********************************************************************** + */ + +#include +#include +#include +#include +#include + +#include +#include + +// MCP23S17 Registers + +#define IOCON 0x0A + +#define IODIRA 0x00 +#define IPOLA 0x02 +#define GPINTENA 0x04 +#define DEFVALA 0x06 +#define INTCONA 0x08 +#define GPPUA 0x0C +#define INTFA 0x0E +#define INTCAPA 0x10 +#define GPIOA 0x12 +#define OLATA 0x14 + +#define IODIRB 0x01 +#define IPOLB 0x03 +#define GPINTENB 0x05 +#define DEFVALB 0x07 +#define INTCONB 0x09 +#define GPPUB 0x0D +#define INTFB 0x0F +#define INTCAPB 0x11 +#define GPIOB 0x13 +#define OLATB 0x15 + +// Bits in the IOCON register + +#define IOCON_BANK_MODE 0x80 +#define IOCON_MIRROR 0x40 +#define IOCON_SEQOP 0x20 +#define IOCON_DISSLW 0x10 +#define IOCON_HAEN 0x08 +#define IOCON_ODR 0x04 +#define IOCON_INTPOL 0x02 +#define IOCON_UNUSED 0x01 + +// Default initialisation mode + +#define IOCON_INIT (IOCON_SEQOP) + + + +/* + ********************************************************************************* + * The works + ********************************************************************************* + */ + +int main (int argc, char *argv []) +{ + int q2w ; + +// if (wiringPiSetup () == -1) +// { fprintf (stderr, "q2w: Unable to initialise wiringPi: %s\n", strerror (errno)) ; return 1 ; } + + if ((q2w = wiringPiI2CSetup (0x20)) == -1) + { fprintf (stderr, "q2w: Unable to initialise I2C: %s\n", strerror (errno)) ; return 1 ; } + +// Very simple direct control of the MCP23017: + + wiringPiI2CWriteReg8 (q2w, IOCON, IOCON_INIT) ; + wiringPiI2CWriteReg8 (q2w, IODIRA, 0x00) ; // Port A -> Outputs + wiringPiI2CWriteReg8 (q2w, IODIRB, 0x00) ; // Port B -> Outputs + + for (;;) + { + wiringPiI2CWriteReg8 (q2w, GPIOA, 0x00) ; // All Off + delay (500) ; + wiringPiI2CWriteReg8 (q2w, GPIOA, 0xFF) ; // All On + delay (500) ; + } + + return 0 ; +} diff --git a/wiringPi/softServo.c b/wiringPi/softServo.c index a6ff1fb..9de9f4f 100644 --- a/wiringPi/softServo.c +++ b/wiringPi/softServo.c @@ -54,6 +54,15 @@ // 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 diff --git a/wiringPi/softTone.c b/wiringPi/softTone.c index d14c2a2..8463627 100644 --- a/wiringPi/softTone.c +++ b/wiringPi/softTone.c @@ -59,7 +59,9 @@ static PI_THREAD (softToneThread) for (;;) { frewq = frewqs [pin] ; - if (frewq != 0) + if (frewq == 0) + delay (1) ; + else { halfPeriod = 500000 / frewq ; diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index df4d969..a68ae33 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -51,9 +51,6 @@ // Added in the 2 UART pins // Change maxPins to numPins to more accurately reflect purpose -// Pad drive current fiddling - -#undef DEBUG_PADS #include #include @@ -65,24 +62,27 @@ #include #include #include +#include #include #include -#include #include +#include +#include #include "wiringPi.h" // Function stubs void (*pinMode) (int pin, int mode) ; +int (*getAlt) (int pin) ; void (*pullUpDnControl) (int pin, int pud) ; void (*digitalWrite) (int pin, int value) ; void (*digitalWriteByte) (int value) ; void (*pwmWrite) (int pin, int value) ; +void (*gpioClockSet) (int pin, int value) ; void (*setPadDrive) (int group, int value) ; int (*digitalRead) (int pin) ; int (*waitForInterrupt) (int pin, int mS) ; -void (*delayMicroseconds) (unsigned int howLong) ; void (*pwmSetMode) (int mode) ; void (*pwmSetRange) (unsigned int range) ; void (*pwmSetClock) (int divisor) ; @@ -98,6 +98,24 @@ void (*pwmSetClock) (int divisor) ; #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 @@ -111,20 +129,21 @@ void (*pwmSetClock) (int divisor) ; #define FSEL_ALT5 0b010 // Access from ARM Running Linux -// Take from Gert/Doms code. Some of this is not in the manual +// Taken from Gert/Doms code. Some of this is not in the manual // that I can find )-: -#define BCM2708_PERI_BASE 0x20000000 -#define GPIO_PADS (BCM2708_PERI_BASE + 0x100000) -#define CLOCK_BASE (BCM2708_PERI_BASE + 0x101000) -#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) -#define GPIO_TIMER (BCM2708_PERI_BASE + 0x00B000) -#define GPIO_PWM (BCM2708_PERI_BASE + 0x20C000) +#define BCM2708_PERI_BASE 0x20000000 +#define GPIO_PADS (BCM2708_PERI_BASE + 0x00100000) +#define CLOCK_BASE (BCM2708_PERI_BASE + 0x00101000) +#define GPIO_BASE (BCM2708_PERI_BASE + 0x00200000) +#define GPIO_TIMER (BCM2708_PERI_BASE + 0x0000B000) +#define GPIO_PWM (BCM2708_PERI_BASE + 0x0020C000) #define PAGE_SIZE (4*1024) #define BLOCK_SIZE (4*1024) // PWM +// Word offsets into the PWM control region #define PWM_CONTROL 0 #define PWM_STATUS 1 @@ -133,17 +152,11 @@ void (*pwmSetClock) (int divisor) ; #define PWM1_RANGE 8 #define PWM1_DATA 9 +// Clock regsiter offsets + #define PWMCLK_CNTL 40 #define PWMCLK_DIV 41 -#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 - #define PWM0_MS_MODE 0x0080 // Run in MS mode #define PWM0_USEFIFO 0x0020 // Data from FIFO #define PWM0_REVPOLAR 0x0010 // Reverse polarity @@ -152,7 +165,16 @@ void (*pwmSetClock) (int divisor) ; #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) @@ -173,33 +195,28 @@ static volatile uint32_t *pads ; static volatile uint32_t *timer ; static volatile uint32_t *timerIrqRaw ; +// Time for easy calculations + +static uint64_t epochMilli, epochMicro ; + +// Misc + +static int wiringPiMode = WPI_MODE_UNINITIALISED ; + // Debugging -static int wiringPiDebug = FALSE ; - -// 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: -// -// 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) +int wiringPiDebug = FALSE ; // sysFds: // Map a file descriptor from the /sys/class/gpio/gpioX/value static int sysFds [64] ; +// 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! @@ -329,11 +346,14 @@ static uint8_t gpioToFEN [] = #endif -// gpioToPUDCLK -// (Word) offset to the Pull Up Down Clock regsiter +// 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, @@ -356,6 +376,9 @@ static uint8_t gpioToPwmALT [] = 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63 } ; +// gpioToPwmPort +// The port value to put a GPIO pin into PWM mode + static uint8_t gpioToPwmPort [] = { 0, 0, 0, 0, 0, 0, 0, 0, // 0 -> 7 @@ -369,10 +392,55 @@ static uint8_t gpioToPwmPort [] = } ; +// gpioToGpClkALT: +// ALT value to put a GPIO pin into GP Clock mode. +// On the Pi we can really only use BCM_GPIO_4 and BCM_GPIO_21 +// for clocks 0 and 1 respectivey, however I'll include the full +// list for completeness - maybe one day... -// Time for easy calculations +#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 +} ; -static unsigned long long epoch ; /* * Functions @@ -407,9 +475,11 @@ int wpiPinToGpio (int wpiPin) * 0001 - Not used * 0002 - Rev 1 * 0003 - Rev 1 - * 0004 - Rev 2 - * 0005 - Rev 2 (but error) + * 0004 - Rev 2 (Early reports? + * 0005 - Rev 2 (but error?) * 0006 - Rev 2 + * 0008 - Rev 2 - Model A + * 000e - Rev 2 + 512MB * 000f - Rev 2 + 512MB * * A small thorn is the olde style overvolting - that will add in @@ -418,6 +488,15 @@ int wpiPinToGpio (int wpiPin) ********************************************************************************* */ +static void piBoardRevOops (char *why) +{ + fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ; + fprintf (stderr, " -> %s\n", why) ; + fprintf (stderr, " -> You may want to check:\n") ; + fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ; + exit (EXIT_FAILURE) ; +} + int piBoardRev (void) { FILE *cpuFd ; @@ -425,13 +504,11 @@ int piBoardRev (void) char *c, lastChar ; static int boardRev = -1 ; -// No point checking twice... - - if (boardRev != -1) + if (boardRev != -1) // No point checking twice return boardRev ; if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL) - return -1 ; + piBoardRevOops ("Unable to open /proc/cpuinfo") ; while (fgets (line, 120, cpuFd) != NULL) if (strncmp (line, "Revision", 8) == 0) @@ -439,25 +516,21 @@ int piBoardRev (void) fclose (cpuFd) ; - if (line == NULL) - { - fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ; - fprintf (stderr, " (No \"Revision\" line)\n") ; - errno = 0 ; - return -1 ; - } + if (strncmp (line, "Revision", 8) != 0) + piBoardRevOops ("No \"Revision\" line") ; + + for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c) + *c = 0 ; + if (wiringPiDebug) + printf ("piboardRev: Revision string: %s\n", line) ; + for (c = line ; *c ; ++c) if (isdigit (*c)) break ; if (!isdigit (*c)) - { - fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ; - fprintf (stderr, " (No numeric revision string in: \"%s\"\n", line) ; - errno = 0 ; - return -1 ; - } + piBoardRevOops ("No numeric revision string") ; // If you have overvolted the Pi, then it appears that the revision // has 100000 added to it! @@ -466,26 +539,18 @@ int piBoardRev (void) if (strlen (c) != 4) printf ("piboardRev: This Pi has/is overvolted!\n") ; - lastChar = c [strlen (c) - 2] ; + lastChar = line [strlen (line) - 1] ; + + if (wiringPiDebug) + printf ("piboardRev: lastChar is: '%c' (%d, 0x%02X)\n", lastChar, lastChar, lastChar) ; /**/ if ((lastChar == '2') || (lastChar == '3')) boardRev = 1 ; else boardRev = 2 ; -#ifdef DO_WE_CARE_ABOUT_THIS_NOW - else - { - fprintf (stderr, "WARNING: wiringPi: Unable to determine board revision from \"%d\"\n", r) ; - fprintf (stderr, " -> You may want to check:\n") ; - fprintf (stderr, " -> http://www.raspberrypi.org/phpBB3/viewtopic.php?p=184410#p184410\n") ; - fprintf (stderr, " -> Assuming a Rev 1 board\n") ; - boardRev = 1 ; - } -#endif - if (wiringPiDebug) - printf ("piboardRev: Revision string: %s, board revision: %d\n", c, boardRev) ; + printf ("piBoardRev: Returning revision: %d\n", boardRev) ; return boardRev ; } @@ -493,15 +558,14 @@ int piBoardRev (void) /* - * pinMode: - * Sets the mode of a pin to be input, output or PWM output + * getAlt: + * Returns the ALT bits for a given port. Only really of-use + * for the gpio readall command (I think) ********************************************************************************* */ -void pinModeGpio (int pin, int mode) +int getAltGpio (int pin) { -// register int barrier ; - int fSel, shift, alt ; pin &= 63 ; @@ -509,73 +573,19 @@ void pinModeGpio (int pin, int mode) fSel = gpioToGPFSEL [pin] ; shift = gpioToShift [pin] ; - /**/ if (mode == INPUT) - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input - else if (mode == OUTPUT) - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ; - else if (mode == PWM_OUTPUT) - { - if ((alt = gpioToPwmALT [pin]) == 0) // Not a PWM pin - return ; - -// Set pin to PWM mode - - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; - - delayMicroseconds (110) ; // See comments in pwmSetClockWPi - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; - -// Page 107 of the BCM Peripherals manual talks about the GPIO clocks, -// but I'm assuming (hoping!) that this applies to other clocks too. - - *(pwm + PWM_CONTROL) = 0 ; // Stop PWM - - *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock - delayMicroseconds (110) ; // See comments in pwmSetClockWPi - - while ((*(clk + PWMCLK_CNTL) & 0x80) != 0) // Wait for clock to be !BUSY - delayMicroseconds (1) ; - - *(clk + PWMCLK_DIV) = BCM_PASSWORD | (32 << 12) ; // set pwm div to 32 (19.2/32 = 600KHz) - *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // enable clk - - delayMicroseconds (110) ; // See comments in pwmSetClockWPi - -// Default range register of 1024 - - *(pwm + PWM0_RANGE) = 1024 ; delayMicroseconds (10) ; - *(pwm + PWM1_RANGE) = 1024 ; delayMicroseconds (10) ; - *(pwm + PWM0_DATA) = 0 ; delayMicroseconds (10) ; - *(pwm + PWM1_DATA) = 0 ; delayMicroseconds (10) ; - -// Enable PWMs in balanced mode (default) - - *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ; - - delay (100) ; - } - - -// When we change mode of any pin, we remove the pull up/downs -// Or we used to... Hm. Commented out now because for some wieird reason, -// it seems to block subsequent attempts to set the pull up/downs and I've -// not quite gotten to the bottom of why this happens -// The down-side is that the pull up/downs are rememberd in the SoC between -// power cycles, so it's going to be a good idea to explicitly set them in -// any new code. -// -// pullUpDnControl (pin, PUD_OFF) ; + alt = (*(gpio + fSel) >> shift) & 7 ; + return alt ; } -void pinModeWPi (int pin, int mode) +int getAltWPi (int pin) { - pinModeGpio (pinToGpio [pin & 63], mode) ; + return getAltGpio (pinToGpio [pin & 63]) ; } -void pinModeSys (int pin, int mode) +int getAltSys (int pin) { - return ; + return 0 ; } @@ -620,7 +630,7 @@ void pwmSetRangeSys (unsigned int range) void pwmSetClockWPi (int divisor) { - unsigned int pwm_control ; + uint32_t pwm_control ; divisor &= 4095 ; if (wiringPiDebug) @@ -741,11 +751,11 @@ void digitalWriteByteGpio (int value) else pinSet |= (1 << pinToGpio [pin]) ; - *(gpio + gpioToGPCLR [0]) = pinClr ; - *(gpio + gpioToGPSET [0]) = pinSet ; - mask <<= 1 ; } + + *(gpio + gpioToGPCLR [0]) = pinClr ; + *(gpio + gpioToGPSET [0]) = pinSet ; } void digitalWriteByteSys (int value) @@ -788,6 +798,44 @@ void pwmWriteSys (int pin, int value) } +/* + * gpioClockSet: + * Set the freuency on a GPIO clock pin + ********************************************************************************* + */ + +void gpioClockSetGpio (int pin, int freq) +{ + int divi, divr, divf ; + + pin &= 63 ; + + divi = 19200000 / freq ; + divr = 19200000 % freq ; + divf = (int)((double)divr * 4096.0 / 19200000.0) ; + + if (divi > 4095) + divi = 4095 ; + + *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | GPIO_CLOCK_SOURCE ; // Stop GPIO Clock + while ((*(clk + gpioToClkCon [pin]) & 0x80) != 0) // ... and wait + ; + + *(clk + gpioToClkDiv [pin]) = BCM_PASSWORD | (divi << 12) | divf ; // Set dividers + *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | 0x10 | GPIO_CLOCK_SOURCE ; // Start Clock +} + +void gpioClockSetWPi (int pin, int freq) +{ + gpioClockSetGpio (pinToGpio [pin & 63], freq) ; +} + +void gpioClockSetSys (int pin, int freq) +{ + return ; +} + + /* * setPadDrive: * Set the PAD driver value @@ -804,10 +852,11 @@ void setPadDriveWPi (int group, int value) wrVal = BCM_PASSWORD | 0x18 | (value & 7) ; *(pads + group + 11) = wrVal ; -#ifdef DEBUG_PADS - printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ; - printf ("Read : %08X\n", *(pads + group + 11)) ; -#endif + if (wiringPiDebug) + { + printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ; + printf ("Read : %08X\n", *(pads + group + 11)) ; + } } void setPadDriveGpio (int group, int value) @@ -894,6 +943,65 @@ void pullUpDnControlSys (int pin, int pud) } +/* + * pinMode: + * Sets the mode of a pin to be input, output or PWM output + ********************************************************************************* + */ + +void pinModeGpio (int pin, int mode) +{ +// register int barrier ; + + int fSel, shift, alt ; + + pin &= 63 ; + + fSel = gpioToGPFSEL [pin] ; + shift = gpioToShift [pin] ; + + /**/ if (mode == INPUT) + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input + else if (mode == OUTPUT) + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ; + else if (mode == PWM_OUTPUT) + { + if ((alt = gpioToPwmALT [pin]) == 0) // Not a PWM pin + return ; + +// Set pin to PWM mode + + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; + delayMicroseconds (110) ; // See comments in pwmSetClockWPi + + pwmSetModeWPi (PWM_MODE_BAL) ; // Pi default mode + pwmSetRangeWPi (1024) ; // Default range of 1024 + pwmSetClockWPi (32) ; // 19.2 / 32 = 600KHz - Also starts the PWM + } + else if (mode == GPIO_CLOCK) + { + if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin + return ; + +// Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz + + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; + delayMicroseconds (110) ; + gpioClockSetGpio (pin, 100000) ; + } +} + +void pinModeWPi (int pin, int mode) +{ + pinModeGpio (pinToGpio [pin & 63], mode) ; +} + +void pinModeSys (int pin, int mode) +{ + return ; +} + + /* * waitForInterrupt: * Wait for Interrupt on a GPIO pin. @@ -906,22 +1014,12 @@ void pullUpDnControlSys (int pin, int pud) int waitForInterruptSys (int pin, int mS) { int fd, x ; - char buf [8] ; + uint8_t c ; struct pollfd polls ; if ((fd = sysFds [pin & 63]) == -1) return -2 ; -// Do a dummy read - - x = read (fd, buf, 6) ; - if (x < 0) - return x ; - -// And seek - - lseek (fd, 0, SEEK_SET) ; - // Setup poll structure polls.fd = fd ; @@ -929,7 +1027,14 @@ int waitForInterruptSys (int pin, int mS) // Wait for it ... - return poll (&polls, 1, mS) ; + x = poll (&polls, 1, mS) ; + +// Do a dummy read to clear the interrupt +// A one character read appars to be enough. + + (void)read (fd, &c, 1) ; + + return x ; } int waitForInterruptWPi (int pin, int mS) @@ -943,6 +1048,123 @@ int waitForInterruptGpio (int pin, int mS) } +/* + * 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 (void *arg) +{ + int myPin = *(int *)arg ; + + (void)piHiPri (55) ; // Only effective if we run as root + + for (;;) + if (waitForInterruptSys (myPin, -1) > 0) + isrFunctions [myPin] () ; + + return NULL ; +} + + +/* + * wiringPiISR: + * 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 ; + char fName [64] ; + char *modeS ; + char pinS [8] ; + pid_t pid ; + int count, i ; + uint8_t c ; + + pin &= 63 ; + + if (wiringPiMode == WPI_MODE_UNINITIALISED) + { + fprintf (stderr, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ; + exit (EXIT_FAILURE) ; + } + else if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [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 pid ; + + if (pid == 0) // Child, exec + { + execl ("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ; + return -1 ; // Failure ... + } + else // Parent, wait + wait (NULL) ; + } + +// Now pre-open the /sys/class node - it may already be open if +// we are in Sys mode, but this will do no harm. + + sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; + if ((sysFds [pin] = open (fName, O_RDWR)) < 0) + return -1 ; + +// Clear any initial pending interrupt + + ioctl (sysFds [pin], FIONREAD, &count) ; + for (i = 0 ; i < count ; ++i) + read (sysFds [pin], &c, 1) ; + + isrFunctions [pin] = function ; + + pthread_create (&threadId, NULL, interruptHandler, &pin) ; + + delay (1) ; + + return 0 ; +} + + +/* + * initialiseEpoch: + * Initialise our start-of-time variable to be the current unix + * time in milliseconds. + ********************************************************************************* + */ + +static void initialiseEpoch (void) +{ + 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) ; +} + /* * delay: * Wait for some number of milli seconds @@ -978,28 +1200,8 @@ void delay (unsigned int howLong) ********************************************************************************* */ -void delayMicrosecondsSys (unsigned int howLong) -{ - struct timespec sleeper, dummy ; - - sleeper.tv_sec = 0 ; - sleeper.tv_nsec = (long)(howLong * 1000) ; - - nanosleep (&sleeper, &dummy) ; -} - void delayMicrosecondsHard (unsigned int howLong) { -#ifdef HARD_TIMER - volatile unsigned int dummy ; - - *(timer + TIMER_LOAD) = howLong ; - *(timer + TIMER_IRQ_CLR) = 0 ; - - dummy = *timerIrqRaw ; - while (dummy == 0) - dummy = *timerIrqRaw ; -#else struct timeval tNow, tLong, tEnd ; gettimeofday (&tNow, NULL) ; @@ -1009,10 +1211,9 @@ void delayMicrosecondsHard (unsigned int howLong) while (timercmp (&tNow, &tEnd, <)) gettimeofday (&tNow, NULL) ; -#endif } -void delayMicrosecondsWPi (unsigned int howLong) +void delayMicroseconds (unsigned int howLong) { struct timespec sleeper ; @@ -1038,13 +1239,30 @@ void delayMicrosecondsWPi (unsigned int howLong) unsigned int millis (void) { struct timeval tv ; - unsigned long long t1 ; + uint64_t now ; gettimeofday (&tv, NULL) ; + now = (uint64_t)tv.tv_sec * (uint64_t)1000 + (uint64_t)(tv.tv_usec / 1000) ; - t1 = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ; + return (uint32_t)(now - epochMilli) ; +} - return (uint32_t)(t1 - epoch) ; + +/* + * micros: + * Return a number of microseconds as an unsigned int. + ********************************************************************************* + */ + +unsigned int micros (void) +{ + struct timeval tv ; + uint64_t now ; + + gettimeofday (&tv, NULL) ; + now = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)tv.tv_usec ; + + return (uint32_t)(now - epochMicro) ; } @@ -1061,30 +1279,37 @@ int wiringPiSetup (void) { int fd ; int boardRev ; - uint8_t *gpioMem, *pwmMem, *clkMem, *padsMem, *timerMem ; - struct timeval tv ; + + if (geteuid () != 0) + { + fprintf (stderr, "wiringPi:\n Must be root to call wiringPiSetup().\n (Did you forget sudo?)\n") ; + exit (EXIT_FAILURE) ; + } if (getenv ("WIRINGPI_DEBUG") != NULL) + { + printf ("wiringPi: Debug mode enabled\n") ; wiringPiDebug = TRUE ; + } if (wiringPiDebug) printf ("wiringPi: wiringPiSetup called\n") ; pinMode = pinModeWPi ; + getAlt = getAltWPi ; pullUpDnControl = pullUpDnControlWPi ; digitalWrite = digitalWriteWPi ; digitalWriteByte = digitalWriteByteGpio ; // Same code + gpioClockSet = gpioClockSetWPi ; pwmWrite = pwmWriteWPi ; setPadDrive = setPadDriveWPi ; digitalRead = digitalReadWPi ; waitForInterrupt = waitForInterruptWPi ; - delayMicroseconds = delayMicrosecondsWPi ; pwmSetMode = pwmSetModeWPi ; pwmSetRange = pwmSetRangeWPi ; pwmSetClock = pwmSetClockWPi ; - if ((boardRev = piBoardRev ()) < 0) - return -1 ; + boardRev = piBoardRev () ; if (boardRev == 1) pinToGpio = pinToGpioR1 ; @@ -1095,111 +1320,82 @@ int wiringPiSetup (void) if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0) { - fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ; + if (wiringPiDebug) + { + int serr = errno ; + fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ; + errno = serr ; + } return -1 ; } // GPIO: -// Allocate 2 pages - 1 ... - - if ((gpioMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) + gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ; + if ((int32_t)gpio == -1) { - fprintf (stderr, "wiringPiSetup: malloc failed: %s\n", strerror (errno)) ; - return -1 ; - } - -// ... presumably to make sure we can round it up to a whole page size - - if (((uint32_t)gpioMem % PAGE_SIZE) != 0) - gpioMem += PAGE_SIZE - ((uint32_t)gpioMem % PAGE_SIZE) ; - - gpio = (uint32_t *)mmap((caddr_t)gpioMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_BASE) ; - - if ((int32_t)gpio < 0) - { - fprintf (stderr, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ; + if (wiringPiDebug) + { + int serr = errno ; + fprintf (stderr, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ; + errno = serr ; + } return -1 ; } // PWM - if ((pwmMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) + pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ; + if ((int32_t)pwm == -1) { - fprintf (stderr, "wiringPiSetup: pwmMem malloc failed: %s\n", strerror (errno)) ; - return -1 ; - } - - if (((uint32_t)pwmMem % PAGE_SIZE) != 0) - pwmMem += PAGE_SIZE - ((uint32_t)pwmMem % PAGE_SIZE) ; - - pwm = (uint32_t *)mmap(pwmMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PWM) ; - - if ((int32_t)pwm < 0) - { - fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ; + if (wiringPiDebug) + { + int serr = errno ; + fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ; + errno = serr ; + } return -1 ; } // Clock control (needed for PWM) - if ((clkMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) + clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, CLOCK_BASE) ; + if ((int32_t)clk == -1) { - fprintf (stderr, "wiringPiSetup: clkMem malloc failed: %s\n", strerror (errno)) ; - return -1 ; - } - - if (((uint32_t)clkMem % PAGE_SIZE) != 0) - clkMem += PAGE_SIZE - ((uint32_t)clkMem % PAGE_SIZE) ; - - clk = (uint32_t *)mmap(clkMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, CLOCK_BASE) ; - - if ((int32_t)clk < 0) - { - fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ; + if (wiringPiDebug) + { + int serr = errno ; + fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ; + errno = serr ; + } return -1 ; } // The drive pads - if ((padsMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) + pads = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PADS) ; + if ((int32_t)pads == -1) { - fprintf (stderr, "wiringPiSetup: padsMem malloc failed: %s\n", strerror (errno)) ; + if (wiringPiDebug) + { + int serr = errno ; + fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ; + errno = serr ; + } return -1 ; } - if (((uint32_t)padsMem % PAGE_SIZE) != 0) - padsMem += PAGE_SIZE - ((uint32_t)padsMem % PAGE_SIZE) ; - - pads = (uint32_t *)mmap(padsMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_PADS) ; - - if ((int32_t)pads < 0) - { - fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ; - return -1 ; - } - -#ifdef DEBUG_PADS - printf ("Checking pads @ 0x%08X\n", (unsigned int)pads) ; - printf (" -> %08X %08X %08X\n", *(pads + 11), *(pads + 12), *(pads + 13)) ; -#endif - // The system timer - if ((timerMem = malloc (BLOCK_SIZE + (PAGE_SIZE-1))) == NULL) + timer = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_TIMER) ; + if ((int32_t)timer == -1) { - fprintf (stderr, "wiringPiSetup: timerMem malloc failed: %s\n", strerror (errno)) ; - return -1 ; - } - - if (((uint32_t)timerMem % PAGE_SIZE) != 0) - timerMem += PAGE_SIZE - ((uint32_t)timerMem % PAGE_SIZE) ; - - timer = (uint32_t *)mmap(timerMem, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, GPIO_TIMER) ; - - if ((int32_t)timer < 0) - { - fprintf (stderr, "wiringPiSetup: mmap failed (timer): %s\n", strerror (errno)) ; + if (wiringPiDebug) + { + int serr = errno ; + fprintf (stderr, "wiringPiSetup: mmap failed (timer): %s\n", strerror (errno)) ; + errno = serr ; + } return -1 ; } @@ -1211,10 +1407,9 @@ int wiringPiSetup (void) *(timer + TIMER_PRE_DIV) = 0x00000F9 ; timerIrqRaw = timer + TIMER_IRQ_RAW ; -// Initialise our epoch for millis() + initialiseEpoch () ; - gettimeofday (&tv, NULL) ; - epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ; + wiringPiMode = WPI_MODE_PINS ; return 0 ; } @@ -1233,25 +1428,34 @@ int wiringPiSetupGpio (void) { int x ; - if (wiringPiDebug) - printf ("wiringPi: wiringPiSetupGpio called\n") ; + if (geteuid () != 0) + { + fprintf (stderr, "Must be root to call wiringPiSetupGpio(). (Did you forget sudo?)\n") ; + exit (EXIT_FAILURE) ; + } if ((x = wiringPiSetup ()) < 0) return x ; + if (wiringPiDebug) + printf ("wiringPi: wiringPiSetupGpio called\n") ; + pinMode = pinModeGpio ; + getAlt = getAltGpio ; pullUpDnControl = pullUpDnControlGpio ; digitalWrite = digitalWriteGpio ; digitalWriteByte = digitalWriteByteGpio ; + gpioClockSet = gpioClockSetGpio ; pwmWrite = pwmWriteGpio ; setPadDrive = setPadDriveGpio ; digitalRead = digitalReadGpio ; waitForInterrupt = waitForInterruptGpio ; - delayMicroseconds = delayMicrosecondsWPi ; // Same pwmSetMode = pwmSetModeWPi ; pwmSetRange = pwmSetRangeWPi ; pwmSetClock = pwmSetClockWPi ; + wiringPiMode = WPI_MODE_GPIO ; + return 0 ; } @@ -1269,34 +1473,35 @@ int wiringPiSetupSys (void) { int boardRev ; int pin ; - struct timeval tv ; char fName [128] ; + if (getenv ("WIRINGPI_DEBUG") != NULL) + wiringPiDebug = TRUE ; + if (wiringPiDebug) printf ("wiringPi: wiringPiSetupSys called\n") ; pinMode = pinModeSys ; + getAlt = getAltSys ; pullUpDnControl = pullUpDnControlSys ; digitalWrite = digitalWriteSys ; digitalWriteByte = digitalWriteByteSys ; + gpioClockSet = gpioClockSetSys ; pwmWrite = pwmWriteSys ; setPadDrive = setPadDriveSys ; digitalRead = digitalReadSys ; waitForInterrupt = waitForInterruptSys ; - delayMicroseconds = delayMicrosecondsSys ; pwmSetMode = pwmSetModeSys ; pwmSetRange = pwmSetRangeSys ; pwmSetClock = pwmSetClockSys ; - if ((boardRev = piBoardRev ()) < 0) - return -1 ; + boardRev = piBoardRev () ; if (boardRev == 1) pinToGpio = pinToGpioR1 ; else pinToGpio = pinToGpioR2 ; - // Open and scan the directory, looking for exported GPIOs, and pre-open // the 'value' interface to speed things up for later @@ -1306,10 +1511,9 @@ int wiringPiSetupSys (void) sysFds [pin] = open (fName, O_RDWR) ; } -// Initialise the epoch for mills() ... + initialiseEpoch () ; - gettimeofday (&tv, NULL) ; - epoch = (tv.tv_sec * 1000000 + tv.tv_usec) / 1000 ; + wiringPiMode = WPI_MODE_GPIO_SYS ; return 0 ; } diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 6a7278e..18c6da5 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -23,32 +23,50 @@ // Handy defines +// Deprecated #define NUM_PINS 17 #define WPI_MODE_PINS 0 #define WPI_MODE_GPIO 1 #define WPI_MODE_GPIO_SYS 2 #define WPI_MODE_PIFACE 3 +#define WPI_MODE_UNINITIALISED -1 -#define INPUT 0 -#define OUTPUT 1 -#define PWM_OUTPUT 2 +// Pin modes -#define LOW 0 -#define HIGH 1 +#define INPUT 0 +#define OUTPUT 1 +#define PWM_OUTPUT 2 +#define GPIO_CLOCK 3 -#define PUD_OFF 0 -#define PUD_DOWN 1 -#define PUD_UP 2 +#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 +#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 + +// Threads + +#define PI_THREAD(X) void *X (void *dummy) // Function prototypes -// c++ wrappers thanks to a commend by Nick Lott +// c++ wrappers thanks to a comment by Nick Lott // (and others on the Raspberry Pi forums) #ifdef __cplusplus @@ -68,13 +86,14 @@ extern int wpiPinToGpio (int wpiPin) ; extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only extern void (*pinMode) (int pin, int mode) ; +extern int (*getAlt) (int pin) ; extern void (*pullUpDnControl) (int pin, int pud) ; extern void (*digitalWrite) (int pin, int value) ; extern void (*digitalWriteByte) (int value) ; +extern void (*gpioClockSet) (int pin, int freq) ; extern void (*pwmWrite) (int pin, int value) ; extern void (*setPadDrive) (int group, int value) ; extern int (*digitalRead) (int pin) ; -extern void (*delayMicroseconds) (unsigned int howLong) ; extern void (*pwmSetMode) (int mode) ; extern void (*pwmSetRange) (unsigned int range) ; extern void (*pwmSetClock) (int divisor) ; @@ -82,11 +101,10 @@ extern void (*pwmSetClock) (int divisor) ; // Interrupts extern int (*waitForInterrupt) (int pin, int mS) ; +extern int wiringPiISR (int pin, int mode, void (*function)(void)) ; // Threads -#define PI_THREAD(X) void *X (void *dummy) - extern int piThreadCreate (void *(*fn)(void *)) ; extern void piLock (int key) ; extern void piUnlock (int key) ; @@ -99,7 +117,9 @@ extern int piHiPri (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 } diff --git a/wiringPi/wiringPiI2C.c b/wiringPi/wiringPiI2C.c new file mode 100644 index 0000000..93fe1d3 --- /dev/null +++ b/wiringPi/wiringPiI2C.c @@ -0,0 +1,122 @@ +/* + * 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 . + *********************************************************************** + */ + +#include +#include +#include +#include +#include + +#include "wiringPi.h" +#include "wiringPiI2C.h" + + +/* + * wiringPiI2CRead: + * Simple device read + ********************************************************************************* + */ + +int wiringPiI2CRead (int fd) +{ + return i2c_smbus_read_byte (fd) ; +} + + +/* + * wiringPiI2CReadReg8: wiringPiI2CReadReg16: + * Read an 8 or 16-bit value from a regsiter on the device + ********************************************************************************* + */ + +int wiringPiI2CReadReg8 (int fd, int reg) +{ + return i2c_smbus_read_byte_data (fd, reg) ; +} + +int wiringPiI2CReadReg16 (int fd, int reg) +{ + return i2c_smbus_read_word_data (fd, reg) ; +} + + +/* + * wiringPiI2CWrite: + * Simple device write + ********************************************************************************* + */ + +int wiringPiI2CWrite (int fd, int data) +{ + return i2c_smbus_write_byte (fd, data) ; +} + + +/* + * wiringPiI2CWriteReg8: wiringPiI2CWriteReg16: + * Write an 8 or 16-bit value to the given register + ********************************************************************************* + */ + +int wiringPiI2CWriteReg8 (int fd, int reg, int data) +{ + return i2c_smbus_write_byte_data (fd, reg, data) ; +} + +int wiringPiI2CWriteReg16 (int fd, int reg, int data) +{ + return i2c_smbus_write_word_data (fd, reg, data) ; +} + + +/* + * wiringPiI2CSetup: + * Open the I2C device, and regsiter the target device + ********************************************************************************* + */ + +int wiringPiI2CSetup (int devId) +{ + int rev, fd ; + char *device ; + + if ((rev = piBoardRev ()) < 0) + { + fprintf (stderr, "wiringPiI2CSetup: Unable to determine Pi board revision\n") ; + exit (1) ; + } + + if (rev == 1) + device = "/dev/i2c-0" ; + else + device = "/dev/i2c-1" ; + + if ((fd = open (device, O_RDWR)) < 0) + return -1 ; + + if (ioctl (fd, I2C_SLAVE, devId) < 0) + return -1 ; + + return fd ; +} diff --git a/wiringPi/wiringPiI2C.h b/wiringPi/wiringPiI2C.h new file mode 100644 index 0000000..6710ff4 --- /dev/null +++ b/wiringPi/wiringPiI2C.h @@ -0,0 +1,41 @@ +/* + * 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) ; + +int wiringPiI2CSetup (int devId) ; + +#ifdef __cplusplus +} +#endif From 9074cc8964be6afb86fec2c3377e00b8797cba74 Mon Sep 17 00:00:00 2001 From: Firobe Date: Thu, 8 May 2014 18:16:30 +0200 Subject: [PATCH 15/29] PULSE_TIME wasn't used. --- wiringPi/softPwm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wiringPi/softPwm.c b/wiringPi/softPwm.c index b568dfb..6187b85 100644 --- a/wiringPi/softPwm.c +++ b/wiringPi/softPwm.c @@ -74,11 +74,11 @@ static PI_THREAD (softPwmThread) if (mark != 0) digitalWrite (pin, HIGH) ; - delayMicroseconds (mark * 100) ; + delayMicroseconds (mark * PULSE_TIME) ; if (space != 0) digitalWrite (pin, LOW) ; - delayMicroseconds (space * 100) ; + delayMicroseconds (space * PULSE_TIME) ; } return NULL ; From e7ca03ac8ec839dd599c878274dfbc5203ca6db1 Mon Sep 17 00:00:00 2001 From: IsaoNakamura Date: Fri, 21 Aug 2015 20:54:36 +0900 Subject: [PATCH 16/29] delete duplicated FSEL_ALT0 definition. --- wiringPi/wiringPi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index a68ae33..844bd64 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -121,7 +121,6 @@ void (*pwmSetClock) (int divisor) ; #define FSEL_INPT 0b000 #define FSEL_OUTP 0b001 #define FSEL_ALT0 0b100 -#define FSEL_ALT0 0b100 #define FSEL_ALT1 0b101 #define FSEL_ALT2 0b110 #define FSEL_ALT3 0b111 From 26c7fe3332d925461c01975d6add286986efd6d0 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Sat, 27 Feb 2016 16:03:10 +0000 Subject: [PATCH 17/29] Updated from git.drogon.net --- INSTALL | 12 - People | 6 + README.TXT | 2 +- VERSION | 1 + build | 167 +- debian-template/wiringPi/DEBIAN/control | 10 + debian-template/wiringPi/DEBIAN/postinst | 5 + debian-template/wiringPi/DEBIAN/postrm | 2 + debian/.gitignore | 9 + debian/changelog | 6 + debian/compat | 1 + debian/control | 29 + debian/copyright | 15 + debian/libwiringpi-dev.dirs | 2 + debian/libwiringpi-dev.install | 3 + debian/libwiringpi2.install | 1 + debian/libwiringpi2.shlibs | 2 + debian/rules | 49 + debian/wiringpi.dirs | 1 + debian/wiringpi.install | 4 + devLib/Makefile | 137 ++ devLib/ds1302.c | 240 ++ devLib/ds1302.h | 44 + devLib/font.h | 2577 ++++++++++++++++++++++ devLib/gertboard.c | 164 ++ devLib/gertboard.h | 45 + devLib/lcd.c | 495 +++++ devLib/lcd.h | 52 + devLib/lcd128x64.c | 673 ++++++ devLib/lcd128x64.h | 39 + devLib/maxdetect.c | 165 ++ devLib/maxdetect.h | 40 + devLib/piFace.c | 112 + devLib/piFace.h | 32 + devLib/piFaceOld.c | 178 ++ devLib/piGlow.c | 118 + devLib/piGlow.h | 45 + devLib/piNes.c | 113 + devLib/piNes.h | 45 + examples/Gertboard/7segments.c | 221 ++ examples/Gertboard/Makefile | 78 + examples/Gertboard/buttons.c | 83 + examples/Gertboard/gertboard.c | 96 + examples/Gertboard/record.c | 60 + examples/Gertboard/temperature.c | 78 + examples/Gertboard/voltmeter.c | 73 + examples/Gertboard/vumeter.c | 152 ++ examples/Makefile | 146 +- examples/PiFace/Makefile | 88 + examples/PiFace/blink.c | 59 + examples/PiFace/buttons.c | 103 + examples/PiFace/ladder.c | 337 +++ examples/PiFace/metro.c | 111 + examples/PiFace/motor.c | 120 + examples/PiFace/reaction.c | 194 ++ examples/PiGlow/Makefile | 82 + examples/PiGlow/piGlow0.c | 51 + examples/PiGlow/piGlow1.c | 258 +++ examples/PiGlow/piglow.c | 176 ++ examples/blink.c | 8 +- examples/blink.sh | 4 +- examples/blink12.c | 111 + examples/blink12drcs.c | 125 ++ examples/blink6drcs.c | 115 + examples/blink8.c | 57 + examples/clock.c | 201 ++ examples/ds1302.c | 238 ++ examples/isr.c | 63 +- examples/lcd-adafruit.c | 347 +++ examples/lcd.c | 281 ++- examples/lowPower.c | 68 + examples/max31855.c | 60 + examples/okLed.c | 13 +- examples/pwm.c | 79 +- examples/q2w/Makefile | 84 + examples/q2w/binary.c | 79 + examples/q2w/blink-io.c | 61 + examples/q2w/blink.c | 50 + examples/q2w/blink.sh | 37 + examples/q2w/bright.c | 59 + examples/q2w/button.c | 63 + examples/q2w/volts.c | 62 + examples/rht03.c | 69 + examples/softPwm.c | 89 + examples/softTone.c | 54 + examples/speed.c | 114 +- examples/spiSpeed.c | 118 + gpio/Makefile | 81 +- gpio/gpio.1 | 166 +- gpio/gpio.c | 639 ++++-- gpio/pins.c | 33 + gpio/pintest | 187 ++ gpio/readall.c | 336 +++ gpio/version.h | 1 + newVersion | 43 + pins/Makefile | 22 + pins/pins.pdf | Bin 0 -> 9833 bytes pins/pins.tex | 116 + wiringPi/Makefile | 192 +- wiringPi/drcSerial.c | 201 ++ wiringPi/drcSerial.h | 33 + wiringPi/max31855.c | 99 + wiringPi/max31855.h | 33 + wiringPi/max5322.c | 84 + wiringPi/max5322.h | 33 + wiringPi/mcp23008.c | 149 ++ wiringPi/mcp23008.h | 33 + wiringPi/mcp23016.c | 164 ++ wiringPi/mcp23016.h | 33 + wiringPi/mcp23016reg.h | 48 + wiringPi/mcp23017.c | 195 ++ wiringPi/mcp23017.h | 33 + wiringPi/mcp23s08.c | 189 ++ wiringPi/mcp23s08.h | 33 + wiringPi/mcp23s17.c | 236 ++ wiringPi/mcp23s17.h | 33 + wiringPi/mcp23x08.h | 73 + wiringPi/mcp23x0817.h | 87 + wiringPi/mcp3002.c | 76 + wiringPi/mcp3002.h | 33 + wiringPi/mcp3004.c | 76 + wiringPi/mcp3004.h | 33 + wiringPi/mcp3422.c | 110 + wiringPi/mcp3422.h | 43 + wiringPi/mcp4802.c | 76 + wiringPi/mcp4802.h | 33 + wiringPi/pcf8574.c | 126 ++ wiringPi/pcf8574.h | 33 + wiringPi/pcf8591.c | 90 + wiringPi/pcf8591.h | 33 + wiringPi/piHiPri.c | 7 +- wiringPi/sn3218.c | 75 + wiringPi/sn3218.h | 33 + wiringPi/softPwm.c | 62 +- wiringPi/softPwm.h | 1 + wiringPi/softTone.c | 55 +- wiringPi/softTone.h | 3 +- wiringPi/sr595.c | 109 + wiringPi/sr595.h | 34 + wiringPi/wiringPi.c | 1840 ++++++++++----- wiringPi/wiringPi.h | 151 +- wiringPi/wiringPiI2C.c | 158 +- wiringPi/wiringPiI2C.h | 15 +- wiringPi/wiringPiSPI.c | 59 +- wiringPi/wiringPiSPI.h | 9 +- wiringPi/wiringSerial.c | 17 +- wiringPi/wiringSerial.h | 16 +- wiringPi/wiringShift.c | 1 - wiringPi/wiringShift.h | 4 +- wiringPi/wpiExtensions.c | 731 ++++++ wiringPi/wpiExtensions.h | 26 + 151 files changed, 17346 insertions(+), 1343 deletions(-) create mode 100644 VERSION create mode 100644 debian-template/wiringPi/DEBIAN/control create mode 100644 debian-template/wiringPi/DEBIAN/postinst create mode 100644 debian-template/wiringPi/DEBIAN/postrm create mode 100644 debian/.gitignore create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/libwiringpi-dev.dirs create mode 100644 debian/libwiringpi-dev.install create mode 100644 debian/libwiringpi2.install create mode 100644 debian/libwiringpi2.shlibs create mode 100644 debian/rules create mode 100644 debian/wiringpi.dirs create mode 100644 debian/wiringpi.install create mode 100644 devLib/Makefile create mode 100644 devLib/ds1302.c create mode 100644 devLib/ds1302.h create mode 100644 devLib/font.h create mode 100644 devLib/gertboard.c create mode 100644 devLib/gertboard.h create mode 100644 devLib/lcd.c create mode 100644 devLib/lcd.h create mode 100644 devLib/lcd128x64.c create mode 100644 devLib/lcd128x64.h create mode 100644 devLib/maxdetect.c create mode 100644 devLib/maxdetect.h create mode 100644 devLib/piFace.c create mode 100644 devLib/piFace.h create mode 100644 devLib/piFaceOld.c create mode 100644 devLib/piGlow.c create mode 100644 devLib/piGlow.h create mode 100644 devLib/piNes.c create mode 100644 devLib/piNes.h create mode 100644 examples/Gertboard/7segments.c create mode 100644 examples/Gertboard/Makefile create mode 100644 examples/Gertboard/buttons.c create mode 100644 examples/Gertboard/gertboard.c create mode 100644 examples/Gertboard/record.c create mode 100644 examples/Gertboard/temperature.c create mode 100644 examples/Gertboard/voltmeter.c create mode 100644 examples/Gertboard/vumeter.c create mode 100644 examples/PiFace/Makefile create mode 100644 examples/PiFace/blink.c create mode 100644 examples/PiFace/buttons.c create mode 100644 examples/PiFace/ladder.c create mode 100644 examples/PiFace/metro.c create mode 100644 examples/PiFace/motor.c create mode 100644 examples/PiFace/reaction.c create mode 100644 examples/PiGlow/Makefile create mode 100644 examples/PiGlow/piGlow0.c create mode 100644 examples/PiGlow/piGlow1.c create mode 100644 examples/PiGlow/piglow.c create mode 100644 examples/blink12.c create mode 100644 examples/blink12drcs.c create mode 100644 examples/blink6drcs.c create mode 100644 examples/blink8.c create mode 100644 examples/clock.c create mode 100644 examples/ds1302.c create mode 100644 examples/lcd-adafruit.c create mode 100644 examples/lowPower.c create mode 100644 examples/max31855.c create mode 100644 examples/q2w/Makefile create mode 100644 examples/q2w/binary.c create mode 100644 examples/q2w/blink-io.c create mode 100644 examples/q2w/blink.c create mode 100644 examples/q2w/blink.sh create mode 100644 examples/q2w/bright.c create mode 100644 examples/q2w/button.c create mode 100644 examples/q2w/volts.c create mode 100644 examples/rht03.c create mode 100644 examples/softPwm.c create mode 100644 examples/softTone.c create mode 100644 examples/spiSpeed.c create mode 100644 gpio/pins.c create mode 100644 gpio/pintest create mode 100644 gpio/readall.c create mode 100644 gpio/version.h create mode 100644 newVersion create mode 100644 pins/Makefile create mode 100644 pins/pins.pdf create mode 100644 pins/pins.tex create mode 100644 wiringPi/drcSerial.c create mode 100644 wiringPi/drcSerial.h create mode 100644 wiringPi/max31855.c create mode 100644 wiringPi/max31855.h create mode 100644 wiringPi/max5322.c create mode 100644 wiringPi/max5322.h create mode 100644 wiringPi/mcp23008.c create mode 100644 wiringPi/mcp23008.h create mode 100644 wiringPi/mcp23016.c create mode 100644 wiringPi/mcp23016.h create mode 100644 wiringPi/mcp23016reg.h create mode 100644 wiringPi/mcp23017.c create mode 100644 wiringPi/mcp23017.h create mode 100644 wiringPi/mcp23s08.c create mode 100644 wiringPi/mcp23s08.h create mode 100644 wiringPi/mcp23s17.c create mode 100644 wiringPi/mcp23s17.h create mode 100644 wiringPi/mcp23x08.h create mode 100644 wiringPi/mcp23x0817.h create mode 100644 wiringPi/mcp3002.c create mode 100644 wiringPi/mcp3002.h create mode 100644 wiringPi/mcp3004.c create mode 100644 wiringPi/mcp3004.h create mode 100644 wiringPi/mcp3422.c create mode 100644 wiringPi/mcp3422.h create mode 100644 wiringPi/mcp4802.c create mode 100644 wiringPi/mcp4802.h create mode 100644 wiringPi/pcf8574.c create mode 100644 wiringPi/pcf8574.h create mode 100644 wiringPi/pcf8591.c create mode 100644 wiringPi/pcf8591.h create mode 100644 wiringPi/sn3218.c create mode 100644 wiringPi/sn3218.h create mode 100644 wiringPi/sr595.c create mode 100644 wiringPi/sr595.h create mode 100644 wiringPi/wpiExtensions.c create mode 100644 wiringPi/wpiExtensions.h diff --git a/INSTALL b/INSTALL index 8a6d38e..8e0c43c 100644 --- a/INSTALL +++ b/INSTALL @@ -30,18 +30,6 @@ To un-install wiringPi: ./build uninstall - -I2C: - -If your system has the correct i2c-dev libraries and headers installed, -then the I2C helpers will be compiled into wiringPi. If you want to -use the I2C helpers and don't have them installed, then under Raspbian, -issue the command: - - sudo apt-get install libi2c-dev - -Consult the documentation for your system if you are not running Raspbian. - Gordon Henderson projects@drogon.net diff --git a/People b/People index 8be8b6d..b339494 100644 --- a/People +++ b/People @@ -25,3 +25,9 @@ CHARLES Thibaut: Xian Stannard Fixing some typos in the man page! + +Andre Crone + Suggested the __WIRING_PI.H__ round wiringPi.h + +Rik Teerling + Pointing out some silly mistooks in the I2C code... diff --git a/README.TXT b/README.TXT index 0fce86a..7789b2e 100644 --- a/README.TXT +++ b/README.TXT @@ -16,7 +16,7 @@ accepted to Github.... Please see - https://projects.drogon.net/raspberry-pi/wiringpi/ + http://wiringpi.com/ for the official documentation, etc. and the best way to submit bug reports, etc. is by sending an email to projects@drogon.net diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..3125d73 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +2.31 diff --git a/build b/build index cbb1a4f..c2a589c 100755 --- a/build +++ b/build @@ -1,7 +1,37 @@ -#!/bin/bash +#!/bin/sh -e -check-make-ok() -{ +# build +# Simple wiringPi build and install script +# +# Copyright (c) 2012-2015 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# Wiring Compatable library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# +# +# wiringPi is designed to run on a Raspberry Pi only. +# However if you're clever enough to actually look at this script to +# see why it's not building for you, then good luck. +# +# To everyone else: Stop using cheap alternatives. Support the +# Raspberry Pi Foundation as they're the only ones putting money +# back into education! +################################################################################# + +check_make_ok() { if [ $? != 0 ]; then echo "" echo "Make Failed..." @@ -13,67 +43,120 @@ check-make-ok() fi } +sudo=${WIRINGPI_SUDO-sudo} + if [ x$1 = "xclean" ]; then - echo Cleaning - echo cd wiringPi - make clean + echo -n "wiringPi: " ; make clean + cd ../devLib + echo -n "DevLib: " ; make clean cd ../gpio - make clean + echo -n "gpio: " ; make clean cd ../examples - make clean + echo -n "Examples: " ; make clean + cd Gertboard + echo -n "Gertboard: " ; make clean + cd ../PiFace + echo -n "PiFace: " ; make clean + cd ../q2w + echo -n "Quick2Wire: " ; make clean + cd ../PiGlow + echo -n "PiGlow: " ; make clean exit fi if [ x$1 = "xuninstall" ]; then - echo Uninstalling - echo - echo "WiringPi library" cd wiringPi - sudo make uninstall - echo - echo "GPIO Utility" + echo -n "wiringPi: " ; $sudo make uninstall + cd ../devLib + echo -n "DevLib: " ; $sudo make uninstall cd ../gpio - sudo make uninstall - cd .. + echo -n "gpio: " ; $sudo make uninstall exit fi +# Only if you know what you're doing! + +if [ x$1 = "xdebian" ]; then + here=`pwd` + cd debian-template/wiringPi + rm -rf usr + cd $here/wiringPi + make install-deb + cd $here/devLib + make install-deb INCLUDE='-I. -I../wiringPi' + cd $here/gpio + make install-deb INCLUDE='-I../wiringPi -I../devLib' LDFLAGS=-L../debian-template/wiringPi/usr/lib + cd $here/debian-template + fakeroot dpkg-deb --build wiringPi + mv wiringPi.deb wiringpi-`cat $here/VERSION`-1.deb + exit +fi + +if [ x$1 != "x" ]; then + echo "Usage: $0 [clean | uninstall]" + exit 1 +fi echo "wiringPi Build script" echo "=====================" echo -# Check for I2C being installed... -# ... and if-so, then automatically make the I2C helpers + hardware=`fgrep Hardware /proc/cpuinfo | head -1 | awk '{ print $3 }'` + +# if [ x$hardware != "xBCM2708" ]; then +# echo "" +# echo " +------------------------------------------------------------+" +# echo " | wiringPi is designed to run on the Raspberry Pi only. |" +# echo " | This processor does not appear to be a Raspberry Pi. |" +# echo " +------------------------------------------------------------+" +# echo " | In the unlikely event that you think it is a Raspberry Pi, |" +# echo " | then please accept my apologies and email the contents of |" +# echo " | /proc/cpuinfo to projects@drogon.net. |" +# echo " | - Thanks, Gordon |" +# echo " +------------------------------------------------------------+" +# echo "" +# exit 1 +# fi - if [ -f /usr/include/linux/i2c-dev.h ]; then - grep -q i2c_smbus_read_byte /usr/include/linux/i2c-dev.h - if [ $? = 0 ]; then - target=i2c - echo "Building wiringPi with the I2C helper libraries." - else - target=all - echo "The wiringPi I2C helper libraries will not be built." - fi - fi echo - echo "WiringPi library" + echo "WiringPi Library" cd wiringPi - sudo make uninstall - make $target - check-make-ok - sudo make install - check-make-ok + $sudo make uninstall + if [ x$1 = "xstatic" ]; then + make -j5 static + check_make_ok + $sudo make install-static + else + make -j5 + check_make_ok + $sudo make install + fi + check_make_ok + + echo + echo "WiringPi Devices Library" + cd ../devLib + $sudo make uninstall + if [ x$1 = "xstatic" ]; then + make -j5 static + check_make_ok + $sudo make install-static + else + make -j5 + check_make_ok + $sudo make install + fi + check_make_ok echo echo "GPIO Utility" cd ../gpio - make - check-make-ok - sudo make install - check-make-ok + make -j5 + check_make_ok + $sudo make install + check_make_ok # echo # echo "Examples" @@ -83,3 +166,11 @@ fi echo echo All Done. +echo "" +echo "NOTE: To compile programs with wiringPi, you need to add:" +echo " -lwiringPi" +echo " to your compile line(s) To use the Gertboard, MaxDetect, etc." +echo " code (the devLib), you need to also add:" +echo " -lwiringPiDev" +echo " to your compile line(s)." +echo "" diff --git a/debian-template/wiringPi/DEBIAN/control b/debian-template/wiringPi/DEBIAN/control new file mode 100644 index 0000000..5d698c8 --- /dev/null +++ b/debian-template/wiringPi/DEBIAN/control @@ -0,0 +1,10 @@ +Package: wiringpi +Version: 2.31 +Section: libraries +Priority: optional +Architecture: armhf +Depends: libc6 +Maintainer: Gordon Henderson +Description: The wiringPi libraries, headers and gpio command + Libraries to allow GPIO access on a Raspberry Pi from C and C++ + programs as well as from the command-line diff --git a/debian-template/wiringPi/DEBIAN/postinst b/debian-template/wiringPi/DEBIAN/postinst new file mode 100644 index 0000000..4997e98 --- /dev/null +++ b/debian-template/wiringPi/DEBIAN/postinst @@ -0,0 +1,5 @@ +#!/bin/sh +set -e +/bin/chown root.root /usr/bin/gpio +/bin/chmod 4755 /usr/bin/gpio +/sbin/ldconfig diff --git a/debian-template/wiringPi/DEBIAN/postrm b/debian-template/wiringPi/DEBIAN/postrm new file mode 100644 index 0000000..4be8c58 --- /dev/null +++ b/debian-template/wiringPi/DEBIAN/postrm @@ -0,0 +1,2 @@ +#!/bin/sh +/sbin/ldconfig diff --git a/debian/.gitignore b/debian/.gitignore new file mode 100644 index 0000000..6296064 --- /dev/null +++ b/debian/.gitignore @@ -0,0 +1,9 @@ +*.debhelper.log +*.substvars +tmp +wiringpi +libwiringpi2 +libwiringpi-dev +files +*.postinst.debhelper +*.postrm.debhelper diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..7f04ad5 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,6 @@ +wiringpi (2.26~iwj) rpi-unstable; urgency=low + + * Initial version with real Debian source package build. + + -- Ian Jackson Sat, 12 Sep 2015 18:31:35 +0100 + diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..45a4fb7 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +8 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..1d6d228 --- /dev/null +++ b/debian/control @@ -0,0 +1,29 @@ +Source: wiringpi +Section: electronics +Priority: optional +Maintainer: Ian Jackson +Standards-Version: 3.8.0 +Homepage: http://wiringpi.com/ +Build-Depends: debhelper (>= 8) + +Package: libwiringpi2 +Section: libs +Architecture: armhf +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: GPIO librariees for Raspberry Pi (runtime). + Runtime for the popular wiringPi library. + +Package: wiringpi +Architecture: armhf +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: gpio utility for Raspberry Pi + The wiringPi gpio command line utility, for GPIO access on a + Raspberry Pi from the command line. + +Package: libwiringpi-dev +Architecture: armhf +Depends: libwiringpi2 (= ${binary:Version}), libc6-dev, ${misc:Depends} +Suggests: wiringpi +Description: GPIO development library for Raspberry Pi + Development libraries to allow GPIO access on a Raspberry Pi from C + and C++ programs. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..de82701 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,15 @@ +wiringPi is Copyright (C) 2012-2015 Gordon Henderson. + +wiringPi is free software; you can redistribute it and/or modify it +under the terms of the GNU Lesser General Public License, as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +wiringPi is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +On all Debian and Raspbian systems, a copy of the GNU Lesser General +Public License version 3 can be found in +`/usr/share/common-licenses/LGPL-3'. diff --git a/debian/libwiringpi-dev.dirs b/debian/libwiringpi-dev.dirs new file mode 100644 index 0000000..4418816 --- /dev/null +++ b/debian/libwiringpi-dev.dirs @@ -0,0 +1,2 @@ +usr/lib +usr/include diff --git a/debian/libwiringpi-dev.install b/debian/libwiringpi-dev.install new file mode 100644 index 0000000..d7ea901 --- /dev/null +++ b/debian/libwiringpi-dev.install @@ -0,0 +1,3 @@ +debian/tmp/usr/include +debian/tmp/usr/lib/*.so +examples usr/share/doc/libwiringpi-dev diff --git a/debian/libwiringpi2.install b/debian/libwiringpi2.install new file mode 100644 index 0000000..c45ebcf --- /dev/null +++ b/debian/libwiringpi2.install @@ -0,0 +1 @@ +debian/tmp/usr/lib/lib*.so.* diff --git a/debian/libwiringpi2.shlibs b/debian/libwiringpi2.shlibs new file mode 100644 index 0000000..0be8db1 --- /dev/null +++ b/debian/libwiringpi2.shlibs @@ -0,0 +1,2 @@ +libwiringPi 2 libwiringpi2 +libwiringPiDev 2 libwiringpi2 diff --git a/debian/rules b/debian/rules new file mode 100644 index 0000000..423a473 --- /dev/null +++ b/debian/rules @@ -0,0 +1,49 @@ +#!/usr/bin/make -f + +.PHONY: build + +VERSION:=$(shell cat VERSION) +export VERSION + +soname:=$(shell echo $${VERSION%%.*}) +WIRINGPI_SONAME_SUFFIX:=.$(soname) +export soname +export WIRINGPI_SONAME_SUFFIX + +build: + dh $@ + +override_dh_auto_configure: + +override_dh_prep: + dh_prep -Xdebian/tmp + +dirs: + dh_installdirs -A + mkdir debian/tmp + set -e; for p in `dh_listpackages`; do \ + (cd debian/$$p; find -type d) | \ + (cd debian/tmp; xargs mkdir -p) \ + done + +override_dh_clean: + dh_clean + WIRINGPI_SUDO= bash -xe ./build clean + +override_dh_auto_build: dirs + V=1 LDCONFIG=: WIRINGPI_SUDO= WIRINGPI_SUID=0 \ + DESTDIR=`pwd`/debian/tmp/usr \ + PREFIX= WIRINGPI_SUDO= \ + bash -xe ./build + +override_dh_auto_install: + dh_install + set -ex; for l in libwiringPi libwiringPiDev; do \ + ln -sf $$l.so.$${VERSION} \ + debian/libwiringpi$$soname/usr/lib/$$l.so.$$soname; \ + ln -sf $$l.so.$${VERSION} \ + debian/libwiringpi-dev/usr/lib/$$l.so; \ + done + +%: + dh $@ diff --git a/debian/wiringpi.dirs b/debian/wiringpi.dirs new file mode 100644 index 0000000..e772481 --- /dev/null +++ b/debian/wiringpi.dirs @@ -0,0 +1 @@ +usr/bin diff --git a/debian/wiringpi.install b/debian/wiringpi.install new file mode 100644 index 0000000..41ae22d --- /dev/null +++ b/debian/wiringpi.install @@ -0,0 +1,4 @@ +debian/tmp/usr/bin +debian/tmp/usr/man usr/share +README.TXT usr/share/doc/wiringpi +People usr/share/doc/wiringpi diff --git a/devLib/Makefile b/devLib/Makefile new file mode 100644 index 0000000..0fb0033 --- /dev/null +++ b/devLib/Makefile @@ -0,0 +1,137 @@ +# +# Makefile: +# wiringPi device - Wiring Compatable library for the Raspberry Pi +# +# Copyright (c) 2012-2015 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# https://projects.drogon.net/raspberry-pi/wiringpi/ +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + +VERSION=$(shell cat ../VERSION) +DESTDIR?=/usr +PREFIX?=/local + +LDCONFIG?=ldconfig + +ifneq ($V,1) +Q ?= @ +endif + +STATIC=libwiringPiDev.a +DYNAMIC=libwiringPiDev.so.$(VERSION) + +#DEBUG = -g -O0 +DEBUG = -O2 +CC = gcc +INCLUDE = -I. +DEFS = -D_GNU_SOURCE +CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Winline $(INCLUDE) -pipe -fPIC + +LIBS = + +############################################################################### + +SRC = ds1302.c maxdetect.c piNes.c \ + gertboard.c piFace.c \ + lcd128x64.c lcd.c \ + piGlow.c + +OBJ = $(SRC:.c=.o) + +HEADERS = ds1302.h gertboard.h lcd128x64.h lcd.h maxdetect.h piFace.h piGlow.h piNes.h + +all: $(DYNAMIC) + +static: $(STATIC) + +$(STATIC): $(OBJ) + $Q echo "[Link (Static)]" + $Q ar rcs $(STATIC) $(OBJ) + $Q ranlib $(STATIC) +# @size $(STATIC) + +$(DYNAMIC): $(OBJ) + $Q echo "[Link (Dynamic)]" + $Q $(CC) -shared -Wl,-soname,libwiringPiDev.so$(WIRINGPI_SONAME_SUFFIX) -o libwiringPiDev.so.$(VERSION) -lpthread $(OBJ) + +.c.o: + $Q echo [Compile] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ + +.PHONY: clean +clean: + $Q echo "[Clean]" + $Q rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPiDev.* + +.PHONY: tags +tags: $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) + + +.PHONY: install +install: $(DYNAMIC) + $Q echo "[Install Headers]" + $Q install -m 0755 -d $(DESTDIR)$(PREFIX)/include + $Q install -m 0644 $(HEADERS) $(DESTDIR)$(PREFIX)/include + $Q echo "[Install Dynamic Lib]" + $Q install -m 0755 -d $(DESTDIR)$(PREFIX)/lib + $Q install -m 0755 libwiringPiDev.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libwiringPiDev.so.$(VERSION) + $Q ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPiDev.so.$(VERSION) $(DESTDIR)/lib/libwiringPiDev.so + $Q $(LDCONFIG) + +.PHONY: install-static +install-static: $(STATIC) + $Q echo "[Install Headers]" + $Q install -m 0755 -d $(DESTDIR)$(PREFIX)/include + $Q install -m 0644 $(HEADERS) $(DESTDIR)$(PREFIX)/include + $Q echo "[Install Static Lib]" + $Q install -m 0755 -d $(DESTDIR)$(PREFIX)/lib + $Q install -m 0755 libwiringPiDev.a $(DESTDIR)$(PREFIX)/lib + +.PHONY: install-deb +install-deb: $(DYNAMIC) + $Q echo "[Install Headers: deb]" + $Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/include + $Q install -m 0644 $(HEADERS) ~/wiringPi/debian-template/wiringPi/usr/include + $Q echo "[Install Dynamic Lib: deb]" + install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/lib + install -m 0755 libwiringPiDev.so.$(VERSION) ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPiDev.so.$(VERSION) + ln -sf ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPiDev.so.$(VERSION) ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPiDev.so + +.PHONY: uninstall +uninstall: + $Q echo "[UnInstall]" + $Q cd $(DESTDIR)$(PREFIX)/include/ && rm -f $(HEADERS) + $Q cd $(DESTDIR)$(PREFIX)/lib/ && rm -f libwiringPiDev.* + $Q $(LDCONFIG) + + +.PHONY: depend +depend: + makedepend -Y $(SRC) + +# DO NOT DELETE + +ds1302.o: ds1302.h +maxdetect.o: maxdetect.h +piNes.o: piNes.h +gertboard.o: gertboard.h +piFace.o: piFace.h +lcd128x64.o: font.h lcd128x64.h +lcd.o: lcd.h +piGlow.o: piGlow.h diff --git a/devLib/ds1302.c b/devLib/ds1302.c new file mode 100644 index 0000000..cf64de7 --- /dev/null +++ b/devLib/ds1302.c @@ -0,0 +1,240 @@ +/* + * ds1302.c: + * Real Time clock + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include + +#include + +#include "ds1302.h" + +// Register defines + +#define RTC_SECS 0 +#define RTC_MINS 1 +#define RTC_HOURS 2 +#define RTC_DATE 3 +#define RTC_MONTH 4 +#define RTC_DAY 5 +#define RTC_YEAR 6 +#define RTC_WP 7 +#define RTC_TC 8 +#define RTC_BM 31 + + +// Locals + +static int dPin, cPin, sPin ; + +/* + * dsShiftIn: + * Shift a number in from the chip, LSB first. Note that the data is + * sampled on the trailing edge of the last clock, so it's valid immediately. + ********************************************************************************* + */ + +static unsigned int dsShiftIn (void) +{ + uint8_t value = 0 ; + int i ; + + pinMode (dPin, INPUT) ; delayMicroseconds (1) ; + + for (i = 0 ; i < 8 ; ++i) + { + value |= (digitalRead (dPin) << i) ; + digitalWrite (cPin, HIGH) ; delayMicroseconds (1) ; + digitalWrite (cPin, LOW) ; delayMicroseconds (1) ; + } + + return value; +} + + +/* + * dsShiftOut: + * A normal LSB-first shift-out, just slowed down a bit - the Pi is + * a bit faster than the chip can handle. + ********************************************************************************* + */ + +static void dsShiftOut (unsigned int data) +{ + int i ; + + pinMode (dPin, OUTPUT) ; + + for (i = 0 ; i < 8 ; ++i) + { + digitalWrite (dPin, data & (1 << i)) ; delayMicroseconds (1) ; + digitalWrite (cPin, HIGH) ; delayMicroseconds (1) ; + digitalWrite (cPin, LOW) ; delayMicroseconds (1) ; + } +} + + +/* + * ds1302regRead: ds1302regWrite: + * Read/Write a value to an RTC Register or RAM location on the chip + ********************************************************************************* + */ + +static unsigned int ds1302regRead (const int reg) +{ + unsigned int data ; + + digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ; + dsShiftOut (reg) ; + data = dsShiftIn () ; + digitalWrite (sPin, LOW) ; delayMicroseconds (1) ; + + return data ; +} + +static void ds1302regWrite (const int reg, const unsigned int data) +{ + digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ; + dsShiftOut (reg) ; + dsShiftOut (data) ; + digitalWrite (sPin, LOW) ; delayMicroseconds (1) ; +} + + +/* + * ds1302rtcWrite: ds1302rtcRead: + * Writes/Reads the data to/from the RTC register + ********************************************************************************* + */ + +unsigned int ds1302rtcRead (const int reg) +{ + return ds1302regRead (0x81 | ((reg & 0x1F) << 1)) ; +} + +void ds1302rtcWrite (int reg, unsigned int data) +{ + ds1302regWrite (0x80 | ((reg & 0x1F) << 1), data) ; +} + + +/* + * ds1302ramWrite: ds1302ramRead: + * Writes/Reads the data to/from the RTC register + ********************************************************************************* + */ + +unsigned int ds1302ramRead (const int addr) +{ + return ds1302regRead (0xC1 | ((addr & 0x1F) << 1)) ; +} + +void ds1302ramWrite (const int addr, const unsigned int data) +{ + ds1302regWrite ( 0xC0 | ((addr & 0x1F) << 1), data) ; +} + +/* + * ds1302clockRead: + * Read all 8 bytes of the clock in a single operation + ********************************************************************************* + */ + +void ds1302clockRead (int clockData [8]) +{ + int i ; + unsigned int regVal = 0x81 | ((RTC_BM & 0x1F) << 1) ; + + digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ; + + dsShiftOut (regVal) ; + for (i = 0 ; i < 8 ; ++i) + clockData [i] = dsShiftIn () ; + + digitalWrite (sPin, LOW) ; delayMicroseconds (1) ; +} + + +/* + * ds1302clockWrite: + * Write all 8 bytes of the clock in a single operation + ********************************************************************************* + */ + +void ds1302clockWrite (const int clockData [8]) +{ + int i ; + unsigned int regVal = 0x80 | ((RTC_BM & 0x1F) << 1) ; + + digitalWrite (sPin, HIGH) ; delayMicroseconds (1) ; + + dsShiftOut (regVal) ; + for (i = 0 ; i < 8 ; ++i) + dsShiftOut (clockData [i]) ; + + digitalWrite (sPin, LOW) ; delayMicroseconds (1) ; +} + + +/* + * ds1302trickleCharge: + * Set the bits on the trickle charger. + * Probably best left alone... + ********************************************************************************* + */ + +void ds1302trickleCharge (const int diodes, const int resistors) +{ + if (diodes + resistors == 0) + ds1302rtcWrite (RTC_TC, 0x5C) ; // Disabled + else + ds1302rtcWrite (RTC_TC, 0xA0 | ((diodes & 3) << 2) | (resistors & 3)) ; +} + + + + +/* + * ds1302setup: + * Initialise the chip & remember the pins we're using + ********************************************************************************* + */ + +void ds1302setup (const int clockPin, const int dataPin, const int csPin) +{ + dPin = dataPin ; + cPin = clockPin ; + sPin = csPin ; + + digitalWrite (dPin, LOW) ; + digitalWrite (cPin, LOW) ; + digitalWrite (sPin, LOW) ; + + pinMode (dPin, OUTPUT) ; + pinMode (cPin, OUTPUT) ; + pinMode (sPin, OUTPUT) ; + + ds1302rtcWrite (RTC_WP, 0) ; // Remove write-protect +} diff --git a/devLib/ds1302.h b/devLib/ds1302.h new file mode 100644 index 0000000..e82b3ed --- /dev/null +++ b/devLib/ds1302.h @@ -0,0 +1,44 @@ +/* + * ds1302.h: + * Real Time clock + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern unsigned int ds1302rtcRead (const int reg) ; +extern void ds1302rtcWrite (const int reg, const unsigned int data) ; + +extern unsigned int ds1302ramRead (const int addr) ; +extern void ds1302ramWrite (const int addr, const unsigned int data) ; + +extern void ds1302clockRead (int clockData [8]) ; +extern void ds1302clockWrite (const int clockData [8]) ; + +extern void ds1302trickleCharge (const int diodes, const int resistors) ; + +extern void ds1302setup (const int clockPin, const int dataPin, const int csPin) ; + +#ifdef __cplusplus +} +#endif diff --git a/devLib/font.h b/devLib/font.h new file mode 100644 index 0000000..ce99e16 --- /dev/null +++ b/devLib/font.h @@ -0,0 +1,2577 @@ +/**********************************************/ +/* */ +/* Font file generated by cpi2fnt */ +/* ------------------------------ */ +/* Combined with the alpha-numeric */ +/* portion of Greg Harp's old PEARL */ +/* font (from earlier versions of */ +/* linux-m86k) by John Shifflett */ +/* */ +/**********************************************/ + +static const int fontHeight = 8 ; +static const int fontWidth = 8 ; + +static unsigned char font [] = +{ + /* 0 0x00 '^@' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 1 0x01 '^A' */ + 0x7e, /* 01111110 */ + 0x81, /* 10000001 */ + 0xa5, /* 10100101 */ + 0x81, /* 10000001 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0x81, /* 10000001 */ + 0x7e, /* 01111110 */ + + /* 2 0x02 '^B' */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xdb, /* 11011011 */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + + /* 3 0x03 '^C' */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + + /* 4 0x04 '^D' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + + /* 5 0x05 '^E' */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + + /* 6 0x06 '^F' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + + /* 7 0x07 '^G' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 8 0x08 '^H' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xe7, /* 11100111 */ + 0xc3, /* 11000011 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 9 0x09 '^I' */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x42, /* 01000010 */ + 0x42, /* 01000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 10 0x0a '^J' */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0x99, /* 10011001 */ + 0xbd, /* 10111101 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0xc3, /* 11000011 */ + 0xff, /* 11111111 */ + + /* 11 0x0b '^K' */ + 0x0f, /* 00001111 */ + 0x07, /* 00000111 */ + 0x0f, /* 00001111 */ + 0x7d, /* 01111101 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + + /* 12 0x0c '^L' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + + /* 13 0x0d '^M' */ + 0x3f, /* 00111111 */ + 0x33, /* 00110011 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x70, /* 01110000 */ + 0xf0, /* 11110000 */ + 0xe0, /* 11100000 */ + + /* 14 0x0e '^N' */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x67, /* 01100111 */ + 0xe6, /* 11100110 */ + 0xc0, /* 11000000 */ + + /* 15 0x0f '^O' */ + 0x18, /* 00011000 */ + 0xdb, /* 11011011 */ + 0x3c, /* 00111100 */ + 0xe7, /* 11100111 */ + 0xe7, /* 11100111 */ + 0x3c, /* 00111100 */ + 0xdb, /* 11011011 */ + 0x18, /* 00011000 */ + + /* 16 0x10 '^P' */ + 0x80, /* 10000000 */ + 0xe0, /* 11100000 */ + 0xf8, /* 11111000 */ + 0xfe, /* 11111110 */ + 0xf8, /* 11111000 */ + 0xe0, /* 11100000 */ + 0x80, /* 10000000 */ + 0x00, /* 00000000 */ + + /* 17 0x11 '^Q' */ + 0x02, /* 00000010 */ + 0x0e, /* 00001110 */ + 0x3e, /* 00111110 */ + 0xfe, /* 11111110 */ + 0x3e, /* 00111110 */ + 0x0e, /* 00001110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + + /* 18 0x12 '^R' */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + + /* 19 0x13 '^S' */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + + /* 20 0x14 '^T' */ + 0x7f, /* 01111111 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7b, /* 01111011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x00, /* 00000000 */ + + /* 21 0x15 '^U' */ + 0x3e, /* 00111110 */ + 0x61, /* 01100001 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x86, /* 10000110 */ + 0x7c, /* 01111100 */ + + /* 22 0x16 '^V' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 23 0x17 '^W' */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + + /* 24 0x18 '^X' */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 25 0x19 '^Y' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 26 0x1a '^Z' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 27 0x1b '^[' */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 28 0x1c '^\' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 29 0x1d '^]' */ + 0x00, /* 00000000 */ + 0x24, /* 00100100 */ + 0x66, /* 01100110 */ + 0xff, /* 11111111 */ + 0x66, /* 01100110 */ + 0x24, /* 00100100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 30 0x1e '^^' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 31 0x1f '^_' */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 32 0x20 ' ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 33 0x21 '!' */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 34 0x22 '"' */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 35 0x23 '#' */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* 36 0x24 '$' */ + 0x18, /* 00011000 */ + 0x3e, /* 00111110 */ + 0x60, /* 01100000 */ + 0x3c, /* 00111100 */ + 0x06, /* 00000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 37 0x25 '%' */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x66, /* 01100110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 38 0x26 '&' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x68, /* 01101000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 39 0x27 ''' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 40 0x28 '(' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + + /* 41 0x29 ')' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + + /* 42 0x2a '*' */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0xff, /* 11111111 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 43 0x2b '+' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 44 0x2c ',' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + + /* 45 0x2d '-' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 46 0x2e '.' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 47 0x2f '/' */ + 0x03, /* 00000011 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* 48 0x30 '0' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xde, /* 11011110 */ + 0xfe, /* 11111110 */ + 0xf6, /* 11110110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 49 0x31 '1' */ + 0x18, /* 00011000 */ + 0x78, /* 01111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 50 0x32 '2' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 51 0x33 '3' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x1c, /* 00011100 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 52 0x34 '4' */ + 0x1c, /* 00011100 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + + /* 53 0x35 '5' */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 54 0x36 '6' */ + 0x38, /* 00111000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 55 0x37 '7' */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + + /* 56 0x38 '8' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 57 0x39 '9' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 58 0x3a ':' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 59 0x3b ';' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + + /* 60 0x3c '<' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + + /* 61 0x3d '=' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 62 0x3e '>' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + + /* 63 0x3f '?' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 64 0x40 '@' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 65 0x41 'A' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 66 0x42 'B' */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 67 0x43 'C' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 68 0x44 'D' */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 69 0x45 'E' */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xf8, /* 11111000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 70 0x46 'F' */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xf8, /* 11111000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* 71 0x47 'G' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 72 0x48 'H' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 73 0x49 'I' */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 74 0x4a 'J' */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 75 0x4b 'K' */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0xd8, /* 11011000 */ + 0xf0, /* 11110000 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 76 0x4c 'L' */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 77 0x4d 'M' */ + 0x82, /* 10000010 */ + 0xc6, /* 11000110 */ + 0xee, /* 11101110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 78 0x4e 'N' */ + 0xc6, /* 11000110 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 79 0x4f 'O' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 80 0x50 'P' */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* 81 0x51 'Q' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xf6, /* 11110110 */ + 0xde, /* 11011110 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + + /* 82 0x52 'R' */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 83 0x53 'S' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x38, /* 00111000 */ + 0x0c, /* 00001100 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 84 0x54 'T' */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 85 0x55 'U' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 86 0x56 'V' */ + 0xc3, /* 11000011 */ + 0xc3, /* 11000011 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 87 0x57 'W' */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0xee, /* 11101110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 88 0x58 'X' */ + 0xc3, /* 11000011 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc3, /* 11000011 */ + 0x00, /* 00000000 */ + + /* 89 0x59 'Y' */ + 0xc3, /* 11000011 */ + 0xc3, /* 11000011 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 90 0x5a 'Z' */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 91 0x5b '[' */ + 0x3c, /* 00111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 92 0x5c '\' */ + 0xc0, /* 11000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x03, /* 00000011 */ + 0x00, /* 00000000 */ + + /* 93 0x5d ']' */ + 0x3c, /* 00111100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 94 0x5e '^' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 95 0x5f '_' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + + /* 96 0x60 '`' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 97 0x61 'a' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + 0x7e, /* 01111110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 98 0x62 'b' */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 99 0x63 'c' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 100 0x64 'd' */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x7e, /* 01111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 101 0x65 'e' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 102 0x66 'f' */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + + /* 103 0x67 'g' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x7c, /* 01111100 */ + + /* 104 0x68 'h' */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 105 0x69 'i' */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 106 0x6a 'j' */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + + /* 107 0x6b 'k' */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xcc, /* 11001100 */ + 0xd8, /* 11011000 */ + 0xf0, /* 11110000 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + + /* 108 0x6c 'l' */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 109 0x6d 'm' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xec, /* 11101100 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 110 0x6e 'n' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 111 0x6f 'o' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 112 0x70 'p' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfc, /* 11111100 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + + /* 113 0x71 'q' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + + /* 114 0x72 'r' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0xe6, /* 11100110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* 115 0x73 's' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 116 0x74 't' */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x7c, /* 01111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x36, /* 00110110 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + + /* 117 0x75 'u' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 118 0x76 'v' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 119 0x77 'w' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* 120 0x78 'x' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 121 0x79 'y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc3, /* 11000011 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + + /* 122 0x7a 'z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x38, /* 00111000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 123 0x7b '{' */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x00, /* 00000000 */ + + /* 124 0x7c '|' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 125 0x7d '}' */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + + /* 126 0x7e '~' */ + 0x72, /* 01110010 */ + 0x9c, /* 10011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 127 0x7f '' */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 128 0x80 '€' */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x78, /* 01111000 */ + + /* 129 0x81 '' */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 130 0x82 '‚' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 131 0x83 'ƒ' */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 132 0x84 '„' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 133 0x85 '…' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 134 0x86 '†' */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 135 0x87 '‡' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x7e, /* 01111110 */ + 0x0c, /* 00001100 */ + 0x38, /* 00111000 */ + + /* 136 0x88 'ˆ' */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 137 0x89 '‰' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 138 0x8a 'Š' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 139 0x8b '‹' */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 140 0x8c 'Œ' */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 141 0x8d '' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 142 0x8e 'Ž' */ + 0xc6, /* 11000110 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 143 0x8f '' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 144 0x90 '' */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xf8, /* 11111000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 145 0x91 '‘' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 146 0x92 '’' */ + 0x3e, /* 00111110 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xce, /* 11001110 */ + 0x00, /* 00000000 */ + + /* 147 0x93 '“' */ + 0x7c, /* 01111100 */ + 0x82, /* 10000010 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 148 0x94 '”' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 149 0x95 '•' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 150 0x96 '–' */ + 0x78, /* 01111000 */ + 0x84, /* 10000100 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 151 0x97 '—' */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 152 0x98 '˜' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0xfc, /* 11111100 */ + + /* 153 0x99 '™' */ + 0xc6, /* 11000110 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 154 0x9a 'š' */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 155 0x9b '›' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 156 0x9c 'œ' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x64, /* 01100100 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x66, /* 01100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + + /* 157 0x9d '' */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 158 0x9e 'ž' */ + 0xf8, /* 11111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xfa, /* 11111010 */ + 0xc6, /* 11000110 */ + 0xcf, /* 11001111 */ + 0xc6, /* 11000110 */ + 0xc7, /* 11000111 */ + + /* 159 0x9f 'Ÿ' */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + + /* 160 0xa0 ' ' */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 161 0xa1 '¡' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 162 0xa2 '¢' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + + /* 163 0xa3 '£' */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 164 0xa4 '¤' */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + + /* 165 0xa5 '¥' */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0x00, /* 00000000 */ + + /* 166 0xa6 '¦' */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 167 0xa7 '§' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 168 0xa8 '¨' */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x63, /* 01100011 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + + /* 169 0xa9 '©' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 170 0xaa 'ª' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 171 0xab '«' */ + 0x63, /* 01100011 */ + 0xe6, /* 11100110 */ + 0x6c, /* 01101100 */ + 0x7e, /* 01111110 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x0f, /* 00001111 */ + + /* 172 0xac '¬' */ + 0x63, /* 01100011 */ + 0xe6, /* 11100110 */ + 0x6c, /* 01101100 */ + 0x7a, /* 01111010 */ + 0x36, /* 00110110 */ + 0x6a, /* 01101010 */ + 0xdf, /* 11011111 */ + 0x06, /* 00000110 */ + + /* 173 0xad '­' */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 174 0xae '®' */ + 0x00, /* 00000000 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x66, /* 01100110 */ + 0x33, /* 00110011 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 175 0xaf '¯' */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0x66, /* 01100110 */ + 0x33, /* 00110011 */ + 0x66, /* 01100110 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 176 0xb0 '°' */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + 0x22, /* 00100010 */ + 0x88, /* 10001000 */ + + /* 177 0xb1 '±' */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + + /* 178 0xb2 '²' */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + + /* 179 0xb3 '³' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 180 0xb4 '´' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 181 0xb5 'µ' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 182 0xb6 '¶' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 183 0xb7 '·' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 184 0xb8 '¸' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 185 0xb9 '¹' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 186 0xba 'º' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 187 0xbb '»' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 188 0xbc '¼' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 189 0xbd '½' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 190 0xbe '¾' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 191 0xbf '¿' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 192 0xc0 'À' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 193 0xc1 'Á' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 194 0xc2 'Â' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 195 0xc3 'Ã' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 196 0xc4 'Ä' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 197 0xc5 'Å' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 198 0xc6 'Æ' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 199 0xc7 'Ç' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 200 0xc8 'È' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 201 0xc9 'É' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 202 0xca 'Ê' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 203 0xcb 'Ë' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 204 0xcc 'Ì' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 205 0xcd 'Í' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 206 0xce 'Î' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 207 0xcf 'Ï' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 208 0xd0 'Ð' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 209 0xd1 'Ñ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 210 0xd2 'Ò' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 211 0xd3 'Ó' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 212 0xd4 'Ô' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 213 0xd5 'Õ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 214 0xd6 'Ö' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 215 0xd7 '×' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 216 0xd8 'Ø' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 217 0xd9 'Ù' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 218 0xda 'Ú' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 219 0xdb 'Û' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 220 0xdc 'Ü' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 221 0xdd 'Ý' */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + + /* 222 0xde 'Þ' */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + + /* 223 0xdf 'ß' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 224 0xe0 'à' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xc8, /* 11001000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + + /* 225 0xe1 'á' */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + + /* 226 0xe2 'â' */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* 227 0xe3 'ã' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + + /* 228 0xe4 'ä' */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + + /* 229 0xe5 'å' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + + /* 230 0xe6 'æ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0xc0, /* 11000000 */ + + /* 231 0xe7 'ç' */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* 232 0xe8 'è' */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + + /* 233 0xe9 'é' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + + /* 234 0xea 'ê' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xee, /* 11101110 */ + 0x00, /* 00000000 */ + + /* 235 0xeb 'ë' */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x3e, /* 00111110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 236 0xec 'ì' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 237 0xed 'í' */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7e, /* 01111110 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + + /* 238 0xee 'î' */ + 0x1e, /* 00011110 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x7e, /* 01111110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x1e, /* 00011110 */ + 0x00, /* 00000000 */ + + /* 239 0xef 'ï' */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + + /* 240 0xf0 'ð' */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 241 0xf1 'ñ' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 242 0xf2 'ò' */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 243 0xf3 'ó' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* 244 0xf4 'ô' */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 245 0xf5 'õ' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + + /* 246 0xf6 'ö' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 247 0xf7 '÷' */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 248 0xf8 'ø' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 249 0xf9 'ù' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 250 0xfa 'ú' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 251 0xfb 'û' */ + 0x0f, /* 00001111 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xec, /* 11101100 */ + 0x6c, /* 01101100 */ + 0x3c, /* 00111100 */ + 0x1c, /* 00011100 */ + + /* 252 0xfc 'ü' */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 253 0xfd 'ý' */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 254 0xfe 'þ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 255 0xff 'ÿ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + +}; diff --git a/devLib/gertboard.c b/devLib/gertboard.c new file mode 100644 index 0000000..5aeaef7 --- /dev/null +++ b/devLib/gertboard.c @@ -0,0 +1,164 @@ +/* + * gertboard.c: + * Access routines for the SPI devices on the Gertboard + * Copyright (c) 2012 Gordon Henderson + * + * The Gertboard has: + * + * An MCP3002 dual-channel A to D convertor connected + * to the SPI bus, selected by chip-select A, and: + * + * An MCP4802 dual-channel D to A convertor connected + * to the SPI bus, selected via chip-select B. + * + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + + +#include +#include +#include +#include +#include + +#include +#include + +#include "gertboard.h" + +// The A-D convertor won't run at more than 1MHz @ 3.3v + +#define SPI_ADC_SPEED 1000000 +#define SPI_DAC_SPEED 1000000 +#define SPI_A2D 0 +#define SPI_D2A 1 + + +/* + * gertboardAnalogWrite: + * Write an 8-bit data value to the MCP4802 Analog to digital + * convertor on the Gertboard. + ********************************************************************************* + */ + +void gertboardAnalogWrite (const int chan, const int value) +{ + uint8_t spiData [2] ; + uint8_t chanBits, dataBits ; + + if (chan == 0) + chanBits = 0x30 ; + else + chanBits = 0xB0 ; + + chanBits |= ((value >> 4) & 0x0F) ; + dataBits = ((value << 4) & 0xF0) ; + + spiData [0] = chanBits ; + spiData [1] = dataBits ; + + wiringPiSPIDataRW (SPI_D2A, spiData, 2) ; +} + + +/* + * gertboardAnalogRead: + * Return the analog value of the given channel (0/1). + * The A/D is a 10-bit device + ********************************************************************************* + */ + +int gertboardAnalogRead (const int chan) +{ + uint8_t spiData [2] ; + + uint8_t chanBits ; + + if (chan == 0) + chanBits = 0b11010000 ; + else + chanBits = 0b11110000 ; + + spiData [0] = chanBits ; + spiData [1] = 0 ; + + wiringPiSPIDataRW (SPI_A2D, spiData, 2) ; + + return ((spiData [0] << 7) | (spiData [1] >> 1)) & 0x3FF ; +} + + +/* + * gertboardSPISetup: + * Initialise the SPI bus, etc. + ********************************************************************************* + */ + +int gertboardSPISetup (void) +{ + if (wiringPiSPISetup (SPI_A2D, SPI_ADC_SPEED) < 0) + return -1 ; + + if (wiringPiSPISetup (SPI_D2A, SPI_DAC_SPEED) < 0) + return -1 ; + + return 0 ; +} + + +/* + * New wiringPi node extension methods. + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, const int chan) +{ + return gertboardAnalogRead (chan - node->pinBase) ; +} + +static void myAnalogWrite (struct wiringPiNodeStruct *node, const int chan, const int value) +{ + gertboardAnalogWrite (chan - node->pinBase, value) ; +} + + +/* + * gertboardAnalogSetup: + * Create a new wiringPi device node for the analog devices on the + * Gertboard. We create one node with 2 pins - each pin being read + * and write - although the operations actually go to different + * hardware devices. + ********************************************************************************* + */ + +int gertboardAnalogSetup (const int pinBase) +{ + struct wiringPiNodeStruct *node ; + int x ; + + if (( x = gertboardSPISetup ()) != 0) + return x; + + node = wiringPiNewNode (pinBase, 2) ; + node->analogRead = myAnalogRead ; + node->analogWrite = myAnalogWrite ; + + return 0 ; +} diff --git a/devLib/gertboard.h b/devLib/gertboard.h new file mode 100644 index 0000000..3fa1919 --- /dev/null +++ b/devLib/gertboard.h @@ -0,0 +1,45 @@ +/* + * gertboard.h: + * Access routines for the SPI devices on the Gertboard + * Copyright (c) 2012 Gordon Henderson + * + * The Gertboard has an MCP4802 dual-channel D to A convertor + * connected to the SPI bus, selected via chip-select B. + * + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +// Old routines + +extern void gertboardAnalogWrite (const int chan, const int value) ; +extern int gertboardAnalogRead (const int chan) ; +extern int gertboardSPISetup (void) ; + +// New + +extern int gertboardAnalogSetup (const int pinBase) ; + +#ifdef __cplusplus +} +#endif diff --git a/devLib/lcd.c b/devLib/lcd.c new file mode 100644 index 0000000..6c0e474 --- /dev/null +++ b/devLib/lcd.c @@ -0,0 +1,495 @@ +/* + * lcd.c: + * Text-based LCD driver. + * This is designed to drive the parallel interface LCD drivers + * based in the Hitachi HD44780U controller and compatables. + * + * Copyright (c) 2012 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#include + +#include "lcd.h" + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==2) +#endif + +// HD44780U Commands + +#define LCD_CLEAR 0x01 +#define LCD_HOME 0x02 +#define LCD_ENTRY 0x04 +#define LCD_CTRL 0x08 +#define LCD_CDSHIFT 0x10 +#define LCD_FUNC 0x20 +#define LCD_CGRAM 0x40 +#define LCD_DGRAM 0x80 + +// Bits in the entry register + +#define LCD_ENTRY_SH 0x01 +#define LCD_ENTRY_ID 0x02 + +// Bits in the control register + +#define LCD_BLINK_CTRL 0x01 +#define LCD_CURSOR_CTRL 0x02 +#define LCD_DISPLAY_CTRL 0x04 + +// Bits in the function register + +#define LCD_FUNC_F 0x04 +#define LCD_FUNC_N 0x08 +#define LCD_FUNC_DL 0x10 + +#define LCD_CDSHIFT_RL 0x04 + +struct lcdDataStruct +{ + int bits, rows, cols ; + int rsPin, strbPin ; + int dataPins [8] ; + int cx, cy ; +} ; + +struct lcdDataStruct *lcds [MAX_LCDS] ; + +static int lcdControl ; + +// Row offsets + +static const int rowOff [4] = { 0x00, 0x40, 0x14, 0x54 } ; + + +/* + * strobe: + * Toggle the strobe (Really the "E") pin to the device. + * According to the docs, data is latched on the falling edge. + ********************************************************************************* + */ + +static void strobe (const struct lcdDataStruct *lcd) +{ + +// Note timing changes for new version of delayMicroseconds () + + digitalWrite (lcd->strbPin, 1) ; delayMicroseconds (50) ; + digitalWrite (lcd->strbPin, 0) ; delayMicroseconds (50) ; +} + + +/* + * sentDataCmd: + * Send an data or command byte to the display. + ********************************************************************************* + */ + +static void sendDataCmd (const struct lcdDataStruct *lcd, unsigned char data) +{ + register unsigned char myData = data ; + unsigned char i, d4 ; + + if (lcd->bits == 4) + { + d4 = (myData >> 4) & 0x0F; + for (i = 0 ; i < 4 ; ++i) + { + digitalWrite (lcd->dataPins [i], (d4 & 1)) ; + d4 >>= 1 ; + } + strobe (lcd) ; + + d4 = myData & 0x0F ; + for (i = 0 ; i < 4 ; ++i) + { + digitalWrite (lcd->dataPins [i], (d4 & 1)) ; + d4 >>= 1 ; + } + } + else + { + for (i = 0 ; i < 8 ; ++i) + { + digitalWrite (lcd->dataPins [i], (myData & 1)) ; + myData >>= 1 ; + } + } + strobe (lcd) ; +} + + +/* + * putCommand: + * Send a command byte to the display + ********************************************************************************* + */ + +static void putCommand (const struct lcdDataStruct *lcd, unsigned char command) +{ + digitalWrite (lcd->rsPin, 0) ; + sendDataCmd (lcd, command) ; + delay (2) ; +} + +static void put4Command (const struct lcdDataStruct *lcd, unsigned char command) +{ + register unsigned char myCommand = command ; + register unsigned char i ; + + digitalWrite (lcd->rsPin, 0) ; + + for (i = 0 ; i < 4 ; ++i) + { + digitalWrite (lcd->dataPins [i], (myCommand & 1)) ; + myCommand >>= 1 ; + } + strobe (lcd) ; +} + + +/* + ********************************************************************************* + * User Callable code below here + ********************************************************************************* + */ + +/* + * lcdHome: lcdClear: + * Home the cursor or clear the screen. + ********************************************************************************* + */ + +void lcdHome (const int fd) +{ + struct lcdDataStruct *lcd = lcds [fd] ; + + putCommand (lcd, LCD_HOME) ; + lcd->cx = lcd->cy = 0 ; + delay (5) ; +} + +void lcdClear (const int fd) +{ + struct lcdDataStruct *lcd = lcds [fd] ; + + putCommand (lcd, LCD_CLEAR) ; + putCommand (lcd, LCD_HOME) ; + lcd->cx = lcd->cy = 0 ; + delay (5) ; +} + + +/* + * lcdDisplay: lcdCursor: lcdCursorBlink: + * Turn the display, cursor, cursor blinking on/off + ********************************************************************************* + */ + +void lcdDisplay (const int fd, int state) +{ + struct lcdDataStruct *lcd = lcds [fd] ; + + if (state) + lcdControl |= LCD_DISPLAY_CTRL ; + else + lcdControl &= ~LCD_DISPLAY_CTRL ; + + putCommand (lcd, LCD_CTRL | lcdControl) ; +} + +void lcdCursor (const int fd, int state) +{ + struct lcdDataStruct *lcd = lcds [fd] ; + + if (state) + lcdControl |= LCD_CURSOR_CTRL ; + else + lcdControl &= ~LCD_CURSOR_CTRL ; + + putCommand (lcd, LCD_CTRL | lcdControl) ; +} + +void lcdCursorBlink (const int fd, int state) +{ + struct lcdDataStruct *lcd = lcds [fd] ; + + if (state) + lcdControl |= LCD_BLINK_CTRL ; + else + lcdControl &= ~LCD_BLINK_CTRL ; + + putCommand (lcd, LCD_CTRL | lcdControl) ; +} + + +/* + * lcdSendCommand: + * Send any arbitary command to the display + ********************************************************************************* + */ + +void lcdSendCommand (const int fd, unsigned char command) +{ + struct lcdDataStruct *lcd = lcds [fd] ; + putCommand (lcd, command) ; +} + + +/* + * lcdPosition: + * Update the position of the cursor on the display. + * Ignore invalid locations. + ********************************************************************************* + */ + +void lcdPosition (const int fd, int x, int y) +{ + struct lcdDataStruct *lcd = lcds [fd] ; + + if ((x > lcd->cols) || (x < 0)) + return ; + if ((y > lcd->rows) || (y < 0)) + return ; + + putCommand (lcd, x + (LCD_DGRAM | rowOff [y])) ; + + lcd->cx = x ; + lcd->cy = y ; +} + + +/* + * lcdCharDef: + * Defines a new character in the CGRAM + ********************************************************************************* + */ + +void lcdCharDef (const int fd, int index, unsigned char data [8]) +{ + struct lcdDataStruct *lcd = lcds [fd] ; + int i ; + + putCommand (lcd, LCD_CGRAM | ((index & 7) << 3)) ; + + digitalWrite (lcd->rsPin, 1) ; + for (i = 0 ; i < 8 ; ++i) + sendDataCmd (lcd, data [i]) ; +} + + +/* + * lcdPutchar: + * Send a data byte to be displayed on the display. We implement a very + * simple terminal here - with line wrapping, but no scrolling. Yet. + ********************************************************************************* + */ + +void lcdPutchar (const int fd, unsigned char data) +{ + struct lcdDataStruct *lcd = lcds [fd] ; + + digitalWrite (lcd->rsPin, 1) ; + sendDataCmd (lcd, data) ; + + if (++lcd->cx == lcd->cols) + { + lcd->cx = 0 ; + if (++lcd->cy == lcd->rows) + lcd->cy = 0 ; + + putCommand (lcd, lcd->cx + (LCD_DGRAM | rowOff [lcd->cy])) ; + } +} + + +/* + * lcdPuts: + * Send a string to be displayed on the display + ********************************************************************************* + */ + +void lcdPuts (const int fd, const char *string) +{ + while (*string) + lcdPutchar (fd, *string++) ; +} + + +/* + * lcdPrintf: + * Printf to an LCD display + ********************************************************************************* + */ + +void lcdPrintf (const int fd, const char *message, ...) +{ + va_list argp ; + char buffer [1024] ; + + va_start (argp, message) ; + vsnprintf (buffer, 1023, message, argp) ; + va_end (argp) ; + + lcdPuts (fd, buffer) ; +} + + +/* + * lcdInit: + * Take a lot of parameters and initialise the LCD, and return a handle to + * that LCD, or -1 if any error. + ********************************************************************************* + */ + +int lcdInit (const int rows, const int cols, const int bits, + const int rs, const int strb, + const int d0, const int d1, const int d2, const int d3, const int d4, + const int d5, const int d6, const int d7) +{ + static int initialised = 0 ; + + unsigned char func ; + int i ; + int lcdFd = -1 ; + struct lcdDataStruct *lcd ; + + if (initialised == 0) + { + initialised = 1 ; + for (i = 0 ; i < MAX_LCDS ; ++i) + lcds [i] = NULL ; + } + +// Simple sanity checks + + if (! ((bits == 4) || (bits == 8))) + return -1 ; + + if ((rows < 0) || (rows > 20)) + return -1 ; + + if ((cols < 0) || (cols > 20)) + return -1 ; + +// Create a new LCD: + + for (i = 0 ; i < MAX_LCDS ; ++i) + { + if (lcds [i] == NULL) + { + lcdFd = i ; + break ; + } + } + + if (lcdFd == -1) + return -1 ; + + lcd = (struct lcdDataStruct *)malloc (sizeof (struct lcdDataStruct)) ; + if (lcd == NULL) + return -1 ; + + lcd->rsPin = rs ; + lcd->strbPin = strb ; + lcd->bits = 8 ; // For now - we'll set it properly later. + lcd->rows = rows ; + lcd->cols = cols ; + lcd->cx = 0 ; + lcd->cy = 0 ; + + lcd->dataPins [0] = d0 ; + lcd->dataPins [1] = d1 ; + lcd->dataPins [2] = d2 ; + lcd->dataPins [3] = d3 ; + lcd->dataPins [4] = d4 ; + lcd->dataPins [5] = d5 ; + lcd->dataPins [6] = d6 ; + lcd->dataPins [7] = d7 ; + + lcds [lcdFd] = lcd ; + + digitalWrite (lcd->rsPin, 0) ; pinMode (lcd->rsPin, OUTPUT) ; + digitalWrite (lcd->strbPin, 0) ; pinMode (lcd->strbPin, OUTPUT) ; + + for (i = 0 ; i < bits ; ++i) + { + digitalWrite (lcd->dataPins [i], 0) ; + pinMode (lcd->dataPins [i], OUTPUT) ; + } + delay (35) ; // mS + + +// 4-bit mode? +// OK. This is a PIG and it's not at all obvious from the documentation I had, +// so I guess some others have worked through either with better documentation +// or more trial and error... Anyway here goes: +// +// It seems that the controller needs to see the FUNC command at least 3 times +// consecutively - in 8-bit mode. If you're only using 8-bit mode, then it appears +// that you can get away with one func-set, however I'd not rely on it... +// +// So to set 4-bit mode, you need to send the commands one nibble at a time, +// the same three times, but send the command to set it into 8-bit mode those +// three times, then send a final 4th command to set it into 4-bit mode, and only +// then can you flip the switch for the rest of the library to work in 4-bit +// mode which sends the commands as 2 x 4-bit values. + + if (bits == 4) + { + func = LCD_FUNC | LCD_FUNC_DL ; // Set 8-bit mode 3 times + put4Command (lcd, func >> 4) ; delay (35) ; + put4Command (lcd, func >> 4) ; delay (35) ; + put4Command (lcd, func >> 4) ; delay (35) ; + func = LCD_FUNC ; // 4th set: 4-bit mode + put4Command (lcd, func >> 4) ; delay (35) ; + lcd->bits = 4 ; + } + else + { + func = LCD_FUNC | LCD_FUNC_DL ; + putCommand (lcd, func ) ; delay (35) ; + putCommand (lcd, func ) ; delay (35) ; + putCommand (lcd, func ) ; delay (35) ; + } + + if (lcd->rows > 1) + { + func |= LCD_FUNC_N ; + putCommand (lcd, func) ; delay (35) ; + } + +// Rest of the initialisation sequence + + lcdDisplay (lcdFd, TRUE) ; + lcdCursor (lcdFd, FALSE) ; + lcdCursorBlink (lcdFd, FALSE) ; + lcdClear (lcdFd) ; + + putCommand (lcd, LCD_ENTRY | LCD_ENTRY_ID) ; + putCommand (lcd, LCD_CDSHIFT | LCD_CDSHIFT_RL) ; + + return lcdFd ; +} diff --git a/devLib/lcd.h b/devLib/lcd.h new file mode 100644 index 0000000..0a0e598 --- /dev/null +++ b/devLib/lcd.h @@ -0,0 +1,52 @@ +/* + * lcd.h: + * Text-based LCD driver. + * This is designed to drive the parallel interface LCD drivers + * based in the Hitachi HD44780U controller and compatables. + * + * Copyright (c) 2012 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#define MAX_LCDS 8 + +#ifdef __cplusplus +extern "C" { +#endif + +extern void lcdHome (const int fd) ; +extern void lcdClear (const int fd) ; +extern void lcdDisplay (const int fd, int state) ; +extern void lcdCursor (const int fd, int state) ; +extern void lcdCursorBlink (const int fd, int state) ; +extern void lcdSendCommand (const int fd, unsigned char command) ; +extern void lcdPosition (const int fd, int x, int y) ; +extern void lcdCharDef (const int fd, int index, unsigned char data [8]) ; +extern void lcdPutchar (const int fd, unsigned char data) ; +extern void lcdPuts (const int fd, const char *string) ; +extern void lcdPrintf (const int fd, const char *message, ...) ; + +extern int lcdInit (const int rows, const int cols, const int bits, + const int rs, const int strb, + const int d0, const int d1, const int d2, const int d3, const int d4, + const int d5, const int d6, const int d7) ; + +#ifdef __cplusplus +} +#endif diff --git a/devLib/lcd128x64.c b/devLib/lcd128x64.c new file mode 100644 index 0000000..accd5c3 --- /dev/null +++ b/devLib/lcd128x64.c @@ -0,0 +1,673 @@ +/* + * lcd128x64.c: + * Graphics-based LCD driver. + * This is designed to drive the parallel interface LCD drivers + * based on the generic 12864H chips + * + * There are many variations on these chips, however they all mostly + * seem to be similar. + * This implementation has the Pins from the Pi hard-wired into it, + * in particular wiringPi pins 0-7 so that we can use + * digitalWriteByete() to speed things up somewhat. + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include + +#include + +#include "font.h" +#include "lcd128x64.h" + +// Size + +#define LCD_WIDTH 128 +#define LCD_HEIGHT 64 + +// Hardware Pins +// Note pins 0-7 are the 8-bit data port + +#define CS1 10 +#define CS2 11 +#define STROBE 12 +#define RS 13 + +// Software copy of the framebuffer +// it's 8-bit deep although the display itself is only 1-bit deep. + +static unsigned char frameBuffer [LCD_WIDTH * LCD_HEIGHT] ; + +static int maxX, maxY ; +static int lastX, lastY ; +static int xOrigin, yOrigin ; +static int lcdOrientation = 0 ; + +/* + * strobe: + * Toggle the strobe (Really the "E") pin to the device. + * According to the docs, data is latched on the falling edge. + ********************************************************************************* + */ + +static void strobe (void) +{ + digitalWrite (STROBE, 1) ; delayMicroseconds (1) ; + digitalWrite (STROBE, 0) ; delayMicroseconds (5) ; +} + + +/* + * sentData: + * Send an data or command byte to the display. + ********************************************************************************* + */ + +static void sendData (const int data, const int chip) +{ + digitalWrite (chip, 0) ; + digitalWriteByte (data) ; + strobe () ; + digitalWrite (chip, 1) ; +} + + +/* + * sendCommand: + * Send a command byte to the display + ********************************************************************************* + */ + +static void sendCommand (const int command, const int chip) +{ + digitalWrite (RS, 0) ; + sendData (command, chip) ; + digitalWrite (RS, 1) ; +} + + +/* + * setCol: SetLine: + * Set the column and line addresses + ********************************************************************************* + */ + +static void setCol (int col, const int chip) + { sendCommand (0x40 | (col & 0x3F), chip) ; } + +static void setLine (int line, const int chip) + { sendCommand (0xB8 | (line & 0x07), chip) ; } + + +/* + * lcd128x64update: + * Copy our software version to the real display + ********************************************************************************* + */ + +void lcd128x64update (void) +{ + int line, x, y, fbLoc ; + unsigned char byte ; + +// Left side + + for (line = 0 ; line < 8 ; ++line) + { + setCol (0, CS1) ; + setLine (line, CS1) ; + + for (x = 63 ; x >= 0 ; --x) + { + byte = 0 ; + for (y = 0 ; y < 8 ; ++y) + { + fbLoc = x + (((7 - line) * 8) + (7 - y)) * LCD_WIDTH ; + if (frameBuffer [fbLoc] != 0) + byte |= (1 << y) ; + } + sendData (byte, CS1) ; + } + } + +// Right side + + for (line = 0 ; line < 8 ; ++line) + { + setCol (0, CS2) ; + setLine (line, CS2) ; + + for (x = 127 ; x >= 64 ; --x) + { + byte = 0 ; + for (y = 0 ; y < 8 ; ++y) + { + fbLoc = x + (((7 - line) * 8) + (7 - y)) * LCD_WIDTH ; + if (frameBuffer [fbLoc] != 0) + byte |= (1 << y) ; + } + sendData (byte, CS2) ; + } + } +} + + +/* + * lcd128x64setOrigin: + * Set the display offset origin + ********************************************************************************* + */ + +void lcd128x64setOrigin (int x, int y) +{ + xOrigin = x ; + yOrigin = y ; +} + + +/* + * lcd128x64setOrientation: + * Set the display orientation: + * 0: Normal, the display is portrait mode, 0,0 is top left + * 1: Landscape + * 2: Portrait, flipped + * 3: Landscape, flipped + ********************************************************************************* + */ + +void lcd128x64setOrientation (int orientation) +{ + lcdOrientation = orientation & 3 ; + + lcd128x64setOrigin (0,0) ; + + switch (lcdOrientation) + { + case 0: + maxX = LCD_WIDTH ; + maxY = LCD_HEIGHT ; + break ; + + case 1: + maxX = LCD_HEIGHT ; + maxY = LCD_WIDTH ; + break ; + + case 2: + maxX = LCD_WIDTH ; + maxY = LCD_HEIGHT ; + break ; + + case 3: + maxX = LCD_HEIGHT ; + maxY = LCD_WIDTH ; + break ; + } +} + + +/* + * lcd128x64orientCoordinates: + * Adjust the coordinates given to the display orientation + ********************************************************************************* + */ + +void lcd128x64orientCoordinates (int *x, int *y) +{ + register int tmp ; + + *x += xOrigin ; + *y += yOrigin ; + *y = maxY - *y - 1 ; + + switch (lcdOrientation) + { + case 0: + break; + + case 1: + tmp = maxY - *y - 1 ; + *y = *x ; + *x = tmp ; + break; + + case 2: + *x = maxX - *x - 1 ; + *y = maxY - *y - 1 ; + break; + + case 3: + *x = maxX - *x - 1 ; + tmp = *y ; + *y = *x ; + *x = tmp ; + break ; + } +} + + +/* + * lcd128x64getScreenSize: + * Return the max X & Y screen sizes. Needs to be called again, if you + * change screen orientation. + ********************************************************************************* + */ + +void lcd128x64getScreenSize (int *x, int *y) +{ + *x = maxX ; + *y = maxY ; +} + + +/* + ********************************************************************************* + * Standard Graphical Functions + ********************************************************************************* + */ + + +/* + * lcd128x64point: + * Plot a pixel. + ********************************************************************************* + */ + +void lcd128x64point (int x, int y, int colour) +{ + lastX = x ; + lastY = y ; + + lcd128x64orientCoordinates (&x, &y) ; + + if ((x < 0) || (x >= LCD_WIDTH) || (y < 0) || (y >= LCD_HEIGHT)) + return ; + + frameBuffer [x + y * LCD_WIDTH] = colour ; +} + + +/* + * lcd128x64line: lcd128x64lineTo: + * Classic Bressenham Line code + ********************************************************************************* + */ + +void lcd128x64line (int x0, int y0, int x1, int y1, int colour) +{ + int dx, dy ; + int sx, sy ; + int err, e2 ; + + lastX = x1 ; + lastY = y1 ; + + dx = abs (x1 - x0) ; + dy = abs (y1 - y0) ; + + sx = (x0 < x1) ? 1 : -1 ; + sy = (y0 < y1) ? 1 : -1 ; + + err = dx - dy ; + + for (;;) + { + lcd128x64point (x0, y0, colour) ; + + if ((x0 == x1) && (y0 == y1)) + break ; + + e2 = 2 * err ; + + if (e2 > -dy) + { + err -= dy ; + x0 += sx ; + } + + if (e2 < dx) + { + err += dx ; + y0 += sy ; + } + } + +} + +void lcd128x64lineTo (int x, int y, int colour) +{ + lcd128x64line (lastX, lastY, x, y, colour) ; +} + + +/* + * lcd128x64rectangle: + * A rectangle is a spoilt days fishing + ********************************************************************************* + */ + +void lcd128x64rectangle (int x1, int y1, int x2, int y2, int colour, int filled) +{ + register int x ; + + if (filled) + { + /**/ if (x1 == x2) + lcd128x64line (x1, y1, x2, y2, colour) ; + else if (x1 < x2) + for (x = x1 ; x <= x2 ; ++x) + lcd128x64line (x, y1, x, y2, colour) ; + else + for (x = x2 ; x <= x1 ; ++x) + lcd128x64line (x, y1, x, y2, colour) ; + } + else + { + lcd128x64line (x1, y1, x2, y1, colour) ; + lcd128x64lineTo (x2, y2, colour) ; + lcd128x64lineTo (x1, y2, colour) ; + lcd128x64lineTo (x1, y1, colour) ; + } +} + + +/* + * lcd128x64circle: + * This is the midpoint circle algorithm. + ********************************************************************************* + */ + +void lcd128x64circle (int x, int y, int r, int colour, int filled) +{ + int ddF_x = 1 ; + int ddF_y = -2 * r ; + + int f = 1 - r ; + int x1 = 0 ; + int y1 = r ; + + if (filled) + { + lcd128x64line (x, y + r, x, y - r, colour) ; + lcd128x64line (x + r, y, x - r, y, colour) ; + } + else + { + lcd128x64point (x, y + r, colour) ; + lcd128x64point (x, y - r, colour) ; + lcd128x64point (x + r, y, colour) ; + lcd128x64point (x - r, y, colour) ; + } + + while (x1 < y1) + { + if (f >= 0) + { + y1-- ; + ddF_y += 2 ; + f += ddF_y ; + } + x1++ ; + ddF_x += 2 ; + f += ddF_x ; + if (filled) + { + lcd128x64line (x + x1, y + y1, x - x1, y + y1, colour) ; + lcd128x64line (x + x1, y - y1, x - x1, y - y1, colour) ; + lcd128x64line (x + y1, y + x1, x - y1, y + x1, colour) ; + lcd128x64line (x + y1, y - x1, x - y1, y - x1, colour) ; + } + else + { + lcd128x64point (x + x1, y + y1, colour) ; lcd128x64point (x - x1, y + y1, colour) ; + lcd128x64point (x + x1, y - y1, colour) ; lcd128x64point (x - x1, y - y1, colour) ; + lcd128x64point (x + y1, y + x1, colour) ; lcd128x64point (x - y1, y + x1, colour) ; + lcd128x64point (x + y1, y - x1, colour) ; lcd128x64point (x - y1, y - x1, colour) ; + } + } +} + + +/* + * lcd128x64ellipse: + * Fast ellipse drawing algorithm by + * John Kennedy + * Mathematics Department + * Santa Monica College + * 1900 Pico Blvd. + * Santa Monica, CA 90405 + * jrkennedy6@gmail.com + * -Confirned in email this algorithm is in the public domain -GH- + ********************************************************************************* + */ + +static void plot4ellipsePoints (int cx, int cy, int x, int y, int colour, int filled) +{ + if (filled) + { + lcd128x64line (cx + x, cy + y, cx - x, cy + y, colour) ; + lcd128x64line (cx - x, cy - y, cx + x, cy - y, colour) ; + } + else + { + lcd128x64point (cx + x, cy + y, colour) ; + lcd128x64point (cx - x, cy + y, colour) ; + lcd128x64point (cx - x, cy - y, colour) ; + lcd128x64point (cx + x, cy - y, colour) ; + } +} + +void lcd128x64ellipse (int cx, int cy, int xRadius, int yRadius, int colour, int filled) +{ + int x, y ; + int xChange, yChange, ellipseError ; + int twoAsquare, twoBsquare ; + int stoppingX, stoppingY ; + + twoAsquare = 2 * xRadius * xRadius ; + twoBsquare = 2 * yRadius * yRadius ; + + x = xRadius ; + y = 0 ; + + xChange = yRadius * yRadius * (1 - 2 * xRadius) ; + yChange = xRadius * xRadius ; + + ellipseError = 0 ; + stoppingX = twoBsquare * xRadius ; + stoppingY = 0 ; + + while (stoppingX >= stoppingY) // 1st set of points + { + plot4ellipsePoints (cx, cy, x, y, colour, filled) ; + ++y ; + stoppingY += twoAsquare ; + ellipseError += yChange ; + yChange += twoAsquare ; + + if ((2 * ellipseError + xChange) > 0 ) + { + --x ; + stoppingX -= twoBsquare ; + ellipseError += xChange ; + xChange += twoBsquare ; + } + } + + x = 0 ; + y = yRadius ; + + xChange = yRadius * yRadius ; + yChange = xRadius * xRadius * (1 - 2 * yRadius) ; + + ellipseError = 0 ; + stoppingX = 0 ; + stoppingY = twoAsquare * yRadius ; + + while (stoppingX <= stoppingY) //2nd set of points + { + plot4ellipsePoints (cx, cy, x, y, colour, filled) ; + ++x ; + stoppingX += twoBsquare ; + ellipseError += xChange ; + xChange += twoBsquare ; + + if ((2 * ellipseError + yChange) > 0 ) + { + --y ; + stoppingY -= twoAsquare ; + ellipseError += yChange ; + yChange += twoAsquare ; + } + } +} + + +/* + * lcd128x64putchar: + * Print a single character to the screen + ********************************************************************************* + */ + +void lcd128x64putchar (int x, int y, int c, int bgCol, int fgCol) +{ + int y1, y2 ; + + unsigned char line ; + unsigned char *fontPtr ; + +// Can't print if we're offscreen + +//if ((x < 0) || (x >= (maxX - fontWidth)) || (y < 0) || (y >= (maxY - fontHeight))) +// return ; + + fontPtr = font + c * fontHeight ; + + for (y1 = fontHeight - 1 ; y1 >= 0 ; --y1) + { + y2 = y + y1 ; + line = *fontPtr++ ; + lcd128x64point (x + 0, y2, (line & 0x80) == 0 ? bgCol : fgCol) ; + lcd128x64point (x + 1, y2, (line & 0x40) == 0 ? bgCol : fgCol) ; + lcd128x64point (x + 2, y2, (line & 0x20) == 0 ? bgCol : fgCol) ; + lcd128x64point (x + 3, y2, (line & 0x10) == 0 ? bgCol : fgCol) ; + lcd128x64point (x + 4, y2, (line & 0x08) == 0 ? bgCol : fgCol) ; + lcd128x64point (x + 5, y2, (line & 0x04) == 0 ? bgCol : fgCol) ; + lcd128x64point (x + 6, y2, (line & 0x02) == 0 ? bgCol : fgCol) ; + lcd128x64point (x + 7, y2, (line & 0x01) == 0 ? bgCol : fgCol) ; + } +} + + +/* + * lcd128x64puts: + * Send a string to the display. Obeys \n and \r formatting + ********************************************************************************* + */ + +void lcd128x64puts (int x, int y, const char *str, int bgCol, int fgCol) +{ + int c, mx, my ; + + mx = x ; my = y ; + + while (*str) + { + c = *str++ ; + + if (c == '\r') + { + mx = x ; + continue ; + } + + if (c == '\n') + { + mx = x ; + my -= fontHeight ; + continue ; + } + + lcd128x64putchar (mx, my, c, bgCol, fgCol) ; + + mx += fontWidth ; + if (mx >= (maxX - fontWidth)) + { + mx = 0 ; + my -= fontHeight ; + } + } +} + + +/* + * lcd128x64clear: + * Clear the display to the given colour. + ********************************************************************************* + */ + +void lcd128x64clear (int colour) +{ + register int i ; + register unsigned char *ptr = frameBuffer ; + + for (i = 0 ; i < (maxX * maxY) ; ++i) + *ptr++ = colour ; +} + + + + +/* + * lcd128x64setup: + * Initialise the display and GPIO. + ********************************************************************************* + */ + +int lcd128x64setup (void) +{ + int i ; + + for (i = 0 ; i < 8 ; ++i) + pinMode (i, OUTPUT) ; + + digitalWrite (CS1, 1) ; + digitalWrite (CS2, 1) ; + digitalWrite (STROBE, 0) ; + digitalWrite (RS, 1) ; + + pinMode (CS1, OUTPUT) ; + pinMode (CS2, OUTPUT) ; + pinMode (STROBE, OUTPUT) ; + pinMode (RS, OUTPUT) ; + + sendCommand (0x3F, CS1) ; // Display ON + sendCommand (0xC0, CS1) ; // Set display start line to 0 + + sendCommand (0x3F, CS2) ; // Display ON + sendCommand (0xC0, CS2) ; // Set display start line to 0 + + lcd128x64clear (0) ; + lcd128x64setOrientation (0) ; + lcd128x64update () ; + + return 0 ; +} diff --git a/devLib/lcd128x64.h b/devLib/lcd128x64.h new file mode 100644 index 0000000..b448bbc --- /dev/null +++ b/devLib/lcd128x64.h @@ -0,0 +1,39 @@ +/* + * lcd128x64.h: + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +extern void lcd128x64setOrigin (int x, int y) ; +extern void lcd128x64setOrientation (int orientation) ; +extern void lcd128x64orientCoordinates (int *x, int *y) ; +extern void lcd128x64getScreenSize (int *x, int *y) ; +extern void lcd128x64point (int x, int y, int colour) ; +extern void lcd128x64line (int x0, int y0, int x1, int y1, int colour) ; +extern void lcd128x64lineTo (int x, int y, int colour) ; +extern void lcd128x64rectangle (int x1, int y1, int x2, int y2, int colour, int filled) ; +extern void lcd128x64circle (int x, int y, int r, int colour, int filled) ; +extern void lcd128x64ellipse (int cx, int cy, int xRadius, int yRadius, int colour, int filled) ; +extern void lcd128x64putchar (int x, int y, int c, int bgCol, int fgCol) ; +extern void lcd128x64puts (int x, int y, const char *str, int bgCol, int fgCol) ; +extern void lcd128x64update (void) ; +extern void lcd128x64clear (int colour) ; + +extern int lcd128x64setup (void) ; diff --git a/devLib/maxdetect.c b/devLib/maxdetect.c new file mode 100644 index 0000000..23eabf8 --- /dev/null +++ b/devLib/maxdetect.c @@ -0,0 +1,165 @@ +/* + * maxdetect.c: + * Driver for the MaxDetect series sensors + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +//#include +//#include +//#include + +#include + +#include "maxdetect.h" + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==2) +#endif + + +/* + * maxDetectLowHighWait: + * Wait for a transition from high to low on the bus + ********************************************************************************* + */ + +static void maxDetectLowHighWait (const int pin) +{ + unsigned int timeOut = millis () + 2000 ; + + while (digitalRead (pin) == HIGH) + if (millis () > timeOut) + return ; + + while (digitalRead (pin) == LOW) + if (millis () > timeOut) + return ; +} + + +/* + * maxDetectClockByte: + * Read in a single byte from the MaxDetect bus + ********************************************************************************* + */ + +static unsigned int maxDetectClockByte (const int pin) +{ + unsigned int byte = 0 ; + int bit ; + + for (bit = 0 ; bit < 8 ; ++bit) + { + maxDetectLowHighWait (pin) ; + +// bit starting now - we need to time it. + + delayMicroseconds (30) ; + byte <<= 1 ; + if (digitalRead (pin) == HIGH) // It's a 1 + byte |= 1 ; + } + + return byte ; +} + + +/* + * maxDetectRead: + * Read in and return the 4 data bytes from the MaxDetect sensor. + * Return TRUE/FALSE depending on the checksum validity + ********************************************************************************* + */ + +int maxDetectRead (const int pin, unsigned char buffer [4]) +{ + int i ; + unsigned int checksum ; + unsigned char localBuf [5] ; + +// Wake up the RHT03 by pulling the data line low, then high +// Low for 10mS, high for 40uS. + + pinMode (pin, OUTPUT) ; + digitalWrite (pin, 0) ; delay (10) ; + digitalWrite (pin, 1) ; delayMicroseconds (40) ; + pinMode (pin, INPUT) ; + +// Now wait for sensor to pull pin low + + maxDetectLowHighWait (pin) ; + +// and read in 5 bytes (40 bits) + + for (i = 0 ; i < 5 ; ++i) + localBuf [i] = maxDetectClockByte (pin) ; + + checksum = 0 ; + for (i = 0 ; i < 4 ; ++i) + { + buffer [i] = localBuf [i] ; + checksum += localBuf [i] ; + } + checksum &= 0xFF ; + + return checksum == localBuf [4] ; +} + + +/* + * readRHT03: + * Read the Temperature & Humidity from an RHT03 sensor + ********************************************************************************* + */ + +int readRHT03 (const int pin, int *temp, int *rh) +{ + static unsigned int nextTime = 0 ; + static int lastTemp = 0 ; + static int lastRh = 0 ; + static int lastResult = TRUE ; + + unsigned char buffer [4] ; + +// Don't read more than once a second + + if (millis () < nextTime) + { + *temp = lastTemp ; + *rh = lastRh ; + return lastResult ; + } + + lastResult = maxDetectRead (pin, buffer) ; + + if (lastResult) + { + *temp = lastTemp = (buffer [2] * 256 + buffer [3]) ; + *rh = lastRh = (buffer [0] * 256 + buffer [1]) ; + nextTime = millis () + 2000 ; + return TRUE ; + } + else + { + return FALSE ; + } +} diff --git a/devLib/maxdetect.h b/devLib/maxdetect.h new file mode 100644 index 0000000..a1fd742 --- /dev/null +++ b/devLib/maxdetect.h @@ -0,0 +1,40 @@ +/* + * maxdetect.h: + * Driver for the MaxDetect series sensors + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +// Main generic function + +int maxDetectRead (const int pin, unsigned char buffer [4]) ; + +// Individual sensors + +int readRHT03 (const int pin, int *temp, int *rh) ; + +#ifdef __cplusplus +} +#endif diff --git a/devLib/piFace.c b/devLib/piFace.c new file mode 100644 index 0000000..4475c7f --- /dev/null +++ b/devLib/piFace.c @@ -0,0 +1,112 @@ +/* + * piFace.: + * This file to interface with the PiFace peripheral device which + * has an MCP23S17 GPIO device connected via the SPI bus. + * + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + + +#include +#include + +#include +#include + +#include "piFace.h" + + +/* + * myDigitalWrite: + * Perform the digitalWrite function on the PiFace board + ********************************************************************************* + */ + +void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + digitalWrite (pin + 16, value) ; +} + + +/* + * myDigitalRead: + * Perform the digitalRead function on the PiFace board + * With a slight twist - if we read from base + 8, then we + * read from the output latch... + ********************************************************************************* + */ + +int myDigitalRead (struct wiringPiNodeStruct *node, int pin) +{ + if ((pin - node->pinBase) >= 8) + return digitalRead (pin + 8) ; + else + return digitalRead (pin + 16 + 8) ; +} + + +/* + * myPullUpDnControl: + * Perform the pullUpDnControl function on the PiFace board + ********************************************************************************* + */ + +void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int pud) +{ + pullUpDnControl (pin + 16 + 8, pud) ; +} + + +/* + * piFaceSetup + * We're going to create an instance of the mcp23s17 here, then + * provide our own read/write routines on-top of it... + * The supplied PiFace code (in Pithon) treats it as an 8-bit device + * where you write the output ports and read the input port using the + * same pin numbers, however I have had a request to be able to read + * the output port, so reading 8..15 will read the output latch. + ********************************************************************************* + */ + +int piFaceSetup (const int pinBase) +{ + int i ; + struct wiringPiNodeStruct *node ; + +// Create an mcp23s17 instance: + + mcp23s17Setup (pinBase + 16, 0, 0) ; + +// Set the direction bits + + for (i = 0 ; i < 8 ; ++i) + { + pinMode (pinBase + 16 + i, OUTPUT) ; // Port A is the outputs + pinMode (pinBase + 16 + 8 + i, INPUT) ; // Port B inputs. + } + + node = wiringPiNewNode (pinBase, 16) ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->pullUpDnControl = myPullUpDnControl ; + + return 0 ; +} diff --git a/devLib/piFace.h b/devLib/piFace.h new file mode 100644 index 0000000..4965314 --- /dev/null +++ b/devLib/piFace.h @@ -0,0 +1,32 @@ +/* + * piFace.h: + * Control the PiFace Interface board for the Raspberry Pi + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int piFaceSetup (const int pinBase) ; + +#ifdef __cplusplus +} +#endif diff --git a/devLib/piFaceOld.c b/devLib/piFaceOld.c new file mode 100644 index 0000000..1b1c0dd --- /dev/null +++ b/devLib/piFaceOld.c @@ -0,0 +1,178 @@ +/* + * piFace.: + * Arduino compatable (ish) Wiring library for the Raspberry Pi + * Copyright (c) 2012-2013 Gordon Henderson + * + * This file to interface with the PiFace peripheral device which + * has an MCP23S17 GPIO device connected via the SPI bus. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + + +#include +#include + +#include +#include + +#include "../wiringPi/mcp23x0817.h" + +#include "piFace.h" + +#define PIFACE_SPEED 4000000 +#define PIFACE_DEVNO 0 + + + +/* + * writeByte: + * Write a byte to a register on the MCP23S17 on the SPI bus. + ********************************************************************************* + */ + +static void writeByte (uint8_t reg, uint8_t data) +{ + uint8_t spiData [4] ; + + spiData [0] = CMD_WRITE ; + spiData [1] = reg ; + spiData [2] = data ; + + wiringPiSPIDataRW (PIFACE_DEVNO, spiData, 3) ; +} + +/* + * readByte: + * Read a byte from a register on the MCP23S17 on the SPI bus. + ********************************************************************************* + */ + +static uint8_t readByte (uint8_t reg) +{ + uint8_t spiData [4] ; + + spiData [0] = CMD_READ ; + spiData [1] = reg ; + + wiringPiSPIDataRW (PIFACE_DEVNO, spiData, 3) ; + + return spiData [2] ; +} + + +/* + * myDigitalWrite: + * Perform the digitalWrite function on the PiFace board + ********************************************************************************* + */ + +void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + uint8_t mask, old ; + + pin -= node->pinBase ; + mask = 1 << pin ; + old = readByte (MCP23x17_GPIOA) ; + + if (value == 0) + old &= (~mask) ; + else + old |= mask ; + + writeByte (MCP23x17_GPIOA, old) ; +} + + +/* + * myDigitalRead: + * Perform the digitalRead function on the PiFace board + ********************************************************************************* + */ + +int myDigitalRead (struct wiringPiNodeStruct *node, int pin) +{ + uint8_t mask, reg ; + + mask = 1 << ((pin - node->pinBase) & 7) ; + + if (pin < 8) + reg = MCP23x17_GPIOB ; // Input regsiter + else + reg = MCP23x17_OLATA ; // Output latch regsiter + + if ((readByte (reg) & mask) != 0) + return HIGH ; + else + return LOW ; +} + + +/* + * myPullUpDnControl: + * Perform the pullUpDnControl function on the PiFace board + ********************************************************************************* + */ + +void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int pud) +{ + uint8_t mask, old ; + + mask = 1 << (pin - node->pinBase) ; + old = readByte (MCP23x17_GPPUB) ; + + if (pud == 0) + old &= (~mask) ; + else + old |= mask ; + + writeByte (MCP23x17_GPPUB, old) ; +} + + +/* + * piFaceSetup + * Setup the SPI interface and initialise the MCP23S17 chip + * We create one node with 16 pins - each if the first 8 pins being read + * and write - although the operations actually go to different + * hardware ports. The top 8 let you read the state of the output register. + ********************************************************************************* + */ + +int piFaceSetup (const int pinBase) +{ + int x ; + struct wiringPiNodeStruct *node ; + + if ((x = wiringPiSPISetup (PIFACE_DEVNO, PIFACE_SPEED)) < 0) + return x ; + +// Setup the MCP23S17 + + writeByte (MCP23x17_IOCON, IOCON_INIT) ; + writeByte (MCP23x17_IODIRA, 0x00) ; // Port A -> Outputs + writeByte (MCP23x17_IODIRB, 0xFF) ; // Port B -> Inputs + + node = wiringPiNewNode (pinBase, 16) ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->pullUpDnControl = myPullUpDnControl ; + + return 0 ; +} diff --git a/devLib/piGlow.c b/devLib/piGlow.c new file mode 100644 index 0000000..44e3db8 --- /dev/null +++ b/devLib/piGlow.c @@ -0,0 +1,118 @@ +/* + * piGlow.c: + * Easy access to the Pimoroni PiGlow board. + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include + +#include "piGlow.h" + +#define PIGLOW_BASE 577 + +static int leg0 [6] = { 6, 7, 8, 5, 4, 9 } ; +static int leg1 [6] = { 17, 16, 15, 13, 11, 10 } ; +static int leg2 [6] = { 0, 1, 2, 3, 14, 12 } ; + + +/* + * piGlow1: + * Light up an individual LED + ********************************************************************************* + */ + +void piGlow1 (const int leg, const int ring, const int intensity) +{ + int *legLeds ; + + if ((leg < 0) || (leg > 2)) return ; + if ((ring < 0) || (ring > 5)) return ; + + /**/ if (leg == 0) + legLeds = leg0 ; + else if (leg == 1) + legLeds = leg1 ; + else + legLeds = leg2 ; + + analogWrite (PIGLOW_BASE + legLeds [ring], intensity) ; +} + +/* + * piGlowLeg: + * Light up all 6 LEDs on a leg + ********************************************************************************* + */ + +void piGlowLeg (const int leg, const int intensity) +{ + int i ; + int *legLeds ; + + if ((leg < 0) || (leg > 2)) + return ; + + /**/ if (leg == 0) + legLeds = leg0 ; + else if (leg == 1) + legLeds = leg1 ; + else + legLeds = leg2 ; + + for (i = 0 ; i < 6 ; ++i) + analogWrite (PIGLOW_BASE + legLeds [i], intensity) ; +} + + +/* + * piGlowRing: + * Light up 3 LEDs in a ring. Ring 0 is the outermost, 5 the innermost + ********************************************************************************* + */ + +void piGlowRing (const int ring, const int intensity) +{ + if ((ring < 0) || (ring > 5)) + return ; + + analogWrite (PIGLOW_BASE + leg0 [ring], intensity) ; + analogWrite (PIGLOW_BASE + leg1 [ring], intensity) ; + analogWrite (PIGLOW_BASE + leg2 [ring], intensity) ; +} + +/* + * piGlowSetup: + * Initialise the board & remember the pins we're using + ********************************************************************************* + */ + +void piGlowSetup (int clear) +{ + sn3218Setup (PIGLOW_BASE) ; + + if (clear) + { + piGlowLeg (0, 0) ; + piGlowLeg (1, 0) ; + piGlowLeg (2, 0) ; + } +} diff --git a/devLib/piGlow.h b/devLib/piGlow.h new file mode 100644 index 0000000..a4d89d0 --- /dev/null +++ b/devLib/piGlow.h @@ -0,0 +1,45 @@ +/* + * piglow.h: + * Easy access to the Pimoroni PiGlow board. + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + + +#define PIGLOW_RED 0 +#define PIGLOW_ORANGE 1 +#define PIGLOW_YELLOW 2 +#define PIGLOW_GREEN 3 +#define PIGLOW_BLUE 4 +#define PIGLOW_WHITE 5 + + +#ifdef __cplusplus +extern "C" { +#endif + +extern void piGlow1 (const int leg, const int ring, const int intensity) ; +extern void piGlowLeg (const int leg, const int intensity) ; +extern void piGlowRing (const int ring, const int intensity) ; +extern void piGlowSetup (int clear) ; + +#ifdef __cplusplus +} +#endif diff --git a/devLib/piNes.c b/devLib/piNes.c new file mode 100644 index 0000000..a115050 --- /dev/null +++ b/devLib/piNes.c @@ -0,0 +1,113 @@ +/* + * piNes.c: + * Driver for the NES Joystick controller on the Raspberry Pi + * Copyright (c) 2012 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include + +#include "piNes.h" + +#define MAX_NES_JOYSTICKS 8 + +#define NES_RIGHT 0x01 +#define NES_LEFT 0x02 +#define NES_DOWN 0x04 +#define NES_UP 0x08 +#define NES_START 0x10 +#define NES_SELECT 0x20 +#define NES_B 0x40 +#define NES_A 0x80 + + +#define PULSE_TIME 25 + +// Data to store the pins for each controller + +struct nesPinsStruct +{ + unsigned int cPin, dPin, lPin ; +} ; + +static struct nesPinsStruct nesPins [MAX_NES_JOYSTICKS] ; + +static int joysticks = 0 ; + + +/* + * setupNesJoystick: + * Create a new NES joystick interface, program the pins, etc. + ********************************************************************************* + */ + +int setupNesJoystick (int dPin, int cPin, int lPin) +{ + if (joysticks == MAX_NES_JOYSTICKS) + return -1 ; + + nesPins [joysticks].dPin = dPin ; + nesPins [joysticks].cPin = cPin ; + nesPins [joysticks].lPin = lPin ; + + digitalWrite (lPin, LOW) ; + digitalWrite (cPin, LOW) ; + + pinMode (lPin, OUTPUT) ; + pinMode (cPin, OUTPUT) ; + pinMode (dPin, INPUT) ; + + return joysticks++ ; +} + + +/* + * readNesJoystick: + * Do a single scan of the NES Joystick. + ********************************************************************************* + */ + +unsigned int readNesJoystick (int joystick) +{ + unsigned int value = 0 ; + int i ; + + struct nesPinsStruct *pins = &nesPins [joystick] ; + +// Toggle Latch - which presents the first bit + + digitalWrite (pins->lPin, HIGH) ; delayMicroseconds (PULSE_TIME) ; + digitalWrite (pins->lPin, LOW) ; delayMicroseconds (PULSE_TIME) ; + +// Read first bit + + value = digitalRead (pins->dPin) ; + +// Now get the next 7 bits with the clock + + for (i = 0 ; i < 7 ; ++i) + { + digitalWrite (pins->cPin, HIGH) ; delayMicroseconds (PULSE_TIME) ; + digitalWrite (pins->cPin, LOW) ; delayMicroseconds (PULSE_TIME) ; + value = (value << 1) | digitalRead (pins->dPin) ; + } + + return value ^ 0xFF ; +} diff --git a/devLib/piNes.h b/devLib/piNes.h new file mode 100644 index 0000000..897f181 --- /dev/null +++ b/devLib/piNes.h @@ -0,0 +1,45 @@ +/* + * piNes.h: + * Driver for the NES Joystick controller on the Raspberry Pi + * Copyright (c) 2012 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#define MAX_NES_JOYSTICKS 8 + +#define NES_RIGHT 0x01 +#define NES_LEFT 0x02 +#define NES_DOWN 0x04 +#define NES_UP 0x08 +#define NES_START 0x10 +#define NES_SELECT 0x20 +#define NES_B 0x40 +#define NES_A 0x80 + +#ifdef __cplusplus +extern "C" { +#endif + +extern int setupNesJoystick (int dPin, int cPin, int lPin) ; +extern unsigned int readNesJoystick (int joystick) ; + +#ifdef __cplusplus +} +#endif diff --git a/examples/Gertboard/7segments.c b/examples/Gertboard/7segments.c new file mode 100644 index 0000000..8797e49 --- /dev/null +++ b/examples/Gertboard/7segments.c @@ -0,0 +1,221 @@ +/* + * 7segments.c: + * Simple test program to see if we can drive a 7-segment LED + * display using the GPIO and little else on the Raspberry Pi + * + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + */ + +#undef PHOTO_HACK + +#include + +#include +#include +#include +#include + +/* + * Segment mapping + * + * --a-- + * | | + * f b + * | | + * --g-- + * | | + * e c + * | | + * --d-- p + */ + +// GPIO Pin Mapping + +static int digits [6] = { 7, 11, 10, 13, 12, 14 } ; +static int segments [7] = { 6, 5, 4, 3, 2, 1, 0 } ; + + +static const int segmentDigits [] = +{ +// a b c d e f g Segments +// 6 5 4 3 2 1 0, // wiringPi pin No. + + 1, 1, 1, 1, 1, 1, 0, // 0 + 0, 1, 1, 0, 0, 0, 0, // 1 + 1, 1, 0, 1, 1, 0, 1, // 2 + 1, 1, 1, 1, 0, 0, 1, // 3 + 0, 1, 1, 0, 0, 1, 1, // 4 + 1, 0, 1, 1, 0, 1, 1, // 5 + 1, 0, 1, 1, 1, 1, 1, // 6 + 1, 1, 1, 0, 0, 0, 0, // 7 + 1, 1, 1, 1, 1, 1, 1, // 8 + 1, 1, 1, 1, 0, 1, 1, // 9 + 1, 1, 1, 0, 1, 1, 1, // A + 0, 0, 1, 1, 1, 1, 1, // b + 1, 0, 0, 1, 1, 1, 0, // C + 0, 1, 1, 1, 1, 0, 1, // d + 1, 0, 0, 1, 1, 1, 1, // E + 1, 0, 0, 0, 1, 1, 1, // F + 0, 0, 0, 0, 0, 0, 0, // blank +} ; + + +// display: +// A global variable which is written to by the main program and +// read from by the thread that updates the display. Only the first +// 6 characters are used. + +char display [8] ; + + +/* + * displayDigits: + * This is our thread that's run concurrently with the main program. + * Essentially sit in a loop, parsing and displaying the data held in + * the "display" global. + ********************************************************************************* + */ + +PI_THREAD (displayDigits) +{ + int digit, segment ; + int index, d, segVal ; + + piHiPri (50) ; + + for (;;) + { + for (digit = 0 ; digit < 6 ; ++digit) + { + for (segment = 0 ; segment < 7 ; ++segment) + { + d = toupper (display [digit]) ; + /**/ if ((d >= '0') && (d <= '9')) // Digit + index = d - '0' ; + else if ((d >= 'A') && (d <= 'F')) // Hex + index = d - 'A' + 10 ; + else + index = 16 ; // Blank + + segVal = segmentDigits [index * 7 + segment] ; + + digitalWrite (segments [segment], segVal) ; + } + digitalWrite (digits [digit], 1) ; + delay (2) ; + digitalWrite (digits [digit], 0) ; + } + } +} + + +/* + * setup: + * Initialise the hardware and start the thread + ********************************************************************************* + */ + +void setup (void) +{ + int i, c ; + + wiringPiSetup () ; + +// 7 segments + + for (i = 0 ; i < 7 ; ++i) + { digitalWrite (segments [i], 0) ; pinMode (segments [i], OUTPUT) ; } + +// 6 digits + + for (i = 0 ; i < 6 ; ++i) + { digitalWrite (digits [i], 0) ; pinMode (digits [i], OUTPUT) ; } + + strcpy (display, " ") ; + piThreadCreate (displayDigits) ; + delay (10) ; // Just to make sure it's started + +// Quick countdown LED test sort of thing + + c = 999999 ; + for (i = 0 ; i < 10 ; ++i) + { + sprintf (display, "%06d", c) ; + delay (400) ; + c -= 111111 ; + } + + strcpy (display, " ") ; + delay (400) ; + +#ifdef PHOTO_HACK + sprintf (display, "%s", "123456") ; + for (;;) + delay (1000) ; +#endif + +} + + +/* + * teenager: + * No explanation needed. (Nor one given!) + ********************************************************************************* + */ + +void teenager (void) +{ + char *message = " feedbeef babe cafe b00b " ; + int i ; + + for (i = 0 ; i < strlen (message) - 4 ; ++i) + { + strncpy (display, &message [i], 6) ; + delay (200) ; + } + delay (1000) ; + for (i = 0 ; i < 3 ; ++i) + { + strcpy (display, " ") ; + delay (150) ; + strcpy (display, " b00b ") ; + delay (250) ; + } + delay (1000) ; + strcpy (display, " ") ; + delay (1000) ; +} + + +/* + ********************************************************************************* + * main: + * Let the fun begin + ********************************************************************************* + */ + +int main (void) +{ + struct tm *t ; + time_t tim ; + + setup () ; + teenager () ; + + tim = time (NULL) ; + for (;;) + { + while (time (NULL) == tim) + delay (5) ; + + tim = time (NULL) ; + t = localtime (&tim) ; + + sprintf (display, "%02d%02d%02d", t->tm_hour, t->tm_min, t->tm_sec) ; + + delay (500) ; + } + + return 0 ; +} diff --git a/examples/Gertboard/Makefile b/examples/Gertboard/Makefile new file mode 100644 index 0000000..1939ad6 --- /dev/null +++ b/examples/Gertboard/Makefile @@ -0,0 +1,78 @@ +# +# Makefile: +# Gertboard - Examples using wiringPi +# +# Copyright (c) 2013 Gordon Henderson +################################################################################# + +ifneq ($V,1) +Q ?= @ +endif + +#DEBUG = -g -O0 +DEBUG = -O3 +CC = gcc +INCLUDE = -I/usr/local/include +CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe + +LDFLAGS = -L/usr/local/lib +LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm + +# Should not alter anything below this line +############################################################################### + +SRC = gertboard.c \ + buttons.c 7segments.c \ + voltmeter.c temperature.c vumeter.c \ + record.c + +OBJ = $(SRC:.c=.o) + +BINS = $(SRC:.c=) + +all: $(BINS) + +gertboard: gertboard.o + $Q echo [link] + $Q $(CC) -o $@ gertboard.o $(LDFLAGS) $(LDLIBS) + +buttons: buttons.o + $Q echo [link] + $Q $(CC) -o $@ buttons.o $(LDFLAGS) $(LDLIBS) + +7segments: 7segments.o + $Q echo [link] + $Q $(CC) -o $@ 7segments.o $(LDFLAGS) $(LDLIBS) + +voltmeter: voltmeter.o + $Q echo [link] + $Q $(CC) -o $@ voltmeter.o $(LDFLAGS) $(LDLIBS) + +temperature: temperature.o + $Q echo [link] + $Q $(CC) -o $@ temperature.o $(LDFLAGS) $(LDLIBS) + +vumeter: vumeter.o + $Q echo [link] + $Q $(CC) -o $@ vumeter.o $(LDFLAGS) $(LDLIBS) + +record: record.o + $Q echo [link] + $Q $(CC) -o $@ record.o $(LDFLAGS) $(LDLIBS) + +.c.o: + $Q echo [CC] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ + +clean: + $Q echo [Clean] + $Q rm -f $(OBJ) *~ core tags $(BINS) + +tags: $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) + +depend: + makedepend -Y $(SRC) + +# DO NOT DELETE diff --git a/examples/Gertboard/buttons.c b/examples/Gertboard/buttons.c new file mode 100644 index 0000000..5f76764 --- /dev/null +++ b/examples/Gertboard/buttons.c @@ -0,0 +1,83 @@ +/* + * buttons.c: + * Read the Gertboard buttons. Each one will act as an on/off + * tiggle switch for 3 different LEDs + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include + +// Array to keep track of our LEDs + +int leds [] = { 0, 0, 0 } ; + +// scanButton: +// See if a button is pushed, if so, then flip that LED and +// wait for the button to be let-go + +void scanButton (int button) +{ + if (digitalRead (button) == HIGH) // Low is pushed + return ; + + leds [button] ^= 1 ; // Invert state + digitalWrite (4 + button, leds [button]) ; + + while (digitalRead (button) == LOW) // Wait for release + delay (10) ; +} + +int main (void) +{ + int i ; + + printf ("Raspberry Pi Gertboard Button Test\n") ; + + wiringPiSetup () ; + +// Setup the outputs: +// Pins 3, 4, 5, 6 and 7 output: +// We're not using 3 or 4, but make sure they're off anyway +// (Using same hardware config as blink12.c) + + for (i = 3 ; i < 8 ; ++i) + { + pinMode (i, OUTPUT) ; + digitalWrite (i, 0) ; + } + +// Setup the inputs + + for (i = 0 ; i < 3 ; ++i) + { + pinMode (i, INPUT) ; + pullUpDnControl (i, PUD_UP) ; + leds [i] = 0 ; + } + + for (;;) + { + for (i = 0 ; i < 3 ; ++i) + scanButton (i) ; + delay (1) ; + } +} diff --git a/examples/Gertboard/gertboard.c b/examples/Gertboard/gertboard.c new file mode 100644 index 0000000..aefcb12 --- /dev/null +++ b/examples/Gertboard/gertboard.c @@ -0,0 +1,96 @@ +/* + * gertboard.c: + * Simple test for the SPI bus on the Gertboard + * + * Hardware setup: + * D/A port 0 jumpered to A/D port 0. + * + * We output a sine wave on D/A port 0 and sample A/D port 0. We then + * plot the input value on the terminal as a sort of vertical scrolling + * oscilloscipe. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include + +// Gertboard D to A is an 8-bit unit. + +#define B_SIZE 256 + +#include +#include + +int main (void) +{ + double angle ; + int i, inputValue ; + int buffer [B_SIZE] ; + int cols ; + struct winsize w ; + + + printf ("Raspberry Pi Gertboard SPI test program\n") ; + printf ("=======================================\n") ; + + ioctl (fileno (stdin), TIOCGWINSZ, &w); + cols = w.ws_col - 2 ; + +// Always initialise wiringPi. Use wiringPiSys() if you don't need +// (or want) to run as root + + wiringPiSetupSys () ; + +// Initialise the Gertboard analog hardware at pin 100 + + gertboardAnalogSetup (100) ; + +// Generate a Sine Wave and store in our buffer + + for (i = 0 ; i < B_SIZE ; ++i) + { + angle = ((double)i / (double)B_SIZE) * M_PI * 2.0 ; + buffer [i] = (int)rint ((sin (angle)) * 127.0 + 128.0) ; + } + +// Loop, output the sine wave on analog out port 0, read it into A-D port 0 +// and display it on the screen + + for (;;) + { + for (i = 0 ; i < B_SIZE ; ++i) + { + analogWrite (100, buffer [i]) ; + + inputValue = analogRead (100) ; + +// We don't need to wory about the scale or sign - the analog hardware is +// a 10-bit value, so 0-1023. Just scale this to our terminal + + printf ("%*s\n", (inputValue * cols) / 1023, "*") ; + delay (2) ; + } + } + + return 0 ; +} diff --git a/examples/Gertboard/record.c b/examples/Gertboard/record.c new file mode 100644 index 0000000..71d8718 --- /dev/null +++ b/examples/Gertboard/record.c @@ -0,0 +1,60 @@ +/* + * record.c: + * Record some audio via the Gertboard + * + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + */ + +#include +#include + +#include +#include + +#define B_SIZE 40000 + +int main () +{ + int i ; + struct timeval tStart, tEnd, tTaken ; + unsigned char buffer [B_SIZE] ; + + printf ("\n") ; + printf ("Gertboard demo: Recorder\n") ; + printf ("========================\n") ; + +// Always initialise wiringPi. Use wiringPiSys() if you don't need +// (or want) to run as root + + wiringPiSetupSys () ; + +// Initialise the Gertboard analog hardware at pin 100 + + gertboardAnalogSetup (100) ; + + gettimeofday (&tStart, NULL) ; + + for (i = 0 ; i < B_SIZE ; ++i) + buffer [i] = analogRead (100) >> 2 ; + + gettimeofday (&tEnd, NULL) ; + + timersub (&tEnd, &tStart, &tTaken) ; + + printf ("Time taken for %d reads: %ld.%ld\n", B_SIZE, tTaken.tv_sec, tTaken.tv_usec) ; + + gettimeofday (&tStart, NULL) ; + + for (i = 0 ; i < B_SIZE ; ++i) + analogWrite (100, buffer [i]) ; + + gettimeofday (&tEnd, NULL) ; + + timersub (&tEnd, &tStart, &tTaken) ; + + printf ("Time taken for %d writes: %ld.%ld\n", B_SIZE, tTaken.tv_sec, tTaken.tv_usec) ; + + return 0 ; +} + diff --git a/examples/Gertboard/temperature.c b/examples/Gertboard/temperature.c new file mode 100644 index 0000000..5985a12 --- /dev/null +++ b/examples/Gertboard/temperature.c @@ -0,0 +1,78 @@ +/* + * temperature.c: + * Demonstrate use of the Gertboard A to D converter to make + * a simple thermometer using the LM35. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include + +#include +#include + +int main () +{ + int x1, x2 ; + double v1, v2 ; + + printf ("\n") ; + printf ("Gertboard demo: Simple Thermemeter\n") ; + printf ("==================================\n") ; + +// Always initialise wiringPi. Use wiringPiSys() if you don't need +// (or want) to run as root + + wiringPiSetupSys () ; + +// Initialise the Gertboard analog hardware at pin 100 + + gertboardAnalogSetup (100) ; + + printf ("\n") ; + printf ("| Channel 0 | Channel 1 | Temperature 1 | Temperature 2 |\n") ; + + for (;;) + { + +// Read the 2 channels: + + x1 = analogRead (100) ; + x2 = analogRead (101) ; + +// Convert to a voltage: + + v1 = (double)x1 / 1023.0 * 3.3 ; + v2 = (double)x2 / 1023.0 * 3.3 ; + +// Print + + printf ("| %6.3f | %6.3f |", v1, v2) ; + +// Print Temperature of both channels by converting the LM35 reading +// to a temperature. Fortunately these are easy: 0.01 volts per C. + + printf (" %4.1f | %4.1f |\r", v1 * 100.0, v2 * 100.0) ; + fflush (stdout) ; + } + + return 0 ; +} + diff --git a/examples/Gertboard/voltmeter.c b/examples/Gertboard/voltmeter.c new file mode 100644 index 0000000..c4d2113 --- /dev/null +++ b/examples/Gertboard/voltmeter.c @@ -0,0 +1,73 @@ +/* + * voltmeter.c: + * Demonstrate use of the Gertboard A to D converter to make + * a simple voltmeter. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include + +#include +#include + +int main () +{ + int x1, x2 ; + double v1, v2 ; + + printf ("\n") ; + printf ("Gertboard demo: Simple Voltmeters\n") ; + printf ("=================================\n") ; + +// Always initialise wiringPi. Use wiringPiSys() if you don't need +// (or want) to run as root + + wiringPiSetupSys () ; + +// Initialise the Gertboard analog hardware at pin 100 + + gertboardAnalogSetup (100) ; + + printf ("\n") ; + printf ("| Channel 0 | Channel 1 |\n") ; + + for (;;) + { + +// Read the 2 channels: + + x1 = analogRead (100) ; + x2 = analogRead (101) ; + +// Convert to a voltage: + + v1 = (double)x1 / 1023.0 * 3.3 ; + v2 = (double)x2 / 1023.0 * 3.3 ; + +// Print + + printf ("| %6.3f | %6.3f |\r", v1, v2) ; + fflush (stdout) ; + } + + return 0 ; +} + diff --git a/examples/Gertboard/vumeter.c b/examples/Gertboard/vumeter.c new file mode 100644 index 0000000..9643ace --- /dev/null +++ b/examples/Gertboard/vumeter.c @@ -0,0 +1,152 @@ +/* + * vumeter.c: + * Simple VU meter + * + * Heres the theory: + * We will sample at 4000 samples/sec and put the data into a + * low-pass filter with a depth of 1000 samples. This will give + * us 1/4 a second of lag on the signal, but I think it might + * produce a more pleasing output. + * + * The input of the microphone should be at mid-pont with no + * sound input, but we might have to sample that too, to get + * our reference zero... + * + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + */ + +#include +#include +#include + +#include +#include + +#ifndef TRUE +#define TRUE (1==1) +#define FALSE (!TRUE) +#endif + +#define B_SIZE 1000 +#define S_SIZE 128 + +static int buffer [B_SIZE] ; +static int bPtr = 0 ; + +/* + * ledPercent: + * Output the given value as a percentage on the LEDs + ********************************************************************************* + */ + +static void ledPercent (int percent) +{ + unsigned int output = 0 ; + + if (percent > 11) output |= 0x01 ; + if (percent > 22) output |= 0x02 ; + if (percent > 33) output |= 0x04 ; + if (percent > 44) output |= 0x08 ; + if (percent > 55) output |= 0x10 ; + if (percent > 66) output |= 0x20 ; + if (percent > 77) output |= 0x40 ; + if (percent > 88) output |= 0x80 ; + + digitalWriteByte (output) ; +} + +static unsigned int tPeriod, tNextSampleTime ; + +/* + * sample: + * Get a sample from the Gertboard. If not enough time has elapsed + * since the last sample, then wait... + ********************************************************************************* + */ + +static void sample (void) +{ + unsigned int tFuture ; + +// Calculate the future sample time + + tFuture = tPeriod + tNextSampleTime ; + +// Wait until the next sample time + + while (micros () < tNextSampleTime) + ; + + buffer [bPtr] = gertboardAnalogRead (0) ; + + tNextSampleTime = tFuture ; +} + + +int main () +{ + int quietLevel, min, max ; + int i, sum ; + unsigned int tStart, tEnd ; + + printf ("\n") ; + printf ("Gertboard demo: VU Meter\n") ; + printf ("========================\n") ; + + wiringPiSetup () ; + gertboardSPISetup () ; + + ledPercent (0) ; + for (i = 0 ; i < 8 ; ++i) + pinMode (i, OUTPUT) ; + + for (bPtr = 0 ; bPtr < B_SIZE ; ++bPtr) + buffer [bPtr] = 99 ; + + tPeriod = 1000000 / 1000 ; + + printf ("Shhhh.... ") ; fflush (stdout) ; + delay (1000) ; + printf ("Sampling quiet... ") ; fflush (stdout) ; + + tStart = micros () ; + + tNextSampleTime = micros () ; + for (bPtr = 0 ; bPtr < B_SIZE ; ++bPtr) + sample () ; + + tEnd = micros () ; + + quietLevel = 0 ; + max = 0 ; + min = 1024 ; + for (i = 0 ; i < B_SIZE ; ++i) + { + quietLevel += buffer [i] ; + if (buffer [i] > max) max = buffer [i] ; + if (buffer [i] < min) min = buffer [i] ; + } + quietLevel /= B_SIZE ; + + printf ("Done. Quiet level is: %d [%d:%d] [%d:%d]\n", quietLevel, min, max, quietLevel - min, max - quietLevel) ; + + printf ("Time taken for %d reads: %duS\n", B_SIZE, tEnd - tStart) ; + + for (bPtr = 0 ;;) + { + sample () ; + sum = 0 ; + for (i = 0 ; i < S_SIZE ; ++i) + sum += buffer [i] ; + sum /= S_SIZE ; + sum = abs (quietLevel - sum) ; + sum = (sum * 1000) / quietLevel ; + ledPercent (sum) ; + if (++bPtr > S_SIZE) + bPtr = 0 ; + } + + + return 0 ; +} diff --git a/examples/Makefile b/examples/Makefile index defd510..4278b6d 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -3,7 +3,7 @@ # wiringPi - Wiring Compatable library for the Raspberry Pi # https://projects.drogon.net/wiring-pi # -# Copyright (c) 2012 Gordon Henderson +# Copyright (c) 2012-2015 Gordon Henderson ################################################################################# # This file is part of wiringPi: # Wiring Compatable library for the Raspberry Pi @@ -22,6 +22,9 @@ # along with wiringPi. If not, see . ################################################################################# +ifneq ($V,1) +Q ?= @ +endif #DEBUG = -g -O0 DEBUG = -O3 @@ -30,110 +33,137 @@ INCLUDE = -I/usr/local/include CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe LDFLAGS = -L/usr/local/lib -LDLIBS = -lwiringPi -lpthread -lm +LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm # Should not alter anything below this line ############################################################################### -SRC = blink.c test1.c test2.c speed.c lcd.c wfi.c isr.c isr-osc.c \ - piface.c gertboard.c nes.c \ - pwm.c tone.c servo.c \ - delayTest.c serialRead.c serialTest.c okLed.c +SRC = blink.c blink8.c blink12.c \ + blink12drcs.c \ + pwm.c \ + speed.c wfi.c isr.c isr-osc.c \ + lcd.c lcd-adafruit.c clock.c \ + nes.c \ + softPwm.c softTone.c \ + delayTest.c serialRead.c serialTest.c okLed.c ds1302.c \ + lowPower.c \ + max31855.c \ + rht03.c OBJ = $(SRC:.c=.o) BINS = $(SRC:.c=) all: - @cat README.TXT - @echo " $(BINS)" | fmt - @echo "" + $Q cat README.TXT + $Q echo " $(BINS)" | fmt + $Q echo "" really-all: $(BINS) blink: blink.o - @echo [link] - @$(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS) -test1: test1.o - @echo [link] - @$(CC) -o $@ test1.o $(LDFLAGS) $(LDLIBS) - -test2: test2.o - @echo [link] - @$(CC) -o $@ test2.o $(LDFLAGS) $(LDLIBS) +blink8: blink8.o + $Q echo [link] + $Q $(CC) -o $@ blink8.o $(LDFLAGS) $(LDLIBS) + +blink12drcs: blink12drcs.o + $Q echo [link] + $Q $(CC) -o $@ blink12drcs.o $(LDFLAGS) $(LDLIBS) + +blink12: blink12.o + $Q echo [link] + $Q $(CC) -o $@ blink12.o $(LDFLAGS) $(LDLIBS) speed: speed.o - @echo [link] - @$(CC) -o $@ speed.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ speed.o $(LDFLAGS) $(LDLIBS) lcd: lcd.o - @echo [link] - @$(CC) -o $@ lcd.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ lcd.o $(LDFLAGS) $(LDLIBS) + +lcd-adafruit: lcd-adafruit.o + $Q echo [link] + $Q $(CC) -o $@ lcd-adafruit.o $(LDFLAGS) $(LDLIBS) + +clock: clock.o + $Q echo [link] + $Q $(CC) -o $@ clock.o $(LDFLAGS) $(LDLIBS) wfi: wfi.o - @echo [link] - @$(CC) -o $@ wfi.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ wfi.o $(LDFLAGS) $(LDLIBS) isr: isr.o - @echo [link] - @$(CC) -o $@ isr.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ isr.o $(LDFLAGS) $(LDLIBS) isr-osc: isr-osc.o - @echo [link] - @$(CC) -o $@ isr-osc.o $(LDFLAGS) $(LDLIBS) - -piface: piface.o - @echo [link] - @$(CC) -o $@ piface.o $(LDFLAGS) $(LDLIBS) - -gertboard: gertboard.o - @echo [link] - @$(CC) -o $@ gertboard.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ isr-osc.o $(LDFLAGS) $(LDLIBS) nes: nes.o - @echo [link] - @$(CC) -o $@ nes.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ nes.o $(LDFLAGS) $(LDLIBS) + +rht03: rht03.o + $Q echo [link] + $Q $(CC) -o $@ rht03.o $(LDFLAGS) $(LDLIBS) pwm: pwm.o - @echo [link] - @$(CC) -o $@ pwm.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ pwm.o $(LDFLAGS) $(LDLIBS) + +softPwm: softPwm.o + $Q echo [link] + $Q $(CC) -o $@ softPwm.o $(LDFLAGS) $(LDLIBS) + +softTone: softTone.o + $Q echo [link] + $Q $(CC) -o $@ softTone.o $(LDFLAGS) $(LDLIBS) delayTest: delayTest.o - @echo [link] - @$(CC) -o $@ delayTest.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ delayTest.o $(LDFLAGS) $(LDLIBS) serialRead: serialRead.o - @echo [link] - @$(CC) -o $@ serialRead.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ serialRead.o $(LDFLAGS) $(LDLIBS) serialTest: serialTest.o - @echo [link] - @$(CC) -o $@ serialTest.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ serialTest.o $(LDFLAGS) $(LDLIBS) okLed: okLed.o - @echo [link] - @$(CC) -o $@ okLed.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ okLed.o $(LDFLAGS) $(LDLIBS) tone: tone.o - @echo [link] - @$(CC) -o $@ tone.o $(LDFLAGS) $(LDLIBS) + $Q echo [link] + $Q $(CC) -o $@ tone.o $(LDFLAGS) $(LDLIBS) -servo: servo.o - @echo [link] - @$(CC) -o $@ servo.o $(LDFLAGS) $(LDLIBS) +ds1302: ds1302.o + $Q echo [link] + $Q $(CC) -o $@ ds1302.o $(LDFLAGS) $(LDLIBS) +max31855: max31855.o + $Q echo [link] + $Q $(CC) -o $@ max31855.o $(LDFLAGS) $(LDLIBS) .c.o: - @echo [CC] $< - @$(CC) -c $(CFLAGS) $< -o $@ + $Q echo [CC] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ clean: - rm -f $(OBJ) *~ core tags $(BINS) + $Q echo "[Clean]" + $Q rm -f $(OBJ) *~ core tags $(BINS) tags: $(SRC) - @echo [ctags] - @ctags $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) depend: makedepend -Y $(SRC) diff --git a/examples/PiFace/Makefile b/examples/PiFace/Makefile new file mode 100644 index 0000000..4685adc --- /dev/null +++ b/examples/PiFace/Makefile @@ -0,0 +1,88 @@ +# +# Makefile: +# wiringPi - Wiring Compatable library for the Raspberry Pi +# https://projects.drogon.net/wiring-pi +# +# Copyright (c) 2012 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# Wiring Compatable library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + +ifneq ($V,1) +Q ?= @ +endif + +#DEBUG = -g -O0 +DEBUG = -O3 +CC = gcc +INCLUDE = -I/usr/local/include +CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe + +LDFLAGS = -L/usr/local/lib +LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm + +# Should not alter anything below this line +############################################################################### + +SRC = blink.c buttons.c reaction.c ladder.c metro.c motor.c + +OBJ = $(SRC:.c=.o) + +BINS = $(SRC:.c=) + +all: $(BINS) + +blink: blink.o + $Q echo [link] + $Q $(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS) + +buttons: buttons.o + $Q echo [link] + $Q $(CC) -o $@ buttons.o $(LDFLAGS) $(LDLIBS) + +reaction: reaction.o + $Q echo [link] + $Q $(CC) -o $@ reaction.o $(LDFLAGS) $(LDLIBS) + +ladder: ladder.o + $Q echo [link] + $Q $(CC) -o $@ ladder.o $(LDFLAGS) $(LDLIBS) + +metro: metro.o + $Q echo [link] + $Q $(CC) -o $@ metro.o $(LDFLAGS) $(LDLIBS) + +motor: motor.o + $Q echo [link] + $Q $(CC) -o $@ motor.o $(LDFLAGS) $(LDLIBS) + +.c.o: + $Q echo [CC] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ + +clean: + $Q echo "[Clean]" + $Q rm -f $(OBJ) *~ core tags $(BINS) + +tags: $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) + +depend: + makedepend -Y $(SRC) + +# DO NOT DELETE diff --git a/examples/PiFace/blink.c b/examples/PiFace/blink.c new file mode 100644 index 0000000..ffb8a2e --- /dev/null +++ b/examples/PiFace/blink.c @@ -0,0 +1,59 @@ +/* + * blink.c: + * Simple "blink" test for the PiFace interface board. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include + +#include +#include + +// Use 200 as the pin-base for the PiFace board, and pick a pin +// for the LED that's not connected to a relay + +#define PIFACE 200 +#define LED (PIFACE+2) + +int main (int argc, char *argv []) +{ + printf ("Raspberry Pi PiFace Blink\n") ; + printf ("=========================\n") ; + +// Always initialise wiringPi. Use wiringPiSys() if you don't need +// (or want) to run as root + + wiringPiSetupSys () ; + +// Setup the PiFace board + + piFaceSetup (PIFACE) ; + + for (;;) + { + digitalWrite (LED, HIGH) ; // On + delay (500) ; // mS + digitalWrite (LED, LOW) ; // Off + delay (500) ; + } + + return 0 ; +} diff --git a/examples/PiFace/buttons.c b/examples/PiFace/buttons.c new file mode 100644 index 0000000..147a4bd --- /dev/null +++ b/examples/PiFace/buttons.c @@ -0,0 +1,103 @@ +/* + * buttons.c: + * Simple test for the PiFace interface board. + * + * Read the buttons and output the same to the LEDs + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include + +#include +#include + +int outputs [4] = { 0,0,0,0 } ; + +// Use 200 as the pin-base for the PiFace board + +#define PIFACE_BASE 200 + + +/* + * scanButton: + * Read the guiven button - if it's pressed, then flip the state + * of the correspoinding output pin + ********************************************************************************* + */ + +void scanButton (int button) +{ + if (digitalRead (PIFACE_BASE + button) == LOW) + { + outputs [button] ^= 1 ; + digitalWrite (PIFACE_BASE + button, outputs [button]) ; + printf ("Button %d pushed - output now: %s\n", + button, (outputs [button] == 0) ? "Off" : "On") ; + } + + while (digitalRead (PIFACE_BASE + button) == LOW) + delay (1) ; +} + + +/* + * start here + ********************************************************************************* + */ + +int main (void) +{ + int pin, button ; + + printf ("Raspberry Pi wiringPi + PiFace test program\n") ; + printf ("===========================================\n") ; + printf ("\n") ; + printf ( +"This program reads the buttons and uses them to toggle the first 4\n" +"outputs. Push a button once to turn an output on, and push it again to\n" +"turn it off again.\n\n") ; + +// Always initialise wiringPi. Use wiringPiSys() if you don't need +// (or want) to run as root + + wiringPiSetupSys () ; + + piFaceSetup (PIFACE_BASE) ; + +// Enable internal pull-ups & start with all off + + for (pin = 0 ; pin < 8 ; ++pin) + { + pullUpDnControl (PIFACE_BASE + pin, PUD_UP) ; + digitalWrite (PIFACE_BASE + pin, 0) ; + } + +// Loop, scanning the buttons + + for (;;) + { + for (button = 0 ; button < 4 ; ++button) + scanButton (button) ; + delay (5) ; + } + + return 0 ; +} diff --git a/examples/PiFace/ladder.c b/examples/PiFace/ladder.c new file mode 100644 index 0000000..4f08a6f --- /dev/null +++ b/examples/PiFace/ladder.c @@ -0,0 +1,337 @@ +/* + * ladder.c: + * + * Gordon Henderson, June 2012 + *********************************************************************** + */ + +#include +#include +#include +#include + +#include +#include + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==2) +#endif + +#undef DEBUG + +#define NUM_LEDS 8 + + +// Map the LEDs to the hardware pins +// using PiFace pin numbers here + +#define PIFACE 200 + +const int ledMap [NUM_LEDS] = +{ +// 0, 1, 2, 3, 4, 5, 6, 7, 8 + 200, 201, 202, 203, 204, 205, 206, 207 +} ; + + +// Some constants for our circuit simulation + +const double vBatt = 9.0 ; // Volts (ie. a PP3) +const double capacitor = 0.001 ; // 1000uF +const double rCharge = 2200.0 ; // ohms +const double rDischarge = 68000.0 ; // ohms +const double timeInc = 0.01 ; // Seconds + +double vCharge, vCap, vCapLast ; + + + +/* + * setup: + * Program the GPIO correctly and initialise the lamps + *********************************************************************** + */ + +void setup (void) +{ + int i ; + + wiringPiSetupSys () ; + + if (piFaceSetup (200) == -1) + exit (1) ; + +// Enable internal pull-ups + + for (i = 0 ; i < 8 ; ++i) + pullUpDnControl (PIFACE + i, PUD_UP) ; + +// Calculate the actual charging voltage - standard calculation of +// vCharge = r2 / (r1 + r2) * vBatt +// +// +// -----+--- vBatt +// | +// R1 +// | +// +---+---- vCharge +// | | +// R2 C +// | | +// -----+---+----- + + vCharge = rDischarge / (rCharge + rDischarge) * vBatt ; + +// Start with no charge + + vCap = vCapLast = 0.0 ; +} + + +/* + * introLeds + * Put a little pattern on the LEDs to start with + ********************************************************************************* + */ + +void introLeds (void) +{ + int i, j ; + + + printf ("Pi Ladder\n") ; + printf ("=========\n\n") ; + printf (" vBatt: %6.2f volts\n", vBatt) ; + printf (" rCharge: %6.0f ohms\n", rCharge) ; + printf (" rDischarge: %6.0f ohms\n", rDischarge) ; + printf (" vCharge: %6.2f volts\n", vCharge) ; + printf (" capacitor: %6.0f uF\n", capacitor * 1000.0) ; + +// Flash 3 times: + + for (j = 0 ; j < 3 ; ++j) + { + for (i = 0 ; i < NUM_LEDS ; ++i) + digitalWrite (ledMap [i], 1) ; + delay (500) ; + for (i = 0 ; i < NUM_LEDS ; ++i) + digitalWrite (ledMap [i], 0) ; + delay (100) ; + } + +// All On + + for (i = 0 ; i < NUM_LEDS ; ++i) + digitalWrite (ledMap [i], 1) ; + delay (500) ; + +// Countdown... + + for (i = NUM_LEDS - 1 ; i >= 0 ; --i) + { + digitalWrite (ledMap [i], 0) ; + delay (100) ; + } + delay (500) ; +} + + +/* + * winningLeds + * Put a little pattern on the LEDs to start with + ********************************************************************************* + */ + +void winningLeds (void) +{ + int i, j ; + +// Flash 3 times: + + for (j = 0 ; j < 3 ; ++j) + { + for (i = 0 ; i < NUM_LEDS ; ++i) + digitalWrite (ledMap [i], 1) ; + delay (500) ; + for (i = 0 ; i < NUM_LEDS ; ++i) + digitalWrite (ledMap [i], 0) ; + delay (100) ; + } + +// All On + + for (i = 0 ; i < NUM_LEDS ; ++i) + digitalWrite (ledMap [i], 1) ; + delay (500) ; + +// Countup... + + for (i = 0 ; i < NUM_LEDS ; ++i) + { + digitalWrite (ledMap [i], 0) ; + delay (100) ; + } + delay (500) ; +} + + +/* + * chargeCapacitor: dischargeCapacitor: + * Add or remove charge to the capacitor. + * Standard capacitor formulae. + ********************************************************************************* + */ + +void chargeCapacitor (void) +{ + vCap = (vCapLast - vCharge) * + exp (- timeInc / (rCharge * capacitor)) + vCharge ; + +#ifdef DEBUG + printf ("+vCap: %7.4f\n", vCap) ; +#endif + + vCapLast = vCap ; +} + +void dischargeCapacitor (void) +{ + vCap = vCapLast * + exp (- timeInc / (rDischarge * capacitor)) ; + +#ifdef DEBUG + printf ("-vCap: %7.4f\n", vCap) ; +#endif + + vCapLast = vCap ; +} + + +/* + * ledBargraph: + * Output the supplied number as a bargraph on the LEDs + ********************************************************************************* + */ + +void ledBargraph (double value, int topLedOn) +{ + int topLed = (int)floor (value / vCharge * (double)NUM_LEDS) + 1 ; + int i ; + + if (topLed > NUM_LEDS) + topLed = NUM_LEDS ; + + if (!topLedOn) + --topLed ; + + for (i = 0 ; i < topLed ; ++i) + digitalWrite (ledMap [i], 1) ; + + for (i = topLed ; i < NUM_LEDS ; ++i) + digitalWrite (ledMap [i], 0) ; +} + + +/* + * ledOnAction: + * Make sure the leading LED is on and check the button + ********************************************************************************* + */ + +void ledOnAction (void) +{ + if (digitalRead (PIFACE) == LOW) + { + chargeCapacitor () ; + ledBargraph (vCap, TRUE) ; + } +} + + +/* + * ledOffAction: + * Make sure the leading LED is off and check the button + ********************************************************************************* + */ + +void ledOffAction (void) +{ + dischargeCapacitor () ; + +// Are we still pushing the button? + + if (digitalRead (PIFACE) == LOW) + { + vCap = vCapLast = 0.0 ; + ledBargraph (vCap, FALSE) ; + +// Wait until we release the button + + while (digitalRead (PIFACE) == LOW) + delay (10) ; + } +} + + +/* + *********************************************************************** + * The main program + *********************************************************************** + */ + +int main (void) +{ + unsigned int then, ledOnTime, ledOffTime ; + unsigned int ourDelay = (int)(1000.0 * timeInc) ; + + setup () ; + introLeds () ; + +// Setup the LED times - TODO reduce the ON time as the game progresses + + ledOnTime = 1000 ; + ledOffTime = 1000 ; + +// This is our Gate/Squarewave loop + + for (;;) + { + +// LED ON: + + (void)ledBargraph (vCap, TRUE) ; + then = millis () + ledOnTime ; + while (millis () < then) + { + ledOnAction () ; + delay (ourDelay) ; + } + +// Have we won yet? +// We need vCap to be in the top NUM_LEDS of the vCharge + + if (vCap > ((double)(NUM_LEDS - 1) / (double)NUM_LEDS * vCharge)) // Woo hoo! + { + winningLeds () ; + while (digitalRead (PIFACE) == HIGH) + delay (10) ; + while (digitalRead (PIFACE) == LOW) + delay (10) ; + vCap = vCapLast = 0.0 ; + } + +// LED OFF: + + (void)ledBargraph (vCap, FALSE) ; + then = millis () + ledOffTime ; + while (millis () < then) + { + ledOffAction () ; + delay (ourDelay) ; + } + + } + + return 0 ; +} diff --git a/examples/PiFace/metro.c b/examples/PiFace/metro.c new file mode 100644 index 0000000..a4a8c1d --- /dev/null +++ b/examples/PiFace/metro.c @@ -0,0 +1,111 @@ +/* + * metronome.c: + * Simple test for the PiFace interface board. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#include +#include + +#define PIFACE 200 + +/* + * middleA: + * Play middle A (on the relays - yea!) + ********************************************************************************* + */ + +static void middleA (void) +{ + unsigned int next ; + + for (;;) + { + next = micros () + 1136 ; + digitalWrite (PIFACE + 0, 0) ; + digitalWrite (PIFACE + 1, 0) ; + while (micros () < next) + delayMicroseconds (1) ; + + next = micros () + 1137 ; + digitalWrite (PIFACE + 0, 1) ; + digitalWrite (PIFACE + 1, 1) ; + while (micros () < next) + delayMicroseconds (1) ; + + } +} + + +int main (int argc, char *argv []) +{ + int bpm, msPerBeat, state = 0 ; + unsigned int end ; + + printf ("Raspberry Pi PiFace Metronome\n") ; + printf ("=============================\n") ; + + piHiPri (50) ; + + wiringPiSetupSys () ; // Needed for timing functions + piFaceSetup (PIFACE) ; + + if (argc != 2) + { + printf ("Usage: %s \n", argv [0]) ; + exit (1) ; + } + + if (strcmp (argv [1], "a") == 0) + middleA () ; + + bpm = atoi (argv [1]) ; + + if ((bpm < 40) || (bpm > 208)) + { + printf ("%s range is 40 through 208 beats per minute\n", argv [0]) ; + exit (1) ; + } + + msPerBeat = 60000 / bpm ; + +// Main loop: +// Put some random LED pairs up for a few seconds, then blank ... + + for (;;) + { + end = millis () + msPerBeat ; + + digitalWrite (PIFACE + 0, state) ; + digitalWrite (PIFACE + 1, state) ; + + while (millis () < end) + delayMicroseconds (500) ; + + state ^= 1 ; + } + + return 0 ; +} diff --git a/examples/PiFace/motor.c b/examples/PiFace/motor.c new file mode 100644 index 0000000..14f5539 --- /dev/null +++ b/examples/PiFace/motor.c @@ -0,0 +1,120 @@ +/* + * motor.c: + * Use the PiFace board to demonstrate an H bridge + * circuit via the 2 relays. + * Then add on an external transsitor to help with PWM. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#include +#include +#include + +int outputs [2] = { 0,0 } ; + +#define PIFACE_BASE 200 +#define PWM_OUT_PIN 204 +#define PWM_UP 202 +#define PWM_DOWN 203 + +void scanButton (int button) +{ + if (digitalRead (PIFACE_BASE + button) == LOW) + { + outputs [button] ^= 1 ; + digitalWrite (PIFACE_BASE + button, outputs [button]) ; + printf ("Button %d pushed - output now: %s\n", + button, (outputs [button] == 0) ? "Off" : "On") ; + } + + while (digitalRead (PIFACE_BASE + button) == LOW) + delay (1) ; +} + + +int main (void) +{ + int pin, button ; + int pwmValue = 0 ; + + printf ("Raspberry Pi PiFace - Motor control\n") ; + printf ("==================================\n") ; + printf ("\n") ; + printf ( +"This program is designed to be used with a motor connected to the relays\n" +"in an H-Bridge type configuration with optional speeed control via PWM.\n" +"\n" +"Use the leftmost buttons to turn each relay on and off, and the rigthmost\n" +"buttons to increase ot decrease the PWM output on the control pin (pin\n" +"4)\n\n") ; + + wiringPiSetup () ; + piFaceSetup (PIFACE_BASE) ; + softPwmCreate (PWM_OUT_PIN, 100, 100) ; + +// Enable internal pull-ups & start with all off + + for (pin = 0 ; pin < 8 ; ++pin) + { + pullUpDnControl (PIFACE_BASE + pin, PUD_UP) ; + digitalWrite (PIFACE_BASE + pin, 0) ; + } + + for (;;) + { + for (button = 0 ; button < 2 ; ++button) + scanButton (button) ; + + if (digitalRead (PWM_UP) == LOW) + { + pwmValue += 10 ; + if (pwmValue > 100) + pwmValue = 100 ; + + softPwmWrite (PWM_OUT_PIN, pwmValue) ; + printf ("PWM -> %3d\n", pwmValue) ; + + while (digitalRead (PWM_UP) == LOW) + delay (5) ; + } + + if (digitalRead (PWM_DOWN) == LOW) + { + pwmValue -= 10 ; + if (pwmValue < 0) + pwmValue = 0 ; + + softPwmWrite (PWM_OUT_PIN, pwmValue) ; + printf ("PWM -> %3d\n", pwmValue) ; + + while (digitalRead (PWM_DOWN) == LOW) + delay (5) ; + } + + delay (5) ; + } + + return 0 ; +} diff --git a/examples/PiFace/reaction.c b/examples/PiFace/reaction.c new file mode 100644 index 0000000..5084508 --- /dev/null +++ b/examples/PiFace/reaction.c @@ -0,0 +1,194 @@ +/* + * reaction.c: + * Simple test for the PiFace interface board. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#include +#include + + +int outputs [4] = { 0,0,0,0 } ; + +#define PIFACE 200 + +/* + * light: + * Light up the given LED - actually lights up a pair + ********************************************************************************* + */ + +void light (int led, int value) +{ + led *= 2 ; + digitalWrite (PIFACE + led + 0, value) ; + digitalWrite (PIFACE + led + 1, value) ; +} + +/* + * lightAll: + * All On or Off + ********************************************************************************* + */ + +void lightAll (int onoff) +{ + light (0, onoff) ; + light (1, onoff) ; + light (2, onoff) ; + light (3, onoff) ; +} + + +/* + * waitForNoButtons: + * Wait for all buttons to be released + ********************************************************************************* + */ + +void waitForNoButtons (void) +{ + int i, button ; + + for (;;) + { + button = 0 ; + for (i = 0 ; i < 4 ; ++i) + button += digitalRead (PIFACE + i) ; + + if (button == 4) + break ; + } +} + + +void scanButton (int button) +{ + if (digitalRead (PIFACE + button) == LOW) + { + outputs [button] ^= 1 ; + digitalWrite (PIFACE + button, outputs [button]) ; + } + + while (digitalRead (PIFACE + button) == LOW) + delay (1) ; +} + + +int main (void) +{ + int i, j ; + int led, button ; + unsigned int start, stop ; + + printf ("Raspberry Pi PiFace Reaction Timer\n") ; + printf ("==================================\n") ; + + if (piFaceSetup (PIFACE) == -1) + exit (1) ; + +// Enable internal pull-ups + + for (i = 0 ; i < 8 ; ++i) + pullUpDnControl (PIFACE + i, PUD_UP) ; + + +// Main game loop: +// Put some random LED pairs up for a few seconds, then blank ... + + for (;;) + { + printf ("Press any button to start ... \n") ; fflush (stdout) ; + + for (;;) + { + led = rand () % 4 ; + light (led, 1) ; + delay (10) ; + light (led, 0) ; + + button = 0 ; + for (j = 0 ; j < 4 ; ++j) + button += digitalRead (PIFACE + j) ; + + if (button != 4) + break ; + } + + waitForNoButtons () ; + + printf ("Wait for it ... ") ; fflush (stdout) ; + + led = rand () % 4 ; + delay (rand () % 500 + 1000) ; + light (led, 1) ; + + start = millis () ; + for (button = -1 ; button == -1 ; ) + { + for (j = 0 ; j < 4 ; ++j) + if (digitalRead (PIFACE + j) == 0) // Pushed + { + button = j ; + break ; + } + } + stop = millis () ; + button = 3 - button ; // Correct for the buttons/LEDs reversed + + light (led, 0) ; + + waitForNoButtons () ; + + light (led, 1) ; + + if (button == led) + { + printf ("You got it in %3d mS\n", stop - start) ; + } + else + { + printf ("Missed: You pushed %d - LED was %d\n", button, led) ; + for (;;) + { + light (button, 1) ; + delay (100) ; + light (button, 0) ; + delay (100) ; + i = 0 ; + for (j = 0 ; j < 4 ; ++j) + i += digitalRead (PIFACE + j) ; + if (i != 4) + break ; + } + + waitForNoButtons () ; + } + light (led, 0) ; + delay (4000) ; + } + + return 0 ; +} diff --git a/examples/PiGlow/Makefile b/examples/PiGlow/Makefile new file mode 100644 index 0000000..acd4818 --- /dev/null +++ b/examples/PiGlow/Makefile @@ -0,0 +1,82 @@ +# +# Makefile: +# wiringPi - Wiring Compatable library for the Raspberry Pi +# https://projects.drogon.net/wiring-pi +# +# Copyright (c) 2012-2015 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# Wiring Compatable library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + +ifneq ($V,1) +Q ?= @ +endif + +#DEBUG = -g -O0 +DEBUG = -O3 +CC = gcc +INCLUDE = -I/usr/local/include +CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe + +LDFLAGS = -L/usr/local/lib +LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm + +# Should not alter anything below this line +############################################################################### + +SRC = piGlow0.c piGlow1.c piglow.c + +OBJ = $(SRC:.c=.o) + +BINS = $(SRC:.c=) + +all: $(BINS) + +piGlow0: piGlow0.o + $Q echo [link] + $Q $(CC) -o $@ piGlow0.o $(LDFLAGS) $(LDLIBS) + +piGlow1: piGlow1.o + $Q echo [link] + $Q $(CC) -o $@ piGlow1.o $(LDFLAGS) $(LDLIBS) + +piglow: piglow.o + $Q echo [link] + $Q $(CC) -o $@ piglow.o $(LDFLAGS) $(LDLIBS) + +.c.o: + $Q echo [CC] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ + +clean: + $Q echo "[Clean]" + $Q rm -f $(OBJ) *~ core tags $(BINS) + +tags: $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) + +install: piglow + $Q echo Installing piglow into /usr/local/bin + $Q cp -a piglow /usr/local/bin/piglow + $Q chmod 755 /usr/local/bin/piglow + $Q echo Done. Remember to load the I2C drivers! + +depend: + makedepend -Y $(SRC) + +# DO NOT DELETE diff --git a/examples/PiGlow/piGlow0.c b/examples/PiGlow/piGlow0.c new file mode 100644 index 0000000..d3fe4b9 --- /dev/null +++ b/examples/PiGlow/piGlow0.c @@ -0,0 +1,51 @@ +/* + * piglow.c: + * Very simple demonstration of the PiGlow board. + * This uses the SN3218 directly - soon there will be a new PiGlow + * devLib device which will handle the PiGlow board on a more easy + * to use manner... + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include + +#define LED_BASE 533 + +int main (void) +{ + int i, j ; + + wiringPiSetupSys () ; + + sn3218Setup (LED_BASE) ; + + for (;;) + { + for (i = 0 ; i < 256 ; ++i) + for (j = 0 ; j < 18 ; ++j) + analogWrite (LED_BASE + j, i) ; + + for (i = 255 ; i >= 0 ; --i) + for (j = 0 ; j < 18 ; ++j) + analogWrite (LED_BASE + j, i) ; + } +} diff --git a/examples/PiGlow/piGlow1.c b/examples/PiGlow/piGlow1.c new file mode 100644 index 0000000..a00b31e --- /dev/null +++ b/examples/PiGlow/piGlow1.c @@ -0,0 +1,258 @@ +/* + * piGlow1.c: + * Very simple demonstration of the PiGlow board. + * This uses the piGlow devLib. + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#include +#include + +#define PIGLOW_BASE 533 + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (!TRUE) +#endif + + +/* + * keypressed: clearKeypressed: + * Simple but effective ways to tell if the enter key has been pressed + ********************************************************************************* + */ + +static int keypressed (void) +{ + struct pollfd polls ; + + polls.fd = fileno (stdin) ; + polls.events = POLLIN ; + + return poll (&polls, 1, 0) != 0 ; +} + +static void clearKeypressed (void) +{ + while (keypressed ()) + (void)getchar () ; +} + + +/* + * pulseLed: + * Pulses the LED at position leg, ring from off to a max. value, + * then off again + ********************************************************************************* + */ + +static void pulseLed (int leg, int ring) +{ + int i ; + + for (i = 0 ; i < 140 ; ++i) + { + piGlow1 (leg, ring, i) ; + delay (1) ; + } + delay (10) ; + for (i = 140 ; i >= 0 ; --i) + { + piGlow1 (leg, ring, i) ; + delay (1) ; + } +} + +/* + * pulseLeg: + * Same as above, but a whole leg at a time + ********************************************************************************* + */ + +static void pulseLeg (int leg) +{ + int i ; + + for (i = 0 ; i < 140 ; ++i) + { + piGlowLeg (leg, i) ; delay (1) ; + } + delay (10) ; + for (i = 140 ; i >= 0 ; --i) + { + piGlowLeg (leg, i) ; delay (1) ; + } +} + + +/* + * pulse Ring: + * Same as above, but a whole ring at a time + ********************************************************************************* + */ + +static void pulseRing (int ring) +{ + int i ; + + for (i = 0 ; i < 140 ; ++i) + { + piGlowRing (ring, i) ; delay (1) ; + } + delay (10) ; + for (i = 140 ; i >= 0 ; --i) + { + piGlowRing (ring, i) ; delay (1) ; + } +} + +#define LEG_STEPS 3 + +static int legSequence [] = +{ + 4, 12, 99, + 99, 4, 12, + 12, 99, 4, +} ; + + +#define RING_STEPS 16 + +static int ringSequence [] = +{ + 0, 0, 0, 0, 0, 64, + 0, 0, 0, 0, 64, 64, + 0, 0, 0, 64, 64, 0, + 0, 0, 64, 64, 0, 0, + 0, 64, 64, 0, 0, 0, + 64, 64, 0, 0, 0, 0, + 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 64, 0, 0, 0, 0, 0, + 64, 64, 0, 0, 0, 0, + 0, 64, 64, 0, 0, 0, + 0, 0, 64, 64, 0, 0, + 0, 0, 0, 64, 64, 0, + 0, 0, 0, 0, 64, 64, + 0, 0, 0, 0, 0, 64, + 0, 0, 0, 0, 0, 0, +} ; + +/* + * main: + * Our little demo prgoram + ********************************************************************************* + */ + +int main (void) +{ + int i ; + int step, ring, leg ; + +// Always initialise wiringPi: +// Use the Sys method if you don't need to run as root + + wiringPiSetupSys () ; + +// Initialise the piGlow devLib with our chosen pin base + + piGlowSetup (1) ; + +// LEDs, one at a time + + printf ("LEDs, one at a time\n") ; + for (; !keypressed () ;) + for (leg = 0 ; leg < 3 ; ++leg) + { + for (ring = 0 ; ring < 6 ; ++ring) + { + pulseLed (leg, ring) ; + if (keypressed ()) + break ; + } + if (keypressed ()) + break ; + } + clearKeypressed () ; + +// Rings, one at a time + + printf ("Rings, one at a time\n") ; + for (; !keypressed () ;) + for (ring = 0 ; ring < 6 ; ++ring) + { + pulseRing (ring) ; + if (keypressed ()) + break ; + } + clearKeypressed () ; + +// Legs, one at a time + + printf ("Legs, one at a time\n") ; + for (; !keypressed () ;) + for (leg = 0 ; leg < 3 ; ++leg) + { + pulseLeg (leg) ; + if (keypressed ()) + break ; + } + clearKeypressed () ; + + delay (1000) ; + +// Sequence - alternating rings, legs and random + + printf ("Sequence now\n") ; + for (; !keypressed () ;) + { + for (i = 0 ; i < 20 ; ++i) + for (step = 0 ; step < LEG_STEPS ; ++step) + { + for (leg = 0 ; leg < 3 ; ++leg) + piGlowLeg (leg, legSequence [step * 3 + leg]) ; + delay (80) ; + } + + for (i = 0 ; i < 10 ; ++i) + for (step = 0 ; step < RING_STEPS ; ++step) + { + for (ring = 0 ; ring < 6 ; ++ring) + piGlowRing (ring, ringSequence [step * 6 + ring]) ; + delay (80) ; + } + + for (i = 0 ; i < 1000 ; ++i) + { + leg = random () % 3 ; + ring = random () % 6 ; + piGlow1 (leg, ring, random () % 256) ; + delay (5) ; + piGlow1 (leg, ring, 0) ; + } + } + + return 0 ; +} diff --git a/examples/PiGlow/piglow.c b/examples/PiGlow/piglow.c new file mode 100644 index 0000000..e6a2db3 --- /dev/null +++ b/examples/PiGlow/piglow.c @@ -0,0 +1,176 @@ +/* + * piglow.c: + * Very simple demonstration of the PiGlow board. + * This uses the piGlow devLib. + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (!TRUE) +#endif + +#include +#include + +static void failUsage (void) +{ + fprintf (stderr, "Usage examples:\n") ; + fprintf (stderr, " piglow off # All off\n") ; + fprintf (stderr, " piglow red 50 # Light the 3 red LEDs to 50%%\n") ; + fprintf (stderr, " colours are: red, yellow, orange, green, blue and white\n") ; + fprintf (stderr, " piglow all 75 # Light all to 75%%\n") ; + fprintf (stderr, " piglow leg 0 25 # Light leg 0 to 25%%\n") ; + fprintf (stderr, " piglow ring 3 100 # Light ring 3 to 100%%\n") ; + fprintf (stderr, " piglow led 2 5 100 # Light the single LED on Leg 2, ring 5 to 100%%\n") ; + + exit (EXIT_FAILURE) ; +} + +static int getPercent (char *typed) +{ + int percent ; + + percent = atoi (typed) ; + if ((percent < 0) || (percent > 100)) + { + fprintf (stderr, "piglow: percent value out of range\n") ; + exit (EXIT_FAILURE) ; + } + return (percent * 255) / 100 ; +} + + +/* + * main: + * Our little demo prgoram + ********************************************************************************* + */ + +int main (int argc, char *argv []) +{ + int percent ; + int ring, leg ; + +// Always initialise wiringPi: +// Use the Sys method if you don't need to run as root + + wiringPiSetupSys () ; + +// Initialise the piGlow devLib + + piGlowSetup (FALSE) ; + + if (argc == 1) + failUsage () ; + + if ((argc == 2) && (strcasecmp (argv [1], "off") == 0)) + { + for (leg = 0 ; leg < 3 ; ++leg) + piGlowLeg (leg, 0) ; + return 0 ; + } + + if (argc == 3) + { + percent = getPercent (argv [2]) ; + + /**/ if (strcasecmp (argv [1], "red") == 0) + piGlowRing (PIGLOW_RED, percent) ; + else if (strcasecmp (argv [1], "yellow") == 0) + piGlowRing (PIGLOW_YELLOW, percent) ; + else if (strcasecmp (argv [1], "orange") == 0) + piGlowRing (PIGLOW_ORANGE, percent) ; + else if (strcasecmp (argv [1], "green") == 0) + piGlowRing (PIGLOW_GREEN, percent) ; + else if (strcasecmp (argv [1], "blue") == 0) + piGlowRing (PIGLOW_BLUE, percent) ; + else if (strcasecmp (argv [1], "white") == 0) + piGlowRing (PIGLOW_WHITE, percent) ; + else if (strcasecmp (argv [1], "all") == 0) + for (ring = 0 ; ring < 6 ; ++ring) + piGlowRing (ring, percent) ; + else + { + fprintf (stderr, "piglow: invalid colour\n") ; + exit (EXIT_FAILURE) ; + } + return 0 ; + } + + if (argc == 4) + { + /**/ if (strcasecmp (argv [1], "leg") == 0) + { + leg = atoi (argv [2]) ; + if ((leg < 0) || (leg > 2)) + { + fprintf (stderr, "piglow: leg value out of range\n") ; + exit (EXIT_FAILURE) ; + } + percent = getPercent (argv [3]) ; + piGlowLeg (leg, percent) ; + } + else if (strcasecmp (argv [1], "ring") == 0) + { + ring = atoi (argv [2]) ; + if ((ring < 0) || (ring > 5)) + { + fprintf (stderr, "piglow: ring value out of range\n") ; + exit (EXIT_FAILURE) ; + } + percent = getPercent (argv [3]) ; + piGlowRing (ring, percent) ; + } + return 0 ; + } + + if (argc == 5) + { + if (strcasecmp (argv [1], "led") != 0) + failUsage () ; + + leg = atoi (argv [2]) ; + if ((leg < 0) || (leg > 2)) + { + fprintf (stderr, "piglow: leg value out of range\n") ; + exit (EXIT_FAILURE) ; + } + ring = atoi (argv [3]) ; + if ((ring < 0) || (ring > 5)) + { + fprintf (stderr, "piglow: ring value out of range\n") ; + exit (EXIT_FAILURE) ; + } + percent = getPercent (argv [4]) ; + piGlow1 (leg, ring, percent) ; + return 0 ; + } + + failUsage () ; + return 0 ; +} + + diff --git a/examples/blink.c b/examples/blink.c index bb9f856..c27a20e 100644 --- a/examples/blink.c +++ b/examples/blink.c @@ -34,16 +34,14 @@ int main (void) { printf ("Raspberry Pi blink\n") ; - if (wiringPiSetup () == -1) - return 1 ; - + wiringPiSetup () ; pinMode (LED, OUTPUT) ; for (;;) { - digitalWrite (LED, 1) ; // On + digitalWrite (LED, HIGH) ; // On delay (500) ; // mS - digitalWrite (LED, 0) ; // Off + digitalWrite (LED, LOW) ; // Off delay (500) ; } return 0 ; diff --git a/examples/blink.sh b/examples/blink.sh index 2aa378a..3975bb7 100644 --- a/examples/blink.sh +++ b/examples/blink.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/sh -e # # blink.sh: # Standard "blink" program in wiringPi. Blinks an LED connected @@ -25,7 +25,7 @@ # LED Pin - wiringPi pin 0 is BCM_GPIO 17. -LED=0 +PIN=0 gpio mode $PIN out diff --git a/examples/blink12.c b/examples/blink12.c new file mode 100644 index 0000000..c9b3d50 --- /dev/null +++ b/examples/blink12.c @@ -0,0 +1,111 @@ +/* + * blink12.c: + * Simple sequence over the first 12 GPIO pins - LEDs + * Aimed at the Gertboard, but it's fairly generic. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include + +// Simple sequencer data +// Triplets of LED, On/Off and delay + +int data [] = +{ + 0, 1, 1, + 1, 1, 1, + 0, 0, 0, 2, 1, 1, + 1, 0, 0, 3, 1, 1, + 2, 0, 0, 4, 1, 1, + 3, 0, 0, 5, 1, 1, + 4, 0, 0, 6, 1, 1, + 5, 0, 0, 7, 1, 1, + 6, 0, 0, 11, 1, 1, + 7, 0, 0, 10, 1, 1, + 11, 0, 0, 13, 1, 1, + 10, 0, 0, 12, 1, 1, + 13, 0, 1, + 12, 0, 1, + + 0, 0, 1, // Extra delay + +// Back again + + 12, 1, 1, + 13, 1, 1, + 12, 0, 0, 10, 1, 1, + 13, 0, 0, 11, 1, 1, + 10, 0, 0, 7, 1, 1, + 11, 0, 0, 6, 1, 1, + 7, 0, 0, 5, 1, 1, + 6, 0, 0, 4, 1, 1, + 5, 0, 0, 3, 1, 1, + 4, 0, 0, 2, 1, 1, + 3, 0, 0, 1, 1, 1, + 2, 0, 0, 0, 1, 1, + 1, 0, 1, + 0, 0, 1, + + 0, 0, 1, // Extra delay + + 0, 9, 0, // End marker + +} ; + + +int main (void) +{ + int pin ; + int dataPtr ; + int l, s, d ; + + printf ("Raspberry Pi - 12-LED Sequence\n") ; + printf ("==============================\n") ; + printf ("\n") ; + printf ("Connect LEDs up to the first 8 GPIO pins, then pins 11, 10, 13, 12 in\n") ; + printf (" that order, then sit back and watch the show!\n") ; + + wiringPiSetup () ; + + for (pin = 0 ; pin < 14 ; ++pin) + pinMode (pin, OUTPUT) ; + + dataPtr = 0 ; + + for (;;) + { + l = data [dataPtr++] ; // LED + s = data [dataPtr++] ; // State + d = data [dataPtr++] ; // Duration (10ths) + + if (s == 9) // 9 -> End Marker + { + dataPtr = 0 ; + continue ; + } + + digitalWrite (l, s) ; + delay (d * 100) ; + } + + return 0 ; +} diff --git a/examples/blink12drcs.c b/examples/blink12drcs.c new file mode 100644 index 0000000..6ee11fd --- /dev/null +++ b/examples/blink12drcs.c @@ -0,0 +1,125 @@ +/* + * blink12drcs.c: + * Simple sequence over the first 12 GPIO pins - LEDs + * Aimed at the Gertboard, but it's fairly generic. + * This version uses DRC totalk to the ATmega on the Gertboard + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#define GERT_BASE 100 + +static int pinMap [] = +{ + 0, 1, 2, 3, // Pi Native + GERT_BASE + 2, GERT_BASE + 3, GERT_BASE + 4, GERT_BASE + 5, + GERT_BASE + 6, GERT_BASE + 7, GERT_BASE + 8, GERT_BASE + 9, +} ; + +// Simple sequencer data +// Triplets of LED, On/Off and delay + + +int data [] = +{ + 0, 1, 1, + 1, 1, 1, + 0, 0, 0, 2, 1, 1, + 1, 0, 0, 3, 1, 1, + 2, 0, 0, 4, 1, 1, + 3, 0, 0, 5, 1, 1, + 4, 0, 0, 6, 1, 1, + 5, 0, 0, 7, 1, 1, + 6, 0, 0, 8, 1, 1, + 7, 0, 0, 9, 1, 1, + 8, 0, 0, 10, 1, 1, + 9, 0, 0, 11, 1, 1, + 10, 0, 1, + 11, 0, 1, + + 0, 0, 1, // Extra delay + +// Back again + + 11, 1, 1, + 10, 1, 1, + 11, 0, 0, 9, 1, 1, + 10, 0, 0, 8, 1, 1, + 9, 0, 0, 7, 1, 1, + 8, 0, 0, 6, 1, 1, + 7, 0, 0, 5, 1, 1, + 6, 0, 0, 4, 1, 1, + 5, 0, 0, 3, 1, 1, + 4, 0, 0, 2, 1, 1, + 3, 0, 0, 1, 1, 1, + 2, 0, 0, 0, 1, 1, + 1, 0, 1, + 0, 0, 1, + + 0, 0, 1, // Extra delay + + 0, 9, 0, // End marker + +} ; + + +int main (void) +{ + int pin ; + int dataPtr ; + int l, s, d ; + + printf ("Raspberry Pi - 12-LED Sequence\n") ; + printf ("==============================\n") ; + printf ("\n") ; + printf ("Connect LEDs up to the first 4 Pi pins and 8 pins on the ATmega\n") ; + printf (" from PD2 through PB1 in that order,\n") ; + printf (" then sit back and watch the show!\n") ; + + wiringPiSetup () ; + drcSetupSerial (GERT_BASE, 20, "/dev/ttyAMA0", 115200) ; + + for (pin = 0 ; pin < 12 ; ++pin) + pinMode (pinMap [pin], OUTPUT) ; + + dataPtr = 0 ; + + for (;;) + { + l = data [dataPtr++] ; // LED + s = data [dataPtr++] ; // State + d = data [dataPtr++] ; // Duration (10ths) + + if (s == 9) // 9 -> End Marker + { + dataPtr = 0 ; + continue ; + } + + digitalWrite (pinMap [l], s) ; + delay (d * analogRead (GERT_BASE) / 4) ; + } + + return 0 ; +} diff --git a/examples/blink6drcs.c b/examples/blink6drcs.c new file mode 100644 index 0000000..32f4921 --- /dev/null +++ b/examples/blink6drcs.c @@ -0,0 +1,115 @@ +/* + * blink6drcs.c: + * Simple sequence over 6 pins on a remote DRC board. + * Aimed at the Gertduino, but it's fairly generic. + * This version uses DRC to talk to the ATmega on the Gertduino + * + * Copyright (c) 2012-2014 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#define GERT_BASE 100 + +static int pinMap [] = +{ + GERT_BASE + 6, GERT_BASE + 5, GERT_BASE + 3, GERT_BASE + 10, GERT_BASE + 9, GERT_BASE + 13, +} ; + +// Simple sequencer data +// Triplets of LED, On/Off and delay + + +int data [] = +{ + 0, 1, 1, + 1, 1, 1, + 0, 0, 0, 2, 1, 1, + 1, 0, 0, 3, 1, 1, + 2, 0, 0, 4, 1, 1, + 3, 0, 0, 5, 1, 1, + 4, 0, 1, + 5, 0, 1, + + 0, 0, 1, // Extra delay + +// Back again + + 5, 1, 1, + 4, 1, 1, + 5, 0, 0, 3, 1, 1, + 4, 0, 0, 2, 1, 1, + 3, 0, 0, 1, 1, 1, + 2, 0, 0, 0, 1, 1, + 1, 0, 1, + 0, 0, 1, + + 0, 0, 1, // Extra delay + + 0, 9, 0, // End marker + +} ; + + +int main (void) +{ + int pin ; + int dataPtr ; + int l, s, d ; + + printf ("Raspberry Pi - 6-LED Sequence\n") ; + printf ("=============================\n") ; + printf ("\n") ; + printf (" Use the 2 buttons to temporarily speed up the sequence\n") ; + + wiringPiSetupSys () ; // Not using the Pi's GPIO here + drcSetupSerial (GERT_BASE, 20, "/dev/ttyAMA0", 115200) ; + + for (pin = 0 ; pin < 6 ; ++pin) + pinMode (pinMap [pin], OUTPUT) ; + + pinMode (GERT_BASE + 16, INPUT) ; // Buttons + pinMode (GERT_BASE + 17, INPUT) ; + + pullUpDnControl (GERT_BASE + 16, PUD_UP) ; + pullUpDnControl (GERT_BASE + 17, PUD_UP) ; + + dataPtr = 0 ; + + for (;;) + { + l = data [dataPtr++] ; // LED + s = data [dataPtr++] ; // State + d = data [dataPtr++] ; // Duration (10ths) + + if (s == 9) // 9 -> End Marker + { + dataPtr = 0 ; + continue ; + } + + digitalWrite (pinMap [l], s) ; + delay (d * digitalRead (GERT_BASE + 16) * 15 + digitalRead (GERT_BASE + 17) * 20) ; + } + + return 0 ; +} diff --git a/examples/blink8.c b/examples/blink8.c new file mode 100644 index 0000000..602d3c0 --- /dev/null +++ b/examples/blink8.c @@ -0,0 +1,57 @@ +/* + * blink8.c: + * Simple sequence over the first 8 GPIO pins - LEDs + * Aimed at the Gertboard, but it's fairly generic. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include + +int main (void) +{ + int i, led ; + + printf ("Raspberry Pi - 8-LED Sequencer\n") ; + printf ("==============================\n") ; + printf ("\n") ; + printf ("Connect LEDs to the first 8 GPIO pins and watch ...\n") ; + + wiringPiSetup () ; + + for (i = 0 ; i < 8 ; ++i) + pinMode (i, OUTPUT) ; + + for (;;) + { + for (led = 0 ; led < 8 ; ++led) + { + digitalWrite (led, 1) ; + delay (100) ; + } + + for (led = 0 ; led < 8 ; ++led) + { + digitalWrite (led, 0) ; + delay (100) ; + } + } +} diff --git a/examples/clock.c b/examples/clock.c new file mode 100644 index 0000000..9a53210 --- /dev/null +++ b/examples/clock.c @@ -0,0 +1,201 @@ +/* + * clock.c: + * Demo of the 128x64 graphics based LCD driver. + * This is designed to drive the parallel interface LCD drivers + * based on the popular 12864H controller chip. + * + * This test program assumes the following: + * (Which is currently hard-wired into the driver) + * + * GPIO 0-7 is connected to display data pins 0-7. + * GPIO 10 is CS1 + * GPIO 11 is CS2 + * GPIO 12 is STROBE + * GPIO 10 is RS + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==2) +#endif + +double clockRadius ; +double thickness, barLen ; +int maxX, maxY ; + +double rads (double degs) +{ + return degs * M_PI / 180.0 ; +} + +void drawClockHands (void) +{ + time_t t ; + struct tm *now ; + double angle, p, x0, y0, x1, y1 ; + int h24, h, m, s ; + char text [20] ; + + time (&t) ; + now = localtime (&t) ; + + h24 = now->tm_hour ; + m = now->tm_min ; + s = now->tm_sec ; + + h = h24 ; + if (h > 12) + h -= 12 ; + +// Hour hand + + angle = h * 30 + m * 0.5 ; + x0 = sin (rads (angle)) * (clockRadius * 0.75) ; + y0 = cos (rads (angle)) * (clockRadius * 0.75) ; + for (p = -3.0 ; p <= 3.0 ; p += 0.2) + { + x1 = sin (rads (angle + p)) * (clockRadius * 0.7) ; + y1 = cos (rads (angle + p)) * (clockRadius * 0.7) ; + lcd128x64line (0, 0, x1, y1, 1) ; + lcd128x64lineTo (x0, y0, 1) ; + } + +// Minute hand + + angle = m * 6 ; + x0 = sin (rads (angle)) * (clockRadius * 0.9) ; + y0 = cos (rads (angle)) * (clockRadius * 0.9) ; + for (p = -1.0 ; p <= 1.0 ; p += 0.2) + { + x1 = sin (rads (angle + p)) * (clockRadius * 0.85) ; + y1 = cos (rads (angle + p)) * (clockRadius * 0.85) ; + lcd128x64line (0, 0, x1, y1, 1) ; + lcd128x64lineTo (x0, y0, 1) ; + } + +// Second hand + + angle = s * 6 ; + x0 = sin (rads (angle)) * (clockRadius * 0.2) ; + y0 = cos (rads (angle)) * (clockRadius * 0.2) ; + x1 = sin (rads (angle)) * (clockRadius * 0.95) ; + y1 = cos (rads (angle)) * (clockRadius * 0.95) ; + lcd128x64line (0 - x0, 0 - y0, x1, y1, 1) ; + lcd128x64circle (0, 0, clockRadius * 0.1, 0, 1) ; + lcd128x64circle (0, 0, clockRadius * 0.05, 1, 1) ; + +// Text: + + sprintf (text, "%02d:%02d:%02d", h24, m, s) ; + lcd128x64puts (32, 24, text, 0, 1) ; + + sprintf (text, "%2d/%2d/%2d", now->tm_mday, now->tm_mon + 1, now->tm_year - 100) ; + lcd128x64puts (32, -23, text, 0, 1) ; +} + +void drawClockFace (void) +{ + int m ; + double d, px1, py1, px2, py2 ; + + lcd128x64clear (0) ; + lcd128x64circle (0,0, clockRadius, 1, TRUE) ; + lcd128x64circle (0,0, clockRadius - thickness, 0, TRUE) ; + +// The four big indicators for 12,15,30 and 45 + + lcd128x64rectangle (- 3, clockRadius - barLen, 3, clockRadius, 1, TRUE) ; // 12 + lcd128x64rectangle (clockRadius - barLen, 3, clockRadius, -3, 1, TRUE) ; // 3 + lcd128x64rectangle (- 3, -clockRadius + barLen, 3, -clockRadius, 1, TRUE) ; // 6 + lcd128x64rectangle (-clockRadius + barLen, 3, -clockRadius, -3, 1, TRUE) ; // 9 + + +// Smaller 5 and 1 minute ticks + + for (m = 0 ; m < 60 ; ++m) + { + px1 = sin (rads (m * 6)) * clockRadius ; + py1 = cos (rads (m * 6)) * clockRadius ; + if ((m % 5) == 0) + d = barLen ; + else + d = barLen / 2.0 ; + + px2 = sin (rads (m * 6)) * (clockRadius - d) ; + py2 = cos (rads (m * 6)) * (clockRadius - d) ; + lcd128x64line (px1, py1, px2, py2, 1) ; + } +} + +void setup (void) +{ + lcd128x64getScreenSize (&maxX, &maxY) ; + clockRadius = maxY / 2 - 1 ; + thickness = maxX / 48 ; + barLen = thickness * 4 ; + lcd128x64setOrigin (32, 32) ; +} + + + + +/* + *********************************************************************** + * The main program + *********************************************************************** + */ + +int main (int argc, char *argv []) +{ + time_t now ; + + wiringPiSetup () ; + + lcd128x64setup () ; + + setup () ; + for (;;) + { + drawClockFace () ; + drawClockHands () ; + lcd128x64update () ; + + now = time (NULL) ; + while (time (NULL) == now) + delay (10) ; + } + + + return 0 ; +} diff --git a/examples/ds1302.c b/examples/ds1302.c new file mode 100644 index 0000000..f1e9e20 --- /dev/null +++ b/examples/ds1302.c @@ -0,0 +1,238 @@ +/* + * ds1302.c: + * Real Time clock + * + * Copyright (c) 2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include +#include + +#include +#include + +// Register defines + +#define RTC_SECS 0 +#define RTC_MINS 1 +#define RTC_HOURS 2 +#define RTC_DATE 3 +#define RTC_MONTH 4 +#define RTC_DAY 5 +#define RTC_YEAR 6 +#define RTC_WP 7 +#define RTC_TC 8 +#define RTC_BM 31 + + +static unsigned int masks [] = { 0x7F, 0x7F, 0x3F, 0x3F, 0x1F, 0x07, 0xFF } ; + + +/* + * bcdToD: dToBCD: + * BCD decode/encode + ********************************************************************************* + */ + +static int bcdToD (unsigned int byte, unsigned int mask) +{ + unsigned int b1, b2 ; + byte &= mask ; + b1 = byte & 0x0F ; + b2 = ((byte >> 4) & 0x0F) * 10 ; + return b1 + b2 ; +} + +static unsigned int dToBcd (unsigned int byte) +{ + return ((byte / 10) << 4) + (byte % 10) ; +} + + +/* + * ramTest: + * Simple test of the 31 bytes of RAM inside the DS1302 chip + ********************************************************************************* + */ + +static int ramTestValues [] = + { 0x00, 0xFF, 0xAA, 0x55, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0xF0, 0x0F, -1 } ; + +static int ramTest (void) +{ + int addr ; + int got ; + int i = 0 ; + int errors = 0 ; + int testVal ; + + printf ("DS1302 RAM TEST\n") ; + + testVal = ramTestValues [i] ; + + while (testVal != -1) + { + for (addr = 0 ; addr < 31 ; ++addr) + ds1302ramWrite (addr, testVal) ; + + for (addr = 0 ; addr < 31 ; ++addr) + if ((got = ds1302ramRead (addr)) != testVal) + { + printf ("DS1302 RAM Failure: Address: %2d, Expected: 0x%02X, Got: 0x%02X\n", + addr, testVal, got) ; + ++errors ; + } + testVal = ramTestValues [++i] ; + } + + for (addr = 0 ; addr < 31 ; ++addr) + ds1302ramWrite (addr, addr) ; + + for (addr = 0 ; addr < 31 ; ++addr) + if ((got = ds1302ramRead (addr)) != addr) + { + printf ("DS1302 RAM Failure: Address: %2d, Expected: 0x%02X, Got: 0x%02X\n", + addr, addr, got) ; + ++errors ; + } + + if (errors == 0) + printf ("-- DS1302 RAM TEST: OK\n") ; + else + printf ("-- DS1302 RAM TEST FAILURE. %d errors.\n", errors) ; + + return 0 ; +} + +/* + * setLinuxClock: + * Set the Linux clock from the hardware + ********************************************************************************* + */ + +static int setLinuxClock (void) +{ + char dateTime [20] ; + char command [64] ; + int clock [8] ; + + + printf ("Setting the Linux Clock from the DS1302... ") ; fflush (stdout) ; + + ds1302clockRead (clock) ; + +// [MMDDhhmm[[CC]YY][.ss]] + + sprintf (dateTime, "%02d%02d%02d%02d%02d%02d.%02d", + bcdToD (clock [RTC_MONTH], masks [RTC_MONTH]), + bcdToD (clock [RTC_DATE], masks [RTC_DATE]), + bcdToD (clock [RTC_HOURS], masks [RTC_HOURS]), + bcdToD (clock [RTC_MINS], masks [RTC_MINS]), + 20, + bcdToD (clock [RTC_YEAR], masks [RTC_YEAR]), + bcdToD (clock [RTC_SECS], masks [RTC_SECS])) ; + + sprintf (command, "/bin/date %s", dateTime) ; + system (command) ; + + return 0 ; +} + + +/* + * setDSclock: + * Set the DS1302 block from Linux time + ********************************************************************************* + */ + +static int setDSclock (void) +{ + struct tm t ; + time_t now ; + int clock [8] ; + + printf ("Setting the clock in the DS1302 from Linux time... ") ; + + now = time (NULL) ; + gmtime_r (&now, &t) ; + + clock [ 0] = dToBcd (t.tm_sec) ; // seconds + clock [ 1] = dToBcd (t.tm_min) ; // mins + clock [ 2] = dToBcd (t.tm_hour) ; // hours + clock [ 3] = dToBcd (t.tm_mday) ; // date + clock [ 4] = dToBcd (t.tm_mon + 1) ; // months 0-11 --> 1-12 + clock [ 5] = dToBcd (t.tm_wday + 1) ; // weekdays (sun 0) + clock [ 6] = dToBcd (t.tm_year - 100) ; // years + clock [ 7] = 0 ; // W-Protect off + + ds1302clockWrite (clock) ; + + printf ("OK\n") ; + + return 0 ; +} + + + + +int main (int argc, char *argv []) +{ + int i ; + int clock [8] ; + + wiringPiSetup () ; + ds1302setup (0, 1, 2) ; + + if (argc == 2) + { + /**/ if (strcmp (argv [1], "-slc") == 0) + return setLinuxClock () ; + else if (strcmp (argv [1], "-sdsc") == 0) + return setDSclock () ; + else if (strcmp (argv [1], "-rtest") == 0) + return ramTest () ; + else + { + printf ("Usage: ds1302 [-slc | -sdsc | -rtest]\n") ; + return EXIT_FAILURE ; + } + } + + for (i = 0 ;; ++i) + { + printf ("%5d: ", i) ; + + ds1302clockRead (clock) ; + printf (" %2d:%02d:%02d", + bcdToD (clock [2], masks [2]), bcdToD (clock [1], masks [1]), bcdToD (clock [0], masks [0])) ; + + printf (" %2d/%02d/%04d", + bcdToD (clock [3], masks [3]), bcdToD (clock [4], masks [4]), bcdToD (clock [6], masks [6]) + 2000) ; + + printf ("\n") ; + + delay (200) ; + } + + return 0 ; +} diff --git a/examples/isr.c b/examples/isr.c index 2bef54a..abc6aec 100644 --- a/examples/isr.c +++ b/examples/isr.c @@ -38,16 +38,11 @@ #include -// What GPIO input are we using? -// This is a wiringPi pin number - -#define BUTTON_PIN 0 - // globalCounter: // Global variable to count interrupts // Should be declared volatile to make sure the compiler doesn't cache it. -static volatile int globalCounter = 0 ; +static volatile int globalCounter [8] ; /* @@ -55,10 +50,14 @@ static volatile int globalCounter = 0 ; ********************************************************************************* */ -void myInterrupt (void) -{ - ++globalCounter ; -} +void myInterrupt0 (void) { ++globalCounter [0] ; } +void myInterrupt1 (void) { ++globalCounter [1] ; } +void myInterrupt2 (void) { ++globalCounter [2] ; } +void myInterrupt3 (void) { ++globalCounter [3] ; } +void myInterrupt4 (void) { ++globalCounter [4] ; } +void myInterrupt5 (void) { ++globalCounter [5] ; } +void myInterrupt6 (void) { ++globalCounter [6] ; } +void myInterrupt7 (void) { ++globalCounter [7] ; } /* @@ -69,30 +68,42 @@ void myInterrupt (void) int main (void) { - int myCounter = 0 ; + int gotOne, pin ; + int myCounter [8] ; - if (wiringPiSetup () < 0) - { - fprintf (stderr, "Unable to setup wiringPi: %s\n", strerror (errno)) ; - return 1 ; - } + for (pin = 0 ; pin < 8 ; ++pin) + globalCounter [pin] = myCounter [pin] = 0 ; - if (wiringPiISR (BUTTON_PIN, INT_EDGE_FALLING, &myInterrupt) < 0) - { - fprintf (stderr, "Unable to setup ISR: %s\n", strerror (errno)) ; - return 1 ; - } + wiringPiSetup () ; + wiringPiISR (0, INT_EDGE_FALLING, &myInterrupt0) ; + wiringPiISR (1, INT_EDGE_FALLING, &myInterrupt1) ; + wiringPiISR (2, INT_EDGE_FALLING, &myInterrupt2) ; + wiringPiISR (3, INT_EDGE_FALLING, &myInterrupt3) ; + wiringPiISR (4, INT_EDGE_FALLING, &myInterrupt4) ; + wiringPiISR (5, INT_EDGE_FALLING, &myInterrupt5) ; + wiringPiISR (6, INT_EDGE_FALLING, &myInterrupt6) ; + wiringPiISR (7, INT_EDGE_FALLING, &myInterrupt7) ; for (;;) { + gotOne = 0 ; printf ("Waiting ... ") ; fflush (stdout) ; - while (myCounter == globalCounter) - delay (100) ; - - printf (" Done. counter: %5d\n", globalCounter) ; - myCounter = globalCounter ; + for (;;) + { + for (pin = 0 ; pin < 8 ; ++pin) + { + if (globalCounter [pin] != myCounter [pin]) + { + printf (" Int on pin %d: Counter: %5d\n", pin, globalCounter [pin]) ; + myCounter [pin] = globalCounter [pin] ; + ++gotOne ; + } + } + if (gotOne != 0) + break ; + } } return 0 ; diff --git a/examples/lcd-adafruit.c b/examples/lcd-adafruit.c new file mode 100644 index 0000000..47c9b9b --- /dev/null +++ b/examples/lcd-adafruit.c @@ -0,0 +1,347 @@ +/* + * lcd-adafruit.c: + * Text-based LCD driver test code + * This is designed to drive the Adafruit RGB LCD Plate + * with the additional 5 buttons for the Raspberry Pi + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==2) +#endif + + +// Defines for the Adafruit Pi LCD interface board + +#define AF_BASE 100 +#define AF_RED (AF_BASE + 6) +#define AF_GREEN (AF_BASE + 7) +#define AF_BLUE (AF_BASE + 8) + +#define AF_E (AF_BASE + 13) +#define AF_RW (AF_BASE + 14) +#define AF_RS (AF_BASE + 15) + +#define AF_DB4 (AF_BASE + 12) +#define AF_DB5 (AF_BASE + 11) +#define AF_DB6 (AF_BASE + 10) +#define AF_DB7 (AF_BASE + 9) + +#define AF_SELECT (AF_BASE + 0) +#define AF_RIGHT (AF_BASE + 1) +#define AF_DOWN (AF_BASE + 2) +#define AF_UP (AF_BASE + 3) +#define AF_LEFT (AF_BASE + 4) + + +// User-Defined character test + +static unsigned char newChar [8] = +{ + 0b00100, + 0b00100, + 0b00000, + 0b00100, + 0b01110, + 0b11011, + 0b11011, + 0b10001, +} ; + +// Global lcd handle: + +static int lcdHandle ; + +/* + * usage: + ********************************************************************************* + */ + +int usage (const char *progName) +{ + fprintf (stderr, "Usage: %s colour\n", progName) ; + return EXIT_FAILURE ; +} + + +/* + * scrollMessage: + ********************************************************************************* + */ + +static const char *message = + " " + "Wiring Pi by Gordon Henderson. HTTP://WIRINGPI.COM/" + " " ; + +void scrollMessage (int line, int width) +{ + char buf [32] ; + static int position = 0 ; + static int timer = 0 ; + + if (millis () < timer) + return ; + + timer = millis () + 200 ; + + strncpy (buf, &message [position], width) ; + buf [width] = 0 ; + lcdPosition (lcdHandle, 0, line) ; + lcdPuts (lcdHandle, buf) ; + + if (++position == (strlen (message) - width)) + position = 0 ; +} + + +/* + * setBacklightColour: + * The colour outputs are inverted. + ********************************************************************************* + */ + +static void setBacklightColour (int colour) +{ + colour &= 7 ; + + digitalWrite (AF_RED, !(colour & 1)) ; + digitalWrite (AF_GREEN, !(colour & 2)) ; + digitalWrite (AF_BLUE, !(colour & 4)) ; +} + + +/* + * adafruitLCDSetup: + * Setup the Adafruit board by making sure the additional pins are + * set to the correct modes, etc. + ********************************************************************************* + */ + +static void adafruitLCDSetup (int colour) +{ + int i ; + +// Backlight LEDs + + pinMode (AF_RED, OUTPUT) ; + pinMode (AF_GREEN, OUTPUT) ; + pinMode (AF_BLUE, OUTPUT) ; + setBacklightColour (colour) ; + +// Input buttons + + for (i = 0 ; i <= 4 ; ++i) + { + pinMode (AF_BASE + i, INPUT) ; + pullUpDnControl (AF_BASE + i, PUD_UP) ; // Enable pull-ups, switches close to 0v + } + +// Control signals + + pinMode (AF_RW, OUTPUT) ; digitalWrite (AF_RW, LOW) ; // Not used with wiringPi - always in write mode + +// The other control pins are initialised with lcdInit () + + lcdHandle = lcdInit (2, 16, 4, AF_RS, AF_E, AF_DB4,AF_DB5,AF_DB6,AF_DB7, 0,0,0,0) ; + + if (lcdHandle < 0) + { + fprintf (stderr, "lcdInit failed\n") ; + exit (EXIT_FAILURE) ; + } +} + + +/* + * waitForEnter: + * On the Adafruit display, wait for the select button + ********************************************************************************* + */ + +static void waitForEnter (void) +{ + printf ("Press SELECT to continue: ") ; fflush (stdout) ; + + while (digitalRead (AF_SELECT) == HIGH) // Wait for push + delay (1) ; + + while (digitalRead (AF_SELECT) == LOW) // Wait for release + delay (1) ; + + printf ("OK\n") ; +} + + +/* + * speedTest: + * Test the update speed of the display + ********************************************************************************* + */ + +static void speedTest (void) +{ + unsigned int start, end, taken ; + int times ; + + lcdClear (lcdHandle) ; + start = millis () ; + for (times = 0 ; times < 10 ; ++times) + { + lcdPuts (lcdHandle, "0123456789ABCDEF") ; + lcdPuts (lcdHandle, "0123456789ABCDEF") ; + } + end = millis () ; + taken = (end - start) / 10; + + lcdClear (lcdHandle) ; + lcdPosition (lcdHandle, 0, 0) ; lcdPrintf (lcdHandle, "Speed: %dmS", taken) ; + lcdPosition (lcdHandle, 0, 1) ; lcdPrintf (lcdHandle, "For full update") ; + + waitForEnter () ; + + lcdClear (lcdHandle) ; + lcdPosition (lcdHandle, 0, 0) ; lcdPrintf (lcdHandle, "Time: %dmS", taken / 32) ; + lcdPosition (lcdHandle, 0, 1) ; lcdPrintf (lcdHandle, "Per character") ; + + waitForEnter () ; + + lcdClear (lcdHandle) ; + lcdPosition (lcdHandle, 0, 0) ; lcdPrintf (lcdHandle, "%d cps...", 32000 / taken) ; + + waitForEnter () ; +} + + +/* + * The works + ********************************************************************************* + */ + +int main (int argc, char *argv[]) +{ + int colour ; + int cols = 16 ; + int waitForRelease = FALSE ; + + struct tm *t ; + time_t tim ; + + char buf [32] ; + + if (argc != 2) + return usage (argv [0]) ; + + printf ("Raspberry Pi Adafruit LCD test\n") ; + printf ("==============================\n") ; + + colour = atoi (argv [1]) ; + + wiringPiSetupSys () ; + mcp23017Setup (AF_BASE, 0x20) ; + + adafruitLCDSetup (colour) ; + + lcdPosition (lcdHandle, 0, 0) ; lcdPuts (lcdHandle, "Gordon Henderson") ; + lcdPosition (lcdHandle, 0, 1) ; lcdPuts (lcdHandle, " wiringpi.com ") ; + + waitForEnter () ; + + lcdPosition (lcdHandle, 0, 1) ; lcdPuts (lcdHandle, "Adafruit RGB LCD") ; + + waitForEnter () ; + + lcdCharDef (lcdHandle, 2, newChar) ; + + lcdClear (lcdHandle) ; + lcdPosition (lcdHandle, 0, 0) ; + lcdPuts (lcdHandle, "User Char: ") ; + lcdPutchar (lcdHandle, 2) ; + + lcdCursor (lcdHandle, TRUE) ; + lcdCursorBlink (lcdHandle, TRUE) ; + + waitForEnter () ; + + lcdCursor (lcdHandle, FALSE) ; + lcdCursorBlink (lcdHandle, FALSE) ; + + speedTest () ; + + lcdClear (lcdHandle) ; + + for (;;) + { + scrollMessage (0, cols) ; + + tim = time (NULL) ; + t = localtime (&tim) ; + + sprintf (buf, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ; + + lcdPosition (lcdHandle, (cols - 8) / 2, 1) ; + lcdPuts (lcdHandle, buf) ; + +// Check buttons to cycle colour + +// If Up or Down are still pushed, then skip + + if (waitForRelease) + { + if ((digitalRead (AF_UP) == LOW) || (digitalRead (AF_DOWN) == LOW)) + continue ; + else + waitForRelease = FALSE ; + } + + if (digitalRead (AF_UP) == LOW) // Pushed + { + colour = colour + 1 ; + if (colour == 8) + colour = 0 ; + setBacklightColour (colour) ; + waitForRelease = TRUE ; + } + + if (digitalRead (AF_DOWN) == LOW) // Pushed + { + colour = colour - 1 ; + if (colour == -1) + colour = 7 ; + setBacklightColour (colour) ; + waitForRelease = TRUE ; + } + + } + + return 0 ; +} diff --git a/examples/lcd.c b/examples/lcd.c index 6024917..510f562 100644 --- a/examples/lcd.c +++ b/examples/lcd.c @@ -4,7 +4,19 @@ * This is designed to drive the parallel interface LCD drivers * based in the Hitachi HD44780U controller and compatables. * - * Copyright (c) 2012 Gordon Henderson. + * This test program assumes the following: + * + * 8-bit displays: + * GPIO 0-7 is connected to display data pins 0-7. + * GPIO 11 is the RS pin. + * GPIO 10 is the Strobe/E pin. + * + * For 4-bit interface: + * GPIO 4-7 is connected to display data pins 4-7. + * GPIO 11 is the RS pin. + * GPIO 10 is the Strobe/E pin. + * + * Copyright (c) 2012-2013 Gordon Henderson. *********************************************************************** * This file is part of wiringPi: * https://projects.drogon.net/raspberry-pi/wiringpi/ @@ -35,94 +47,239 @@ #include #include -int main (void) -{ - int i, j ; - int fd1, fd2 ; +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==2) +#endif - char message1 [256] ; - char message2 [256] ; - char buf1 [30] ; - char buf2 [30] ; +static unsigned char newChar [8] = +{ + 0b11111, + 0b10001, + 0b10001, + 0b10101, + 0b11111, + 0b10001, + 0b10001, + 0b11111, +} ; + + +// Global lcd handle: + +static int lcdHandle ; + +/* + * usage: + ********************************************************************************* + */ + +int usage (const char *progName) +{ + fprintf (stderr, "Usage: %s bits cols rows\n", progName) ; + return EXIT_FAILURE ; +} + + +/* + * scrollMessage: + ********************************************************************************* + */ + +static const char *message = + " " + "Wiring Pi by Gordon Henderson. HTTP://WIRINGPI.COM/" + " " ; + +void scrollMessage (int line, int width) +{ + char buf [32] ; + static int position = 0 ; + static int timer = 0 ; + + if (millis () < timer) + return ; + + timer = millis () + 200 ; + + strncpy (buf, &message [position], width) ; + buf [width] = 0 ; + lcdPosition (lcdHandle, 0, line) ; + lcdPuts (lcdHandle, buf) ; + + if (++position == (strlen (message) - width)) + position = 0 ; +} + + +/* + * pingPong: + * Bounce a character - only on 4-line displays + ********************************************************************************* + */ + +static void pingPong (int lcd, int cols) +{ + static int position = 0 ; + static int dir = 0 ; + + if (dir == 0) // Setup + { + dir = 1 ; + lcdPosition (lcdHandle, 0, 3) ; + lcdPutchar (lcdHandle, '*') ; + return ; + } + + lcdPosition (lcdHandle, position, 3) ; + lcdPutchar (lcdHandle, ' ') ; + position += dir ; + + if (position == cols) + { + dir = -1 ; + --position ; + } + + if (position < 0) + { + dir = 1 ; + ++position ; + } + + lcdPosition (lcdHandle, position, 3) ; + lcdPutchar (lcdHandle, '#') ; +} + + +/* + * waitForEnter: + ********************************************************************************* + */ + +static void waitForEnter (void) +{ + printf ("Press ENTER to continue: ") ; + (void)fgetc (stdin) ; +} + + +/* + * The works + ********************************************************************************* + */ + +int main (int argc, char *argv[]) +{ + int i ; + int lcd ; + int bits, rows, cols ; struct tm *t ; time_t tim ; - printf ("Raspberry Pi LCD test program\n") ; + char buf [32] ; - if (wiringPiSetup () == -1) - exit (1) ; + if (argc != 4) + return usage (argv [0]) ; - fd1 = lcdInit (4, 20, 4, 8, 9, 4,5,6,7,0,0,0,0) ; - fd2 = lcdInit (2, 16, 4, 8, 10, 4,5,6,7,0,0,0,0) ; + printf ("Raspberry Pi LCD test\n") ; + printf ("=====================\n") ; -//fd1 = lcdInit (4, 20, 8, 8, 9, 0,1,2,3,4,5,6,7) ; -//fd2 = lcdInit (2, 16, 8, 8, 10, 0,1,2,3,4,5,6,7) ; + bits = atoi (argv [1]) ; + cols = atoi (argv [2]) ; + rows = atoi (argv [3]) ; - if (fd1 == -1) + if (!((rows == 1) || (rows == 2) || (rows == 4))) { - printf ("lcdInit 1 failed\n") ; - return 1 ; + fprintf (stderr, "%s: rows must be 1, 2 or 4\n", argv [0]) ; + return EXIT_FAILURE ; } - if (fd2 == -1) + if (!((cols == 16) || (cols == 20))) { - printf ("lcdInit 2 failed\n") ; - return 1 ; + fprintf (stderr, "%s: cols must be 16 or 20\n", argv [0]) ; + return EXIT_FAILURE ; } - sleep (1) ; + wiringPiSetup () ; - lcdPosition (fd1, 0, 0) ; lcdPuts (fd1, " Gordon Henderson") ; - lcdPosition (fd1, 0, 1) ; lcdPuts (fd1, " --------------") ; -/* - lcdPosition (fd1, 0, 2) ; lcdPuts (fd1, " 00:00:00") ; - lcdPosition (fd1, 0, 3) ; lcdPuts (fd1, " DD:MM:YY") ; -*/ + if (bits == 4) + lcdHandle = lcdInit (rows, cols, 4, 11,10, 4,5,6,7,0,0,0,0) ; + else + lcdHandle = lcdInit (rows, cols, 8, 11,10, 0,1,2,3,4,5,6,7) ; - lcdPosition (fd2, 0, 0) ; lcdPuts (fd2, "Gordon Henderson") ; - lcdPosition (fd2, 0, 1) ; lcdPuts (fd2, "----------------") ; + if (lcdHandle < 0) + { + fprintf (stderr, "%s: lcdInit failed\n", argv [0]) ; + return -1 ; + } - sleep (2) ; + lcdPosition (lcdHandle, 0, 0) ; lcdPuts (lcdHandle, "Gordon Henderson") ; + lcdPosition (lcdHandle, 0, 1) ; lcdPuts (lcdHandle, " wiringpi.com ") ; - sprintf (message1, "%s", " http://projects.drogon.net/ ") ; - sprintf (message2, "%s", " This is a long message to go into the smaller display just for a demonstration of what we can do. ") ; + waitForEnter () ; + + if (rows > 1) + { + lcdPosition (lcdHandle, 0, 1) ; lcdPuts (lcdHandle, " wiringpi.com ") ; + + if (rows == 4) + { + lcdPosition (lcdHandle, 0, 2) ; + for (i = 0 ; i < ((cols - 1) / 2) ; ++i) + lcdPuts (lcdHandle, "=-") ; + lcdPuts (lcdHandle, "=3") ; + + lcdPosition (lcdHandle, 0, 3) ; + for (i = 0 ; i < ((cols - 1) / 2) ; ++i) + lcdPuts (lcdHandle, "-=") ; + lcdPuts (lcdHandle, "-4") ; + } + } + + waitForEnter () ; + + lcdCharDef (lcdHandle, 2, newChar) ; + + lcdClear (lcdHandle) ; + lcdPosition (lcdHandle, 0, 0) ; + lcdPuts (lcdHandle, "User Char: ") ; + lcdPutchar (lcdHandle, 2) ; + + lcdCursor (lcdHandle, TRUE) ; + lcdCursorBlink (lcdHandle, TRUE) ; + + waitForEnter () ; + + lcdCursor (lcdHandle, FALSE) ; + lcdCursorBlink (lcdHandle, FALSE) ; + lcdClear (lcdHandle) ; for (;;) { - i = 0 ; - j = 0 ; - for (;;) - { - strncpy (buf1, &message1 [i], 20) ; - buf1 [20] = 0 ; - lcdPosition (fd1, 0, 1) ; - lcdPuts (fd1, buf1) ; - ++i ; - if (i == strlen (message1) - 20) - i = 0 ; + scrollMessage (0, cols) ; + + if (rows == 1) + continue ; - strncpy (buf2, &message2 [j], 16) ; - buf2 [16] = 0 ; - lcdPosition (fd2, 0, 1) ; - lcdPuts (fd2, buf2) ; - ++j ; - if (j == strlen (message2) - 16) - j = 0 ; + tim = time (NULL) ; + t = localtime (&tim) ; - tim = time (NULL) ; - t = localtime (&tim) ; + sprintf (buf, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ; - sprintf (buf1, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec) ; - lcdPosition (fd1, 5, 2) ; - lcdPuts (fd1, buf1) ; + lcdPosition (lcdHandle, (cols - 8) / 2, 1) ; + lcdPuts (lcdHandle, buf) ; - sprintf (buf1, "%02d/%02d/%02d", t->tm_mday, t->tm_mon + 1, t->tm_year+1900) ; - lcdPosition (fd1, 4, 3) ; - lcdPuts (fd1, buf1) ; + if (rows == 2) + continue ; - delay (250) ; - } + sprintf (buf, "%02d/%02d/%04d", t->tm_mday, t->tm_mon + 1, t->tm_year+1900) ; + + lcdPosition (lcdHandle, (cols - 10) / 2, 2) ; + lcdPuts (lcdHandle, buf) ; + + pingPong (lcd, cols) ; } return 0 ; diff --git a/examples/lowPower.c b/examples/lowPower.c new file mode 100644 index 0000000..e901e7f --- /dev/null +++ b/examples/lowPower.c @@ -0,0 +1,68 @@ +/* + * lowPower.c: + * Check the Pi's LOW-Power signal. + * + * This is a demonstration program that could be turned into some sort + * of logger via e.g. syslog - however it's also probably something + * that might be better handled by a future kernel - who knows. + * + * Copyright (c) 2014 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + + +#define LOW_POWER 35 + +/* + * lowPower: + * This is an ISR that waits for the low-power signal going low and + * prints the result. + ********************************************************************************* + */ + +void lowPower (void) +{ + time_t t ; + + time (&t) ; + printf ("%s: LOW POWER DETECTED\n", ctime (&t)) ; +} + + +/* + ********************************************************************************* + * main + ********************************************************************************* + */ + +int main (void) +{ + wiringPiSetupGpio () ; // GPIO mode as it's an internal pin + + wiringPiISR (LOW_POWER, INT_EDGE_FALLING, &lowPower) ; + + for (;;) + delay (1000) ; + + return 0 ; +} diff --git a/examples/max31855.c b/examples/max31855.c new file mode 100644 index 0000000..36b3cf6 --- /dev/null +++ b/examples/max31855.c @@ -0,0 +1,60 @@ +/* + * max31855.c: + * SPI Thermocouple interface chip + * + * Copyright (c) 2015 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include +#include + +#include +#include + +int main (int argc, char *argv []) +{ + int i = 0 ; + + wiringPiSetup () ; + max31855Setup (200, 0) ; + max31855Setup (400, 1) ; + + for (;;) + { + if (i == 0) + { + printf ("+------+------+------+------++------+------+------+------+\n") ; + printf ("| Raw | Err | C | F || Raw | Err | C | F |\n") ; + printf ("+------+------+------+------++------+------+------+------+\n") ; + } + + printf ("| %4d | %4d | %4d | %4d |", analogRead (200), analogRead (201), analogRead (202), analogRead (203)) ; + printf ("| %4d | %4d | %4d | %4d |\n", analogRead (400), analogRead (401), analogRead (402), analogRead (403)) ; + delay (500) ; + + if (++i == 10) + i = 0 ; + + } + +} diff --git a/examples/okLed.c b/examples/okLed.c index 9b3a170..930f266 100644 --- a/examples/okLed.c +++ b/examples/okLed.c @@ -39,27 +39,26 @@ #include #include +// The OK/Act LED is connected to BCM_GPIO pin 16 + #define OK_LED 16 int main () { int fd, i ; + wiringPiSetupGpio () ; + +// Change the trigger on the OK/Act LED to "none" + if ((fd = open ("/sys/class/leds/led0/trigger", O_RDWR)) < 0) { fprintf (stderr, "Unable to change LED trigger: %s\n", strerror (errno)) ; return 1 ; } - write (fd, "none\n", 5) ; close (fd) ; - if (wiringPiSetupGpio () < 0) - { - fprintf (stderr, "Unable to setup GPIO: %s\n", strerror (errno)) ; - return 1 ; - } - softPwmCreate (OK_LED, 0, 100) ; for (;;) diff --git a/examples/pwm.c b/examples/pwm.c index c1fc331..816c832 100644 --- a/examples/pwm.c +++ b/examples/pwm.c @@ -1,7 +1,6 @@ /* * pwm.c: - * Test of the software PWM driver. Needs 12 LEDs connected - * to the Pi. + * This tests the hardware PWM channel. * * Copyright (c) 2012-2013 Gordon Henderson. *********************************************************************** @@ -23,71 +22,37 @@ *********************************************************************** */ -#include -#include -#include - #include -#include -#define RANGE 100 -#define NUM_LEDS 12 +#include +#include +#include -int ledMap [NUM_LEDS] = { 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13 } ; - -int values [NUM_LEDS] = { 0, 17, 32, 50, 67, 85, 100, 85, 67, 50, 32, 17 } ; - -int main () +int main (void) { - int i, j ; - char buf [80] ; + int bright ; + + printf ("Raspberry Pi wiringPi PWM test program\n") ; if (wiringPiSetup () == -1) - { - fprintf (stdout, "oops: %s\n", strerror (errno)) ; - return 1 ; - } + exit (1) ; - for (i = 0 ; i < NUM_LEDS ; ++i) - { - softPwmCreate (ledMap [i], 0, RANGE) ; - printf ("%3d, %3d, %3d\n", i, ledMap [i], values [i]) ; - } - - fgets (buf, 80, stdin) ; - -// Bring all up one by one: - - for (i = 0 ; i < NUM_LEDS ; ++i) - for (j = 0 ; j <= 100 ; ++j) - { - softPwmWrite (ledMap [i], j) ; - delay (10) ; - } - - fgets (buf, 80, stdin) ; - -// Down fast - - for (i = 100 ; i > 0 ; --i) - { - for (j = 0 ; j < NUM_LEDS ; ++j) - softPwmWrite (ledMap [j], i) ; - delay (10) ; - } - - fgets (buf, 80, stdin) ; + pinMode (1, PWM_OUTPUT) ; for (;;) { - for (i = 0 ; i < NUM_LEDS ; ++i) - softPwmWrite (ledMap [i], values [i]) ; + for (bright = 0 ; bright < 1024 ; ++bright) + { + pwmWrite (1, bright) ; + delay (1) ; + } - delay (50) ; - - i = values [0] ; - for (j = 0 ; j < NUM_LEDS - 1 ; ++j) - values [j] = values [j + 1] ; - values [NUM_LEDS - 1] = i ; + for (bright = 1023 ; bright >= 0 ; --bright) + { + pwmWrite (1, bright) ; + delay (1) ; + } } + + return 0 ; } diff --git a/examples/q2w/Makefile b/examples/q2w/Makefile new file mode 100644 index 0000000..6f50fa0 --- /dev/null +++ b/examples/q2w/Makefile @@ -0,0 +1,84 @@ +# +# Makefile: +# wiringPi - Wiring Compatable library for the Raspberry Pi +# https://projects.drogon.net/wiring-pi +# +# Copyright (c) 2012-2013 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# Wiring Compatable library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + +ifneq ($V,1) +Q ?= @ +endif + +#DEBUG = -g -O0 +DEBUG = -O3 +CC = gcc +INCLUDE = -I/usr/local/include +CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe + +LDFLAGS = -L/usr/local/lib +LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm + +############################################################################### + +SRC = blink.c button.c blink-io.c volts.c bright.c + +OBJ = $(SRC:.c=.o) + +BINS = $(SRC:.c=) + +all: $(BINS) + +blink: blink.o + $Q echo [link] + $Q $(CC) -o $@ blink.o $(LDFLAGS) $(LDLIBS) + +blink-io: blink-io.o + $Q echo [link] + $Q $(CC) -o $@ blink-io.o $(LDFLAGS) $(LDLIBS) + +button: button.o + $Q echo [link] + $Q $(CC) -o $@ button.o $(LDFLAGS) $(LDLIBS) + +volts: volts.o + $Q echo [link] + $Q $(CC) -o $@ volts.o $(LDFLAGS) $(LDLIBS) + +bright: bright.o + $Q echo [link] + $Q $(CC) -o $@ bright.o $(LDFLAGS) $(LDLIBS) + + +.c.o: + $Q echo [CC] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ + +clean: + $Q echo "[Clean]" + $Q rm -f $(OBJ) *~ core tags $(BINS) + +tags: $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) + +depend: + makedepend -Y $(SRC) + +# DO NOT DELETE diff --git a/examples/q2w/binary.c b/examples/q2w/binary.c new file mode 100644 index 0000000..3c987c6 --- /dev/null +++ b/examples/q2w/binary.c @@ -0,0 +1,79 @@ +/* + * binary.c: + * Using the Quick 2 wire 16-bit GPIO expansion board to output + * a binary counter. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#define Q2W_BASE 100 + +int main (void) +{ + int i, bit ; + +// Enable the on-goard GPIO + + wiringPiSetup () ; + +// Add in the mcp23017 on the q2w board + + mcp23017Setup (Q2W_BASE, 0x20) ; + + printf ("Raspberry Pi - quite2Wire MCP23017 Test\n") ; + +// On-board button Input: + + pinMode (0, INPUT) ; + +// First 10 pins on q2w board as outputs: + + for (i = 0 ; i < 10 ; ++i) + pinMode (Q2W_BASE + i, OUTPUT) ; + +// Last pin as an input with the internal pull-up enabled + + pinMode (Q2W_BASE + 15, INPUT) ; + pullUpDnControl (Q2W_BASE + 15, PUD_UP) ; + +// Loop, outputting a binary number, +// Go faster with the button, or stop if the +// on-board button is pushed + + for (;;) + { + for (i = 0 ; i < 1024 ; ++i) + { + for (bit = 0 ; bit < 10 ; ++bit) + digitalWrite (Q2W_BASE + bit, i & (1 << bit)) ; + + while (digitalRead (0) == HIGH) // While pushed + delay (1) ; + + if (digitalRead (Q2W_BASE + 15) == HIGH) // Not Pushed + delay (100) ; + } + } + return 0 ; +} diff --git a/examples/q2w/blink-io.c b/examples/q2w/blink-io.c new file mode 100644 index 0000000..4dd4276 --- /dev/null +++ b/examples/q2w/blink-io.c @@ -0,0 +1,61 @@ +/* + * blink-io.c: + * Simple "blink" test for the Quick2Wire 16-pin IO board. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#define LED 1 +#define Q2W_BASE 100 + +int main (void) +{ + +// Enable the on-goard GPIO + + wiringPiSetup () ; + +// Add in the mcp23017 on the q2w board + + mcp23017Setup (Q2W_BASE, 0x20) ; + + printf ("Raspberry Pi - Quick2Wire MCP23017 Blink Test\n") ; + +// Blink the on-board LED as well as one on the mcp23017 + + pinMode (LED, OUTPUT) ; + pinMode (Q2W_BASE + 0, OUTPUT) ; + + for (;;) + { + digitalWrite (LED, HIGH) ; + digitalWrite (Q2W_BASE + 0, HIGH) ; + delay (500) ; + digitalWrite (LED, LOW) ; + digitalWrite (Q2W_BASE + 0, LOW) ; + delay (500) ; + } + + return 0 ; +} diff --git a/examples/q2w/blink.c b/examples/q2w/blink.c new file mode 100644 index 0000000..62b694a --- /dev/null +++ b/examples/q2w/blink.c @@ -0,0 +1,50 @@ +/* + * blink.c: + * Simple "blink" test for the Quick2Wire interface board. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include + +#define LED 1 + +int main (void) +{ + +// Enable the on-goard GPIO + + wiringPiSetup () ; + + printf ("Raspberry Pi - Quick2Wire Mainboard LED Blink Test\n") ; + + pinMode (LED, OUTPUT) ; + + for (;;) + { + digitalWrite (LED, HIGH) ; + delay (500) ; + digitalWrite (LED, LOW) ; + delay (500) ; + } + + return 0 ; +} diff --git a/examples/q2w/blink.sh b/examples/q2w/blink.sh new file mode 100644 index 0000000..bb6107a --- /dev/null +++ b/examples/q2w/blink.sh @@ -0,0 +1,37 @@ +#!/bin/sh -e +# +# blink.sh: +# Standard "blink" program in wiringPi. Blinks an LED connected +# to the LED on the Quick2Wire board +# +# Copyright (c) 2012-2013 Gordon Henderson. +####################################################################### +# This file is part of wiringPi: +# https://projects.drogon.net/raspberry-pi/wiringpi/ +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +####################################################################### + +# LED Pin - wiringPi pin 1 is BCM_GPIO 18. + +LED=1 + +gpio mode $LED out + +while true; do + gpio write $LED 1 + sleep 0.5 + gpio write $LED 0 + sleep 0.5 +done diff --git a/examples/q2w/bright.c b/examples/q2w/bright.c new file mode 100644 index 0000000..2318834 --- /dev/null +++ b/examples/q2w/bright.c @@ -0,0 +1,59 @@ +/* + * bright.c: + * Vary the Q2W LED brightness with the analog card + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#define LED 1 +#define Q2W_ABASE 120 + +int main (void) +{ + int value ; + +// Enable the on-goard GPIO + + wiringPiSetup () ; + +// Add in the pcf8591 on the q2w board + + pcf8591Setup (Q2W_ABASE, 0x48) ; + + printf ("Raspberry Pi - Quick2Wire Analog Test\n") ; + +// Setup the LED + + pinMode (LED, PWM_OUTPUT) ; + pwmWrite (LED, 0) ; + + for (;;) + { + value = analogRead (Q2W_ABASE + 0) ; + pwmWrite (LED, value * 4) ; + delay (10) ; + } + + return 0 ; +} diff --git a/examples/q2w/button.c b/examples/q2w/button.c new file mode 100644 index 0000000..1781f02 --- /dev/null +++ b/examples/q2w/button.c @@ -0,0 +1,63 @@ +/* + * button.c: + * Simple button test for the Quick2Wire interface board. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include + +#define BUTTON 0 +#define LED1 1 +#define LED2 7 + +int main (void) +{ + +// Enable the on-goard GPIO + + wiringPiSetup () ; + + printf ("Raspberry Pi - Quick2Wire Mainboard Button & LED Test\n") ; + + pinMode (BUTTON, INPUT) ; + pinMode (LED1, OUTPUT) ; + pinMode (LED2, OUTPUT) ; + + digitalWrite (LED1, HIGH) ; // On-board LED on + digitalWrite (LED2, LOW) ; // 2nd LED off + + for (;;) + { + if (digitalRead (BUTTON) == HIGH) // Swap LED states + { + digitalWrite (LED1, LOW) ; + digitalWrite (LED2, HIGH) ; + while (digitalRead (BUTTON) == HIGH) + delay (1) ; + digitalWrite (LED1, HIGH) ; + digitalWrite (LED2, LOW) ; + } + delay (1) ; + } + + return 0 ; +} diff --git a/examples/q2w/volts.c b/examples/q2w/volts.c new file mode 100644 index 0000000..e091093 --- /dev/null +++ b/examples/q2w/volts.c @@ -0,0 +1,62 @@ +/* + * volts.c: + * Read in all 4 analogs on the Q2W analog board. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#define LED 1 +#define Q2W_ABASE 120 + +int main (void) +{ + int value, pin ; + +// Enable the on-goard GPIO + + wiringPiSetup () ; + + pinMode (LED, OUTPUT) ; // On-board LED + +// Add in the pcf8591 on the q2w board + + pcf8591Setup (Q2W_ABASE, 0x48) ; + + printf ("Raspberry Pi - Quick2Wire Voltmeter\n") ; + + for (;;) + { + for (pin = 0 ; pin < 4 ; ++pin) + { + value = analogRead (Q2W_ABASE + pin) ; + printf (" %5.2f", (double)value * 3.3 / 255.0) ; + } + printf ("\r") ; fflush (stdout) ; + + delay (100) ; + digitalWrite (LED, !digitalRead (LED)) ; // Flicker the LED + } + + return 0 ; +} diff --git a/examples/rht03.c b/examples/rht03.c new file mode 100644 index 0000000..566e954 --- /dev/null +++ b/examples/rht03.c @@ -0,0 +1,69 @@ +/* + * rht03.c: + * Driver for the MaxDetect series sensors + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include + +#include +#include + +#define RHT03_PIN 0 + +/* + *********************************************************************** + * The main program + *********************************************************************** + */ + +int main (void) +{ + int temp, rh ; + int newTemp, newRh ; + + temp = rh = newTemp = newRh = 0 ; + + wiringPiSetup () ; + piHiPri (55) ; + + for (;;) + { + delay (100) ; + + if (!readRHT03 (RHT03_PIN, &newTemp, &newRh)) + continue ; + + if ((temp != newTemp) || (rh != newRh)) + { + temp = newTemp ; + rh = newRh ; + if ((temp & 0x8000) != 0) // Negative + { + temp &= 0x7FFF ; + temp = -temp ; + } + printf ("Temp: %5.1f, RH: %5.1f%%\n", temp / 10.0, rh / 10.0) ; + } + } + + return 0 ; +} diff --git a/examples/softPwm.c b/examples/softPwm.c new file mode 100644 index 0000000..11f7ad0 --- /dev/null +++ b/examples/softPwm.c @@ -0,0 +1,89 @@ +/* + * softPwm.c: + * Test of the software PWM driver. Needs 8 LEDs connected + * to the Pi - e.g. Ladder board. + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#include +#include + +#define RANGE 100 +#define NUM_LEDS 8 + +int ledMap [NUM_LEDS] = { 0, 1, 2, 3, 4, 5, 6, 7 } ; + +int values [NUM_LEDS] = { 0, 25, 50, 75, 100, 75, 50, 25 } ; + +int main () +{ + int i, j ; + char buf [80] ; + + wiringPiSetup () ; + + for (i = 0 ; i < NUM_LEDS ; ++i) + { + softPwmCreate (ledMap [i], 0, RANGE) ; + printf ("%3d, %3d, %3d\n", i, ledMap [i], values [i]) ; + } + + fgets (buf, 80, stdin) ; + +// Bring all up one by one: + + for (i = 0 ; i < NUM_LEDS ; ++i) + for (j = 0 ; j <= 100 ; ++j) + { + softPwmWrite (ledMap [i], j) ; + delay (10) ; + } + + fgets (buf, 80, stdin) ; + +// All Down + + for (i = 100 ; i > 0 ; --i) + { + for (j = 0 ; j < NUM_LEDS ; ++j) + softPwmWrite (ledMap [j], i) ; + delay (10) ; + } + + fgets (buf, 80, stdin) ; + + for (;;) + { + for (i = 0 ; i < NUM_LEDS ; ++i) + softPwmWrite (ledMap [i], values [i]) ; + + delay (50) ; + + i = values [0] ; + for (j = 0 ; j < NUM_LEDS - 1 ; ++j) + values [j] = values [j + 1] ; + values [NUM_LEDS - 1] = i ; + } +} diff --git a/examples/softTone.c b/examples/softTone.c new file mode 100644 index 0000000..2f46783 --- /dev/null +++ b/examples/softTone.c @@ -0,0 +1,54 @@ +/* + * softTone.c: + * Test of the softTone module in wiringPi + * Plays a scale out on pin 3 - connect pizeo disc to pin 3 & 0v + * + * Copyright (c) 2012-2013 Gordon Henderson. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + +#include +#include +#include + +#include +#include + +#define PIN 3 + +int scale [8] = { 262, 294, 330, 349, 392, 440, 494, 525 } ; + +int main () +{ + int i ; + + wiringPiSetup () ; + + softToneCreate (PIN) ; + + for (;;) + { + for (i = 0 ; i < 8 ; ++i) + { + printf ("%3d\n", i) ; + softToneWrite (PIN, scale [i]) ; + delay (500) ; + } + } +} diff --git a/examples/speed.c b/examples/speed.c index 863317e..0a42b36 100644 --- a/examples/speed.c +++ b/examples/speed.c @@ -31,93 +31,65 @@ #define FAST_COUNT 10000000 #define SLOW_COUNT 1000000 +#define PASSES 5 + +void speedTest (int pin, int maxCount) +{ + int count, sum, perSec, i ; + unsigned int start, end ; + + sum = 0 ; + + for (i = 0 ; i < PASSES ; ++i) + { + start = millis () ; + for (count = 0 ; count < maxCount ; ++count) + digitalWrite (pin, 1) ; + end = millis () ; + printf (" %6d", end - start) ; + fflush (stdout) ; + sum += (end - start) ; + } + + digitalWrite (pin, 0) ; + printf (". Av: %6dmS", sum / PASSES) ; + perSec = (int)(double)maxCount / (double)((double)sum / (double)PASSES) * 1000.0 ; + printf (": %7d/sec\n", perSec) ; +} int main (void) { - int i ; - uint32_t start, end, count, sum, perSec ; - - printf ("Raspberry Pi wiringPi speed test program\n") ; + printf ("Raspberry Pi wiringPi GPIO speed test program\n") ; + printf ("=============================================\n") ; // Start the standard way - if (wiringPiSetup () == -1) - exit (1) ; - - printf ("Native wiringPi method: (%8d iterations)\n", FAST_COUNT) ; - + printf ("\nNative wiringPi method: (%8d iterations)\n", FAST_COUNT) ; + wiringPiSetup () ; pinMode (0, OUTPUT) ; + speedTest (0, FAST_COUNT) ; - sum = 0 ; - for (i = 0 ; i < 3 ; ++i) - { - printf (" Pass: %d: ", i) ; - fflush (stdout) ; - - start = millis () ; - for (count = 0 ; count < FAST_COUNT ; ++count) - digitalWrite (0, 1) ; - end = millis () ; - printf (" %8dmS\n", end - start) ; - sum += (end - start) ; - } - digitalWrite (0, 0) ; - printf (" Average: %8dmS", sum / 3) ; - perSec = (int)(double)FAST_COUNT / (double)((double)sum / 3.0) * 1000.0 ; - printf (": %6d/sec\n", perSec) ; - - - printf ("Native GPIO method: (%8d iterations)\n", FAST_COUNT) ; - - if (wiringPiSetupGpio () == -1) - exit (1) ; +// GPIO + printf ("\nNative GPIO method: (%8d iterations)\n", FAST_COUNT) ; + wiringPiSetupGpio () ; pinMode (17, OUTPUT) ; + speedTest (17, FAST_COUNT) ; - sum = 0 ; - for (i = 0 ; i < 3 ; ++i) - { - printf (" Pass: %d: ", i) ; - fflush (stdout) ; - - start = millis () ; - for (count = 0 ; count < 10000000 ; ++count) - digitalWrite (17, 1) ; - end = millis () ; - printf (" %8dmS\n", end - start) ; - sum += (end - start) ; - } - digitalWrite (17, 0) ; - printf (" Average: %8dmS", sum / 3) ; - perSec = (int)(double)FAST_COUNT / (double)((double)sum / 3.0) * 1000.0 ; - printf (": %6d/sec\n", perSec) ; +// Phys + printf ("\nPhysical pin GPIO method: (%8d iterations)\n", FAST_COUNT) ; + wiringPiSetupPhys () ; + pinMode (11, OUTPUT) ; + speedTest (11, FAST_COUNT) ; // Switch to SYS mode: - if (wiringPiSetupSys () == -1) - exit (1) ; - - printf ("/sys/class/gpio method: (%8d iterations)\n", SLOW_COUNT) ; - - sum = 0 ; - for (i = 0 ; i < 3 ; ++i) - { - printf (" Pass: %d: ", i) ; - fflush (stdout) ; - - start = millis () ; - for (count = 0 ; count < SLOW_COUNT ; ++count) - digitalWrite (17, 1) ; - end = millis () ; - printf (" %8dmS\n", end - start) ; - sum += (end - start) ; - } - digitalWrite (17, 0) ; - printf (" Average: %8dmS", sum / 3) ; - perSec = (int)(double)SLOW_COUNT / (double)((double)sum / 3.0) * 1000.0 ; - printf (": %6d/sec\n", perSec) ; + system ("/usr/local/bin/gpio export 17 out") ; + printf ("\n/sys/class/gpio method: (%8d iterations)\n", SLOW_COUNT) ; + wiringPiSetupSys () ; + speedTest (17, SLOW_COUNT) ; return 0 ; } diff --git a/examples/spiSpeed.c b/examples/spiSpeed.c new file mode 100644 index 0000000..0208f0a --- /dev/null +++ b/examples/spiSpeed.c @@ -0,0 +1,118 @@ +/* + * spiSpeed.c: + * Code to measure the SPI speed/latency. + * Copyright (c) 2014 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + + +#include +#include +#include +#include +#include +#include +//#include +//#include +//#include + +#include +#include + +#define TRUE (1==1) +#define FALSE (!TRUE) + +#define SPI_CHAN 0 +#define NUM_TIMES 100 +#define MAX_SIZE (1024*1024) + +static int myFd ; + + +void spiSetup (int speed) +{ + if ((myFd = wiringPiSPISetup (SPI_CHAN, speed)) < 0) + { + fprintf (stderr, "Can't open the SPI bus: %s\n", strerror (errno)) ; + exit (EXIT_FAILURE) ; + } +} + + +int main (void) +{ + int speed, times, size ; + unsigned int start, end ; + int spiFail ; + unsigned char *myData ; + double timePerTransaction, perfectTimePerTransaction, dataSpeed ; + + if ((myData = malloc (MAX_SIZE)) == NULL) + { + fprintf (stderr, "Unable to allocate buffer: %s\n", strerror (errno)) ; + exit (EXIT_FAILURE) ; + } + + wiringPiSetup () ; + + for (speed = 1 ; speed <= 32 ; speed *= 2) + { + printf ("+-------+--------+----------+----------+-----------+------------+\n") ; + printf ("| MHz | Size | mS/Trans | TpS | Mb/Sec | Latency mS |\n") ; + printf ("+-------+--------+----------+----------+-----------+------------+\n") ; + + spiFail = FALSE ; + spiSetup (speed * 1000000) ; + for (size = 1 ; size <= MAX_SIZE ; size *= 2) + { + printf ("| %5d | %6d ", speed, size) ; + + start = millis () ; + for (times = 0 ; times < NUM_TIMES ; ++times) + if (wiringPiSPIDataRW (SPI_CHAN, myData, size) == -1) + { + printf ("SPI failure: %s\n", strerror (errno)) ; + spiFail = TRUE ; + break ; + } + end = millis () ; + + if (spiFail) + break ; + + timePerTransaction = ((double)(end - start) / (double)NUM_TIMES) / 1000.0 ; + dataSpeed = (double)(size * 8) / (1024.0 * 1024.0) / timePerTransaction ; + perfectTimePerTransaction = ((double)(size * 8)) / ((double)(speed * 1000000)) ; + + printf ("| %8.3f ", timePerTransaction * 1000.0) ; + printf ("| %8.1f ", 1.0 / timePerTransaction) ; + printf ("| %9.5f ", dataSpeed) ; + printf ("| %8.5f ", (timePerTransaction - perfectTimePerTransaction) * 1000.0) ; + printf ("|\n") ; + + } + + close (myFd) ; + printf ("+-------+--------+----------+----------+-----------+------------+\n") ; + printf ("\n") ; + } + + return 0 ; +} diff --git a/gpio/Makefile b/gpio/Makefile index a043962..7dcd090 100644 --- a/gpio/Makefile +++ b/gpio/Makefile @@ -1,9 +1,10 @@ # # Makefile: -# wiringPi - Wiring Compatable library for the Raspberry Pi +# The gpio command: +# A swiss-army knige of GPIO shenanigans. # https://projects.drogon.net/wiring-pi # -# Copyright (c) 2012 Gordon Henderson +# Copyright (c) 2012-2015 Gordon Henderson ################################################################################# # This file is part of wiringPi: # Wiring Compatable library for the Raspberry Pi @@ -22,59 +23,79 @@ # along with wiringPi. If not, see . ################################################################################# +DESTDIR?=/usr +PREFIX?=/local + +ifneq ($V,1) +Q ?= @ +endif #DEBUG = -g -O0 DEBUG = -O2 CC = gcc -INCLUDE = -I/usr/local/include +INCLUDE = -I$(DESTDIR)$(PREFIX)/include CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe -LDFLAGS = -L/usr/local/lib -LIBS = -lwiringPi -lpthread -lm +LDFLAGS = -L$(DESTDIR)$(PREFIX)/lib +LIBS = -lwiringPi -lwiringPiDev -lpthread # May not need to alter anything below this line ############################################################################### -SRC = gpio.c +SRC = gpio.c readall.c pins.c OBJ = $(SRC:.c=.o) all: gpio -gpio: gpio.o - @echo [Link] - @$(CC) -o $@ gpio.o $(LDFLAGS) $(LIBS) - +version.h: ../VERSION + $Q echo Need to run newVersion above. + +gpio: $(OBJ) + $Q echo [Link] + $Q $(CC) -o $@ $(OBJ) $(LDFLAGS) $(LIBS) + .c.o: - @echo [Compile] $< - @$(CC) -c $(CFLAGS) $< -o $@ + $Q echo [Compile] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ -.PHONEY: clean +.PHONY: clean clean: - rm -f $(OBJ) gpio *~ core tags *.bak + $Q echo "[Clean]" + $Q rm -f $(OBJ) gpio *~ core tags *.bak -.PHONEY: tags +.PHONY: tags tags: $(SRC) - @echo [ctags] - @ctags $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) -.PHONEY: install -install: - @echo "[Install]" - @cp gpio /usr/local/bin - @chown root.root /usr/local/bin/gpio - @chmod 4755 /usr/local/bin/gpio - @mkdir -p /usr/local/man/man1 - @cp gpio.1 /usr/local/man/man1 +.PHONY: install +install: gpio + $Q echo "[Install]" + $Q cp gpio $(DESTDIR)$(PREFIX)/bin +ifneq ($(WIRINGPI_SUID),0) + $Q chown root.root $(DESTDIR)$(PREFIX)/bin/gpio + $Q chmod 4755 $(DESTDIR)$(PREFIX)/bin/gpio +endif + $Q mkdir -p $(DESTDIR)$(PREFIX)/man/man1 + $Q cp gpio.1 $(DESTDIR)$(PREFIX)/man/man1 -.PHONEY: uninstall +.PHONY: install-deb +install-deb: gpio + $Q echo "[Install: deb]" + $Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/bin + $Q install -m 0755 gpio ~/wiringPi/debian-template/wiringPi/usr/bin + +.PHONY: uninstall uninstall: - @echo "[UnInstall]" - @rm -f /usr/local/bin/gpio - @rm -f /usr/local/man/man1/gpio.1 + $Q echo "[UnInstall]" + $Q rm -f $(DESTDIR)$(PREFIX)/bin/gpio + $Q rm -f $(DESTDIR)$(PREFIX)/man/man1/gpio.1 -.PHONEY: depend +.PHONY: depend depend: makedepend -Y $(SRC) # DO NOT DELETE + +gpio.o: version.h diff --git a/gpio/gpio.1 b/gpio/gpio.1 index ec65519..e5fe181 100644 --- a/gpio/gpio.1 +++ b/gpio/gpio.1 @@ -1,19 +1,23 @@ -.TH "GPIO" "21st October 2012" "Command-Line access to Raspberry Pi and PiFace GPIO" +.TH GPIO 1 "September 2015" wiringPi "Command-Line access to Raspberry Pi's GPIO" .SH NAME -gpio \- Command-line access to Raspberry Pi and PiFace GPIO +gpio \- Command-line access to Raspberry Pi's GPIO .SH SYNOPSIS .B gpio .B \-v .PP .B gpio -.B [ \-g ] -.B read/write/wb/pwm/clock/mode ... +.B [ \-g | \-1 ] +.B mode/read/write/aread/awrite/wb/pwm/clock ... +.PP +.B gpio +.B [ \-x extension:params ] +.B mode/read/write/aread/awrite/pwm/pwmTone ... .PP .B gpio .B [ \-p ] -.B read/write/wb +.B read/write/toggle/wb .B ... .PP .B gpio @@ -27,10 +31,18 @@ gpio \- Command-line access to Raspberry Pi and PiFace GPIO .B ... .PP .B gpio +.B wfi +.B ... +.PP +.B gpio .B drive group value .PP .B gpio +.B usbp +high | low +.PP +.B gpio .B pwm-bal/pwm-ms .PP .B gpio @@ -73,12 +85,28 @@ Output the current version including the board revision of the Raspberry Pi. .TP .B \-g Use the BCM_GPIO pins numbers rather than wiringPi pin numbers. -\fINOTE:\fR The BCM_GPIO pin numbers are always used with the +\fINote:\fR The BCM_GPIO pin numbers are always used with the export and edge commands. +.TP +.B \-1 +Use the physical pin numbers rather than wiringPi pin numbers. +\fINote:\fR that this applies to the P1 connector only. It is not possible to +use pins on the Revision 2 P5 connector this way, and as with \-g the +BCM_GPIO pin numbers are always used with the export and edge commands. + +.TP +.B \-x extension +This causes the named extension to be initialised. Extensions +comprise of a name (e.g. mcp23017) followed by a colon, then the +pin-base, then more optional parameters depending on the extension type. +See the web page on http://wiringpi.com/the-gpio-utility/ + .TP .B \-p -Use the PiFace interface board and its corresponding pin numbers. +Use the PiFace interface board and its corresponding pin numbers. The PiFace +will always appear at pin number 200 in the gpio command. You can assign any +pin numbers you like in your own programs though. .TP .B read @@ -90,6 +118,28 @@ respective logic levels. Write the given value (0 or 1) to the pin. You need to set the pin to output mode first. +.TP +.B aread +Read the analog value of the given pin. This needs to be uses in +conjunction with a -x flag to add in an extension that handles analog +inputs. respective logic levels. + +e.g. gpio -x mcp3002:200:0 aread 200 + +will read the first analog input on an mcp3002 SPI ADC chip. + +.TP +.B awrite +Write the analog value to the given pin. This needs to be used in +conjunction with a -x flag to add in an extension that handles analog +inputs. respective logic levels. + +e.g. gpio -x mcp4802:200:0 awrite 200 128 + +will write the value 128 to the first DAC port on an mcp4802 chip on +the Pi's SPI bus 0. + + .TP .B wb Write the given byte to the 8 main GPIO pins. You can prefix it with 0x @@ -102,6 +152,10 @@ Output a table of all GPIO pins values. The values represent the actual values r if the pin is in input mode, or the last value written if the pin is in output mode. +The readall command is usable with an extension module (via the -x parameter), +but it's unable to determine pin modes or states, so will perform both a +digital and analog read on each pin in-turn. + .TP .B pwm Write a PWM value (0-1023) to the given pin. The pin needs to be put @@ -118,6 +172,8 @@ Set a pin into \fIinput\fR, \fIoutput\fR or \fIpwm\fR mode. Can also use the literals \fIup\fR, \fIdown\fR or \fItri\fR to set the internal pull-up, pull-down or tristate (off) controls. +The ALT modes can also be set using \fIalt0\fR, \fIalt1\fR, ... \fIalt5\fR. + .TP .B unexportall Un-Export all the GPIO pins in the /sys/class/gpio directory. @@ -129,9 +185,11 @@ Print a list (if any) of all the exported GPIO pins and their current values. .TP .B export Export a GPIO pin in the \fI/sys/class/gpio\fR directory. Use like the -mode command above however only \fIin\fR and \fIout\fR are supported at -this time. Note that the pin number is the \fBBCM_GPIO\fR number and -not the wiringPi number. +mode command above however only \fIin\fR, \fIout\fR, \fIhigh\fR and +\fRlow\fR are supported at this time. Note that the pin number is the +\fBBCM_GPIO\fR number and not the wiringPi number. The \fIhigh\fR and +\fIlow\fR commands pre-set the output value at the same time as the +export to output mode. Once a GPIO pin has been exported, the \fBgpio\fR program changes the ownership of the \fI/sys/class/gpio/gpioX/value\fR and if present in @@ -157,6 +215,12 @@ requiring root/sudo. .B unexport Un-Export a GPIO pin in the /sys/class/gpio directory. +.TP +.B wfi +This set the given pin to the supplied interrupt mode: rising, falling +or both then waits for the interrupt to happen. It's a non-busy wait, +so does not consume and CPU while it's waiting. + .TP .B drive group value @@ -165,6 +229,13 @@ Change the pad driver value for the given pad group to the supplied drive value. Group is 0, 1 or 2 and value is 0-7. Do not use unless you are absolutely sure you know what you're doing. +.TP +.B usbp +high | low + +Change the USB current limiter to high (1.2 amps) or low (the default, 600mA) +This is only applicable to the model B+ + .TP .B pwm-bal/pwm-ms Change the PWM mode to balanced (the default) or mark:space ratio (traditional) @@ -177,15 +248,27 @@ Change the PWM range register. The default is 1024. .B load i2c [baudrate] This loads the i2c or drivers into the kernel and changes the permissions on the associated /dev/ entries so that the current user has access to -them. Optionally it will set the I2C baudrate to that supplied (or as -close as the Pi can manage) The default speed is 100Kb/sec. +them. Optionally it will set the I2C baudrate to that supplied in Kb/sec +(or as close as the Pi can manage) The default speed is 100Kb/sec. + +Note: On recent kernels with the device tree enabled you should use the +raspi-config program to load/unload the I2C device at boot time. +(or disable the device tree to continue to use this method) .TP -.B load spi [buffer size in KB] +.B load spi This loads the spi drivers into the kernel and changes the permissions on the associated /dev/ entries so that the current user has access to -them. Optionally it will set the SPI buffer size to that supplied. The -default is 4KB. +them. It used to have the ability to change the buffer size from the +default of 4096 bytes to an arbitrary value, however for some time the +Pi Foundation have compiled the SPI device driver into the kernel and +this has fixed the buffer size. The way to change it now is to edit +the /boot/cmdline.txt file and add on spdev.bufsiz=8192 to set it to +e.g. 8192 bytes then reboot. + +Note: On recent kernels with the device tree enabled you should use the +raspi-config program to load/unload the SPI device at boot time. +(or disable the device tree to continue to use this method) .TP .B gbr @@ -203,41 +286,12 @@ SPI digital to analogue converter. The board jumpers need to be in-place to do this operation. -.SH "WiringPi vs. BCM_GPIO Pin numbering" +.SH "WiringPi vs. BCM_GPIO Pin numbering vs. Physical pin numbering" .PP -.TS -r r r l. -WiringPi GPIO-r1 GPIO-r2 Function -_ -0 17 17 -1 18 18 (PWM) -2 21 27 -3 22 22 -4 23 23 -5 24 24 -6 25 25 -7 4 4 -8 0 2 I2C: SDA0 -9 1 3 I2C: SCL0 -10 8 8 SPI: CE0 -11 7 7 SPI: CE1 -12 10 10 SPI: MOSI -13 9 9 SPI: MISO -14 11 11 SPI: SCLK -15 14 14 TxD -16 15 16 RxD -17 - 28 -18 - 29 -19 - 30 -20 - 31 -.TE - -Note that "r1" and "r2" above refers to the board revision. Normally -wiringPi detects the correct board revision with use for it's own -numbering scheme, but if you are using a Revision 2 board with some -of the pins which change numbers between revisions you will need -to alter your software. +The quickest way to get a list of the pin differences is to run the command +.TP +gpio readall .SH FILES @@ -267,12 +321,24 @@ When using the \fIexport\fR, \fIedge\fR or \fIunexport\fR commands, the pin numbers are \fBalways\fR native BCM_GPIO numbers and never wiringPi pin numbers. +As of kernels 4.1.7, a user-level GPIO access mechanism is available, +however wiringPi will not use this by default - because at this time +there appears to be issues when trying to program the PWM or clock output +hardware. If you can live without PWM or GPIO clocks and you want to use +the GPIO from a non-root program, then you need to make sure that the +module \fIbcm2835_gpiomem\fR is loaded at boot time. This should happen +automatically when you enable the device tree in raspi-config. You may +also need some additional information in /etc/udev/rules.d/ to change the +mode and ownership of the /dev/gpiomem file. Finally, you need to set +the environment variable \fIWIRINGPI_GPIOMEM\fR. This will go-away +in future releases once the /dev/gpiomem interface is fully operational. + .SH "SEE ALSO" .LP WiringPi's home page .IP -https://projects.drogon.net/raspberry-pi/wiringpi/ +http://wiringpi.com/ .SH AUTHOR @@ -284,7 +350,7 @@ Please report bugs to .SH COPYRIGHT -Copyright (c) 2012 Gordon Henderson +Copyright (c) 2012-2015 Gordon Henderson This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/gpio/gpio.c b/gpio/gpio.c index e71e432..6c95b21 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -2,7 +2,7 @@ * gpio.c: * Swiss-Army-Knife, Set-UID command-line interface to the Raspberry * Pi's GPIO. - * Copyright (c) 2012 Gordon Henderson + * Copyright (c) 2012-2015 Gordon Henderson *********************************************************************** * This file is part of wiringPi: * https://projects.drogon.net/raspberry-pi/wiringpi/ @@ -26,42 +26,81 @@ #include #include #include +#include #include #include #include -#include #include +#include +#include #include +#include + #include +#include + +#include "version.h" extern int wiringPiDebug ; +// External functions I can't be bothered creating a separate .h file for: + +extern void doReadall (void) ; +extern void doPins (void) ; + #ifndef TRUE # define TRUE (1==1) # define FALSE (1==2) #endif -#define VERSION "1.12" +#define PI_USB_POWER_CONTROL 38 +#define I2CDETECT "/usr/sbin/i2cdetect" -static int wpMode ; +int wpMode ; char *usage = "Usage: gpio -v\n" " gpio -h\n" - " gpio [-g] ...\n" + " gpio [-g|-1] [-x extension:params] ...\n" " gpio [-p] ...\n" - " gpio readall\n" - " gpio unexportall/exports ...\n" + " gpio ...\n" + " gpio readall/reset\n" + " gpio unexportall/exports\n" " gpio export/edge/unexport ...\n" + " gpio wfi \n" " gpio drive \n" " gpio pwm-bal/pwm-ms \n" " gpio pwmr \n" " gpio pwmc \n" " gpio load spi/i2c\n" + " gpio unload spi/i2c\n" + " gpio i2cd/i2cdetect\n" + " gpio usbp high/low\n" " gpio gbr \n" " gpio gbw " ; // No trailing newline needed here. +#ifdef NOT_FOR_NOW +/* + * decodePin: + * Decode a pin "number" which can actually be a pin name to represent + * one of the Pi's on-board pins. + ********************************************************************************* + */ + +static int decodePin (const char *str) +{ + +// The first case - see if it's a number: + + if (isdigit (str [0])) + return atoi (str) ; + + return 0 ; +} +#endif + + /* * changeOwner: * Change the ownership of the file to the real userId of the calling @@ -77,12 +116,9 @@ static void changeOwner (char *cmd, char *file) if (chown (file, uid, gid) != 0) { if (errno == ENOENT) // Warn that it's not there - fprintf (stderr, "%s: Warning: File not present: %s\n", cmd, file) ; + fprintf (stderr, "%s: Warning (not an error, do not report): File not present: %s\n", cmd, file) ; else - { - fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ; - exit (1) ; - } + fprintf (stderr, "%s: Warning (not an error): Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ; } } @@ -127,9 +163,25 @@ static int moduleLoaded (char *modName) ********************************************************************************* */ +static void checkDevTree (char *argv []) +{ + struct stat statBuf ; + + if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ... + { + fprintf (stderr, +"%s: Unable to load/unload modules as this Pi has the device tree enabled.\n" +" You need to run the raspi-config program (as root) and select the\n" +" modules (SPI or I2C) that you wish to load/unload there and reboot.\n" +" There is more information here:\n" +" https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=97314\n", argv [0]) ; + exit (1) ; + } +} + static void _doLoadUsage (char *argv []) { - fprintf (stderr, "Usage: %s load [SPI bufferSize in KB | I2C baudrate in Kb/sec]\n", argv [0]) ; + fprintf (stderr, "Usage: %s load [I2C baudrate in Kb/sec]\n", argv [0]) ; exit (1) ; } @@ -140,6 +192,8 @@ static void doLoad (int argc, char *argv []) char *file1, *file2 ; char args1 [32], args2 [32] ; + checkDevTree (argv) ; + if (argc < 3) _doLoadUsage (argv) ; @@ -152,7 +206,10 @@ static void doLoad (int argc, char *argv []) file1 = "/dev/spidev0.0" ; file2 = "/dev/spidev0.1" ; if (argc == 4) - sprintf (args1, " bufsiz=%d", atoi (argv [3]) * 1024) ; + { + fprintf (stderr, "%s: Unable to set the buffer size now. Load aborted. Please see the man page.\n", argv [0]) ; + exit (1) ; + } else if (argc > 4) _doLoadUsage (argv) ; } @@ -172,13 +229,13 @@ static void doLoad (int argc, char *argv []) if (!moduleLoaded (module1)) { - sprintf (cmd, "modprobe %s%s", module1, args1) ; + sprintf (cmd, "/sbin/modprobe %s%s", module1, args1) ; system (cmd) ; } if (!moduleLoaded (module2)) { - sprintf (cmd, "modprobe %s%s", module2, args2) ; + sprintf (cmd, "/sbin/modprobe %s%s", module2, args2) ; system (cmd) ; } @@ -196,46 +253,82 @@ static void doLoad (int argc, char *argv []) /* - * doReadall: - * Read all the GPIO pins + * doUnLoad: + * Un-Load either the spi or i2c modules and change device ownerships, etc. ********************************************************************************* */ -static char *pinNames [] = +static void _doUnLoadUsage (char *argv []) { - "GPIO 0", "GPIO 1", "GPIO 2", "GPIO 3", "GPIO 4", "GPIO 5", "GPIO 6", "GPIO 7", - "SDA ", "SCL ", - "CE0 ", "CE1 ", "MOSI ", "MISO ", "SCLK ", - "TxD ", "RxD ", - "GPIO 8", "GPIO 9", "GPIO10", "GPIO11", -} ; + fprintf (stderr, "Usage: %s unload \n", argv [0]) ; + exit (1) ; +} -static char *alts [] = +static void doUnLoad (int argc, char *argv []) { - "IN ", "OUT ", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3" -} ; + char *module1, *module2 ; + char cmd [80] ; -static void doReadall (void) -{ - int pin ; + checkDevTree (argv) ; - printf ("+----------+------+--------+------+-------+\n") ; - printf ("| wiringPi | GPIO | Name | Mode | Value |\n") ; - printf ("+----------+------+--------+------+-------+\n") ; + if (argc != 3) + _doUnLoadUsage (argv) ; - for (pin = 0 ; pin < 64 ; ++pin) + /**/ if (strcasecmp (argv [2], "spi") == 0) { - if (wpiPinToGpio (pin) == -1) - continue ; + module1 = "spidev" ; + module2 = "spi_bcm2708" ; + } + else if (strcasecmp (argv [2], "i2c") == 0) + { + module1 = "i2c_dev" ; + module2 = "i2c_bcm2708" ; + } + else + _doUnLoadUsage (argv) ; - printf ("| %6d | %3d | %s | %s | %s |\n", - pin, wpiPinToGpio (pin), - pinNames [pin], - alts [getAlt (pin)], - digitalRead (pin) == HIGH ? "High" : "Low ") ; + if (moduleLoaded (module1)) + { + sprintf (cmd, "/sbin/rmmod %s", module1) ; + system (cmd) ; } - printf ("+----------+------+--------+------+-------+\n") ; + if (moduleLoaded (module2)) + { + sprintf (cmd, "/sbin/rmmod %s", module2) ; + system (cmd) ; + } +} + + +/* + * doI2Cdetect: + * Run the i2cdetect command with the right runes for this Pi revision + ********************************************************************************* + */ + +static void doI2Cdetect (int argc, char *argv []) +{ + int port = piBoardRev () == 1 ? 0 : 1 ; + char command [128] ; + struct stat statBuf ; + + if (stat (I2CDETECT, &statBuf) < 0) + { + fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ; + return ; + } + + if (!moduleLoaded ("i2c_dev")) + { + fprintf (stderr, "%s: The I2C kernel module(s) are not loaded.\n", argv [0]) ; + return ; + } + + sprintf (command, "%s -y %d", I2CDETECT, port) ; + if (system (command) < 0) + fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ; + } @@ -252,9 +345,7 @@ static void doExports (int argc, char *argv []) char fName [128] ; char buf [16] ; -// Rather crude, but who knows what others are up to... - - for (first = 0, i = 0 ; i < 64 ; ++i) + for (first = 0, i = 0 ; i < 64 ; ++i) // Crude, but effective { // Try to read the direction @@ -363,19 +454,23 @@ void doExport (int argc, char *argv []) exit (1) ; } - /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0)) + /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0)) fprintf (fd, "in\n") ; - else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0)) + else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0)) fprintf (fd, "out\n") ; + else if ((strcasecmp (mode, "high") == 0) || (strcasecmp (mode, "up") == 0)) + fprintf (fd, "high\n") ; + else if ((strcasecmp (mode, "low") == 0) || (strcasecmp (mode, "down") == 0)) + fprintf (fd, "low\n") ; else { - fprintf (stderr, "%s: Invalid mode: %s. Should be in or out\n", argv [1], mode) ; + fprintf (stderr, "%s: Invalid mode: %s. Should be in, out, high or low\n", argv [1], mode) ; exit (1) ; } fclose (fd) ; -// Change ownership so the current user can actually use it! +// Change ownership so the current user can actually use it sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; changeOwner (argv [0], fName) ; @@ -386,6 +481,52 @@ void doExport (int argc, char *argv []) } +/* + * doWfi: + * gpio wfi pin mode + * Wait for Interrupt on a given pin. + * Slight cheat here - it's easier to actually use ISR now (which calls + * gpio to set the pin modes!) then we simply sleep, and expect the thread + * to exit the program. Crude but effective. + ********************************************************************************* + */ + +static void wfi (void) + { exit (0) ; } + +void doWfi (int argc, char *argv []) +{ + int pin, mode ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s wfi pin mode\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + + /**/ if (strcasecmp (argv [3], "rising") == 0) mode = INT_EDGE_RISING ; + else if (strcasecmp (argv [3], "falling") == 0) mode = INT_EDGE_FALLING ; + else if (strcasecmp (argv [3], "both") == 0) mode = INT_EDGE_BOTH ; + else + { + fprintf (stderr, "%s: wfi: Invalid mode: %s. Should be rising, falling or both\n", argv [1], argv [3]) ; + exit (1) ; + } + + if (wiringPiISR (pin, mode, &wfi) < 0) + { + fprintf (stderr, "%s: wfi: Unable to setup ISR: %s\n", argv [1], strerror (errno)) ; + exit (1) ; + } + + for (;;) + delay (9999) ; +} + + + /* * doEdge: * gpio edge pin mode @@ -499,7 +640,7 @@ void doUnexport (int argc, char *argv []) ********************************************************************************* */ -void doUnexportall (int argc, char *argv []) +void doUnexportall (char *progName) { FILE *fd ; int pin ; @@ -508,7 +649,7 @@ void doUnexportall (int argc, char *argv []) { if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL) { - fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ; + fprintf (stderr, "%s: Unable to open GPIO export interface\n", progName) ; exit (1) ; } fprintf (fd, "%d\n", pin) ; @@ -517,6 +658,20 @@ void doUnexportall (int argc, char *argv []) } +/* + * doReset: + * Reset the GPIO pins - as much as we can do + ********************************************************************************* + */ + +static void doReset (char *progName) +{ + printf ("GPIO Reset is dangerous and has been removed from the gpio command.\n") ; + printf (" - Please write a shell-script to reset the GPIO pins into the state\n") ; + printf (" that you need them in for your applications.\n") ; +} + + /* * doMode: * gpio mode pin mode ... @@ -536,18 +691,25 @@ void doMode (int argc, char *argv []) pin = atoi (argv [2]) ; - if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) - return ; - mode = argv [3] ; - /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ; - else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ; - else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ; - else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ; - else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ; - else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ; - else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ; + /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ; + else if (strcasecmp (mode, "input") == 0) pinMode (pin, INPUT) ; + else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ; + else if (strcasecmp (mode, "output") == 0) pinMode (pin, OUTPUT) ; + else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ; + else if (strcasecmp (mode, "pwmTone") == 0) pinMode (pin, PWM_TONE_OUTPUT) ; + else if (strcasecmp (mode, "clock") == 0) pinMode (pin, GPIO_CLOCK) ; + else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ; + else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ; + else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ; + else if (strcasecmp (mode, "off") == 0) pullUpDnControl (pin, PUD_OFF) ; + else if (strcasecmp (mode, "alt0") == 0) pinModeAlt (pin, 0b100) ; + else if (strcasecmp (mode, "alt1") == 0) pinModeAlt (pin, 0b101) ; + else if (strcasecmp (mode, "alt2") == 0) pinModeAlt (pin, 0b110) ; + else if (strcasecmp (mode, "alt3") == 0) pinModeAlt (pin, 0b111) ; + else if (strcasecmp (mode, "alt4") == 0) pinModeAlt (pin, 0b011) ; + else if (strcasecmp (mode, "alt5") == 0) pinModeAlt (pin, 0b010) ; else { fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/clock/up/down/tri\n", argv [1], mode) ; @@ -591,6 +753,58 @@ static void doPadDrive (int argc, char *argv []) } +/* + * doUsbP: + * Control USB Power - High (1.2A) or Low (600mA) + * gpio usbp high/low + ********************************************************************************* + */ + +static void doUsbP (int argc, char *argv []) +{ + int model, rev, mem, maker, overVolted ; + + if (argc != 3) + { + fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ; + exit (1) ; + } + +// Make sure we're on a B+ + + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; + + if (model != PI_MODEL_BP) + { + fprintf (stderr, "USB power contol is applicable to B+ boards only.\n") ; + exit (1) ; + } + +// Need to force BCM_GPIO mode: + + wiringPiSetupGpio () ; + + if ((strcasecmp (argv [2], "high") == 0) || (strcasecmp (argv [2], "hi") == 0)) + { + digitalWrite (PI_USB_POWER_CONTROL, 1) ; + pinMode (PI_USB_POWER_CONTROL, OUTPUT) ; + printf ("Switched to HIGH current USB (1.2A)\n") ; + return ; + } + + if ((strcasecmp (argv [2], "low") == 0) || (strcasecmp (argv [2], "lo") == 0)) + { + digitalWrite (PI_USB_POWER_CONTROL, 0) ; + pinMode (PI_USB_POWER_CONTROL, OUTPUT) ; + printf ("Switched to LOW current USB (600mA)\n") ; + return ; + } + + fprintf (stderr, "Usage: %s usbp high|low\n", argv [0]) ; + exit (1) ; +} + + /* * doGbw: * gpio gbw channel value @@ -604,7 +818,7 @@ static void doGbw (int argc, char *argv []) if (argc != 4) { - fprintf (stderr, "Usage: %s gbr \n", argv [0]) ; + fprintf (stderr, "Usage: %s gbw \n", argv [0]) ; exit (1) ; } @@ -613,23 +827,23 @@ static void doGbw (int argc, char *argv []) if ((channel < 0) || (channel > 1)) { - fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ; + fprintf (stderr, "%s: gbw: Channel number must be 0 or 1\n", argv [0]) ; exit (1) ; } - if ((value < 0) || (value > 1023)) + if ((value < 0) || (value > 255)) { - fprintf (stderr, "%s: value must be from 0 to 255\n", argv [0]) ; + fprintf (stderr, "%s: gbw: Value must be from 0 to 255\n", argv [0]) ; exit (1) ; } - if (gertboardSPISetup () == -1) + if (gertboardAnalogSetup (64) < 0) { fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ; exit (1) ; } - gertboardAnalogWrite (channel, value) ; + analogWrite (64 + channel, value) ; } @@ -654,21 +868,20 @@ static void doGbr (int argc, char *argv []) if ((channel < 0) || (channel > 1)) { - fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ; + fprintf (stderr, "%s: gbr: Channel number must be 0 or 1\n", argv [0]) ; exit (1) ; } - if (gertboardSPISetup () == -1) + if (gertboardAnalogSetup (64) < 0) { fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ; exit (1) ; } - printf ("%d\n",gertboardAnalogRead (channel)) ; + printf ("%d\n", analogRead (64 + channel)) ; } - /* * doWrite: * gpio write pin value @@ -687,9 +900,6 @@ static void doWrite (int argc, char *argv []) pin = atoi (argv [2]) ; - if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) - return ; - /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0)) val = 1 ; else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0)) @@ -703,6 +913,31 @@ static void doWrite (int argc, char *argv []) digitalWrite (pin, HIGH) ; } + +/* + * doAwriterite: + * gpio awrite pin value + ********************************************************************************* + */ + +static void doAwrite (int argc, char *argv []) +{ + int pin, val ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s awrite pin value\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + + val = atoi (argv [3]) ; + + analogWrite (pin, val) ; +} + + /* * doWriteByte: * gpio write value @@ -742,19 +977,75 @@ void doRead (int argc, char *argv []) } pin = atoi (argv [2]) ; - - if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) - { - printf ("0\n") ; - return ; - } - val = digitalRead (pin) ; printf ("%s\n", val == 0 ? "0" : "1") ; } +/* + * doAread: + * Read an analog pin and return the value + ********************************************************************************* + */ + +void doAread (int argc, char *argv []) +{ + if (argc != 3) + { + fprintf (stderr, "Usage: %s aread pin\n", argv [0]) ; + exit (1) ; + } + + printf ("%d\n", analogRead (atoi (argv [2]))) ; +} + + +/* + * doToggle: + * Toggle an IO pin + ********************************************************************************* + */ + +void doToggle (int argc, char *argv []) +{ + int pin ; + + if (argc != 3) + { + fprintf (stderr, "Usage: %s toggle pin\n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + + digitalWrite (pin, !digitalRead (pin)) ; +} + + +/* + * doPwmTone: + * Output a tone in a PWM pin + ********************************************************************************* + */ + +void doPwmTone (int argc, char *argv []) +{ + int pin, freq ; + + if (argc != 4) + { + fprintf (stderr, "Usage: %s pwmTone \n", argv [0]) ; + exit (1) ; + } + + pin = atoi (argv [2]) ; + freq = atoi (argv [3]) ; + + pwmToneWrite (pin, freq) ; +} + + /* * doClock: * Output a clock on a pin @@ -773,9 +1064,6 @@ void doClock (int argc, char *argv []) pin = atoi (argv [2]) ; - if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) - return ; - freq = atoi (argv [3]) ; gpioClockSet (pin, freq) ; @@ -800,9 +1088,6 @@ void doPwm (int argc, char *argv []) pin = atoi (argv [2]) ; - if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS))) - return ; - val = atoi (argv [3]) ; pwmWrite (pin, val) ; @@ -863,6 +1148,56 @@ static void doPwmClock (int argc, char *argv []) } +/* + * doVersion: + * Handle the ever more complicated version command + ********************************************************************************* + */ + +static void doVersion (char *argv []) +{ + int model, rev, mem, maker, warranty ; + struct stat statBuf ; + + printf ("gpio version: %s\n", VERSION) ; + printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ; + printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ; + printf ("For details type: %s -warranty\n", argv [0]) ; + printf ("\n") ; + piBoardId (&model, &rev, &mem, &maker, &warranty) ; + +/************* + if (model == PI_MODEL_UNKNOWN) + { + printf ("Your Raspberry Pi has an unknown model type. Please report this to\n") ; + printf (" projects@drogon.net\n") ; + printf ("with a copy of your /proc/cpuinfo if possible\n") ; + } + else +***************/ + + { + printf ("Raspberry Pi Details:\n") ; + printf (" Type: %s, Revision: %s, Memory: %dMB, Maker: %s %s\n", + piModelNames [model], piRevisionNames [rev], piMemorySize [mem], piMakerNames [maker], warranty ? "[Out of Warranty]" : "") ; + +// Check for device tree + + if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ... + printf (" Device tree is enabled.\n") ; + + if (stat ("/dev/gpiomem", &statBuf) == 0) // User level GPIO is GO + { + printf (" This Raspberry Pi supports user-level GPIO access.\n") ; + printf (" -> See the man-page for more details\n") ; + } + else + printf (" * Root or sudo required for GPIO access.\n") ; + + } +} + + /* * main: * Start here @@ -885,27 +1220,35 @@ int main (int argc, char *argv []) return 1 ; } +// Help + if (strcasecmp (argv [1], "-h") == 0) { printf ("%s: %s\n", argv [0], usage) ; return 0 ; } - if (strcasecmp (argv [1], "-v") == 0) +// Version & Warranty +// Wish I could remember why I have both -R and -V ... + + if ((strcmp (argv [1], "-R") == 0) || (strcmp (argv [1], "-V") == 0)) { - printf ("gpio version: %s\n", VERSION) ; - printf ("Copyright (c) 2012 Gordon Henderson\n") ; - printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ; - printf ("For details type: %s -warranty\n", argv [0]) ; - printf ("\n") ; - printf ("This Raspberry Pi is a revision %d board.\n", piBoardRev ()) ; + printf ("%d\n", piBoardRev ()) ; + return 0 ; + } + +// Version and information + + if (strcmp (argv [1], "-v") == 0) + { + doVersion (argv) ; return 0 ; } if (strcasecmp (argv [1], "-warranty") == 0) { printf ("gpio version: %s\n", VERSION) ; - printf ("Copyright (c) 2012 Gordon Henderson\n") ; + printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ; printf ("\n") ; printf (" This program is free software; you can redistribute it and/or modify\n") ; printf (" it under the terms of the GNU Leser General Public License as published\n") ; @@ -934,12 +1277,13 @@ int main (int argc, char *argv []) /**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; } else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; } else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; } - else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argc, argv) ; return 0 ; } else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; } + else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argv [0]) ; return 0 ; } // Check for load command: - if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; } + if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; } + if (strcasecmp (argv [1], "unload" ) == 0) { doUnLoad (argc, argv) ; return 0 ; } // Gertboard commands @@ -948,13 +1292,9 @@ int main (int argc, char *argv []) // Check for -g argument - if (strcasecmp (argv [1], "-g") == 0) + /**/ if (strcasecmp (argv [1], "-g") == 0) { - if (wiringPiSetupGpio () == -1) - { - fprintf (stderr, "%s: Unable to initialise GPIO mode.\n", argv [0]) ; - exit (1) ; - } + wiringPiSetupGpio () ; for (i = 2 ; i < argc ; ++i) argv [i - 1] = argv [i] ; @@ -962,15 +1302,23 @@ int main (int argc, char *argv []) wpMode = WPI_MODE_GPIO ; } +// Check for -1 argument + + else if (strcasecmp (argv [1], "-1") == 0) + { + wiringPiSetupPhys () ; + + for (i = 2 ; i < argc ; ++i) + argv [i - 1] = argv [i] ; + --argc ; + wpMode = WPI_MODE_PHYS ; + } + // Check for -p argument for PiFace else if (strcasecmp (argv [1], "-p") == 0) { - if (wiringPiSetupPiFaceForGpioProg () == -1) - { - fprintf (stderr, "%s: Unable to initialise PiFace.\n", argv [0]) ; - exit (1) ; - } + piFaceSetup (200) ; for (i = 2 ; i < argc ; ++i) argv [i - 1] = argv [i] ; @@ -982,38 +1330,69 @@ int main (int argc, char *argv []) else { - if (wiringPiSetup () == -1) - { - fprintf (stderr, "%s: Unable to initialise wiringPi mode\n", argv [0]) ; - exit (1) ; - } + wiringPiSetup () ; wpMode = WPI_MODE_PINS ; } -// Check for PWM or Pad Drive operations +// Check for -x argument to load in a new extension - if (wpMode != WPI_MODE_PIFACE) + if (strcasecmp (argv [1], "-x") == 0) { - if (strcasecmp (argv [1], "pwm-bal") == 0) { doPwmMode (PWM_MODE_BAL) ; return 0 ; } - if (strcasecmp (argv [1], "pwm-ms") == 0) { doPwmMode (PWM_MODE_MS) ; return 0 ; } - if (strcasecmp (argv [1], "pwmr") == 0) { doPwmRange (argc, argv) ; return 0 ; } - if (strcasecmp (argv [1], "pwmc") == 0) { doPwmClock (argc, argv) ; return 0 ; } - if (strcasecmp (argv [1], "drive") == 0) { doPadDrive (argc, argv) ; return 0 ; } + if (argc < 3) + { + fprintf (stderr, "%s: -x missing extension specification.\n", argv [0]) ; + exit (EXIT_FAILURE) ; + } + + if (!loadWPiExtension (argv [0], argv [2], TRUE)) // Prints its own error messages + exit (EXIT_FAILURE) ; + + for (i = 3 ; i < argc ; ++i) + argv [i - 2] = argv [i] ; + argc -= 2 ; } -// Check for wiring commands + if (argc <= 1) + { + fprintf (stderr, "%s: no command given\n", argv [0]) ; + exit (EXIT_FAILURE) ; + } - /**/ if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ; - else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ; - else if (strcasecmp (argv [1], "write") == 0) doWrite (argc, argv) ; - else if (strcasecmp (argv [1], "wb") == 0) doWriteByte (argc, argv) ; - else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ; - else if (strcasecmp (argv [1], "clock") == 0) doClock (argc, argv) ; - else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ; +// Core wiringPi functions + + /**/ if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ; + else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ; + else if (strcasecmp (argv [1], "write" ) == 0) doWrite (argc, argv) ; + else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ; + else if (strcasecmp (argv [1], "awrite" ) == 0) doAwrite (argc, argv) ; + else if (strcasecmp (argv [1], "aread" ) == 0) doAread (argc, argv) ; + +// GPIO Nicies + + else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle (argc, argv) ; + +// Pi Specifics + + else if (strcasecmp (argv [1], "pwm-bal" ) == 0) doPwmMode (PWM_MODE_BAL) ; + else if (strcasecmp (argv [1], "pwm-ms" ) == 0) doPwmMode (PWM_MODE_MS) ; + else if (strcasecmp (argv [1], "pwmr" ) == 0) doPwmRange (argc, argv) ; + else if (strcasecmp (argv [1], "pwmc" ) == 0) doPwmClock (argc, argv) ; + else if (strcasecmp (argv [1], "pwmTone" ) == 0) doPwmTone (argc, argv) ; + else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ; + else if (strcasecmp (argv [1], "usbp" ) == 0) doUsbP (argc, argv) ; + else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ; + else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ; + else if (strcasecmp (argv [1], "pins" ) == 0) doPins () ; + else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ; + else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argc, argv) ; + else if (strcasecmp (argv [1], "reset" ) == 0) doReset (argv [0]) ; + else if (strcasecmp (argv [1], "wb" ) == 0) doWriteByte (argc, argv) ; + else if (strcasecmp (argv [1], "clock" ) == 0) doClock (argc, argv) ; + else if (strcasecmp (argv [1], "wfi" ) == 0) doWfi (argc, argv) ; else { fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ; - exit (1) ; + exit (EXIT_FAILURE) ; } return 0 ; } diff --git a/gpio/pins.c b/gpio/pins.c new file mode 100644 index 0000000..d889a45 --- /dev/null +++ b/gpio/pins.c @@ -0,0 +1,33 @@ +/* + * pins.c: + * Just display a handy Pi pinnout diagram. + * Copyright (c) 2012-2015 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + + +#include + +void doPins (void) +{ + printf ("The pins command has been deprecated - sorry. Please use the\n") ; + printf (" gpio readall\n") ; + printf ("command to get a list of the pinnouts for your Pi.\n") ; +} + diff --git a/gpio/pintest b/gpio/pintest new file mode 100644 index 0000000..4da3d94 --- /dev/null +++ b/gpio/pintest @@ -0,0 +1,187 @@ +#!/bin/bash +# +# pintest +# Test the Pi's GPIO port +# Copyright (c) 2013-2015 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# Wiring Compatable library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + + +# logErr pin, expected got +################################################################################ + +logErr () +{ + if [ $errs = 0 ]; then + echo "" + fi + echo " --> Pin $1 failure. Expected $2, got $3" + let errs+=1 +} + + +# printErrorCount +################################################################################ + +printErrCount() +{ + if [ $errs = 0 ]; then + echo "No faults detected." + elif [ $errs = 1 ]; then + echo "One fault detected." + else + echo "$errs faults detected" + fi +} + + +# testPins start end +################################################################################ + +testPins() +{ + start=$1 + end=$2 + errs=0 + + printf "%30s %2d:%2d: " "$3" $1 $2 + +# Set range to inputs + + for i in `seq $start $end`; do + gpio mode $i in + done + +# Enable internal pull-ups and expect to read high + + for i in `seq $start $end`; do + gpio mode $i up + if [ `gpio read $i` = 0 ]; then + logErr $i 1 0 + fi + done + +# Enable internal pull-downs and expect to read low + + for i in `seq $start $end`; do + gpio mode $i down + if [ `gpio read $i` = 1 ]; then + echo "Pin $i failure - expected 0, got 1" + let errs+=1 + fi + done + +# Remove the internal pull up/downs + + for i in `seq $start $end`; do + gpio mode $i tri + done + + if [ $errs = 0 ]; then + echo " OK" + else + printErrCount + fi + + let totErrs+=errs +} + + +intro() +{ + cat <. + *********************************************************************** + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +extern int wpMode ; + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==2) +#endif + +/* + * doReadallExternal: + * A relatively crude way to read the pins on an external device. + * We don't know the input/output mode of pins, but we can tell + * if it's an analog pin or a digital one... + ********************************************************************************* + */ + +static void doReadallExternal (void) +{ + int pin ; + + printf ("+------+---------+--------+\n") ; + printf ("| Pin | Digital | Analog |\n") ; + printf ("+------+---------+--------+\n") ; + + for (pin = wiringPiNodes->pinBase ; pin <= wiringPiNodes->pinMax ; ++pin) + printf ("| %4d | %4d | %4d |\n", pin, digitalRead (pin), analogRead (pin)) ; + + printf ("+------+---------+--------+\n") ; +} + + +/* + * doReadall: + * Read all the GPIO pins + * We also want to use this to read the state of pins on an externally + * connected device, so we need to do some fiddling with the internal + * wiringPi node structures - since the gpio command can only use + * one external device at a time, we'll use that to our advantage... + ********************************************************************************* + */ + +static char *alts [] = +{ + "IN", "OUT", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3" +} ; + +static int physToWpi [64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 8, -1, + 9, -1, + 7, 15, + -1, 16, + 0, 1, + 2, -1, + 3, 4, + -1, 5, + 12, -1, + 13, 6, + 14, 10, + -1, 11, // 25, 26 + 30, 31, // Actually I2C, but not used + 21, -1, + 22, 26, + 23, -1, + 24, 27, + 25, 28, + -1, 29, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + 17, 18, + 19, 20, + -1, -1, -1, -1, -1, -1, -1, -1, -1 +} ; + +static char *physNames [64] = +{ + NULL, + + " 3.3v", "5v ", + " SDA.1", "5V ", + " SCL.1", "0v ", + "GPIO. 7", "TxD ", + " 0v", "RxD ", + "GPIO. 0", "GPIO. 1", + "GPIO. 2", "0v ", + "GPIO. 3", "GPIO. 4", + " 3.3v", "GPIO. 5", + " MOSI", "0v ", + " MISO", "GPIO. 6", + " SCLK", "CE0 ", + " 0v", "CE1 ", + " SDA.0", "SCL.0 ", + "GPIO.21", "0v ", + "GPIO.22", "GPIO.26", + "GPIO.23", "0v ", + "GPIO.24", "GPIO.27", + "GPIO.25", "GPIO.28", + " 0v", "GPIO.29", + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + "GPIO.17", "GPIO.18", + "GPIO.19", "GPIO.20", + NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, +} ; + + +/* + * readallPhys: + * Given a physical pin output the data on it and the next pin: + *| BCM | wPi | Name | Mode | Val| Physical |Val | Mode | Name | wPi | BCM | + ********************************************************************************* + */ + +static void readallPhys (int physPin) +{ + int pin ; + + if (physPinToGpio (physPin) == -1) + printf (" | | ") ; + else + printf (" | %3d | %3d", physPinToGpio (physPin), physToWpi [physPin]) ; + + printf (" | %s", physNames [physPin]) ; + + if (physToWpi [physPin] == -1) + printf (" | | ") ; + else + { + /**/ if (wpMode == WPI_MODE_GPIO) + pin = physPinToGpio (physPin) ; + else if (wpMode == WPI_MODE_PHYS) + pin = physPin ; + else + pin = physToWpi [physPin] ; + + printf (" | %4s", alts [getAlt (pin)]) ; + printf (" | %d", digitalRead (pin)) ; + } + +// Pin numbers: + + printf (" | %2d", physPin) ; + ++physPin ; + printf (" || %-2d", physPin) ; + +// Same, reversed + + if (physToWpi [physPin] == -1) + printf (" | | ") ; + else + { + /**/ if (wpMode == WPI_MODE_GPIO) + pin = physPinToGpio (physPin) ; + else if (wpMode == WPI_MODE_PHYS) + pin = physPin ; + else + pin = physToWpi [physPin] ; + + printf (" | %d", digitalRead (pin)) ; + printf (" | %-4s", alts [getAlt (pin)]) ; + } + + printf (" | %-5s", physNames [physPin]) ; + + if (physToWpi [physPin] == -1) + printf (" | | ") ; + else + printf (" | %-3d | %-3d", physToWpi [physPin], physPinToGpio (physPin)) ; + + printf (" |\n") ; +} + + +void cmReadall (void) +{ + int pin ; + + printf ("+-----+------+-------+ +-----+------+-------+\n") ; + printf ("| Pin | Mode | Value | | Pin | Mode | Value |\n") ; + printf ("+-----+------+-------+ +-----+------+-------+\n") ; + + for (pin = 0 ; pin < 28 ; ++pin) + { + printf ("| %3d ", pin) ; + printf ("| %-4s ", alts [getAlt (pin)]) ; + printf ("| %s ", digitalRead (pin) == HIGH ? "High" : "Low ") ; + printf ("| ") ; + printf ("| %3d ", pin + 28) ; + printf ("| %-4s ", alts [getAlt (pin + 28)]) ; + printf ("| %s ", digitalRead (pin + 28) == HIGH ? "High" : "Low ") ; + printf ("|\n") ; + } + + printf ("+-----+------+-------+ +-----+------+-------+\n") ; +} + + +/* + * abReadall: + * Read all the pins on the model A or B. + ********************************************************************************* + */ + +void abReadall (int model, int rev) +{ + int pin ; + char *type ; + + if (model == PI_MODEL_A) + type = " A" ; + else + if (rev == PI_VERSION_2) + type = "B2" ; + else + type = "B1" ; + + printf (" +-----+-----+---------+------+---+-Model %s-+---+------+---------+-----+-----+\n", type) ; + printf (" | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |\n") ; + printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ; + for (pin = 1 ; pin <= 26 ; pin += 2) + readallPhys (pin) ; + + if (rev == PI_VERSION_2) // B version 2 + { + printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ; + for (pin = 51 ; pin <= 54 ; pin += 2) + readallPhys (pin) ; + } + + printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ; + printf (" | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |\n") ; + printf (" +-----+-----+---------+------+---+-Model %s-+---+------+---------+-----+-----+\n", type) ; +} + + +/* + * piPlusReadall: + * Read all the pins on the model A+ or the B+ + ********************************************************************************* + */ + +static void plus2header (int model) +{ + /**/ if (model == PI_MODEL_AP) + printf (" +-----+-----+---------+------+---+--A Plus--+---+------+---------+-----+-----+\n") ; + else if (model == PI_MODEL_BP) + printf (" +-----+-----+---------+------+---+--B Plus--+---+------+---------+-----+-----+\n") ; + else if (model == PI_MODEL_ZERO) + printf (" +-----+-----+---------+------+---+-Pi Zero--+---+------+---------+-----+-----+\n") ; + else + printf (" +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+\n") ; +} + + +void piPlusReadall (int model) +{ + int pin ; + + plus2header (model) ; + + printf (" | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |\n") ; + printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ; + for (pin = 1 ; pin <= 40 ; pin += 2) + readallPhys (pin) ; + printf (" +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+\n") ; + printf (" | BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |\n") ; + + plus2header (model) ; +} + + +void doReadall (void) +{ + int model, rev, mem, maker, overVolted ; + + if (wiringPiNodes != NULL) // External readall + { + doReadallExternal () ; + return ; + } + + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; + + /**/ if ((model == PI_MODEL_A) || (model == PI_MODEL_B)) + abReadall (model, rev) ; + else if ((model == PI_MODEL_BP) || (model == PI_MODEL_AP) || (model == PI_MODEL_2) || (model == PI_MODEL_ZERO)) + piPlusReadall (model) ; + else if (model == PI_MODEL_CM) + cmReadall () ; + else + printf ("Oops - unable to determine board type... model: %d\n", model) ; +} diff --git a/gpio/version.h b/gpio/version.h new file mode 100644 index 0000000..290ab36 --- /dev/null +++ b/gpio/version.h @@ -0,0 +1 @@ +#define VERSION "2.31" diff --git a/newVersion b/newVersion new file mode 100644 index 0000000..bab6dc5 --- /dev/null +++ b/newVersion @@ -0,0 +1,43 @@ +#!/bin/sh -e +# +# newVersion: +# Utility to create the version.h include file for the gpio command. +# and the Debian package +# +# Copyright (c) 2012-2015 Gordon Henderson +################################################################################# +# This file is part of wiringPi: +# Wiring Compatable library for the Raspberry Pi +# +# wiringPi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# wiringPi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with wiringPi. If not, see . +################################################################################# + +echo Updating to version: `cat VERSION` + +rm -f gpio/version.h +echo "#define VERSION \"`cat VERSION`\"" > gpio/version.h + +rm -f debian-template/wiringPi/DEBIAN/control +cat > debian-template/wiringPi/DEBIAN/control < +Description: The wiringPi libraries, headers and gpio command + Libraries to allow GPIO access on a Raspberry Pi from C and C++ + programs as well as from the command-line +EOF diff --git a/pins/Makefile b/pins/Makefile new file mode 100644 index 0000000..9535fb5 --- /dev/null +++ b/pins/Makefile @@ -0,0 +1,22 @@ + +SRC = pins.tex + +ifneq ($V,1) +Q ?= @ +endif + + +all: ${SRC} + $Q echo Generating DVI + $Q latex pins.tex + +pins.dvi: pins.tex + $Q latex pins.tex + +pdf: pins.dvi + $Q dvipdf pins.dvi + + +.PHONY: clean +clean: + $Q rm -f *.dvi *.aux *.log *.ps *.toc *.bak *~ diff --git a/pins/pins.pdf b/pins/pins.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bd9629d62044179a5532a68a0eb0dbd7b3ac2dd1 GIT binary patch literal 9833 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 literal 0 HcmV?d00001 diff --git a/pins/pins.tex b/pins/pins.tex new file mode 100644 index 0000000..c3753e9 --- /dev/null +++ b/pins/pins.tex @@ -0,0 +1,116 @@ +\documentclass[12pt,a4paper]{article} +\parskip 1ex +\parindent 0em +\thispagestyle{empty} +\pagestyle{plain} +\pagenumbering{arabic} +\setlength{\topmargin}{0pt} +\setlength{\headheight}{0pt} +\setlength{\headsep}{0pt} +\setlength{\topskip}{0pt} +\setlength{\textheight}{240mm} +\setlength{\footskip}{5ex} +\setlength{\oddsidemargin}{0pt} +\setlength{\evensidemargin}{0pt} +\setlength{\textwidth}{160mm} +\usepackage[dvips]{graphics,color} +\usepackage{helvet} +\renewcommand{\familydefault}{\sfdefault} +\begin{document} +\begin{sffamily} +\definecolor{rtb-black}{rgb} {0.0, 0.0, 0.0} +\definecolor{rtb-navy}{rgb} {0.0, 0.0, 0.5} +\definecolor{rtb-green}{rgb} {0.0, 0.5, 0.0} +\definecolor{rtb-teal}{rgb} {0.0, 0.5, 0.5} +\definecolor{rtb-maroon}{rgb} {0.5, 0.0, 0.0} +\definecolor{rtb-purple}{rgb} {0.5, 0.0, 0.5} +\definecolor{rtb-olive}{rgb} {0.5, 0.5, 0.0} +\definecolor{rtb-silver}{rgb} {0.7, 0.7, 0.7} +\definecolor{rtb-grey}{rgb} {0.5, 0.5, 0.5} +\definecolor{rtb-blue}{rgb} {0.0, 0.0, 1.0} +\definecolor{rtb-lime}{rgb} {0.0, 1.0, 0.0} +\definecolor{rtb-aqua}{rgb} {0.0, 1.0, 1.0} +\definecolor{rtb-red}{rgb} {1.0, 0.0, 0.0} +\definecolor{rtb-fuchsia}{rgb}{1.0, 0.0, 1.0} +\definecolor{rtb-yellow}{rgb} {1.0, 1.0, 0.0} +\definecolor{rtb-white}{rgb} {1.0, 1.0, 1.0} + +\begin{center} +\bfseries{WiringPi: GPIO Pin Numbering Tables}\\ +\tt{http://wiringpi.com/} +\end{center} + +\begin{center} +\begin{tabular}{|c|c|c||p{8mm}|p{8mm}||c|c|c|c|} +\hline +\multicolumn{8}{|c|}{\bfseries{P1: The Main GPIO connector}}\\ +\hline +\hline +WiringPi Pin & BCM GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & BCM GPIO & WiringPi Pin\\ +\hline +\hline + & & \textcolor{rtb-red}{3.3v} & \raggedleft{1} & 2 & \textcolor{rtb-maroon}{5v} & & \\ +\hline +8 & Rv1:0 - Rv2:2 & \textcolor{rtb-aqua}{SDA} & \raggedleft{3} & 4 & \textcolor{rtb-maroon}{5v} & & \\ +\hline +9 & Rv1:1 - Rv2:3 & \textcolor{rtb-aqua}{SCL} & \raggedleft{5} & 6 & \textcolor{rtb-black}{0v} & & \\ +\hline +7 & 4 & \textcolor{rtb-green}{GPIO7} & \raggedleft{7} & 8 & \textcolor{rtb-yellow}{TxD} & 14 & 15\\ +\hline + & & \textcolor{rtb-black}{0v} & \raggedleft{9} & 10 & \textcolor{rtb-yellow}{RxD} & 15 & 16\\ +\hline +0 & 17 & \textcolor{rtb-green}{GPIO0} & \raggedleft{11} & 12 & \textcolor{rtb-green}{GPIO1} & 18 & 1\\ +\hline +2 & Rv1:21 - Rv2:27 & \textcolor{rtb-green}{GPIO2} & \raggedleft{13} & 14 & \textcolor{rtb-black}{0v} & & \\ +\hline +3 & 22 & \textcolor{rtb-green}{GPIO3} & \raggedleft{15} & 16 & \textcolor{rtb-green}{GPIO4} & 23 & 4\\ +\hline + & & \textcolor{rtb-red}{3.3v} & \raggedleft{17} & 18 & \textcolor{rtb-green}{GPIO5} & 24 & 5\\ +\hline +12 & 10 & \textcolor{rtb-teal}{MOSI} & \raggedleft{19} & 20 & \textcolor{rtb-black}{0v} & & \\ +\hline +13 & 9 & \textcolor{rtb-teal}{MISO} & \raggedleft{21} & 22 & \textcolor{rtb-green}{GPIO6} & 25 & 6\\ +\hline +14 & 11 & \textcolor{rtb-teal}{SCLK} & \raggedleft{23} & 24 & \textcolor{rtb-teal}{CE0} & 8 & 10\\ +\hline + & & \textcolor{rtb-black}{0v} & \raggedleft{25} & 26 & \textcolor{rtb-teal}{CE1} & 7 & 11\\ +\hline +\hline +WiringPi Pin & BCM GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & BCM GPIO & WiringPi Pin\\ +\hline +\end{tabular} +\end{center} + +Note the differences between Revision 1 and Revision 2 Raspberry +Pi's. The Revision 2 is readily identifiable by the presence of the 2 +mounting holes. + +The revision 2 Raspberry Pi has an additional GPIO connector, P5, which is next to the main P1 GPIO +connector: + +\begin{center} +\begin{tabular}{|c|c|c||p{8mm}|p{8mm}||c|c|c|c|} +\hline +\multicolumn{8}{|c|}{\bfseries{P5: Secondary GPIO connector (Rev. 2 Pi only)}}\\ +\hline +\hline +WiringPi Pin & BCM GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & BCM GPIO & WiringPi Pin\\ +\hline +\hline + & & \textcolor{rtb-maroon}{5v} & \raggedleft{1} & 2 & \textcolor{rtb-red}{3.3v} & & \\ +\hline +17 & 28 & \textcolor{rtb-green}{GPIO8} & \raggedleft{3} & 4 & \textcolor{rtb-green}{GPIO9} & 29 & 18 \\ +\hline +19 & 30 & \textcolor{rtb-green}{GPIO10} & \raggedleft{5} & 6 & \textcolor{rtb-green}{GPIO11} & 31 & 20 \\ +\hline + & & \textcolor{rtb-black}{0v} & \raggedleft{7} & 8 & \textcolor{rtb-black}{0v} & & \\ +\hline +\hline +WiringPi Pin & BCM GPIO & Name & \multicolumn{2}{|c||}{Header} & Name & BCM GPIO & WiringPi Pin\\ +\hline +\end{tabular} +\end{center} + + +\end{sffamily} +\end{document} diff --git a/wiringPi/Makefile b/wiringPi/Makefile index c6a4555..6bbcc5d 100644 --- a/wiringPi/Makefile +++ b/wiringPi/Makefile @@ -1,8 +1,8 @@ -# ; +# # Makefile: # wiringPi - Wiring Compatable library for the Raspberry Pi # -# Copyright (c) 2012 Gordon Henderson +# Copyright (c) 2012-2015 Gordon Henderson ################################################################################# # This file is part of wiringPi: # https://projects.drogon.net/raspberry-pi/wiringpi/ @@ -21,12 +21,15 @@ # along with wiringPi. If not, see . ################################################################################# -DYN_VERS_MAJ=1 -DYN_VERS_MIN=0 +VERSION=$(shell cat ../VERSION) +DESTDIR?=/usr +PREFIX?=/local -VERSION=$(DYN_VERS_MAJ).$(DYN_VERS_MIN) -DESTDIR=/usr -PREFIX=/local +LDCONFIG?=ldconfig + +ifneq ($V,1) +Q ?= @ +endif STATIC=libwiringPi.a DYNAMIC=libwiringPi.so.$(VERSION) @@ -35,118 +38,145 @@ DYNAMIC=libwiringPi.so.$(VERSION) DEBUG = -O2 CC = gcc INCLUDE = -I. -CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe -fPIC +DEFS = -D_GNU_SOURCE +CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Winline $(INCLUDE) -pipe -fPIC LIBS = -# Should not alter anything below this line ############################################################################### -SRC = wiringPi.c wiringPiFace.c wiringSerial.c wiringShift.c \ - gertboard.c \ - piNes.c \ - lcd.c piHiPri.c piThread.c \ - wiringPiSPI.c \ - softPwm.c softServo.c softTone.c +SRC = wiringPi.c \ + wiringSerial.c wiringShift.c \ + piHiPri.c piThread.c \ + wiringPiSPI.c wiringPiI2C.c \ + softPwm.c softTone.c \ + mcp23008.c mcp23016.c mcp23017.c \ + mcp23s08.c mcp23s17.c \ + sr595.c \ + pcf8574.c pcf8591.c \ + mcp3002.c mcp3004.c mcp4802.c mcp3422.c \ + max31855.c max5322.c \ + sn3218.c \ + drcSerial.c \ + wpiExtensions.c + +HEADERS = wiringPi.h \ + wiringSerial.h wiringShift.h \ + wiringPiSPI.h wiringPiI2C.h \ + softPwm.h softTone.h \ + mcp23008.h mcp23016.h mcp23017.h \ + mcp23s08.h mcp23s17.h \ + sr595.h \ + pcf8574.h pcf8591.h \ + mcp3002.h mcp3004.h mcp4802.h mcp3422.h \ + max31855.h max5322.h \ + sn3218.h \ + drcSerial.h \ + wpiExtensions.h -SRC_I2C = wiringPiI2C.c OBJ = $(SRC:.c=.o) -OBJ_I2C = $(SRC_I2C:.c=.o) - all: $(DYNAMIC) static: $(STATIC) $(STATIC): $(OBJ) - @echo "[Link (Static)]" - @ar rcs $(STATIC) $(OBJ) - @ranlib $(STATIC) + $Q echo "[Link (Static)]" + $Q ar rcs $(STATIC) $(OBJ) + $Q ranlib $(STATIC) # @size $(STATIC) $(DYNAMIC): $(OBJ) - @echo "[Link (Dynamic)]" - @$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ) - -i2c: $(OBJ) $(OBJ_I2C) - @echo "[Link (Dynamic + I2C)]" - @$(CC) -shared -Wl,-soname,libwiringPi.so.1 -o libwiringPi.so.1.0 -lpthread $(OBJ) $(OBJ_I2C) + $Q echo "[Link (Dynamic)]" + $Q $(CC) -shared -Wl,-soname,libwiringPi.so$(WIRINGPI_SONAME_SUFFIX) -o libwiringPi.so.$(VERSION) -lpthread $(OBJ) .c.o: - @echo [Compile] $< - @$(CC) -c $(CFLAGS) $< -o $@ + $Q echo [Compile] $< + $Q $(CC) -c $(CFLAGS) $< -o $@ -.PHONEY: clean + +.PHONY: clean clean: - rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPi.* + $Q echo "[Clean]" + $Q rm -f $(OBJ) $(OBJ_I2C) *~ core tags Makefile.bak libwiringPi.* -.PHONEY: tags +.PHONY: tags tags: $(SRC) - @echo [ctags] - @ctags $(SRC) + $Q echo [ctags] + $Q ctags $(SRC) -.PHONEY: install + +.PHONY: install install: $(DYNAMIC) - @echo "[Install]" - @install -m 0755 -d $(DESTDIR)$(PREFIX)/lib - @install -m 0755 -d $(DESTDIR)$(PREFIX)/include - @install -m 0644 wiringPi.h $(DESTDIR)$(PREFIX)/include - @install -m 0644 wiringSerial.h $(DESTDIR)$(PREFIX)/include - @install -m 0644 wiringShift.h $(DESTDIR)$(PREFIX)/include - @install -m 0644 gertboard.h $(DESTDIR)$(PREFIX)/include - @install -m 0644 piNes.h $(DESTDIR)$(PREFIX)/include - @install -m 0644 softPwm.h $(DESTDIR)$(PREFIX)/include - @install -m 0644 softServo.h $(DESTDIR)$(PREFIX)/include - @install -m 0644 softTone.h $(DESTDIR)$(PREFIX)/include - @install -m 0644 lcd.h $(DESTDIR)$(PREFIX)/include - @install -m 0644 wiringPiSPI.h $(DESTDIR)$(PREFIX)/include - @install -m 0644 wiringPiI2C.h $(DESTDIR)$(PREFIX)/include - @install -m 0755 libwiringPi.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib - @ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so - @ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so.1 - @ldconfig + $Q echo "[Install Headers]" + $Q install -m 0755 -d $(DESTDIR)$(PREFIX)/include + $Q install -m 0644 $(HEADERS) $(DESTDIR)$(PREFIX)/include + $Q echo "[Install Dynamic Lib]" + $Q install -m 0755 -d $(DESTDIR)$(PREFIX)/lib + $Q install -m 0755 libwiringPi.so.$(VERSION) $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) + $Q ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so + $Q $(LDCONFIG) -.PHONEY: install-static +.PHONY: install-static install-static: $(STATIC) - @echo "[Install Static]" - @install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib + $Q echo "[Install Headers]" + $Q install -m 0755 -d $(DESTDIR)$(PREFIX)/include + $Q install -m 0644 $(HEADERS) $(DESTDIR)$(PREFIX)/include + $Q echo "[Install Static Lib]" + $Q install -m 0755 -d $(DESTDIR)$(PREFIX)/lib + $Q install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib -.PHONEY: uninstall +.PHONY: install-deb +install-deb: $(DYNAMIC) + $Q echo "[Install Headers: deb]" + $Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/include + $Q install -m 0644 $(HEADERS) ~/wiringPi/debian-template/wiringPi/usr/include + $Q echo "[Install Dynamic Lib: deb]" + install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/lib + install -m 0755 libwiringPi.so.$(VERSION) ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPi.so.$(VERSION) + ln -sf ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPi.so.$(VERSION) ~/wiringPi/debian-template/wiringPi/usr/lib/libwiringPi.so + +.PHONY: uninstall uninstall: - @echo "[UnInstall]" - @rm -f $(DESTDIR)$(PREFIX)/include/wiringPi.h - @rm -f $(DESTDIR)$(PREFIX)/include/wiringSerial.h - @rm -f $(DESTDIR)$(PREFIX)/include/wiringShift.h - @rm -f $(DESTDIR)$(PREFIX)/include/gertboard.h - @rm -f $(DESTDIR)$(PREFIX)/include/piNes.h - @rm -f $(DESTDIR)$(PREFIX)/include/softPwm.h - @rm -f $(DESTDIR)$(PREFIX)/include/softServo.h - @rm -f $(DESTDIR)$(PREFIX)/include/softTone.h - @rm -f $(DESTDIR)$(PREFIX)/include/lcd.h - @rm -f $(DESTDIR)$(PREFIX)/include/wiringPiSPI.h - @rm -f $(DESTDIR)$(PREFIX)/include/wiringPiI2C.h - @rm -f $(DESTDIR)$(PREFIX)/lib/libwiringPi.* - @ldconfig + $Q echo "[UnInstall]" + $Q cd $(DESTDIR)$(PREFIX)/include/ && rm -f $(HEADERS) + $Q cd $(DESTDIR)$(PREFIX)/lib/ && rm -f libwiringPi.* + $Q $(LDCONFIG) -.PHONEY: depend +.PHONY: depend depend: makedepend -Y $(SRC) $(SRC_I2C) # DO NOT DELETE -wiringPi.o: wiringPi.h -wiringPiFace.o: wiringPi.h +wiringPi.o: softPwm.h softTone.h wiringPi.h wiringSerial.o: wiringSerial.h wiringShift.o: wiringPi.h wiringShift.h -gertboard.o: wiringPiSPI.h gertboard.h -piNes.o: wiringPi.h piNes.h -lcd.o: wiringPi.h lcd.h piHiPri.o: wiringPi.h piThread.o: wiringPi.h -wiringPiSPI.o: wiringPiSPI.h -softPwm.o: wiringPi.h softPwm.h -softServo.o: wiringPi.h softServo.h -softTone.o: wiringPi.h softTone.h +wiringPiSPI.o: wiringPi.h wiringPiSPI.h wiringPiI2C.o: wiringPi.h wiringPiI2C.h +softPwm.o: wiringPi.h softPwm.h +softTone.o: wiringPi.h softTone.h +mcp23008.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23008.h +mcp23016.o: wiringPi.h wiringPiI2C.h mcp23016.h mcp23016reg.h +mcp23017.o: wiringPi.h wiringPiI2C.h mcp23x0817.h mcp23017.h +mcp23s08.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s08.h +mcp23s17.o: wiringPi.h wiringPiSPI.h mcp23x0817.h mcp23s17.h +sr595.o: wiringPi.h sr595.h +pcf8574.o: wiringPi.h wiringPiI2C.h pcf8574.h +pcf8591.o: wiringPi.h wiringPiI2C.h pcf8591.h +mcp3002.o: wiringPi.h wiringPiSPI.h mcp3002.h +mcp3004.o: wiringPi.h wiringPiSPI.h mcp3004.h +mcp4802.o: wiringPi.h wiringPiSPI.h mcp4802.h +mcp3422.o: wiringPi.h wiringPiI2C.h mcp3422.h +max31855.o: wiringPi.h wiringPiSPI.h max31855.h +max5322.o: wiringPi.h wiringPiSPI.h max5322.h +sn3218.o: wiringPi.h wiringPiI2C.h sn3218.h +drcSerial.o: wiringPi.h wiringSerial.h drcSerial.h +wpiExtensions.o: wiringPi.h mcp23008.h mcp23016.h mcp23017.h mcp23s08.h +wpiExtensions.o: mcp23s17.h sr595.h pcf8574.h pcf8591.h mcp3002.h mcp3004.h +wpiExtensions.o: mcp4802.h mcp3422.h max31855.h max5322.h sn3218.h +wpiExtensions.o: drcSerial.h wpiExtensions.h diff --git a/wiringPi/drcSerial.c b/wiringPi/drcSerial.c new file mode 100644 index 0000000..6491a98 --- /dev/null +++ b/wiringPi/drcSerial.c @@ -0,0 +1,201 @@ +/* + * drcSerial.c: + * Extend wiringPi with the DRC Serial protocol (e.g. to Arduino) + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include +#include +#include + +#include "wiringPi.h" +#include "wiringSerial.h" + +#include "drcSerial.h" + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==2) +#endif + + +/* + * myPinMode: + * Change the pin mode on the remote DRC device + ********************************************************************************* + */ + +static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode) +{ + /**/ if (mode == OUTPUT) + serialPutchar (node->fd, 'o') ; // Input + else if (mode == PWM_OUTPUT) + serialPutchar (node->fd, 'p') ; // PWM + else + serialPutchar (node->fd, 'i') ; // Default to input + + serialPutchar (node->fd, pin - node->pinBase) ; +} + + +/* + * myPullUpDnControl: + * ATmegas only have pull-up's on of off. No pull-downs. + ********************************************************************************* + */ + +static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode) +{ + +// Force pin into input mode + + serialPutchar (node->fd, 'i' ) ; + serialPutchar (node->fd, pin - node->pinBase) ; + + /**/ if (mode == PUD_UP) + { + serialPutchar (node->fd, '1') ; + serialPutchar (node->fd, pin - node->pinBase) ; + } + else if (mode == PUD_OFF) + { + serialPutchar (node->fd, '0') ; + serialPutchar (node->fd, pin - node->pinBase) ; + } +} + + +/* + * myDigitalWrite: + ********************************************************************************* + */ + +static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + serialPutchar (node->fd, value == 0 ? '0' : '1') ; + serialPutchar (node->fd, pin - node->pinBase) ; +} + + +/* + * myPwmWrite: + ********************************************************************************* + */ + +static void myPwmWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + serialPutchar (node->fd, 'v') ; + serialPutchar (node->fd, pin - node->pinBase) ; + serialPutchar (node->fd, value & 0xFF) ; +} + + +/* + * myAnalogRead: + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + int vHi, vLo ; + + serialPutchar (node->fd, 'a') ; + serialPutchar (node->fd, pin - node->pinBase) ; + vHi = serialGetchar (node->fd) ; + vLo = serialGetchar (node->fd) ; + + return (vHi << 8) | vLo ; +} + + +/* + * myDigitalRead: + ********************************************************************************* + */ + +static int myDigitalRead (struct wiringPiNodeStruct *node, int pin) +{ + serialPutchar (node->fd, 'r') ; // Send read command + serialPutchar (node->fd, pin - node->pinBase) ; + return (serialGetchar (node->fd) == '0') ? 0 : 1 ; +} + + +/* + * drcSetup: + * Create a new instance of an DRC GPIO interface. + * Could be a variable nunber of pins here - we might not know in advance + * if it's an ATmega with 14 pins, or something with less or more! + ********************************************************************************* + */ + +int drcSetupSerial (const int pinBase, const int numPins, const char *device, const int baud) +{ + int fd ; + int ok, tries ; + time_t then ; + struct wiringPiNodeStruct *node ; + + if ((fd = serialOpen (device, baud)) < 0) + return wiringPiFailure (WPI_ALMOST, "Unable to open DRC device (%s): %s", device, strerror (errno)) ; + + delay (10) ; // May need longer if it's an Uno that reboots on the open... + +// Flush any pending input + + while (serialDataAvail (fd)) + (void)serialGetchar (fd) ; + + ok = FALSE ; + for (tries = 1 ; (tries < 5) && (!ok) ; ++tries) + { + serialPutchar (fd, '@') ; // Ping + then = time (NULL) + 2 ; + while (time (NULL) < then) + if (serialDataAvail (fd)) + { + if (serialGetchar (fd) == '@') + { + ok = TRUE ; + break ; + } + } + } + + if (!ok) + { + serialClose (fd) ; + return wiringPiFailure (WPI_FATAL, "Unable to communicate with DRC serial device") ; + } + + node = wiringPiNewNode (pinBase, numPins) ; + + node->fd = fd ; + node->pinMode = myPinMode ; + node->pullUpDnControl = myPullUpDnControl ; + node->analogRead = myAnalogRead ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->pwmWrite = myPwmWrite ; + + return 0 ; +} diff --git a/wiringPi/drcSerial.h b/wiringPi/drcSerial.h new file mode 100644 index 0000000..29e988e --- /dev/null +++ b/wiringPi/drcSerial.h @@ -0,0 +1,33 @@ +/* + * drcSerial.h: + * Extend wiringPi with the DRC Serial protocol (e.g. to Arduino) + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int drcSetupSerial (const int pinBase, const int numPins, const char *device, const int baud) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/max31855.c b/wiringPi/max31855.c new file mode 100644 index 0000000..ea184d8 --- /dev/null +++ b/wiringPi/max31855.c @@ -0,0 +1,99 @@ +/* + * max31855.c: + * Extend wiringPi with the max31855 SPI Analog to Digital convertor + * Copyright (c) 2012-2015 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include +#include + +#include "max31855.h" + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + uint32_t spiData ; + int temp ; + int chan = pin - node->pinBase ; + + wiringPiSPIDataRW (node->fd, (unsigned char *)&spiData, 4) ; + + spiData = __bswap_32(spiData) ; + + switch (chan) + { + case 0: // Existing read - return raw value * 4 + spiData >>= 18 ; + temp = spiData & 0x1FFF ; // Bottom 13 bits + if ((spiData & 0x2000) != 0) // Negative + temp = -temp ; + + return temp ; + + case 1: // Return error bits + return spiData & 0x7 ; + + case 2: // Return temp in C * 10 + spiData >>= 18 ; + temp = spiData & 0x1FFF ; // Bottom 13 bits + if ((spiData & 0x2000) != 0) // Negative + temp = -temp ; + + return (int)((((double)temp * 25) + 0.5) / 10.0) ; + + case 3: // Return temp in F * 10 + spiData >>= 18 ; + temp = spiData & 0x1FFF ; // Bottom 13 bits + if ((spiData & 0x2000) != 0) // Negative + temp = -temp ; + + return (int)((((((double)temp * 0.25 * 9.0 / 5.0) + 32.0) * 100.0) + 0.5) / 10.0) ; + + default: // Who knows... + return 0 ; + + } +} + + +/* + * max31855Setup: + * Create a new wiringPi device node for an max31855 on the Pi's + * SPI interface. + ********************************************************************************* + */ + +int max31855Setup (const int pinBase, int spiChannel) +{ + struct wiringPiNodeStruct *node ; + + if (wiringPiSPISetup (spiChannel, 5000000) < 0) // 5MHz - prob 4 on the Pi + return -1 ; + + node = wiringPiNewNode (pinBase, 4) ; + + node->fd = spiChannel ; + node->analogRead = myAnalogRead ; + + return 0 ; +} diff --git a/wiringPi/max31855.h b/wiringPi/max31855.h new file mode 100644 index 0000000..385c4bd --- /dev/null +++ b/wiringPi/max31855.h @@ -0,0 +1,33 @@ +/* + * max31855.c: + * Extend wiringPi with the MAX31855 SPI Thermocouple driver + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int max31855Setup (int pinBase, int spiChannel) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/max5322.c b/wiringPi/max5322.c new file mode 100644 index 0000000..b7cd6a9 --- /dev/null +++ b/wiringPi/max5322.c @@ -0,0 +1,84 @@ +/* + * max5322.c: + * Extend wiringPi with the MAX5322 SPI Digital to Analog convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "max5322.h" + +/* + * myAnalogWrite: + * Write analog value on the given pin + ********************************************************************************* + */ + +static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + unsigned char spiData [2] ; + unsigned char chanBits, dataBits ; + int chan = pin - node->pinBase ; + + if (chan == 0) + chanBits = 0b01000000 ; + else + chanBits = 0b01010000 ; + + chanBits |= ((value >> 12) & 0x0F) ; + dataBits = ((value ) & 0xFF) ; + + spiData [0] = chanBits ; + spiData [1] = dataBits ; + + wiringPiSPIDataRW (node->fd, spiData, 2) ; +} + +/* + * max5322Setup: + * Create a new wiringPi device node for an max5322 on the Pi's + * SPI interface. + ********************************************************************************* + */ + +int max5322Setup (const int pinBase, int spiChannel) +{ + struct wiringPiNodeStruct *node ; + unsigned char spiData [2] ; + + if (wiringPiSPISetup (spiChannel, 8000000) < 0) // 10MHz Max + return -1 ; + + node = wiringPiNewNode (pinBase, 2) ; + + node->fd = spiChannel ; + node->analogWrite = myAnalogWrite ; + +// Enable both DACs + + spiData [0] = 0b11100000 ; + spiData [1] = 0 ; + + wiringPiSPIDataRW (node->fd, spiData, 2) ; + + return 0 ; +} diff --git a/wiringPi/max5322.h b/wiringPi/max5322.h new file mode 100644 index 0000000..a217cf8 --- /dev/null +++ b/wiringPi/max5322.h @@ -0,0 +1,33 @@ +/* + * max5322.h: + * Extend wiringPi with the MAX5322 SPI Digital to Analog convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int max5322Setup (int pinBase, int spiChannel) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp23008.c b/wiringPi/mcp23008.c new file mode 100644 index 0000000..d21d237 --- /dev/null +++ b/wiringPi/mcp23008.c @@ -0,0 +1,149 @@ +/* + * mcp23008.c: + * Extend wiringPi with the MCP 23008 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "wiringPi.h" +#include "wiringPiI2C.h" +#include "mcp23x0817.h" + +#include "mcp23008.h" + + +/* + * myPinMode: + ********************************************************************************* + */ + +static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode) +{ + int mask, old, reg ; + + reg = MCP23x08_IODIR ; + mask = 1 << (pin - node->pinBase) ; + old = wiringPiI2CReadReg8 (node->fd, reg) ; + + if (mode == OUTPUT) + old &= (~mask) ; + else + old |= mask ; + + wiringPiI2CWriteReg8 (node->fd, reg, old) ; +} + + +/* + * myPullUpDnControl: + ********************************************************************************* + */ + +static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode) +{ + int mask, old, reg ; + + reg = MCP23x08_GPPU ; + mask = 1 << (pin - node->pinBase) ; + + old = wiringPiI2CReadReg8 (node->fd, reg) ; + + if (mode == PUD_UP) + old |= mask ; + else + old &= (~mask) ; + + wiringPiI2CWriteReg8 (node->fd, reg, old) ; +} + + +/* + * myDigitalWrite: + ********************************************************************************* + */ + +static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + int bit, old ; + + bit = 1 << ((pin - node->pinBase) & 7) ; + + old = node->data2 ; + if (value == LOW) + old &= (~bit) ; + else + old |= bit ; + + wiringPiI2CWriteReg8 (node->fd, MCP23x08_GPIO, old) ; + node->data2 = old ; +} + + +/* + * myDigitalRead: + ********************************************************************************* + */ + +static int myDigitalRead (struct wiringPiNodeStruct *node, int pin) +{ + int mask, value ; + + mask = 1 << ((pin - node->pinBase) & 7) ; + value = wiringPiI2CReadReg8 (node->fd, MCP23x08_GPIO) ; + + if ((value & mask) == 0) + return LOW ; + else + return HIGH ; +} + + +/* + * mcp23008Setup: + * Create a new instance of an MCP23008 I2C GPIO interface. We know it + * has 8 pins, so all we need to know here is the I2C address and the + * user-defined pin base. + ********************************************************************************* + */ + +int mcp23008Setup (const int pinBase, const int i2cAddress) +{ + int fd ; + struct wiringPiNodeStruct *node ; + + if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) + return fd ; + + wiringPiI2CWriteReg8 (fd, MCP23x08_IOCON, IOCON_INIT) ; + + node = wiringPiNewNode (pinBase, 8) ; + + node->fd = fd ; + node->pinMode = myPinMode ; + node->pullUpDnControl = myPullUpDnControl ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->data2 = wiringPiI2CReadReg8 (fd, MCP23x08_OLAT) ; + + return 0 ; +} diff --git a/wiringPi/mcp23008.h b/wiringPi/mcp23008.h new file mode 100644 index 0000000..e9299a8 --- /dev/null +++ b/wiringPi/mcp23008.h @@ -0,0 +1,33 @@ +/* + * 23008.h: + * Extend wiringPi with the MCP 23008 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp23008Setup (const int pinBase, const int i2cAddress) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp23016.c b/wiringPi/mcp23016.c new file mode 100644 index 0000000..e5cc632 --- /dev/null +++ b/wiringPi/mcp23016.c @@ -0,0 +1,164 @@ +/* + * mcp23016.c: + * Extend wiringPi with the MCP 23016 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "wiringPi.h" +#include "wiringPiI2C.h" +#include "mcp23016.h" + +#include "mcp23016reg.h" + + +/* + * myPinMode: + ********************************************************************************* + */ + +static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode) +{ + int mask, old, reg ; + + pin -= node->pinBase ; + + if (pin < 8) // Bank A + reg = MCP23016_IODIR0 ; + else + { + reg = MCP23016_IODIR1 ; + pin &= 0x07 ; + } + + mask = 1 << pin ; + old = wiringPiI2CReadReg8 (node->fd, reg) ; + + if (mode == OUTPUT) + old &= (~mask) ; + else + old |= mask ; + + wiringPiI2CWriteReg8 (node->fd, reg, old) ; +} + + +/* + * myDigitalWrite: + ********************************************************************************* + */ + +static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + int bit, old ; + + pin -= node->pinBase ; // Pin now 0-15 + + bit = 1 << (pin & 7) ; + + if (pin < 8) // Bank A + { + old = node->data2 ; + + if (value == LOW) + old &= (~bit) ; + else + old |= bit ; + + wiringPiI2CWriteReg8 (node->fd, MCP23016_GP0, old) ; + node->data2 = old ; + } + else // Bank B + { + old = node->data3 ; + + if (value == LOW) + old &= (~bit) ; + else + old |= bit ; + + wiringPiI2CWriteReg8 (node->fd, MCP23016_GP1, old) ; + node->data3 = old ; + } +} + + +/* + * myDigitalRead: + ********************************************************************************* + */ + +static int myDigitalRead (struct wiringPiNodeStruct *node, int pin) +{ + int mask, value, gpio ; + + pin -= node->pinBase ; + + if (pin < 8) // Bank A + gpio = MCP23016_GP0 ; + else + { + gpio = MCP23016_GP1 ; + pin &= 0x07 ; + } + + mask = 1 << pin ; + value = wiringPiI2CReadReg8 (node->fd, gpio) ; + + if ((value & mask) == 0) + return LOW ; + else + return HIGH ; +} + + +/* + * mcp23016Setup: + * Create a new instance of an MCP23016 I2C GPIO interface. We know it + * has 16 pins, so all we need to know here is the I2C address and the + * user-defined pin base. + ********************************************************************************* + */ + +int mcp23016Setup (const int pinBase, const int i2cAddress) +{ + int fd ; + struct wiringPiNodeStruct *node ; + + if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) + return fd ; + + wiringPiI2CWriteReg8 (fd, MCP23016_IOCON0, IOCON_INIT) ; + wiringPiI2CWriteReg8 (fd, MCP23016_IOCON1, IOCON_INIT) ; + + node = wiringPiNewNode (pinBase, 16) ; + + node->fd = fd ; + node->pinMode = myPinMode ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->data2 = wiringPiI2CReadReg8 (fd, MCP23016_OLAT0) ; + node->data3 = wiringPiI2CReadReg8 (fd, MCP23016_OLAT1) ; + + return 0 ; +} diff --git a/wiringPi/mcp23016.h b/wiringPi/mcp23016.h new file mode 100644 index 0000000..f9b5cc5 --- /dev/null +++ b/wiringPi/mcp23016.h @@ -0,0 +1,33 @@ +/* + * mcp23016.h: + * Extend wiringPi with the MCP 23016 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp23016Setup (const int pinBase, const int i2cAddress) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp23016reg.h b/wiringPi/mcp23016reg.h new file mode 100644 index 0000000..9aea92d --- /dev/null +++ b/wiringPi/mcp23016reg.h @@ -0,0 +1,48 @@ +/* + * mcp23016: + * Copyright (c) 2012-2013 Gordon Henderson + * + * Header file for code using the MCP23016 GPIO expander + * chip. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +// MCP23016 Registers + +#define MCP23016_GP0 0x00 +#define MCP23016_GP1 0x01 +#define MCP23016_OLAT0 0x02 +#define MCP23016_OLAT1 0x03 +#define MCP23016_IPOL0 0x04 +#define MCP23016_IPOL1 0x05 +#define MCP23016_IODIR0 0x06 +#define MCP23016_IODIR1 0x07 +#define MCP23016_INTCAP0 0x08 +#define MCP23016_INTCAP1 0x09 +#define MCP23016_IOCON0 0x0A +#define MCP23016_IOCON1 0x0B + +// Bits in the IOCON register + +#define IOCON_IARES 0x01 + +// Default initialisation mode + +#define IOCON_INIT 0 diff --git a/wiringPi/mcp23017.c b/wiringPi/mcp23017.c new file mode 100644 index 0000000..5174195 --- /dev/null +++ b/wiringPi/mcp23017.c @@ -0,0 +1,195 @@ +/* + * mcp23017.c: + * Extend wiringPi with the MCP 23017 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "wiringPi.h" +#include "wiringPiI2C.h" +#include "mcp23x0817.h" + +#include "mcp23017.h" + + +/* + * myPinMode: + ********************************************************************************* + */ + +static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode) +{ + int mask, old, reg ; + + pin -= node->pinBase ; + + if (pin < 8) // Bank A + reg = MCP23x17_IODIRA ; + else + { + reg = MCP23x17_IODIRB ; + pin &= 0x07 ; + } + + mask = 1 << pin ; + old = wiringPiI2CReadReg8 (node->fd, reg) ; + + if (mode == OUTPUT) + old &= (~mask) ; + else + old |= mask ; + + wiringPiI2CWriteReg8 (node->fd, reg, old) ; +} + + +/* + * myPullUpDnControl: + ********************************************************************************* + */ + +static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode) +{ + int mask, old, reg ; + + pin -= node->pinBase ; + + if (pin < 8) // Bank A + reg = MCP23x17_GPPUA ; + else + { + reg = MCP23x17_GPPUB ; + pin &= 0x07 ; + } + + mask = 1 << pin ; + old = wiringPiI2CReadReg8 (node->fd, reg) ; + + if (mode == PUD_UP) + old |= mask ; + else + old &= (~mask) ; + + wiringPiI2CWriteReg8 (node->fd, reg, old) ; +} + + +/* + * myDigitalWrite: + ********************************************************************************* + */ + +static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + int bit, old ; + + pin -= node->pinBase ; // Pin now 0-15 + + bit = 1 << (pin & 7) ; + + if (pin < 8) // Bank A + { + old = node->data2 ; + + if (value == LOW) + old &= (~bit) ; + else + old |= bit ; + + wiringPiI2CWriteReg8 (node->fd, MCP23x17_GPIOA, old) ; + node->data2 = old ; + } + else // Bank B + { + old = node->data3 ; + + if (value == LOW) + old &= (~bit) ; + else + old |= bit ; + + wiringPiI2CWriteReg8 (node->fd, MCP23x17_GPIOB, old) ; + node->data3 = old ; + } +} + + +/* + * myDigitalRead: + ********************************************************************************* + */ + +static int myDigitalRead (struct wiringPiNodeStruct *node, int pin) +{ + int mask, value, gpio ; + + pin -= node->pinBase ; + + if (pin < 8) // Bank A + gpio = MCP23x17_GPIOA ; + else + { + gpio = MCP23x17_GPIOB ; + pin &= 0x07 ; + } + + mask = 1 << pin ; + value = wiringPiI2CReadReg8 (node->fd, gpio) ; + + if ((value & mask) == 0) + return LOW ; + else + return HIGH ; +} + + +/* + * mcp23017Setup: + * Create a new instance of an MCP23017 I2C GPIO interface. We know it + * has 16 pins, so all we need to know here is the I2C address and the + * user-defined pin base. + ********************************************************************************* + */ + +int mcp23017Setup (const int pinBase, const int i2cAddress) +{ + int fd ; + struct wiringPiNodeStruct *node ; + + if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) + return fd ; + + wiringPiI2CWriteReg8 (fd, MCP23x17_IOCON, IOCON_INIT) ; + + node = wiringPiNewNode (pinBase, 16) ; + + node->fd = fd ; + node->pinMode = myPinMode ; + node->pullUpDnControl = myPullUpDnControl ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->data2 = wiringPiI2CReadReg8 (fd, MCP23x17_OLATA) ; + node->data3 = wiringPiI2CReadReg8 (fd, MCP23x17_OLATB) ; + + return 0 ; +} diff --git a/wiringPi/mcp23017.h b/wiringPi/mcp23017.h new file mode 100644 index 0000000..79b4d7b --- /dev/null +++ b/wiringPi/mcp23017.h @@ -0,0 +1,33 @@ +/* + * 23017.h: + * Extend wiringPi with the MCP 23017 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp23017Setup (const int pinBase, const int i2cAddress) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp23s08.c b/wiringPi/mcp23s08.c new file mode 100644 index 0000000..d0acb5e --- /dev/null +++ b/wiringPi/mcp23s08.c @@ -0,0 +1,189 @@ +/* + * mcp23s08.c: + * Extend wiringPi with the MCP 23s08 SPI GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "wiringPi.h" +#include "wiringPiSPI.h" +#include "mcp23x0817.h" + +#include "mcp23s08.h" + +#define MCP_SPEED 4000000 + + + +/* + * writeByte: + * Write a byte to a register on the MCP23s08 on the SPI bus. + ********************************************************************************* + */ + +static void writeByte (uint8_t spiPort, uint8_t devId, uint8_t reg, uint8_t data) +{ + uint8_t spiData [4] ; + + spiData [0] = CMD_WRITE | ((devId & 7) << 1) ; + spiData [1] = reg ; + spiData [2] = data ; + + wiringPiSPIDataRW (spiPort, spiData, 3) ; +} + +/* + * readByte: + * Read a byte from a register on the MCP23s08 on the SPI bus. + ********************************************************************************* + */ + +static uint8_t readByte (uint8_t spiPort, uint8_t devId, uint8_t reg) +{ + uint8_t spiData [4] ; + + spiData [0] = CMD_READ | ((devId & 7) << 1) ; + spiData [1] = reg ; + + wiringPiSPIDataRW (spiPort, spiData, 3) ; + + return spiData [2] ; +} + + +/* + * myPinMode: + ********************************************************************************* + */ + +static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode) +{ + int mask, old, reg ; + + reg = MCP23x08_IODIR ; + mask = 1 << (pin - node->pinBase) ; + old = readByte (node->data0, node->data1, reg) ; + + if (mode == OUTPUT) + old &= (~mask) ; + else + old |= mask ; + + writeByte (node->data0, node->data1, reg, old) ; +} + + +/* + * myPullUpDnControl: + ********************************************************************************* + */ + +static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode) +{ + int mask, old, reg ; + + reg = MCP23x08_GPPU ; + mask = 1 << (pin - node->pinBase) ; + + old = readByte (node->data0, node->data1, reg) ; + + if (mode == PUD_UP) + old |= mask ; + else + old &= (~mask) ; + + writeByte (node->data0, node->data1, reg, old) ; +} + + +/* + * myDigitalWrite: + ********************************************************************************* + */ + +static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + int bit, old ; + + bit = 1 << ((pin - node->pinBase) & 7) ; + + old = node->data2 ; + if (value == LOW) + old &= (~bit) ; + else + old |= bit ; + + writeByte (node->data0, node->data1, MCP23x08_GPIO, old) ; + node->data2 = old ; +} + + +/* + * myDigitalRead: + ********************************************************************************* + */ + +static int myDigitalRead (struct wiringPiNodeStruct *node, int pin) +{ + int mask, value ; + + mask = 1 << ((pin - node->pinBase) & 7) ; + value = readByte (node->data0, node->data1, MCP23x08_GPIO) ; + + if ((value & mask) == 0) + return LOW ; + else + return HIGH ; +} + + +/* + * mcp23s08Setup: + * Create a new instance of an MCP23s08 SPI GPIO interface. We know it + * has 8 pins, so all we need to know here is the SPI address and the + * user-defined pin base. + ********************************************************************************* + */ + +int mcp23s08Setup (const int pinBase, const int spiPort, const int devId) +{ + int x ; + struct wiringPiNodeStruct *node ; + + if ((x = wiringPiSPISetup (spiPort, MCP_SPEED)) < 0) + return x ; + + writeByte (spiPort, devId, MCP23x08_IOCON, IOCON_INIT) ; + + node = wiringPiNewNode (pinBase, 8) ; + + node->data0 = spiPort ; + node->data1 = devId ; + node->pinMode = myPinMode ; + node->pullUpDnControl = myPullUpDnControl ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->data2 = readByte (spiPort, devId, MCP23x08_OLAT) ; + + return 0 ; +} diff --git a/wiringPi/mcp23s08.h b/wiringPi/mcp23s08.h new file mode 100644 index 0000000..ebf93d1 --- /dev/null +++ b/wiringPi/mcp23s08.h @@ -0,0 +1,33 @@ +/* + * 23s08.h: + * Extend wiringPi with the MCP 23s08 SPI GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp23s08Setup (const int pinBase, const int spiPort, const int devId) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp23s17.c b/wiringPi/mcp23s17.c new file mode 100644 index 0000000..c2d1be3 --- /dev/null +++ b/wiringPi/mcp23s17.c @@ -0,0 +1,236 @@ +/* + * mcp23s17.c: + * Extend wiringPi with the MCP 23s17 SPI GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "wiringPi.h" +#include "wiringPiSPI.h" +#include "mcp23x0817.h" + +#include "mcp23s17.h" + +#define MCP_SPEED 4000000 + + + +/* + * writeByte: + * Write a byte to a register on the MCP23s17 on the SPI bus. + ********************************************************************************* + */ + +static void writeByte (uint8_t spiPort, uint8_t devId, uint8_t reg, uint8_t data) +{ + uint8_t spiData [4] ; + + spiData [0] = CMD_WRITE | ((devId & 7) << 1) ; + spiData [1] = reg ; + spiData [2] = data ; + + wiringPiSPIDataRW (spiPort, spiData, 3) ; +} + +/* + * readByte: + * Read a byte from a register on the MCP23s17 on the SPI bus. + ********************************************************************************* + */ + +static uint8_t readByte (uint8_t spiPort, uint8_t devId, uint8_t reg) +{ + uint8_t spiData [4] ; + + spiData [0] = CMD_READ | ((devId & 7) << 1) ; + spiData [1] = reg ; + + wiringPiSPIDataRW (spiPort, spiData, 3) ; + + return spiData [2] ; +} + + +/* + * myPinMode: + ********************************************************************************* + */ + +static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode) +{ + int mask, old, reg ; + + pin -= node->pinBase ; + + if (pin < 8) // Bank A + reg = MCP23x17_IODIRA ; + else + { + reg = MCP23x17_IODIRB ; + pin &= 0x07 ; + } + + mask = 1 << pin ; + old = readByte (node->data0, node->data1, reg) ; + + if (mode == OUTPUT) + old &= (~mask) ; + else + old |= mask ; + + writeByte (node->data0, node->data1, reg, old) ; +} + + +/* + * myPullUpDnControl: + ********************************************************************************* + */ + +static void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int mode) +{ + int mask, old, reg ; + + pin -= node->pinBase ; + + if (pin < 8) // Bank A + reg = MCP23x17_GPPUA ; + else + { + reg = MCP23x17_GPPUB ; + pin &= 0x07 ; + } + + mask = 1 << pin ; + old = readByte (node->data0, node->data1, reg) ; + + if (mode == PUD_UP) + old |= mask ; + else + old &= (~mask) ; + + writeByte (node->data0, node->data1, reg, old) ; +} + + +/* + * myDigitalWrite: + ********************************************************************************* + */ + +static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + int bit, old ; + + pin -= node->pinBase ; // Pin now 0-15 + + bit = 1 << (pin & 7) ; + + if (pin < 8) // Bank A + { + old = node->data2 ; + + if (value == LOW) + old &= (~bit) ; + else + old |= bit ; + + writeByte (node->data0, node->data1, MCP23x17_GPIOA, old) ; + node->data2 = old ; + } + else // Bank B + { + old = node->data3 ; + + if (value == LOW) + old &= (~bit) ; + else + old |= bit ; + + writeByte (node->data0, node->data1, MCP23x17_GPIOB, old) ; + node->data3 = old ; + } +} + + +/* + * myDigitalRead: + ********************************************************************************* + */ + +static int myDigitalRead (struct wiringPiNodeStruct *node, int pin) +{ + int mask, value, gpio ; + + pin -= node->pinBase ; + + if (pin < 8) // Bank A + gpio = MCP23x17_GPIOA ; + else + { + gpio = MCP23x17_GPIOB ; + pin &= 0x07 ; + } + + mask = 1 << pin ; + value = readByte (node->data0, node->data1, gpio) ; + + if ((value & mask) == 0) + return LOW ; + else + return HIGH ; +} + + +/* + * mcp23s17Setup: + * Create a new instance of an MCP23s17 SPI GPIO interface. We know it + * has 16 pins, so all we need to know here is the SPI address and the + * user-defined pin base. + ********************************************************************************* + */ + +int mcp23s17Setup (const int pinBase, const int spiPort, const int devId) +{ + int x ; + struct wiringPiNodeStruct *node ; + + if ((x = wiringPiSPISetup (spiPort, MCP_SPEED)) < 0) + return x ; + + writeByte (spiPort, devId, MCP23x17_IOCON, IOCON_INIT | IOCON_HAEN) ; + writeByte (spiPort, devId, MCP23x17_IOCONB, IOCON_INIT | IOCON_HAEN) ; + + node = wiringPiNewNode (pinBase, 16) ; + + node->data0 = spiPort ; + node->data1 = devId ; + node->pinMode = myPinMode ; + node->pullUpDnControl = myPullUpDnControl ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->data2 = readByte (spiPort, devId, MCP23x17_OLATA) ; + node->data3 = readByte (spiPort, devId, MCP23x17_OLATB) ; + + return 0 ; +} diff --git a/wiringPi/mcp23s17.h b/wiringPi/mcp23s17.h new file mode 100644 index 0000000..3b2a808 --- /dev/null +++ b/wiringPi/mcp23s17.h @@ -0,0 +1,33 @@ +/* + * 23s17.h: + * Extend wiringPi with the MCP 23s17 SPI GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp23s17Setup (int pinBase, int spiPort, int devId) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp23x08.h b/wiringPi/mcp23x08.h new file mode 100644 index 0000000..c4e6b27 --- /dev/null +++ b/wiringPi/mcp23x08.h @@ -0,0 +1,73 @@ +/* + * mcp23x17: + * Copyright (c) 2012-2013 Gordon Henderson + * + * Header file for code using the MCP23x17 GPIO expander chip. + * This comes in 2 flavours: MCP23017 which has an I2C interface, + * an the MXP23S17 which has an SPI interface. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + + +// MCP23x17 Registers + +#define IODIRA 0x00 +#define IPOLA 0x02 +#define GPINTENA 0x04 +#define DEFVALA 0x06 +#define INTCONA 0x08 +#define IOCON 0x0A +#define GPPUA 0x0C +#define INTFA 0x0E +#define INTCAPA 0x10 +#define GPIOA 0x12 +#define OLATA 0x14 + +#define IODIRB 0x01 +#define IPOLB 0x03 +#define GPINTENB 0x05 +#define DEFVALB 0x07 +#define INTCONB 0x09 +#define IOCONB 0x0B +#define GPPUB 0x0D +#define INTFB 0x0F +#define INTCAPB 0x11 +#define GPIOB 0x13 +#define OLATB 0x15 + +// Bits in the IOCON register + +#define IOCON_UNUSED 0x01 +#define IOCON_INTPOL 0x02 +#define IOCON_ODR 0x04 +#define IOCON_HAEN 0x08 +#define IOCON_DISSLW 0x10 +#define IOCON_SEQOP 0x20 +#define IOCON_MIRROR 0x40 +#define IOCON_BANK_MODE 0x80 + +// Default initialisation mode + +#define IOCON_INIT (IOCON_SEQOP) + +// SPI Command codes + +#define CMD_WRITE 0x40 +#define CMD_READ 0x41 diff --git a/wiringPi/mcp23x0817.h b/wiringPi/mcp23x0817.h new file mode 100644 index 0000000..58bc038 --- /dev/null +++ b/wiringPi/mcp23x0817.h @@ -0,0 +1,87 @@ +/* + * mcp23xxx: + * Copyright (c) 2012-2013 Gordon Henderson + * + * Header file for code using the MCP23x08 and 17 GPIO expander + * chips. + * This comes in 2 flavours: MCP230xx (08/17) which has an I2C + * interface, and the MXP23Sxx (08/17) which has an SPI interface. + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +// MCP23x08 Registers + +#define MCP23x08_IODIR 0x00 +#define MCP23x08_IPOL 0x01 +#define MCP23x08_GPINTEN 0x02 +#define MCP23x08_DEFVAL 0x03 +#define MCP23x08_INTCON 0x04 +#define MCP23x08_IOCON 0x05 +#define MCP23x08_GPPU 0x06 +#define MCP23x08_INTF 0x07 +#define MCP23x08_INTCAP 0x08 +#define MCP23x08_GPIO 0x09 +#define MCP23x08_OLAT 0x0A + +// MCP23x17 Registers + +#define MCP23x17_IODIRA 0x00 +#define MCP23x17_IPOLA 0x02 +#define MCP23x17_GPINTENA 0x04 +#define MCP23x17_DEFVALA 0x06 +#define MCP23x17_INTCONA 0x08 +#define MCP23x17_IOCON 0x0A +#define MCP23x17_GPPUA 0x0C +#define MCP23x17_INTFA 0x0E +#define MCP23x17_INTCAPA 0x10 +#define MCP23x17_GPIOA 0x12 +#define MCP23x17_OLATA 0x14 + +#define MCP23x17_IODIRB 0x01 +#define MCP23x17_IPOLB 0x03 +#define MCP23x17_GPINTENB 0x05 +#define MCP23x17_DEFVALB 0x07 +#define MCP23x17_INTCONB 0x09 +#define MCP23x17_IOCONB 0x0B +#define MCP23x17_GPPUB 0x0D +#define MCP23x17_INTFB 0x0F +#define MCP23x17_INTCAPB 0x11 +#define MCP23x17_GPIOB 0x13 +#define MCP23x17_OLATB 0x15 + +// Bits in the IOCON register + +#define IOCON_UNUSED 0x01 +#define IOCON_INTPOL 0x02 +#define IOCON_ODR 0x04 +#define IOCON_HAEN 0x08 +#define IOCON_DISSLW 0x10 +#define IOCON_SEQOP 0x20 +#define IOCON_MIRROR 0x40 +#define IOCON_BANK_MODE 0x80 + +// Default initialisation mode + +#define IOCON_INIT (IOCON_SEQOP) + +// SPI Command codes + +#define CMD_WRITE 0x40 +#define CMD_READ 0x41 diff --git a/wiringPi/mcp3002.c b/wiringPi/mcp3002.c new file mode 100644 index 0000000..5d44940 --- /dev/null +++ b/wiringPi/mcp3002.c @@ -0,0 +1,76 @@ +/* + * mcp3002.c: + * Extend wiringPi with the MCP3002 SPI Analog to Digital convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "mcp3002.h" + +/* + * myAnalogRead: + * Return the analog value of the given pin + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + unsigned char spiData [2] ; + unsigned char chanBits ; + int chan = pin - node->pinBase ; + + if (chan == 0) + chanBits = 0b11010000 ; + else + chanBits = 0b11110000 ; + + spiData [0] = chanBits ; + spiData [1] = 0 ; + + wiringPiSPIDataRW (node->fd, spiData, 2) ; + + return ((spiData [0] << 7) | (spiData [1] >> 1)) & 0x3FF ; +} + + +/* + * mcp3002Setup: + * Create a new wiringPi device node for an mcp3002 on the Pi's + * SPI interface. + ********************************************************************************* + */ + +int mcp3002Setup (const int pinBase, int spiChannel) +{ + struct wiringPiNodeStruct *node ; + + if (wiringPiSPISetup (spiChannel, 1000000) < 0) + return -1 ; + + node = wiringPiNewNode (pinBase, 2) ; + + node->fd = spiChannel ; + node->analogRead = myAnalogRead ; + + return 0 ; +} diff --git a/wiringPi/mcp3002.h b/wiringPi/mcp3002.h new file mode 100644 index 0000000..0cd727f --- /dev/null +++ b/wiringPi/mcp3002.h @@ -0,0 +1,33 @@ +/* + * mcp3002.c: + * Extend wiringPi with the MCP3002 SPI Analog to Digital convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp3002Setup (int pinBase, int spiChannel) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp3004.c b/wiringPi/mcp3004.c new file mode 100644 index 0000000..82c73dd --- /dev/null +++ b/wiringPi/mcp3004.c @@ -0,0 +1,76 @@ +/* + * mcp3004.c: + * Extend wiringPi with the MCP3004 SPI Analog to Digital convertor + * Copyright (c) 2012-2013 Gordon Henderson + * + * Thanks also to "ShorTie" on IRC for some remote debugging help! + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "mcp3004.h" + +/* + * myAnalogRead: + * Return the analog value of the given pin + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + unsigned char spiData [3] ; + unsigned char chanBits ; + int chan = pin - node->pinBase ; + + chanBits = 0b10000000 | (chan << 4) ; + + spiData [0] = 1 ; // Start bit + spiData [1] = chanBits ; + spiData [2] = 0 ; + + wiringPiSPIDataRW (node->fd, spiData, 3) ; + + return ((spiData [1] << 8) | spiData [2]) & 0x3FF ; +} + + +/* + * mcp3004Setup: + * Create a new wiringPi device node for an mcp3004 on the Pi's + * SPI interface. + ********************************************************************************* + */ + +int mcp3004Setup (const int pinBase, int spiChannel) +{ + struct wiringPiNodeStruct *node ; + + if (wiringPiSPISetup (spiChannel, 1000000) < 0) + return -1 ; + + node = wiringPiNewNode (pinBase, 8) ; + + node->fd = spiChannel ; + node->analogRead = myAnalogRead ; + + return 0 ; +} diff --git a/wiringPi/mcp3004.h b/wiringPi/mcp3004.h new file mode 100644 index 0000000..a07c0bf --- /dev/null +++ b/wiringPi/mcp3004.h @@ -0,0 +1,33 @@ +/* + * mcp3004.c: + * Extend wiringPi with the MCP3004 SPI Analog to Digital convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp3004Setup (int pinBase, int spiChannel) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp3422.c b/wiringPi/mcp3422.c new file mode 100644 index 0000000..831aece --- /dev/null +++ b/wiringPi/mcp3422.c @@ -0,0 +1,110 @@ +/* + * mcp3422.c: + * Extend wiringPi with the MCP3422 I2C ADC chip + * Also works for the MCP3423 and MCP3224 (4 channel) chips + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "mcp3422.h" + + +/* + * myAnalogRead: + * Read a channel from the device + ********************************************************************************* + */ + +int myAnalogRead (struct wiringPiNodeStruct *node, int chan) +{ + unsigned char config ; + unsigned char buffer [4] ; + int value = 0 ; + +// One-shot mode, trigger plus the other configs. + + config = 0x80 | ((chan - node->pinBase) << 5) | (node->data0 << 2) | (node->data1) ; + + wiringPiI2CWrite (node->fd, config) ; + + switch (node->data0) // Sample rate + { + case MCP3422_SR_3_75: // 18 bits + delay (270) ; + read (node->fd, buffer, 4) ; + value = ((buffer [0] & 3) << 16) | (buffer [1] << 8) | buffer [0] ; + break ; + + case MCP3422_SR_15: // 16 bits + delay ( 70) ; + read (node->fd, buffer, 3) ; + value = (buffer [0] << 8) | buffer [1] ; + break ; + + case MCP3422_SR_60: // 14 bits + delay ( 17) ; + read (node->fd, buffer, 3) ; + value = ((buffer [0] & 0x3F) << 8) | buffer [1] ; + break ; + + case MCP3422_SR_240: // 12 bits + delay ( 5) ; + read (node->fd, buffer, 3) ; + value = ((buffer [0] & 0x0F) << 8) | buffer [0] ; + break ; + } + + return value ; +} + + +/* + * mcp3422Setup: + * Create a new wiringPi device node for the mcp3422 + ********************************************************************************* + */ + +int mcp3422Setup (int pinBase, int i2cAddress, int sampleRate, int gain) +{ + int fd ; + struct wiringPiNodeStruct *node ; + + if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) + return fd ; + + node = wiringPiNewNode (pinBase, 4) ; + + node->data0 = sampleRate ; + node->data1 = gain ; + node->analogRead = myAnalogRead ; + + return 0 ; +} diff --git a/wiringPi/mcp3422.h b/wiringPi/mcp3422.h new file mode 100644 index 0000000..bb4692d --- /dev/null +++ b/wiringPi/mcp3422.h @@ -0,0 +1,43 @@ +/* + * mcp3422.c: + * Extend wiringPi with the MCP3422 I2C ADC chip + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#define MCP3422_SR_3_75 0 +#define MCP3422_SR_15 1 +#define MCP3422_SR_60 2 +#define MCP3422_SR_240 3 + +#define MCP3422_GAIN_1 0 +#define MCP3422_GAIN_2 1 +#define MCP3422_GAIN_4 2 +#define MCP3422_GAIN_8 3 + + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp3422Setup (int pinBase, int i2cAddress, int sampleRate, int gain) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/mcp4802.c b/wiringPi/mcp4802.c new file mode 100644 index 0000000..5c5c17a --- /dev/null +++ b/wiringPi/mcp4802.c @@ -0,0 +1,76 @@ +/* + * mcp4802.c: + * Extend wiringPi with the MCP4802 SPI Digital to Analog convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "mcp4802.h" + +/* + * myAnalogWrite: + * Write analog value on the given pin + ********************************************************************************* + */ + +static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + unsigned char spiData [2] ; + unsigned char chanBits, dataBits ; + int chan = pin - node->pinBase ; + + if (chan == 0) + chanBits = 0x30 ; + else + chanBits = 0xB0 ; + + chanBits |= ((value >> 4) & 0x0F) ; + dataBits = ((value << 4) & 0xF0) ; + + spiData [0] = chanBits ; + spiData [1] = dataBits ; + + wiringPiSPIDataRW (node->fd, spiData, 2) ; +} + +/* + * mcp4802Setup: + * Create a new wiringPi device node for an mcp4802 on the Pi's + * SPI interface. + ********************************************************************************* + */ + +int mcp4802Setup (const int pinBase, int spiChannel) +{ + struct wiringPiNodeStruct *node ; + + if (wiringPiSPISetup (spiChannel, 1000000) < 0) + return -1 ; + + node = wiringPiNewNode (pinBase, 2) ; + + node->fd = spiChannel ; + node->analogWrite = myAnalogWrite ; + + return 0 ; +} diff --git a/wiringPi/mcp4802.h b/wiringPi/mcp4802.h new file mode 100644 index 0000000..effa024 --- /dev/null +++ b/wiringPi/mcp4802.h @@ -0,0 +1,33 @@ +/* + * mcp4802.c: + * Extend wiringPi with the MCP4802 SPI Digital to Analog convertor + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mcp4802Setup (int pinBase, int spiChannel) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/pcf8574.c b/wiringPi/pcf8574.c new file mode 100644 index 0000000..c172d1c --- /dev/null +++ b/wiringPi/pcf8574.c @@ -0,0 +1,126 @@ +/* + * pcf8574.c: + * Extend wiringPi with the PCF8574 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "wiringPi.h" +#include "wiringPiI2C.h" + +#include "pcf8574.h" + + +/* + * myPinMode: + * The PCF8574 is an odd chip - the pins are effectively bi-directional, + * however the pins should be drven high when used as an input pin... + * So, we're effectively copying digitalWrite... + ********************************************************************************* + */ + +static void myPinMode (struct wiringPiNodeStruct *node, int pin, int mode) +{ + int bit, old ; + + bit = 1 << ((pin - node->pinBase) & 7) ; + + old = node->data2 ; + if (mode == OUTPUT) + old &= (~bit) ; // Write bit to 0 + else + old |= bit ; // Write bit to 1 + + wiringPiI2CWrite (node->fd, old) ; + node->data2 = old ; +} + + + +/* + * myDigitalWrite: + ********************************************************************************* + */ + +static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + int bit, old ; + + bit = 1 << ((pin - node->pinBase) & 7) ; + + old = node->data2 ; + if (value == LOW) + old &= (~bit) ; + else + old |= bit ; + + wiringPiI2CWrite (node->fd, old) ; + node->data2 = old ; +} + + +/* + * myDigitalRead: + ********************************************************************************* + */ + +static int myDigitalRead (struct wiringPiNodeStruct *node, int pin) +{ + int mask, value ; + + mask = 1 << ((pin - node->pinBase) & 7) ; + value = wiringPiI2CRead (node->fd) ; + + if ((value & mask) == 0) + return LOW ; + else + return HIGH ; +} + + +/* + * pcf8574Setup: + * Create a new instance of a PCF8574 I2C GPIO interface. We know it + * has 8 pins, so all we need to know here is the I2C address and the + * user-defined pin base. + ********************************************************************************* + */ + +int pcf8574Setup (const int pinBase, const int i2cAddress) +{ + int fd ; + struct wiringPiNodeStruct *node ; + + if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) + return fd ; + + node = wiringPiNewNode (pinBase, 8) ; + + node->fd = fd ; + node->pinMode = myPinMode ; + node->digitalRead = myDigitalRead ; + node->digitalWrite = myDigitalWrite ; + node->data2 = wiringPiI2CRead (fd) ; + + return 0 ; +} diff --git a/wiringPi/pcf8574.h b/wiringPi/pcf8574.h new file mode 100644 index 0000000..8e2d818 --- /dev/null +++ b/wiringPi/pcf8574.h @@ -0,0 +1,33 @@ +/* + * pcf8574.h: + * Extend wiringPi with the PCF8574 I2C GPIO expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int pcf8574Setup (const int pinBase, const int i2cAddress) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/pcf8591.c b/wiringPi/pcf8591.c new file mode 100644 index 0000000..0c86056 --- /dev/null +++ b/wiringPi/pcf8591.c @@ -0,0 +1,90 @@ +/* + * pcf8591.c: + * Extend wiringPi with the PCF8591 I2C GPIO Analog expander chip + * The chip has 1 8-bit DAC and 4 x 8-bit ADCs + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include + +#include "wiringPi.h" +#include "wiringPiI2C.h" + +#include "pcf8591.h" + + +/* + * myAnalogWrite: + ********************************************************************************* + */ + +static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + unsigned char b [2] ; + b [0] = 0x40 ; + b [1] = value & 0xFF ; + write (node->fd, b, 2) ; +} + + +/* + * myAnalogRead: + ********************************************************************************* + */ + +static int myAnalogRead (struct wiringPiNodeStruct *node, int pin) +{ + int x ; + + wiringPiI2CWrite (node->fd, 0x40 | ((pin - node->pinBase) & 3)) ; + + x = wiringPiI2CRead (node->fd) ; // Throw away the first read + x = wiringPiI2CRead (node->fd) ; + + return x ; +} + + +/* + * pcf8591Setup: + * Create a new instance of a PCF8591 I2C GPIO interface. We know it + * has 4 pins, (4 analog inputs and 1 analog output which we'll shadow + * input 0) so all we need to know here is the I2C address and the + * user-defined pin base. + ********************************************************************************* + */ + +int pcf8591Setup (const int pinBase, const int i2cAddress) +{ + int fd ; + struct wiringPiNodeStruct *node ; + + if ((fd = wiringPiI2CSetup (i2cAddress)) < 0) + return fd ; + + node = wiringPiNewNode (pinBase, 4) ; + + node->fd = fd ; + node->analogRead = myAnalogRead ; + node->analogWrite = myAnalogWrite ; + + return 0 ; +} diff --git a/wiringPi/pcf8591.h b/wiringPi/pcf8591.h new file mode 100644 index 0000000..6b44ccf --- /dev/null +++ b/wiringPi/pcf8591.h @@ -0,0 +1,33 @@ +/* + * pcf8591.h: + * Extend wiringPi with the PCF8591 I2C GPIO Analog expander chip + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int pcf8591Setup (const int pinBase, const int i2cAddress) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/piHiPri.c b/wiringPi/piHiPri.c index e7e06b4..d2f3b4e 100644 --- a/wiringPi/piHiPri.c +++ b/wiringPi/piHiPri.c @@ -36,15 +36,16 @@ ********************************************************************************* */ -int piHiPri (int pri) +int piHiPri (const int pri) { struct sched_param sched ; memset (&sched, 0, sizeof(sched)) ; if (pri > sched_get_priority_max (SCHED_RR)) - pri = sched_get_priority_max (SCHED_RR) ; + sched.sched_priority = sched_get_priority_max (SCHED_RR) ; + else + sched.sched_priority = pri ; - sched.sched_priority = pri ; return sched_setscheduler (0, SCHED_RR, &sched) ; } diff --git a/wiringPi/sn3218.c b/wiringPi/sn3218.c new file mode 100644 index 0000000..7ceb156 --- /dev/null +++ b/wiringPi/sn3218.c @@ -0,0 +1,75 @@ +/* + * sn3218.c: + * Extend wiringPi with the SN3218 I2C LEd Driver + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "sn3218.h" + +/* + * myAnalogWrite: + * Write analog value on the given pin + ********************************************************************************* + */ + +static void myAnalogWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + int fd = node->fd ; + int chan = 0x01 + (pin - node->pinBase) ; + + wiringPiI2CWriteReg8 (fd, chan, value & 0xFF) ; // Value + wiringPiI2CWriteReg8 (fd, 0x16, 0x00) ; // Update +} + +/* + * sn3218Setup: + * Create a new wiringPi device node for an sn3218 on the Pi's + * SPI interface. + ********************************************************************************* + */ + +int sn3218Setup (const int pinBase) +{ + int fd ; + struct wiringPiNodeStruct *node ; + + if ((fd = wiringPiI2CSetup (0x54)) < 0) + return fd ; + +// Setup the chip - initialise all 18 LEDs to off + +//wiringPiI2CWriteReg8 (fd, 0x17, 0) ; // Reset + wiringPiI2CWriteReg8 (fd, 0x00, 1) ; // Not Shutdown + wiringPiI2CWriteReg8 (fd, 0x13, 0x3F) ; // Enable LEDs 0- 5 + wiringPiI2CWriteReg8 (fd, 0x14, 0x3F) ; // Enable LEDs 6-11 + wiringPiI2CWriteReg8 (fd, 0x15, 0x3F) ; // Enable LEDs 12-17 + wiringPiI2CWriteReg8 (fd, 0x16, 0x00) ; // Update + + node = wiringPiNewNode (pinBase, 18) ; + + node->fd = fd ; + node->analogWrite = myAnalogWrite ; + + return 0 ; +} diff --git a/wiringPi/sn3218.h b/wiringPi/sn3218.h new file mode 100644 index 0000000..580d5f9 --- /dev/null +++ b/wiringPi/sn3218.h @@ -0,0 +1,33 @@ +/* + * sn3218.c: + * Extend wiringPi with the SN3218 I2C LED driver board. + * Copyright (c) 2012-2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int sn3218Setup (int pinBase) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/softPwm.c b/wiringPi/softPwm.c index b568dfb..98b408f 100644 --- a/wiringPi/softPwm.c +++ b/wiringPi/softPwm.c @@ -1,7 +1,7 @@ /* * softPwm.c: * Provide 2 channels of software driven PWM. - * Copyright (c) 2012 Gordon Henderson + * Copyright (c) 2012-2014 Gordon Henderson *********************************************************************** * This file is part of wiringPi: * https://projects.drogon.net/raspberry-pi/wiringpi/ @@ -28,17 +28,22 @@ #include "wiringPi.h" #include "softPwm.h" -#define MAX_PINS 64 +// MAX_PINS: +// This is more than the number of Pi pins because we can actually softPwm +// pins that are on GPIO expanders. It's not that efficient and more than 1 or +// 2 pins on e.g. (SPI) mcp23s17 won't really be that effective, however... + +#define MAX_PINS 1024 // The PWM Frequency is derived from the "pulse time" below. Essentially, // the frequency is a function of the range and this pulse time. -// The total period will be range * pulse time in uS, so a pulse time -// of 100 and a range of 100 gives a period of 100 * 100 = 10,000 uS +// The total period will be range * pulse time in µS, so a pulse time +// of 100 and a range of 100 gives a period of 100 * 100 = 10,000 µS // which is a frequency of 100Hz. // // It's possible to get a higher frequency by lowering the pulse time, // however CPU uage will skyrocket as wiringPi uses a hard-loop to time -// periods under 100uS - this is because the Linux timer calls are just +// periods under 100µS - this is because the Linux timer calls are just // accurate at all, and have an overhead. // // Another way to increase the frequency is to reduce the range - however @@ -46,10 +51,10 @@ #define PULSE_TIME 100 -static int marks [MAX_PINS] ; -static int range [MAX_PINS] ; - -int newPin = -1 ; +static volatile int marks [MAX_PINS] ; +static volatile int range [MAX_PINS] ; +static volatile pthread_t threads [MAX_PINS] ; +static volatile int newPin = -1 ; /* @@ -61,11 +66,15 @@ int newPin = -1 ; static PI_THREAD (softPwmThread) { int pin, mark, space ; + struct sched_param param ; + + param.sched_priority = sched_get_priority_max (SCHED_RR) ; + pthread_setschedparam (pthread_self (), SCHED_RR, ¶m) ; pin = newPin ; newPin = -1 ; - piHiPri (50) ; + piHiPri (90) ; for (;;) { @@ -93,7 +102,7 @@ static PI_THREAD (softPwmThread) void softPwmWrite (int pin, int value) { - pin &= 63 ; + pin &= (MAX_PINS - 1) ; /**/ if (value < 0) value = 0 ; @@ -106,13 +115,20 @@ void softPwmWrite (int pin, int value) /* * softPwmCreate: - * Create a new PWM thread. + * Create a new softPWM thread. ********************************************************************************* */ int softPwmCreate (int pin, int initialValue, int pwmRange) { int res ; + pthread_t myThread ; + + if (range [pin] != 0) // Already running on this pin + return -1 ; + + if (range <= 0) + return -1 ; pinMode (pin, OUTPUT) ; digitalWrite (pin, LOW) ; @@ -121,10 +137,30 @@ int softPwmCreate (int pin, int initialValue, int pwmRange) range [pin] = pwmRange ; newPin = pin ; - res = piThreadCreate (softPwmThread) ; + res = pthread_create (&myThread, NULL, softPwmThread, NULL) ; while (newPin != -1) delay (1) ; + threads [pin] = myThread ; + return res ; } + + +/* + * softPwmStop: + * Stop an existing softPWM thread + ********************************************************************************* + */ + +void softPwmStop (int pin) +{ + if (range [pin] != 0) + { + pthread_cancel (threads [pin]) ; + pthread_join (threads [pin], NULL) ; + range [pin] = 0 ; + digitalWrite (pin, LOW) ; + } +} diff --git a/wiringPi/softPwm.h b/wiringPi/softPwm.h index 28ad299..0351da5 100644 --- a/wiringPi/softPwm.h +++ b/wiringPi/softPwm.h @@ -28,6 +28,7 @@ extern "C" { extern int softPwmCreate (int pin, int value, int range) ; extern void softPwmWrite (int pin, int value) ; +extern void softPwmStop (int pin) ; #ifdef __cplusplus } diff --git a/wiringPi/softTone.c b/wiringPi/softTone.c index 8463627..e2fb737 100644 --- a/wiringPi/softTone.c +++ b/wiringPi/softTone.c @@ -36,7 +36,8 @@ #define PULSE_TIME 100 -static int frewqs [MAX_PINS] ; +static int freqs [MAX_PINS] ; +static pthread_t threads [MAX_PINS] ; static int newPin = -1 ; @@ -49,7 +50,11 @@ static int newPin = -1 ; static PI_THREAD (softToneThread) { - int pin, frewq, halfPeriod ; + int pin, freq, halfPeriod ; + struct sched_param param ; + + param.sched_priority = sched_get_priority_max (SCHED_RR) ; + pthread_setschedparam (pthread_self (), SCHED_RR, ¶m) ; pin = newPin ; newPin = -1 ; @@ -58,12 +63,12 @@ static PI_THREAD (softToneThread) for (;;) { - frewq = frewqs [pin] ; - if (frewq == 0) + freq = freqs [pin] ; + if (freq == 0) delay (1) ; else { - halfPeriod = 500000 / frewq ; + halfPeriod = 500000 / freq ; digitalWrite (pin, HIGH) ; delayMicroseconds (halfPeriod) ; @@ -83,16 +88,16 @@ static PI_THREAD (softToneThread) ********************************************************************************* */ -void softToneWrite (int pin, int frewq) +void softToneWrite (int pin, int freq) { pin &= 63 ; - /**/ if (frewq < 0) - frewq = 0 ; - else if (frewq > 5000) // Max 5KHz - frewq = 5000 ; + /**/ if (freq < 0) + freq = 0 ; + else if (freq > 5000) // Max 5KHz + freq = 5000 ; - frewqs [pin] = frewq ; + freqs [pin] = freq ; } @@ -105,17 +110,41 @@ void softToneWrite (int pin, int frewq) int softToneCreate (int pin) { int res ; + pthread_t myThread ; pinMode (pin, OUTPUT) ; digitalWrite (pin, LOW) ; - frewqs [pin] = 0 ; + if (threads [pin] != 0) + return -1 ; + + freqs [pin] = 0 ; newPin = pin ; - res = piThreadCreate (softToneThread) ; + res = pthread_create (&myThread, NULL, softToneThread, NULL) ; while (newPin != -1) delay (1) ; + threads [pin] = myThread ; + return res ; } + + +/* + * softToneStop: + * Stop an existing softTone thread + ********************************************************************************* + */ + +void softToneStop (int pin) +{ + if (threads [pin] != 0) + { + pthread_cancel (threads [pin]) ; + pthread_join (threads [pin], NULL) ; + threads [pin] = 0 ; + digitalWrite (pin, LOW) ; + } +} diff --git a/wiringPi/softTone.h b/wiringPi/softTone.h index 80c64fe..a93c5af 100644 --- a/wiringPi/softTone.h +++ b/wiringPi/softTone.h @@ -31,7 +31,8 @@ extern "C" { #endif extern int softToneCreate (int pin) ; -extern void softToneWrite (int pin, int frewq) ; +extern void softToneStop (int pin) ; +extern void softToneWrite (int pin, int freq) ; #ifdef __cplusplus } diff --git a/wiringPi/sr595.c b/wiringPi/sr595.c new file mode 100644 index 0000000..87210c2 --- /dev/null +++ b/wiringPi/sr595.c @@ -0,0 +1,109 @@ +/* + * sr595.c: + * Extend wiringPi with the 74x595 shift register as a GPIO + * expander chip. + * Note that the code can cope with a number of 595's + * daisy-chained together - up to 4 for now as we're storing + * the output "register" in a single unsigned int. + * + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#include +#include + +#include "wiringPi.h" + +#include "sr595.h" + + +/* + * myDigitalWrite: + ********************************************************************************* + */ + +static void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) +{ + unsigned int mask ; + int dataPin, clockPin, latchPin ; + int bit, bits, output ; + + pin -= node->pinBase ; // Normalise pin number + bits = node->pinMax - node->pinBase + 1 ; // ie. number of clock pulses + dataPin = node->data0 ; + clockPin = node->data1 ; + latchPin = node->data2 ; + output = node->data3 ; + + mask = 1 << pin ; + + if (value == LOW) + output &= (~mask) ; + else + output |= mask ; + + node->data3 = output ; + +// A low -> high latch transition copies the latch to the output pins + + digitalWrite (latchPin, LOW) ; delayMicroseconds (1) ; + for (bit = bits - 1 ; bit >= 0 ; --bit) + { + digitalWrite (dataPin, output & (1 << bit)) ; + + digitalWrite (clockPin, HIGH) ; delayMicroseconds (1) ; + digitalWrite (clockPin, LOW) ; delayMicroseconds (1) ; + } + digitalWrite (latchPin, HIGH) ; delayMicroseconds (1) ; +} + + +/* + * sr595Setup: + * Create a new instance of a 74x595 shift register GPIO expander. + ********************************************************************************* + */ + +int sr595Setup (const int pinBase, const int numPins, + const int dataPin, const int clockPin, const int latchPin) +{ + struct wiringPiNodeStruct *node ; + + node = wiringPiNewNode (pinBase, numPins) ; + + node->data0 = dataPin ; + node->data1 = clockPin ; + node->data2 = latchPin ; + node->data3 = 0 ; // Output register + node->digitalWrite = myDigitalWrite ; + +// Initialise the underlying hardware + + digitalWrite (dataPin, LOW) ; + digitalWrite (clockPin, LOW) ; + digitalWrite (latchPin, HIGH) ; + + pinMode (dataPin, OUTPUT) ; + pinMode (clockPin, OUTPUT) ; + pinMode (latchPin, OUTPUT) ; + + return 0 ; +} diff --git a/wiringPi/sr595.h b/wiringPi/sr595.h new file mode 100644 index 0000000..4a26dc7 --- /dev/null +++ b/wiringPi/sr595.h @@ -0,0 +1,34 @@ +/* + * sr595.h: + * Extend wiringPi with the 74x595 shift registers. + * Copyright (c) 2013 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with wiringPi. + * If not, see . + *********************************************************************** + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int sr595Setup (const int pinBase, const int numPins, + const int dataPin, const int clockPin, const int latchPin) ; + +#ifdef __cplusplus +} +#endif diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index a68ae33..503151f 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -1,7 +1,7 @@ /* * wiringPi: - * Arduino compatable (ish) Wiring library for the Raspberry Pi - * Copyright (c) 2012 Gordon Henderson + * Arduino look-a-like Wiring library for the Raspberry Pi + * Copyright (c) 2012-2015 Gordon Henderson * Additional code for pwmSetClock by Chris Hall * * Thanks to code samples from Gert Jan van Loo and the @@ -53,6 +53,7 @@ #include +#include #include #include #include @@ -69,30 +70,30 @@ #include #include +#include "softPwm.h" +#include "softTone.h" + #include "wiringPi.h" -// Function stubs - -void (*pinMode) (int pin, int mode) ; -int (*getAlt) (int pin) ; -void (*pullUpDnControl) (int pin, int pud) ; -void (*digitalWrite) (int pin, int value) ; -void (*digitalWriteByte) (int value) ; -void (*pwmWrite) (int pin, int value) ; -void (*gpioClockSet) (int pin, int value) ; -void (*setPadDrive) (int group, int value) ; -int (*digitalRead) (int pin) ; -int (*waitForInterrupt) (int pin, int mS) ; -void (*pwmSetMode) (int mode) ; -void (*pwmSetRange) (unsigned int range) ; -void (*pwmSetClock) (int divisor) ; - - #ifndef TRUE #define TRUE (1==1) #define FALSE (1==2) #endif +// Environment Variables + +#define ENV_DEBUG "WIRINGPI_DEBUG" +#define ENV_CODES "WIRINGPI_CODES" +#define ENV_GPIOMEM "WIRINGPI_GPIOMEM" + + +// Mask for the bottom 64 pins which belong to the Raspberry Pi +// The others are available for the other devices + +#define PI_GPIO_MASK (0xFFFFFFC0) + +struct wiringPiNodeStruct *wiringPiNodes = NULL ; + // BCM Magic #define BCM_PASSWORD 0x5A000000 @@ -121,7 +122,6 @@ void (*pwmSetClock) (int divisor) ; #define FSEL_INPT 0b000 #define FSEL_OUTP 0b001 #define FSEL_ALT0 0b100 -#define FSEL_ALT0 0b100 #define FSEL_ALT1 0b101 #define FSEL_ALT2 0b110 #define FSEL_ALT3 0b111 @@ -131,13 +131,16 @@ void (*pwmSetClock) (int divisor) ; // Access from ARM Running Linux // Taken from Gert/Doms code. Some of this is not in the manual // that I can find )-: +// +// Updates in September 2015 - all now static variables (and apologies for the caps) +// due to the Pi v2 and the new /dev/gpiomem interface -#define BCM2708_PERI_BASE 0x20000000 -#define GPIO_PADS (BCM2708_PERI_BASE + 0x00100000) -#define CLOCK_BASE (BCM2708_PERI_BASE + 0x00101000) -#define GPIO_BASE (BCM2708_PERI_BASE + 0x00200000) -#define GPIO_TIMER (BCM2708_PERI_BASE + 0x0000B000) -#define GPIO_PWM (BCM2708_PERI_BASE + 0x0020C000) +static volatile unsigned int RASPBERRY_PI_PERI_BASE ; +static volatile unsigned int GPIO_PADS ; +static volatile unsigned int GPIO_CLOCK_BASE ; +static volatile unsigned int GPIO_BASE ; +static volatile unsigned int GPIO_TIMER ; +static volatile unsigned int GPIO_PWM ; #define PAGE_SIZE (4*1024) #define BLOCK_SIZE (4*1024) @@ -192,8 +195,91 @@ static volatile uint32_t *gpio ; static volatile uint32_t *pwm ; static volatile uint32_t *clk ; static volatile uint32_t *pads ; + +#ifdef USE_TIMER static volatile uint32_t *timer ; static volatile uint32_t *timerIrqRaw ; +#endif + + +// Data for use with the boardId functions. +// The order of entries here to correspond with the PI_MODEL_X +// and PI_VERSION_X defines in wiringPi.h +// Only intended for the gpio command - use at your own risk! + +static int piModel2 = FALSE ; + +const char *piModelNames [16] = +{ + "Model A", // 0 + "Model B", // 1 + "Model A+", // 2 + "Model B+", // 3 + "Pi 2", // 4 + "Alpha", // 5 + "CM", // 6 + "Unknown07", // 07 + "Unknown08", // 08 + "Pi Zero", // 09 + "Unknown10", // 10 + "Unknown11", // 11 + "Unknown12", // 12 + "Unknown13", // 13 + "Unknown14", // 14 + "Unknown15", // 15 +} ; + +const char *piRevisionNames [16] = +{ + "00", + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10", + "11", + "12", + "13", + "14", + "15", +} ; + +const char *piMakerNames [16] = +{ + "Sony", // 0 + "Egoman", // 1 + "Embest", // 2 + "Unknown", // 3 + "Embest", // 4 + "Unknown05", // 5 + "Unknown06", // 6 + "Unknown07", // 7 + "Unknown08", // 8 + "Unknown09", // 9 + "Unknown10", // 10 + "Unknown11", // 11 + "Unknown12", // 12 + "Unknown13", // 13 + "Unknown14", // 14 + "Unknown15", // 15 +} ; + +const int piMemorySize [8] = +{ + 256, // 0 + 512, // 1 + 1024, // 2 + 0, // 3 + 0, // 4 + 0, // 5 + 0, // 6 + 0, // 7 +} ; // Time for easy calculations @@ -202,15 +288,28 @@ static uint64_t epochMilli, epochMicro ; // Misc static int wiringPiMode = WPI_MODE_UNINITIALISED ; +static volatile int pinPass = -1 ; +static pthread_mutex_t pinMutex ; -// Debugging +// Debugging & Return codes -int wiringPiDebug = FALSE ; +int wiringPiDebug = FALSE ; +int wiringPiReturnCodes = FALSE ; + +// Use /dev/gpiomem ? + +int wiringPiTryGpioMem = FALSE ; // sysFds: // Map a file descriptor from the /sys/class/gpio/gpioX/value -static int sysFds [64] ; +static int sysFds [64] = +{ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +} ; // ISR Data @@ -223,17 +322,19 @@ static void (*isrFunctions [64])(void) ; // pinToGpio: // Take a Wiring pin (0 through X) and re-map it to the BCM_GPIO pin -// Cope for 2 different board revieions here +// Cope for 3 different board revisions here. static int *pinToGpio ; +// Revision 1, 1.1: + static int pinToGpioR1 [64] = { - 17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7 - 0, 1, // I2C - SDA0, SCL0 - 8, 7, // SPI - CE1, CE0 - 10, 9, 11, // SPI - MOSI, MISO, SCLK - 14, 15, // UART - Tx, Rx + 17, 18, 21, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7 + 0, 1, // I2C - SDA1, SCL1 wpi 8 - 9 + 8, 7, // SPI - CE1, CE0 wpi 10 - 11 + 10, 9, 11, // SPI - MOSI, MISO, SCLK wpi 12 - 14 + 14, 15, // UART - Tx, Rx wpi 15 - 16 // Padding: @@ -242,6 +343,8 @@ static int pinToGpioR1 [64] = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 } ; +// Revision 2: + static int pinToGpioR2 [64] = { 17, 18, 27, 22, 23, 24, 25, 4, // From the Original Wiki - GPIO 0 through 7: wpi 0 - 7 @@ -249,18 +352,93 @@ static int pinToGpioR2 [64] = 8, 7, // SPI - CE1, CE0 wpi 10 - 11 10, 9, 11, // SPI - MOSI, MISO, SCLK wpi 12 - 14 14, 15, // UART - Tx, Rx wpi 15 - 16 - 28, 29, 30, 31, // New GPIOs 8 though 11 wpi 17 - 20 + 28, 29, 30, 31, // Rev 2: New GPIOs 8 though 11 wpi 17 - 20 + 5, 6, 13, 19, 26, // B+ wpi 21, 22, 23, 24, 25 + 12, 16, 20, 21, // B+ wpi 26, 27, 28, 29 + 0, 1, // B+ wpi 30, 31 // Padding: - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 } ; +// physToGpio: +// Take a physical pin (1 through 26) and re-map it to the BCM_GPIO pin +// Cope for 2 different board revisions here. +// Also add in the P5 connector, so the P5 pins are 3,4,5,6, so 53,54,55,56 + +static int *physToGpio ; + +static int physToGpioR1 [64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 0, -1, + 1, -1, + 4, 14, + -1, 15, + 17, 18, + 21, -1, + 22, 23, + -1, 24, + 10, -1, + 9, 25, + 11, 8, + -1, 7, // 25, 26 + + -1, -1, -1, -1, -1, // ... 31 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 47 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ... 63 +} ; + +static int physToGpioR2 [64] = +{ + -1, // 0 + -1, -1, // 1, 2 + 2, -1, + 3, -1, + 4, 14, + -1, 15, + 17, 18, + 27, -1, + 22, 23, + -1, 24, + 10, -1, + 9, 25, + 11, 8, + -1, 7, // 25, 26 + +// B+ + + 0, 1, + 5, -1, + 6, 12, + 13, -1, + 19, 16, + 26, 20, + -1, 21, + +// the P5 connector on the Rev 2 boards: + + -1, -1, + -1, -1, + -1, -1, + -1, -1, + -1, -1, + 28, 29, + 30, 31, + -1, -1, + -1, -1, + -1, -1, + -1, -1, +} ; + // gpioToGPFSEL: -// Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5) +// Map a BCM_GPIO pin to it's Function Selection +// control port. (GPFSEL 0-5) +// Groups of 10 - 3 bits per Function - 30 bits per port static uint8_t gpioToGPFSEL [] = { @@ -295,7 +473,6 @@ static uint8_t gpioToGPSET [] = 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, } ; - // gpioToGPCLR: // (Word) offset to the GPIO Clear registers for each GPIO pin @@ -327,7 +504,7 @@ static uint8_t gpioToEDS [] = } ; // gpioToREN -// (Word) offset to the Rising edgde ENable register +// (Word) offset to the Rising edge ENable register static uint8_t gpioToREN [] = { @@ -376,6 +553,7 @@ static uint8_t gpioToPwmALT [] = 0, 0, 0, 0, 0, 0, 0, 0, // 56 -> 63 } ; + // gpioToPwmPort // The port value to put a GPIO pin into PWM mode @@ -395,7 +573,7 @@ static uint8_t gpioToPwmPort [] = // gpioToGpClkALT: // ALT value to put a GPIO pin into GP Clock mode. // On the Pi we can really only use BCM_GPIO_4 and BCM_GPIO_21 -// for clocks 0 and 1 respectivey, however I'll include the full +// for clocks 0 and 1 respectively, however I'll include the full // list for completeness - maybe one day... #define GPIO_CLOCK_SOURCE 1 @@ -449,46 +627,52 @@ static uint8_t gpioToClkDiv [] = /* - * wpiPinToGpio: - * Translate a wiringPi Pin number to native GPIO pin number. - * (We don't use this here, prefering to just do the lookup directly, - * but it's been requested!) + * wiringPiFailure: + * Fail. Or not. ********************************************************************************* */ -int wpiPinToGpio (int wpiPin) +int wiringPiFailure (int fatal, const char *message, ...) { - return pinToGpio [wpiPin & 63] ; + va_list argp ; + char buffer [1024] ; + + if (!fatal && wiringPiReturnCodes) + return -1 ; + + va_start (argp, message) ; + vsnprintf (buffer, 1023, message, argp) ; + va_end (argp) ; + + fprintf (stderr, "%s", buffer) ; + exit (EXIT_FAILURE) ; + + return 0 ; } /* * piBoardRev: * Return a number representing the hardware revision of the board. - * Revision is currently 1 or 2. -1 is returned on error. + * This is not strictly the board revision but is used to check the + * layout of the GPIO connector - and there are 2 types that we are + * really interested in here. The very earliest Pi's and the + * ones that came after that which switched some pins .... * - * Much confusion here )-: - * Seems there are some boards with 0000 in them (mistake in manufacture) - * and some board with 0005 in them (another mistake in manufacture?) - * So the distinction between boards that I can see is: - * 0000 - Error - * 0001 - Not used - * 0002 - Rev 1 - * 0003 - Rev 1 - * 0004 - Rev 2 (Early reports? - * 0005 - Rev 2 (but error?) - * 0006 - Rev 2 - * 0008 - Rev 2 - Model A - * 000e - Rev 2 + 512MB - * 000f - Rev 2 + 512MB + * Revision 1 really means the early Model A and B's. + * Revision 2 is everything else - it covers the B, B+ and CM. + * ... and the Pi 2 - which is a B+ ++ ... + * ... and the Pi 0 - which is an A+ ... * - * A small thorn is the olde style overvolting - that will add in - * 1000000 + * The main difference between the revision 1 and 2 system that I use here + * is the mapping of the GPIO pins. From revision 2, the Pi Foundation changed + * 3 GPIO pins on the (original) 26-way header - BCM_GPIO 22 was dropped and + * replaced with 27, and 0 + 1 - I2C bus 0 was changed to 2 + 3; I2C bus 1. * ********************************************************************************* */ -static void piBoardRevOops (char *why) +static void piBoardRevOops (const char *why) { fprintf (stderr, "piBoardRev: Unable to determine board revision from /proc/cpuinfo\n") ; fprintf (stderr, " -> %s\n", why) ; @@ -501,7 +685,7 @@ int piBoardRev (void) { FILE *cpuFd ; char line [120] ; - char *c, lastChar ; + char *c ; static int boardRev = -1 ; if (boardRev != -1) // No point checking twice @@ -510,6 +694,190 @@ int piBoardRev (void) if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL) piBoardRevOops ("Unable to open /proc/cpuinfo") ; +// Start by looking for the Architecture to make sure we're really running +// on a Pi. I'm getting fed-up with people whinging at me because +// they can't get it to work on weirdFruitPi boards... + + while (fgets (line, 120, cpuFd) != NULL) + if (strncmp (line, "Hardware", 8) == 0) + break ; + + if (strncmp (line, "Hardware", 8) != 0) + piBoardRevOops ("No hardware line") ; + + if (wiringPiDebug) + printf ("piboardRev: Hardware: %s\n", line) ; + +// See if it's BCM2708 or BCM2709 + + if (strstr (line, "BCM2709") != NULL) // Pi v2 - no point doing anything more at this point + { + piModel2 = TRUE ; + fclose (cpuFd) ; + return boardRev = 2 ; + } + else if (strstr (line, "BCM2708") == NULL) + { + fprintf (stderr, "Unable to determine hardware version. I see: %s,\n", line) ; + fprintf (stderr, " - expecting BCM2708 or BCM2709.\n") ; + fprintf (stderr, "If this is a genuine Raspberry Pi then please report this\n") ; + fprintf (stderr, "to projects@drogon.net. If this is not a Raspberry Pi then you\n") ; + fprintf (stderr, "are on your own as wiringPi is designed to support the\n") ; + fprintf (stderr, "Raspberry Pi ONLY.\n") ; + exit (EXIT_FAILURE) ; + } + +// Now do the rest of it as before - we just need to see if it's an older +// Rev 1 as anything else is rev 2. + +// Isolate the Revision line + + rewind (cpuFd) ; + while (fgets (line, 120, cpuFd) != NULL) + if (strncmp (line, "Revision", 8) == 0) + break ; + + fclose (cpuFd) ; + + if (strncmp (line, "Revision", 8) != 0) + piBoardRevOops ("No \"Revision\" line") ; + +// Chomp trailing CR/NL + + for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c) + *c = 0 ; + + if (wiringPiDebug) + printf ("piboardRev: Revision string: %s\n", line) ; + +// Scan to the first character of the revision number + + for (c = line ; *c ; ++c) + if (*c == ':') + break ; + + if (*c != ':') + piBoardRevOops ("Bogus \"Revision\" line (no colon)") ; + +// Chomp spaces + + ++c ; + while (isspace (*c)) + ++c ; + + if (!isxdigit (*c)) + piBoardRevOops ("Bogus \"Revision\" line (no hex digit at start of revision)") ; + +// Make sure its long enough + + if (strlen (c) < 4) + piBoardRevOops ("Bogus revision line (too small)") ; + +// If you have overvolted the Pi, then it appears that the revision +// has 100000 added to it! +// The actual condition for it being set is: +// (force_turbo || current_limit_override || temp_limit>85) && over_voltage>0 + + +// This test is not correct for the new encoding scheme, so we'll remove it here as +// we don't really need it at this point. + +/******************** + if (wiringPiDebug) + if (strlen (c) != 4) + printf ("piboardRev: This Pi has/is (force_turbo || current_limit_override || temp_limit>85) && over_voltage>0\n") ; +*******************/ + +// Isolate last 4 characters: + + c = c + strlen (c) - 4 ; + + if (wiringPiDebug) + printf ("piboardRev: last4Chars are: \"%s\"\n", c) ; + + if ( (strcmp (c, "0002") == 0) || (strcmp (c, "0003") == 0)) + boardRev = 1 ; + else + boardRev = 2 ; // Covers everything else from the B revision 2 to the B+, the Pi v2 and CM's. + + if (wiringPiDebug) + printf ("piBoardRev: Returning revision: %d\n", boardRev) ; + + return boardRev ; +} + + +/* + * piBoardId: + * Return the real details of the board we have. + * + * This is undocumented and really only intended for the GPIO command. + * Use at your own risk! + * + * Seems there are some boards with 0000 in them (mistake in manufacture) + * So the distinction between boards that I can see is: + * + * 0000 - Error + * 0001 - Not used + * + * Original Pi boards: + * 0002 - Model B, Rev 1, 256MB, Egoman + * 0003 - Model B, Rev 1.1, 256MB, Egoman, Fuses/D14 removed. + * + * Newer Pi's with remapped GPIO: + * 0004 - Model B, Rev 2, 256MB, Sony + * 0005 - Model B, Rev 2, 256MB, Qisda + * 0006 - Model B, Rev 2, 256MB, Egoman + * 0007 - Model A, Rev 2, 256MB, Egoman + * 0008 - Model A, Rev 2, 256MB, Sony + * 0009 - Model A, Rev 2, 256MB, Qisda + * 000d - Model B, Rev 2, 512MB, Egoman (Red Pi, Blue Pi?) + * 000e - Model B, Rev 2, 512MB, Sony + * 000f - Model B, Rev 2, 512MB, Qisda + * 0010 - Model B+, Rev 1.2, 512MB, Sony + * 0011 - Pi CM, Rev 1.2, 512MB, Sony + * 0012 - Model A+ Rev 1.2, 256MB, Sony + * 0014 - Pi CM, Rev 1.1, 512MB, Sony (Actual Revision might be different) + * 0015 - Model A+ Rev 1.1, 256MB, Sony + * + * A small thorn is the olde style overvolting - that will add in + * 1000000 + * + * The Pi compute module has an revision of 0011 or 0014 - since we only + * check the last digit, then it's 1, therefore it'll default to not 2 or + * 3 for a Rev 1, so will appear as a Rev 2. This is fine for the most part, but + * we'll properly detect the Compute Module later and adjust accordingly. + * + * And then things changed with the introduction of the v2... + * + * For Pi v2 and subsequent models - e.g. the Zero: + * + * [USER:8] [NEW:1] [MEMSIZE:3] [MANUFACTURER:4] [PROCESSOR:4] [TYPE:8] [REV:4] + * NEW 23: will be 1 for the new scheme, 0 for the old scheme + * MEMSIZE 20: 0=256M 1=512M 2=1G + * MANUFACTURER 16: 0=SONY 1=EGOMAN 2=EMBEST + * PROCESSOR 12: 0=2835 1=2836 + * TYPE 04: 0=MODELA 1=MODELB 2=MODELA+ 3=MODELB+ 4=Pi2 MODEL B 5=ALPHA 6=CM + * REV 00: 0=REV0 1=REV1 2=REV2 + ********************************************************************************* + */ + +void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) +{ + FILE *cpuFd ; + char line [120] ; + char *c ; + unsigned int revision ; + int bRev, bType, bProc, bMfg, bMem, bWarranty ; + +// Will deal with the properly later on - for now, lets just get it going... +// unsigned int modelNum ; + + (void)piBoardRev () ; // Call this first to make sure all's OK. Don't care about the result. + + if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL) + piBoardRevOops ("Unable to open /proc/cpuinfo") ; + while (fgets (line, 120, cpuFd) != NULL) if (strncmp (line, "Revision", 8) == 0) break ; @@ -519,43 +887,161 @@ int piBoardRev (void) if (strncmp (line, "Revision", 8) != 0) piBoardRevOops ("No \"Revision\" line") ; +// Chomp trailing CR/NL + for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c) *c = 0 ; if (wiringPiDebug) - printf ("piboardRev: Revision string: %s\n", line) ; + printf ("piboardId: Revision string: %s\n", line) ; + +// Need to work out if it's using the new or old encoding scheme: + +// Scan to the first character of the revision number for (c = line ; *c ; ++c) - if (isdigit (*c)) + if (*c == ':') break ; - if (!isdigit (*c)) - piBoardRevOops ("No numeric revision string") ; + if (*c != ':') + piBoardRevOops ("Bogus \"Revision\" line (no colon)") ; -// If you have overvolted the Pi, then it appears that the revision -// has 100000 added to it! +// Chomp spaces - if (wiringPiDebug) - if (strlen (c) != 4) - printf ("piboardRev: This Pi has/is overvolted!\n") ; + ++c ; + while (isspace (*c)) + ++c ; - lastChar = line [strlen (line) - 1] ; + if (!isxdigit (*c)) + piBoardRevOops ("Bogus \"Revision\" line (no hex digit at start of revision)") ; - if (wiringPiDebug) - printf ("piboardRev: lastChar is: '%c' (%d, 0x%02X)\n", lastChar, lastChar, lastChar) ; + revision = (unsigned int)strtol (c, NULL, 16) ; // Hex number with no leading 0x - /**/ if ((lastChar == '2') || (lastChar == '3')) - boardRev = 1 ; - else - boardRev = 2 ; +// Check for new way: - if (wiringPiDebug) - printf ("piBoardRev: Returning revision: %d\n", boardRev) ; + if ((revision & (1 << 23)) != 0) // New way + { + if (wiringPiDebug) + printf ("piBoardId: New Way: revision is: 0x%08X\n", revision) ; - return boardRev ; + bRev = (revision & (0x0F << 0)) >> 0 ; + bType = (revision & (0xFF << 4)) >> 4 ; + bProc = (revision & (0x0F << 12)) >> 12 ; // Not used for now. + bMfg = (revision & (0x0F << 16)) >> 16 ; + bMem = (revision & (0x07 << 20)) >> 20 ; + bWarranty = (revision & (0x03 << 24)) != 0 ; + + *model = bType ; + *rev = bRev ; + *mem = bMem ; + *maker = bMfg ; + *warranty = bWarranty ; + + if (wiringPiDebug) + printf ("piboardId: rev: %d, type: %d, proc: %d, mfg: %d, mem: %d, warranty: %d\n", + bRev, bType, bProc, bMfg, bMem, bWarranty) ; + } + else // Old way + { + if (wiringPiDebug) + printf ("piBoardId: Old Way: revision is: %s\n", c) ; + + if (!isdigit (*c)) + piBoardRevOops ("Bogus \"Revision\" line (no digit at start of revision)") ; + +// Make sure its long enough + + if (strlen (c) < 4) + piBoardRevOops ("Bogus \"Revision\" line (not long enough)") ; + +// If longer than 4, we'll assume it's been overvolted + + *warranty = strlen (c) > 4 ; + +// Extract last 4 characters: + + c = c + strlen (c) - 4 ; + +// Fill out the replys as appropriate + + /**/ if (strcmp (c, "0002") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0003") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0004") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0005") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_UNKNOWN ; } + else if (strcmp (c, "0006") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0007") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0008") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; ; } + else if (strcmp (c, "0009") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 0 ; *maker = PI_MAKER_UNKNOWN ; } + else if (strcmp (c, "000d") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "000e") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "000f") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0010") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0011") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0012") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0013") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0014") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0015") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else { *model = 0 ; *rev = 0 ; *mem = 0 ; *maker = 0 ; } + } +} + + + +/* + * wpiPinToGpio: + * Translate a wiringPi Pin number to native GPIO pin number. + * Provided for external support. + ********************************************************************************* + */ + +int wpiPinToGpio (int wpiPin) +{ + return pinToGpio [wpiPin & 63] ; } +/* + * physPinToGpio: + * Translate a physical Pin number to native GPIO pin number. + * Provided for external support. + ********************************************************************************* + */ + +int physPinToGpio (int physPin) +{ + return physToGpio [physPin & 63] ; +} + + +/* + * setPadDrive: + * Set the PAD driver value + ********************************************************************************* + */ + +void setPadDrive (int group, int value) +{ + uint32_t wrVal ; + + if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) + { + if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; + + if ((group < 0) || (group > 2)) + return ; + + wrVal = BCM_PASSWORD | 0x18 | (value & 7) ; + *(pads + group + 11) = wrVal ; + + if (wiringPiDebug) + { + printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ; + printf ("Read : %08X\n", *(pads + group + 11)) ; + } + } +} + /* * getAlt: @@ -564,12 +1050,19 @@ int piBoardRev (void) ********************************************************************************* */ -int getAltGpio (int pin) +int getAlt (int pin) { int fSel, shift, alt ; pin &= 63 ; + /**/ if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [pin] ; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio [pin] ; + else if (wiringPiMode != WPI_MODE_GPIO) + return 0 ; + fSel = gpioToGPFSEL [pin] ; shift = gpioToShift [pin] ; @@ -578,70 +1071,72 @@ int getAltGpio (int pin) return alt ; } -int getAltWPi (int pin) -{ - return getAltGpio (pinToGpio [pin & 63]) ; -} - -int getAltSys (int pin) -{ - return 0 ; -} - /* - * pwmControl: - * Allow the user to control some of the PWM functions + * pwmSetMode: + * Select the native "balanced" mode, or standard mark:space mode ********************************************************************************* */ -void pwmSetModeWPi (int mode) +void pwmSetMode (int mode) { - if (mode == PWM_MODE_MS) - *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ; - else - *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ; + if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) + { + if (mode == PWM_MODE_MS) + *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE | PWM0_MS_MODE | PWM1_MS_MODE ; + else + *(pwm + PWM_CONTROL) = PWM0_ENABLE | PWM1_ENABLE ; + } } -void pwmSetModeSys (int mode) -{ - return ; -} - - -void pwmSetRangeWPi (unsigned int range) -{ - *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ; - *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ; -} - -void pwmSetRangeSys (unsigned int range) -{ - return ; -} /* - * pwmSetClockWPi: + * pwmSetRange: + * Set the PWM range register. We set both range registers to the same + * value. If you want different in your own code, then write your own. + ********************************************************************************* + */ + +void pwmSetRange (unsigned int range) +{ + if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) + { + if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; + + *(pwm + PWM0_RANGE) = range ; delayMicroseconds (10) ; + *(pwm + PWM1_RANGE) = range ; delayMicroseconds (10) ; + } +} + + +/* + * pwmSetClock: * Set/Change the PWM clock. Originally my code, but changed * (for the better!) by Chris Hall, * after further study of the manual and testing with a 'scope ********************************************************************************* */ -void pwmSetClockWPi (int divisor) +void pwmSetClock (int divisor) { uint32_t pwm_control ; divisor &= 4095 ; - if (wiringPiDebug) - printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ; + if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO)) + { + if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; - pwm_control = *(pwm + PWM_CONTROL) ; // preserve PWM_CONTROL + if (wiringPiDebug) + printf ("Setting to: %d. Current: 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ; + + pwm_control = *(pwm + PWM_CONTROL) ; // preserve PWM_CONTROL // We need to stop PWM prior to stopping PWM clock in MS mode otherwise BUSY // stays high. - *(pwm + PWM_CONTROL) = 0 ; // Stop PWM + *(pwm + PWM_CONTROL) = 0 ; // Stop PWM // Stop PWM clock before changing divisor. The delay after this does need to // this big (95uS occasionally fails, 100uS OK), it's almost as though the BUSY @@ -649,24 +1144,128 @@ void pwmSetClockWPi (int divisor) // adjusted the clock sometimes switches to very slow, once slow further DIV // adjustments do nothing and it's difficult to get out of this mode. - *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock - delayMicroseconds (110) ; // prevents clock going sloooow + *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x01 ; // Stop PWM Clock + delayMicroseconds (110) ; // prevents clock going sloooow - while ((*(clk + PWMCLK_CNTL) & 0x80) != 0) // Wait for clock to be !BUSY - delayMicroseconds (1) ; + while ((*(clk + PWMCLK_CNTL) & 0x80) != 0) // Wait for clock to be !BUSY + delayMicroseconds (1) ; - *(clk + PWMCLK_DIV) = BCM_PASSWORD | (divisor << 12) ; + *(clk + PWMCLK_DIV) = BCM_PASSWORD | (divisor << 12) ; - *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Start PWM clock - *(pwm + PWM_CONTROL) = pwm_control ; // restore PWM_CONTROL + *(clk + PWMCLK_CNTL) = BCM_PASSWORD | 0x11 ; // Start PWM clock + *(pwm + PWM_CONTROL) = pwm_control ; // restore PWM_CONTROL - if (wiringPiDebug) - printf ("Set to: %d. Now : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ; + if (wiringPiDebug) + printf ("Set to: %d. Now : 0x%08X\n", divisor, *(clk + PWMCLK_DIV)) ; + } } -void pwmSetClockSys (int divisor) + +/* + * gpioClockSet: + * Set the freuency on a GPIO clock pin + ********************************************************************************* + */ + +void gpioClockSet (int pin, int freq) { - return ; + int divi, divr, divf ; + + pin &= 63 ; + + /**/ if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [pin] ; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio [pin] ; + else if (wiringPiMode != WPI_MODE_GPIO) + return ; + + if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; + + divi = 19200000 / freq ; + divr = 19200000 % freq ; + divf = (int)((double)divr * 4096.0 / 19200000.0) ; + + if (divi > 4095) + divi = 4095 ; + + *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | GPIO_CLOCK_SOURCE ; // Stop GPIO Clock + while ((*(clk + gpioToClkCon [pin]) & 0x80) != 0) // ... and wait + ; + + *(clk + gpioToClkDiv [pin]) = BCM_PASSWORD | (divi << 12) | divf ; // Set dividers + *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | 0x10 | GPIO_CLOCK_SOURCE ; // Start Clock +} + + +/* + * wiringPiFindNode: + * Locate our device node + ********************************************************************************* + */ + +struct wiringPiNodeStruct *wiringPiFindNode (int pin) +{ + struct wiringPiNodeStruct *node = wiringPiNodes ; + + while (node != NULL) + if ((pin >= node->pinBase) && (pin <= node->pinMax)) + return node ; + else + node = node->next ; + + return NULL ; +} + + +/* + * wiringPiNewNode: + * Create a new GPIO node into the wiringPi handling system + ********************************************************************************* + */ + +static void pinModeDummy (struct wiringPiNodeStruct *node, int pin, int mode) { return ; } +static void pullUpDnControlDummy (struct wiringPiNodeStruct *node, int pin, int pud) { return ; } +static int digitalReadDummy (struct wiringPiNodeStruct *node, int pin) { return LOW ; } +static void digitalWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; } +static void pwmWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; } +static int analogReadDummy (struct wiringPiNodeStruct *node, int pin) { return 0 ; } +static void analogWriteDummy (struct wiringPiNodeStruct *node, int pin, int value) { return ; } + +struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) +{ + int pin ; + struct wiringPiNodeStruct *node ; + +// Minimum pin base is 64 + + if (pinBase < 64) + (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: pinBase of %d is < 64\n", pinBase) ; + +// Check all pins in-case there is overlap: + + for (pin = pinBase ; pin < (pinBase + numPins) ; ++pin) + if (wiringPiFindNode (pin) != NULL) + (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Pin %d overlaps with existing definition\n", pin) ; + + node = (struct wiringPiNodeStruct *)calloc (sizeof (struct wiringPiNodeStruct), 1) ; // calloc zeros + if (node == NULL) + (void)wiringPiFailure (WPI_FATAL, "wiringPiNewNode: Unable to allocate memory: %s\n", strerror (errno)) ; + + node->pinBase = pinBase ; + node->pinMax = pinBase + numPins - 1 ; + node->pinMode = pinModeDummy ; + node->pullUpDnControl = pullUpDnControlDummy ; + node->digitalRead = digitalReadDummy ; + node->digitalWrite = digitalWriteDummy ; + node->pwmWrite = pwmWriteDummy ; + node->analogRead = analogReadDummy ; + node->analogWrite = analogWriteDummy ; + node->next = wiringPiNodes ; + wiringPiNodes = node ; + + return node ; } @@ -686,230 +1285,122 @@ void pinEnableED01Pi (int pin) #endif - /* - * digitalWrite: - * Set an output bit + ********************************************************************************* + * Core Functions ********************************************************************************* */ -void digitalWriteWPi (int pin, int value) -{ - pin = pinToGpio [pin & 63] ; +/* + * pinModeAlt: + * This is an un-documented special to let you set any pin to any mode + ********************************************************************************* + */ - if (value == LOW) - *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ; +void pinModeAlt (int pin, int mode) +{ + int fSel, shift ; + + if ((pin & PI_GPIO_MASK) == 0) // On-board pin + { + /**/ if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [pin] ; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio [pin] ; + else if (wiringPiMode != WPI_MODE_GPIO) + return ; + + fSel = gpioToGPFSEL [pin] ; + shift = gpioToShift [pin] ; + + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | ((mode & 0x7) << shift) ; + } +} + + +/* + * pinMode: + * Sets the mode of a pin to be input, output or PWM output + ********************************************************************************* + */ + +void pinMode (int pin, int mode) +{ + int fSel, shift, alt ; + struct wiringPiNodeStruct *node = wiringPiNodes ; + int origPin = pin ; + + if ((pin & PI_GPIO_MASK) == 0) // On-board pin + { + /**/ if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [pin] ; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio [pin] ; + else if (wiringPiMode != WPI_MODE_GPIO) + return ; + + softPwmStop (origPin) ; + softToneStop (origPin) ; + + fSel = gpioToGPFSEL [pin] ; + shift = gpioToShift [pin] ; + + /**/ if (mode == INPUT) + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input + else if (mode == OUTPUT) + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ; + else if (mode == SOFT_PWM_OUTPUT) + softPwmCreate (origPin, 0, 100) ; + else if (mode == SOFT_TONE_OUTPUT) + softToneCreate (origPin) ; + else if (mode == PWM_TONE_OUTPUT) + { + if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; + + pinMode (origPin, PWM_OUTPUT) ; // Call myself to enable PWM mode + pwmSetMode (PWM_MODE_MS) ; + } + else if (mode == PWM_OUTPUT) + { + if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; + + if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin + return ; + +// Set pin to PWM mode + + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; + delayMicroseconds (110) ; // See comments in pwmSetClockWPi + + pwmSetMode (PWM_MODE_BAL) ; // Pi default mode + pwmSetRange (1024) ; // Default range of 1024 + pwmSetClock (32) ; // 19.2 / 32 = 600KHz - Also starts the PWM + } + else if (mode == GPIO_CLOCK) + { + if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; + + if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin + return ; + +// Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz + + *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; + delayMicroseconds (110) ; + gpioClockSet (pin, 100000) ; + } + } else - *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ; -} - -void digitalWriteGpio (int pin, int value) -{ - pin &= 63 ; - - if (value == LOW) - *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ; - else - *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ; -} - -void digitalWriteSys (int pin, int value) -{ - pin &= 63 ; - - if (sysFds [pin] != -1) { - if (value == LOW) - write (sysFds [pin], "0\n", 2) ; - else - write (sysFds [pin], "1\n", 2) ; - } -} - - -/* - * digitalWriteByte: - * Write an 8-bit byte to the first 8 GPIO pins - try to do it as - * fast as possible. - * However it still needs 2 operations to set the bits, so any external - * hardware must not rely on seeing a change as there will be a change - * to set the outputs bits to zero, then another change to set the 1's - ********************************************************************************* - */ - -void digitalWriteByteGpio (int value) -{ - uint32_t pinSet = 0 ; - uint32_t pinClr = 0 ; - int mask = 1 ; - int pin ; - - for (pin = 0 ; pin < 8 ; ++pin) - { - if ((value & mask) == 0) - pinClr |= (1 << pinToGpio [pin]) ; - else - pinSet |= (1 << pinToGpio [pin]) ; - - mask <<= 1 ; - } - - *(gpio + gpioToGPCLR [0]) = pinClr ; - *(gpio + gpioToGPSET [0]) = pinSet ; -} - -void digitalWriteByteSys (int value) -{ - int mask = 1 ; - int pin ; - - for (pin = 0 ; pin < 8 ; ++pin) - { - digitalWriteSys (pinToGpio [pin], value & mask) ; - mask <<= 1 ; - } -} - - -/* - * pwmWrite: - * Set an output PWM value - ********************************************************************************* - */ - -void pwmWriteGpio (int pin, int value) -{ - int port ; - - pin = pin & 63 ; - port = gpioToPwmPort [pin] ; - - *(pwm + port) = value ; -} - -void pwmWriteWPi (int pin, int value) -{ - pwmWriteGpio (pinToGpio [pin & 63], value) ; -} - -void pwmWriteSys (int pin, int value) -{ - return ; -} - - -/* - * gpioClockSet: - * Set the freuency on a GPIO clock pin - ********************************************************************************* - */ - -void gpioClockSetGpio (int pin, int freq) -{ - int divi, divr, divf ; - - pin &= 63 ; - - divi = 19200000 / freq ; - divr = 19200000 % freq ; - divf = (int)((double)divr * 4096.0 / 19200000.0) ; - - if (divi > 4095) - divi = 4095 ; - - *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | GPIO_CLOCK_SOURCE ; // Stop GPIO Clock - while ((*(clk + gpioToClkCon [pin]) & 0x80) != 0) // ... and wait - ; - - *(clk + gpioToClkDiv [pin]) = BCM_PASSWORD | (divi << 12) | divf ; // Set dividers - *(clk + gpioToClkCon [pin]) = BCM_PASSWORD | 0x10 | GPIO_CLOCK_SOURCE ; // Start Clock -} - -void gpioClockSetWPi (int pin, int freq) -{ - gpioClockSetGpio (pinToGpio [pin & 63], freq) ; -} - -void gpioClockSetSys (int pin, int freq) -{ - return ; -} - - -/* - * setPadDrive: - * Set the PAD driver value - ********************************************************************************* - */ - -void setPadDriveWPi (int group, int value) -{ - uint32_t wrVal ; - - if ((group < 0) || (group > 2)) + if ((node = wiringPiFindNode (pin)) != NULL) + node->pinMode (node, pin, mode) ; return ; - - wrVal = BCM_PASSWORD | 0x18 | (value & 7) ; - *(pads + group + 11) = wrVal ; - - if (wiringPiDebug) - { - printf ("setPadDrive: Group: %d, value: %d (%08X)\n", group, value, wrVal) ; - printf ("Read : %08X\n", *(pads + group + 11)) ; } } -void setPadDriveGpio (int group, int value) -{ - setPadDriveWPi (group, value) ; -} - -void setPadDriveSys (int group, int value) -{ - return ; -} - - -/* - * digitalRead: - * Read the value of a given Pin, returning HIGH or LOW - ********************************************************************************* - */ - -int digitalReadWPi (int pin) -{ - pin = pinToGpio [pin & 63] ; - - if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0) - return HIGH ; - else - return LOW ; -} - -int digitalReadGpio (int pin) -{ - pin &= 63 ; - - if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0) - return HIGH ; - else - return LOW ; -} - -int digitalReadSys (int pin) -{ - char c ; - - pin &= 63 ; - - if (sysFds [pin] == -1) - return 0 ; - - lseek (sysFds [pin], 0L, SEEK_SET) ; - read (sysFds [pin], &c, 1) ; - return (c == '0') ? 0 : 1 ; -} - /* * pullUpDownCtrl: @@ -920,90 +1411,264 @@ int digitalReadSys (int pin) ********************************************************************************* */ -void pullUpDnControlGpio (int pin, int pud) +void pullUpDnControl (int pin, int pud) { - pin &= 63 ; - pud &= 3 ; + struct wiringPiNodeStruct *node = wiringPiNodes ; - *(gpio + GPPUD) = pud ; delayMicroseconds (5) ; - *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ; - - *(gpio + GPPUD) = 0 ; delayMicroseconds (5) ; - *(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ; -} + if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin + { + /**/ if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [pin] ; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio [pin] ; + else if (wiringPiMode != WPI_MODE_GPIO) + return ; -void pullUpDnControlWPi (int pin, int pud) -{ - pullUpDnControlGpio (pinToGpio [pin & 63], pud) ; -} - -void pullUpDnControlSys (int pin, int pud) -{ - return ; + *(gpio + GPPUD) = pud & 3 ; delayMicroseconds (5) ; + *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ; + + *(gpio + GPPUD) = 0 ; delayMicroseconds (5) ; + *(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ; + } + else // Extension module + { + if ((node = wiringPiFindNode (pin)) != NULL) + node->pullUpDnControl (node, pin, pud) ; + return ; + } } /* - * pinMode: - * Sets the mode of a pin to be input, output or PWM output + * digitalRead: + * Read the value of a given Pin, returning HIGH or LOW ********************************************************************************* */ -void pinModeGpio (int pin, int mode) +int digitalRead (int pin) { -// register int barrier ; + char c ; + struct wiringPiNodeStruct *node = wiringPiNodes ; - int fSel, shift, alt ; - - pin &= 63 ; - - fSel = gpioToGPFSEL [pin] ; - shift = gpioToShift [pin] ; - - /**/ if (mode == INPUT) - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to zero = input - else if (mode == OUTPUT) - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ; - else if (mode == PWM_OUTPUT) + if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin { - if ((alt = gpioToPwmALT [pin]) == 0) // Not a PWM pin - return ; + /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode + { + if (sysFds [pin] == -1) + return LOW ; -// Set pin to PWM mode + lseek (sysFds [pin], 0L, SEEK_SET) ; + read (sysFds [pin], &c, 1) ; + return (c == '0') ? LOW : HIGH ; + } + else if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [pin] ; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio [pin] ; + else if (wiringPiMode != WPI_MODE_GPIO) + return LOW ; - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; - delayMicroseconds (110) ; // See comments in pwmSetClockWPi - - pwmSetModeWPi (PWM_MODE_BAL) ; // Pi default mode - pwmSetRangeWPi (1024) ; // Default range of 1024 - pwmSetClockWPi (32) ; // 19.2 / 32 = 600KHz - Also starts the PWM + if ((*(gpio + gpioToGPLEV [pin]) & (1 << (pin & 31))) != 0) + return HIGH ; + else + return LOW ; } - else if (mode == GPIO_CLOCK) + else { - if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin - return ; - -// Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz - - *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; - delayMicroseconds (110) ; - gpioClockSetGpio (pin, 100000) ; + if ((node = wiringPiFindNode (pin)) == NULL) + return LOW ; + return node->digitalRead (node, pin) ; } } -void pinModeWPi (int pin, int mode) + +/* + * digitalWrite: + * Set an output bit + ********************************************************************************* + */ + +void digitalWrite (int pin, int value) { - pinModeGpio (pinToGpio [pin & 63], mode) ; + struct wiringPiNodeStruct *node = wiringPiNodes ; + + if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin + { + /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode + { + if (sysFds [pin] != -1) + { + if (value == LOW) + write (sysFds [pin], "0\n", 2) ; + else + write (sysFds [pin], "1\n", 2) ; + } + return ; + } + else if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [pin] ; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio [pin] ; + else if (wiringPiMode != WPI_MODE_GPIO) + return ; + + if (value == LOW) + *(gpio + gpioToGPCLR [pin]) = 1 << (pin & 31) ; + else + *(gpio + gpioToGPSET [pin]) = 1 << (pin & 31) ; + } + else + { + if ((node = wiringPiFindNode (pin)) != NULL) + node->digitalWrite (node, pin, value) ; + } } -void pinModeSys (int pin, int mode) + +/* + * pwmWrite: + * Set an output PWM value + ********************************************************************************* + */ + +void pwmWrite (int pin, int value) { - return ; + struct wiringPiNodeStruct *node = wiringPiNodes ; + + if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin + { + if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; + + /**/ if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [pin] ; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio [pin] ; + else if (wiringPiMode != WPI_MODE_GPIO) + return ; + + *(pwm + gpioToPwmPort [pin]) = value ; + } + else + { + if ((node = wiringPiFindNode (pin)) != NULL) + node->pwmWrite (node, pin, value) ; + } +} + + +/* + * analogRead: + * Read the analog value of a given Pin. + * There is no on-board Pi analog hardware, + * so this needs to go to a new node. + ********************************************************************************* + */ + +int analogRead (int pin) +{ + struct wiringPiNodeStruct *node = wiringPiNodes ; + + if ((node = wiringPiFindNode (pin)) == NULL) + return 0 ; + else + return node->analogRead (node, pin) ; +} + + +/* + * analogWrite: + * Write the analog value to the given Pin. + * There is no on-board Pi analog hardware, + * so this needs to go to a new node. + ********************************************************************************* + */ + +void analogWrite (int pin, int value) +{ + struct wiringPiNodeStruct *node = wiringPiNodes ; + + if ((node = wiringPiFindNode (pin)) == NULL) + return ; + + node->analogWrite (node, pin, value) ; +} + + +/* + * pwmToneWrite: + * Pi Specific. + * Output the given frequency on the Pi's PWM pin + ********************************************************************************* + */ + +void pwmToneWrite (int pin, int freq) +{ + int range ; + + if (RASPBERRY_PI_PERI_BASE == 0) // Ignore for now + return ; + + if (freq == 0) + pwmWrite (pin, 0) ; // Off + else + { + range = 600000 / freq ; + pwmSetRange (range) ; + pwmWrite (pin, freq / 2) ; + } +} + + + +/* + * digitalWriteByte: + * Pi Specific + * Write an 8-bit byte to the first 8 GPIO pins - try to do it as + * fast as possible. + * However it still needs 2 operations to set the bits, so any external + * hardware must not rely on seeing a change as there will be a change + * to set the outputs bits to zero, then another change to set the 1's + ********************************************************************************* + */ + +void digitalWriteByte (int value) +{ + uint32_t pinSet = 0 ; + uint32_t pinClr = 0 ; + int mask = 1 ; + int pin ; + + /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) + { + for (pin = 0 ; pin < 8 ; ++pin) + { + digitalWrite (pin, value & mask) ; + mask <<= 1 ; + } + return ; + } + else + { + for (pin = 0 ; pin < 8 ; ++pin) + { + if ((value & mask) == 0) + pinClr |= (1 << pinToGpio [pin]) ; + else + pinSet |= (1 << pinToGpio [pin]) ; + + mask <<= 1 ; + } + + *(gpio + gpioToGPCLR [0]) = pinClr ; + *(gpio + gpioToGPSET [0]) = pinSet ; + } } /* * waitForInterrupt: + * Pi Specific. * Wait for Interrupt on a GPIO pin. * This is actually done via the /sys/class/gpio interface regardless of * the wiringPi access mode in-use. Maybe sometime it might get a better @@ -1011,13 +1676,18 @@ void pinModeSys (int pin, int mode) ********************************************************************************* */ -int waitForInterruptSys (int pin, int mS) +int waitForInterrupt (int pin, int mS) { int fd, x ; uint8_t c ; struct pollfd polls ; - if ((fd = sysFds [pin & 63]) == -1) + /**/ if (wiringPiMode == WPI_MODE_PINS) + pin = pinToGpio [pin] ; + else if (wiringPiMode == WPI_MODE_PHYS) + pin = physToGpio [pin] ; + + if ((fd = sysFds [pin]) == -1) return -2 ; // Setup poll structure @@ -1031,22 +1701,14 @@ int waitForInterruptSys (int pin, int mS) // Do a dummy read to clear the interrupt // A one character read appars to be enough. +// Followed by a seek to reset it. (void)read (fd, &c, 1) ; + lseek (fd, 0, SEEK_SET) ; return x ; } -int waitForInterruptWPi (int pin, int mS) -{ - return waitForInterruptSys (pinToGpio [pin & 63], mS) ; -} - -int waitForInterruptGpio (int pin, int mS) -{ - return waitForInterruptSys (pin, mS) ; -} - /* * interruptHandler: @@ -1058,12 +1720,15 @@ int waitForInterruptGpio (int pin, int mS) static void *interruptHandler (void *arg) { - int myPin = *(int *)arg ; + int myPin ; (void)piHiPri (55) ; // Only effective if we run as root + myPin = pinPass ; + pinPass = -1 ; + for (;;) - if (waitForInterruptSys (myPin, -1) > 0) + if (waitForInterrupt (myPin, -1) > 0) isrFunctions [myPin] () ; return NULL ; @@ -1072,6 +1737,7 @@ static void *interruptHandler (void *arg) /* * wiringPiISR: + * Pi Specific. * Take the details and create an interrupt handler that will do a call- * back to the user supplied function. ********************************************************************************* @@ -1080,22 +1746,25 @@ static void *interruptHandler (void *arg) int wiringPiISR (int pin, int mode, void (*function)(void)) { pthread_t threadId ; + const char *modeS ; char fName [64] ; - char *modeS ; char pinS [8] ; pid_t pid ; int count, i ; - uint8_t c ; + char c ; + int bcmGpioPin ; - pin &= 63 ; + if ((pin < 0) || (pin > 63)) + return wiringPiFailure (WPI_FATAL, "wiringPiISR: pin must be 0-63 (%d)\n", pin) ; - if (wiringPiMode == WPI_MODE_UNINITIALISED) - { - fprintf (stderr, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ; - exit (EXIT_FAILURE) ; - } + /**/ if (wiringPiMode == WPI_MODE_UNINITIALISED) + return wiringPiFailure (WPI_FATAL, "wiringPiISR: wiringPi has not been initialised. Unable to continue.\n") ; else if (wiringPiMode == WPI_MODE_PINS) - pin = pinToGpio [pin] ; + bcmGpioPin = pinToGpio [pin] ; + else if (wiringPiMode == WPI_MODE_PHYS) + bcmGpioPin = physToGpio [pin] ; + else + bcmGpioPin = pin ; // Now export the pin and set the right edge // We're going to use the gpio program to do this, so it assumes @@ -1112,38 +1781,54 @@ int wiringPiISR (int pin, int mode, void (*function)(void)) else modeS = "both" ; - sprintf (pinS, "%d", pin) ; + sprintf (pinS, "%d", bcmGpioPin) ; if ((pid = fork ()) < 0) // Fail - return pid ; + return wiringPiFailure (WPI_FATAL, "wiringPiISR: fork failed: %s\n", strerror (errno)) ; if (pid == 0) // Child, exec { - execl ("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ; - return -1 ; // Failure ... + /**/ if (access ("/usr/local/bin/gpio", X_OK) == 0) + { + execl ("/usr/local/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ; + return wiringPiFailure (WPI_FATAL, "wiringPiISR: execl failed: %s\n", strerror (errno)) ; + } + else if (access ("/usr/bin/gpio", X_OK) == 0) + { + execl ("/usr/bin/gpio", "gpio", "edge", pinS, modeS, (char *)NULL) ; + return wiringPiFailure (WPI_FATAL, "wiringPiISR: execl failed: %s\n", strerror (errno)) ; + } + else + return wiringPiFailure (WPI_FATAL, "wiringPiISR: Can't find gpio program\n") ; } else // Parent, wait wait (NULL) ; } -// Now pre-open the /sys/class node - it may already be open if -// we are in Sys mode, but this will do no harm. +// Now pre-open the /sys/class node - but it may already be open if +// we are in Sys mode... - sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; - if ((sysFds [pin] = open (fName, O_RDWR)) < 0) - return -1 ; + if (sysFds [bcmGpioPin] == -1) + { + sprintf (fName, "/sys/class/gpio/gpio%d/value", bcmGpioPin) ; + if ((sysFds [bcmGpioPin] = open (fName, O_RDWR)) < 0) + return wiringPiFailure (WPI_FATAL, "wiringPiISR: unable to open %s: %s\n", fName, strerror (errno)) ; + } // Clear any initial pending interrupt - ioctl (sysFds [pin], FIONREAD, &count) ; + ioctl (sysFds [bcmGpioPin], FIONREAD, &count) ; for (i = 0 ; i < count ; ++i) - read (sysFds [pin], &c, 1) ; + read (sysFds [bcmGpioPin], &c, 1) ; isrFunctions [pin] = function ; - pthread_create (&threadId, NULL, interruptHandler, &pin) ; - - delay (1) ; + pthread_mutex_lock (&pinMutex) ; + pinPass = pin ; + pthread_create (&threadId, NULL, interruptHandler, NULL) ; + while (pinPass != -1) + delay (1) ; + pthread_mutex_unlock (&pinMutex) ; return 0 ; } @@ -1152,7 +1837,7 @@ int wiringPiISR (int pin, int mode, void (*function)(void)) /* * initialiseEpoch: * Initialise our start-of-time variable to be the current unix - * time in milliseconds. + * time in milliseconds and microseconds. ********************************************************************************* */ @@ -1165,9 +1850,10 @@ static void initialiseEpoch (void) epochMicro = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)(tv.tv_usec) ; } + /* * delay: - * Wait for some number of milli seconds + * Wait for some number of milliseconds ********************************************************************************* */ @@ -1216,6 +1902,8 @@ void delayMicrosecondsHard (unsigned int howLong) void delayMicroseconds (unsigned int howLong) { struct timespec sleeper ; + unsigned int uSecs = howLong % 1000000 ; + unsigned int wSecs = howLong / 1000000 ; /**/ if (howLong == 0) return ; @@ -1223,8 +1911,8 @@ void delayMicroseconds (unsigned int howLong) delayMicrosecondsHard (howLong) ; else { - sleeper.tv_sec = 0 ; - sleeper.tv_nsec = (long)(howLong * 1000) ; + sleeper.tv_sec = wSecs ; + sleeper.tv_nsec = (long)(uSecs * 1000L) ; nanosleep (&sleeper, NULL) ; } } @@ -1272,132 +1960,117 @@ unsigned int micros (void) * * Default setup: Initialises the system into wiringPi Pin mode and uses the * memory mapped hardware directly. + * + * Changed now to revert to "gpio" mode if we're running on a Compute Module. ********************************************************************************* */ int wiringPiSetup (void) { - int fd ; - int boardRev ; + int fd ; + int boardRev ; + int model, rev, mem, maker, overVolted ; - if (geteuid () != 0) - { - fprintf (stderr, "wiringPi:\n Must be root to call wiringPiSetup().\n (Did you forget sudo?)\n") ; - exit (EXIT_FAILURE) ; - } - - if (getenv ("WIRINGPI_DEBUG") != NULL) - { - printf ("wiringPi: Debug mode enabled\n") ; + if (getenv (ENV_DEBUG) != NULL) wiringPiDebug = TRUE ; - } + + if (getenv (ENV_CODES) != NULL) + wiringPiReturnCodes = TRUE ; + + if (getenv (ENV_GPIOMEM) != NULL) + wiringPiTryGpioMem = TRUE ; if (wiringPiDebug) - printf ("wiringPi: wiringPiSetup called\n") ; - - pinMode = pinModeWPi ; - getAlt = getAltWPi ; - pullUpDnControl = pullUpDnControlWPi ; - digitalWrite = digitalWriteWPi ; - digitalWriteByte = digitalWriteByteGpio ; // Same code - gpioClockSet = gpioClockSetWPi ; - pwmWrite = pwmWriteWPi ; - setPadDrive = setPadDriveWPi ; - digitalRead = digitalReadWPi ; - waitForInterrupt = waitForInterruptWPi ; - pwmSetMode = pwmSetModeWPi ; - pwmSetRange = pwmSetRangeWPi ; - pwmSetClock = pwmSetClockWPi ; - - boardRev = piBoardRev () ; - - if (boardRev == 1) - pinToGpio = pinToGpioR1 ; - else - pinToGpio = pinToGpioR2 ; - -// Open the master /dev/memory device - - if ((fd = open ("/dev/mem", O_RDWR | O_SYNC) ) < 0) { - if (wiringPiDebug) - { - int serr = errno ; - fprintf (stderr, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ; - errno = serr ; - } - return -1 ; + printf ("wiringPi: wiringPiSetup called\n") ; + if (wiringPiTryGpioMem) + printf ("wiringPi: Using /dev/gpiomem\n") ; } -// GPIO: + boardRev = piBoardRev () ; + + /**/ if (boardRev == 1) // A, B, Rev 1, 1.1 + { + pinToGpio = pinToGpioR1 ; + physToGpio = physToGpioR1 ; + } + else // A, B, Rev 2, B+, CM, Pi2 + { + pinToGpio = pinToGpioR2 ; + physToGpio = physToGpioR2 ; + } + + if (piModel2) + RASPBERRY_PI_PERI_BASE = 0x3F000000 ; + else + RASPBERRY_PI_PERI_BASE = 0x20000000 ; + +// Open the master /dev/ memory control device + +// See if /dev/gpiomem exists and we can open it... + + if (wiringPiTryGpioMem) + { + if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/gpiomem: %s\n", strerror (errno)) ; + RASPBERRY_PI_PERI_BASE = 0 ; + } + +// ... otherwise fall back to the original /dev/mem which requires root level access + + else + { + +// This check is here because people are too stupid to check for themselves or read +// error messages. + + if (geteuid () != 0) + (void)wiringPiFailure (WPI_FATAL, "wiringPiSetup: Must be root. (Did you forget sudo?)\n") ; + + if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem: %s\n", strerror (errno)) ; + } + +// Set the offsets into the memory interface. + + GPIO_PADS = RASPBERRY_PI_PERI_BASE + 0x00100000 ; + GPIO_CLOCK_BASE = RASPBERRY_PI_PERI_BASE + 0x00101000 ; + GPIO_BASE = RASPBERRY_PI_PERI_BASE + 0x00200000 ; + GPIO_TIMER = RASPBERRY_PI_PERI_BASE + 0x0000B000 ; + GPIO_PWM = RASPBERRY_PI_PERI_BASE + 0x0020C000 ; + +// Map the individual hardware components + +// GPIO: gpio = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_BASE) ; if ((int32_t)gpio == -1) - { - if (wiringPiDebug) - { - int serr = errno ; - fprintf (stderr, "wiringPiSetup: mmap failed: %s\n", strerror (errno)) ; - errno = serr ; - } - return -1 ; - } + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (GPIO) failed: %s\n", strerror (errno)) ; -// PWM +// PWM pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ; if ((int32_t)pwm == -1) - { - if (wiringPiDebug) - { - int serr = errno ; - fprintf (stderr, "wiringPiSetup: mmap failed (pwm): %s\n", strerror (errno)) ; - errno = serr ; - } - return -1 ; - } + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PWM) failed: %s\n", strerror (errno)) ; -// Clock control (needed for PWM) +// Clock control (needed for PWM) - clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, CLOCK_BASE) ; + clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_CLOCK_BASE) ; if ((int32_t)clk == -1) - { - if (wiringPiDebug) - { - int serr = errno ; - fprintf (stderr, "wiringPiSetup: mmap failed (clk): %s\n", strerror (errno)) ; - errno = serr ; - } - return -1 ; - } + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (CLOCK) failed: %s\n", strerror (errno)) ; -// The drive pads +// The drive pads pads = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PADS) ; if ((int32_t)pads == -1) - { - if (wiringPiDebug) - { - int serr = errno ; - fprintf (stderr, "wiringPiSetup: mmap failed (pads): %s\n", strerror (errno)) ; - errno = serr ; - } - return -1 ; - } + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PADS) failed: %s\n", strerror (errno)) ; -// The system timer +#ifdef USE_TIMER +// The system timer timer = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_TIMER) ; if ((int32_t)timer == -1) - { - if (wiringPiDebug) - { - int serr = errno ; - fprintf (stderr, "wiringPiSetup: mmap failed (timer): %s\n", strerror (errno)) ; - errno = serr ; - } - return -1 ; - } + return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (TIMER) failed: %s\n", strerror (errno)) ; // Set the timer to free-running, 1MHz. // 0xF9 is 249, the timer divide is base clock / (divide+1) @@ -1406,10 +2079,17 @@ int wiringPiSetup (void) *(timer + TIMER_CONTROL) = 0x0000280 ; *(timer + TIMER_PRE_DIV) = 0x00000F9 ; timerIrqRaw = timer + TIMER_IRQ_RAW ; +#endif initialiseEpoch () ; - wiringPiMode = WPI_MODE_PINS ; +// If we're running on a compute module, then wiringPi pin numbers don't really many anything... + + piBoardId (&model, &rev, &mem, &maker, &overVolted) ; + if (model == PI_MODEL_CM) + wiringPiMode = WPI_MODE_GPIO ; + else + wiringPiMode = WPI_MODE_PINS ; return 0 ; } @@ -1426,40 +2106,39 @@ int wiringPiSetup (void) int wiringPiSetupGpio (void) { - int x ; - - if (geteuid () != 0) - { - fprintf (stderr, "Must be root to call wiringPiSetupGpio(). (Did you forget sudo?)\n") ; - exit (EXIT_FAILURE) ; - } - - if ((x = wiringPiSetup ()) < 0) - return x ; + (void)wiringPiSetup () ; if (wiringPiDebug) printf ("wiringPi: wiringPiSetupGpio called\n") ; - pinMode = pinModeGpio ; - getAlt = getAltGpio ; - pullUpDnControl = pullUpDnControlGpio ; - digitalWrite = digitalWriteGpio ; - digitalWriteByte = digitalWriteByteGpio ; - gpioClockSet = gpioClockSetGpio ; - pwmWrite = pwmWriteGpio ; - setPadDrive = setPadDriveGpio ; - digitalRead = digitalReadGpio ; - waitForInterrupt = waitForInterruptGpio ; - pwmSetMode = pwmSetModeWPi ; - pwmSetRange = pwmSetRangeWPi ; - pwmSetClock = pwmSetClockWPi ; - wiringPiMode = WPI_MODE_GPIO ; return 0 ; } +/* + * wiringPiSetupPhys: + * Must be called once at the start of your program execution. + * + * Phys setup: Initialises the system into Physical Pin mode and uses the + * memory mapped hardware directly. + ********************************************************************************* + */ + +int wiringPiSetupPhys (void) +{ + (void)wiringPiSetup () ; + + if (wiringPiDebug) + printf ("wiringPi: wiringPiSetupPhys called\n") ; + + wiringPiMode = WPI_MODE_PHYS ; + + return 0 ; +} + + /* * wiringPiSetupSys: * Must be called once at the start of your program execution. @@ -1475,32 +2154,27 @@ int wiringPiSetupSys (void) int pin ; char fName [128] ; - if (getenv ("WIRINGPI_DEBUG") != NULL) + if (getenv (ENV_DEBUG) != NULL) wiringPiDebug = TRUE ; + if (getenv (ENV_CODES) != NULL) + wiringPiReturnCodes = TRUE ; + if (wiringPiDebug) printf ("wiringPi: wiringPiSetupSys called\n") ; - pinMode = pinModeSys ; - getAlt = getAltSys ; - pullUpDnControl = pullUpDnControlSys ; - digitalWrite = digitalWriteSys ; - digitalWriteByte = digitalWriteByteSys ; - gpioClockSet = gpioClockSetSys ; - pwmWrite = pwmWriteSys ; - setPadDrive = setPadDriveSys ; - digitalRead = digitalReadSys ; - waitForInterrupt = waitForInterruptSys ; - pwmSetMode = pwmSetModeSys ; - pwmSetRange = pwmSetRangeSys ; - pwmSetClock = pwmSetClockSys ; - boardRev = piBoardRev () ; if (boardRev == 1) - pinToGpio = pinToGpioR1 ; + { + pinToGpio = pinToGpioR1 ; + physToGpio = physToGpioR1 ; + } else - pinToGpio = pinToGpioR2 ; + { + pinToGpio = pinToGpioR2 ; + physToGpio = physToGpioR2 ; + } // Open and scan the directory, looking for exported GPIOs, and pre-open // the 'value' interface to speed things up for later diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 18c6da5..7b9605f 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -21,15 +21,18 @@ *********************************************************************** */ +#ifndef __WIRING_PI_H__ +#define __WIRING_PI_H__ + // Handy defines -// Deprecated -#define NUM_PINS 17 +// wiringPi modes #define WPI_MODE_PINS 0 #define WPI_MODE_GPIO 1 #define WPI_MODE_GPIO_SYS 2 -#define WPI_MODE_PIFACE 3 +#define WPI_MODE_PHYS 3 +#define WPI_MODE_PIFACE 4 #define WPI_MODE_UNINITIALISED -1 // Pin modes @@ -38,6 +41,9 @@ #define OUTPUT 1 #define PWM_OUTPUT 2 #define GPIO_CLOCK 3 +#define SOFT_PWM_OUTPUT 4 +#define SOFT_TONE_OUTPUT 5 +#define PWM_TONE_OUTPUT 6 #define LOW 0 #define HIGH 1 @@ -60,10 +66,80 @@ #define INT_EDGE_RISING 2 #define INT_EDGE_BOTH 3 +// Pi model types and version numbers +// Intended for the GPIO program Use at your own risk. + +#define PI_MODEL_A 0 +#define PI_MODEL_B 1 +#define PI_MODEL_AP 2 +#define PI_MODEL_BP 3 +#define PI_MODEL_2 4 +#define PI_ALPHA 5 +#define PI_MODEL_CM 6 +#define PI_MODEL_07 7 +#define PI_MODEL_08 8 +#define PI_MODEL_ZERO 9 + +#define PI_VERSION_1 0 +#define PI_VERSION_1_1 1 +#define PI_VERSION_1_2 2 +#define PI_VERSION_2 3 + +#define PI_MAKER_SONY 0 +#define PI_MAKER_EGOMAN 1 +#define PI_MAKER_MBEST 2 +#define PI_MAKER_UNKNOWN 3 + +extern const char *piModelNames [16] ; +extern const char *piRevisionNames [16] ; +extern const char *piMakerNames [16] ; +extern const int piMemorySize [ 8] ; + + +// Intended for the GPIO program Use at your own risk. + // Threads #define PI_THREAD(X) void *X (void *dummy) +// Failure modes + +#define WPI_FATAL (1==1) +#define WPI_ALMOST (1==2) + + +// wiringPiNodeStruct: +// This describes additional device nodes in the extended wiringPi +// 2.0 scheme of things. +// It's a simple linked list for now, but will hopefully migrate to +// a binary tree for efficiency reasons - but then again, the chances +// of more than 1 or 2 devices being added are fairly slim, so who +// knows.... + +struct wiringPiNodeStruct +{ + int pinBase ; + int pinMax ; + + int fd ; // Node specific + unsigned int data0 ; // ditto + unsigned int data1 ; // ditto + unsigned int data2 ; // ditto + unsigned int data3 ; // ditto + + void (*pinMode) (struct wiringPiNodeStruct *node, int pin, int mode) ; + void (*pullUpDnControl) (struct wiringPiNodeStruct *node, int pin, int mode) ; + int (*digitalRead) (struct wiringPiNodeStruct *node, int pin) ; + void (*digitalWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; + void (*pwmWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; + int (*analogRead) (struct wiringPiNodeStruct *node, int pin) ; + void (*analogWrite) (struct wiringPiNodeStruct *node, int pin, int value) ; + + struct wiringPiNodeStruct *next ; +} ; + +extern struct wiringPiNodeStruct *wiringPiNodes ; + // Function prototypes // c++ wrappers thanks to a comment by Nick Lott @@ -73,46 +149,67 @@ extern "C" { #endif -// Basic wiringPi functions +// Data + +// Internal + +extern int wiringPiFailure (int fatal, const char *message, ...) ; + +// Core wiringPi functions + +extern struct wiringPiNodeStruct *wiringPiFindNode (int pin) ; +extern struct wiringPiNodeStruct *wiringPiNewNode (int pinBase, int numPins) ; extern int wiringPiSetup (void) ; extern int wiringPiSetupSys (void) ; extern int wiringPiSetupGpio (void) ; +extern int wiringPiSetupPhys (void) ; + +extern void pinModeAlt (int pin, int mode) ; +extern void pinMode (int pin, int mode) ; +extern void pullUpDnControl (int pin, int pud) ; +extern int digitalRead (int pin) ; +extern void digitalWrite (int pin, int value) ; +extern void pwmWrite (int pin, int value) ; +extern int analogRead (int pin) ; +extern void analogWrite (int pin, int value) ; + +// PiFace specifics +// (Deprecated) + extern int wiringPiSetupPiFace (void) ; - -extern int piBoardRev (void) ; -extern int wpiPinToGpio (int wpiPin) ; - extern int wiringPiSetupPiFaceForGpioProg (void) ; // Don't use this - for gpio program only -extern void (*pinMode) (int pin, int mode) ; -extern int (*getAlt) (int pin) ; -extern void (*pullUpDnControl) (int pin, int pud) ; -extern void (*digitalWrite) (int pin, int value) ; -extern void (*digitalWriteByte) (int value) ; -extern void (*gpioClockSet) (int pin, int freq) ; -extern void (*pwmWrite) (int pin, int value) ; -extern void (*setPadDrive) (int group, int value) ; -extern int (*digitalRead) (int pin) ; -extern void (*pwmSetMode) (int mode) ; -extern void (*pwmSetRange) (unsigned int range) ; -extern void (*pwmSetClock) (int divisor) ; +// On-Board Raspberry Pi hardware specific stuff + +extern int piBoardRev (void) ; +extern void piBoardId (int *model, int *rev, int *mem, int *maker, int *overVolted) ; +extern int wpiPinToGpio (int wpiPin) ; +extern int physPinToGpio (int physPin) ; +extern void setPadDrive (int group, int value) ; +extern int getAlt (int pin) ; +extern void pwmToneWrite (int pin, int freq) ; +extern void digitalWriteByte (int value) ; +extern void pwmSetMode (int mode) ; +extern void pwmSetRange (unsigned int range) ; +extern void pwmSetClock (int divisor) ; +extern void gpioClockSet (int pin, int freq) ; // Interrupts +// (Also Pi hardware specific) -extern int (*waitForInterrupt) (int pin, int mS) ; +extern int waitForInterrupt (int pin, int mS) ; extern int wiringPiISR (int pin, int mode, void (*function)(void)) ; // Threads -extern int piThreadCreate (void *(*fn)(void *)) ; -extern void piLock (int key) ; -extern void piUnlock (int key) ; +extern int piThreadCreate (void *(*fn)(void *)) ; +extern void piLock (int key) ; +extern void piUnlock (int key) ; // Schedulling priority -extern int piHiPri (int pri) ; - +extern int piHiPri (const int pri) ; // Extras from arduino land @@ -124,3 +221,5 @@ extern unsigned int micros (void) ; #ifdef __cplusplus } #endif + +#endif diff --git a/wiringPi/wiringPiI2C.c b/wiringPi/wiringPiI2C.c index 93fe1d3..c787bce 100644 --- a/wiringPi/wiringPiI2C.c +++ b/wiringPi/wiringPiI2C.c @@ -22,15 +22,93 @@ *********************************************************************** */ +/* + * Notes: + * The Linux I2C code is actually the same (almost) as the SMBus code. + * SMBus is System Management Bus - and in essentially I2C with some + * additional functionality added, and stricter controls on the electrical + * specifications, etc. however I2C does work well with it and the + * protocols work over both. + * + * I'm directly including the SMBus functions here as some Linux distros + * lack the correct header files, and also some header files are GPLv2 + * rather than the LGPL that wiringPi is released under - presumably because + * originally no-one expected I2C/SMBus to be used outside the kernel - + * however enter the Raspberry Pi with people now taking directly to I2C + * devices without going via the kernel... + * + * This may ultimately reduce the flexibility of this code, but it won't be + * hard to maintain it and keep it current, should things change. + * + * Information here gained from: kernel/Documentation/i2c/dev-interface + * as well as other online resources. + ********************************************************************************* + */ + #include #include +#include +#include +#include #include #include -#include #include "wiringPi.h" #include "wiringPiI2C.h" +// I2C definitions + +#define I2C_SLAVE 0x0703 +#define I2C_SMBUS 0x0720 /* SMBus-level access */ + +#define I2C_SMBUS_READ 1 +#define I2C_SMBUS_WRITE 0 + +// SMBus transaction types + +#define I2C_SMBUS_QUICK 0 +#define I2C_SMBUS_BYTE 1 +#define I2C_SMBUS_BYTE_DATA 2 +#define I2C_SMBUS_WORD_DATA 3 +#define I2C_SMBUS_PROC_CALL 4 +#define I2C_SMBUS_BLOCK_DATA 5 +#define I2C_SMBUS_I2C_BLOCK_BROKEN 6 +#define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */ +#define I2C_SMBUS_I2C_BLOCK_DATA 8 + +// SMBus messages + +#define I2C_SMBUS_BLOCK_MAX 32 /* As specified in SMBus standard */ +#define I2C_SMBUS_I2C_BLOCK_MAX 32 /* Not specified but we use same structure */ + +// Structures used in the ioctl() calls + +union i2c_smbus_data +{ + uint8_t byte ; + uint16_t word ; + uint8_t block [I2C_SMBUS_BLOCK_MAX + 2] ; // block [0] is used for length + one more for PEC +} ; + +struct i2c_smbus_ioctl_data +{ + char read_write ; + uint8_t command ; + int size ; + union i2c_smbus_data *data ; +} ; + +static inline int i2c_smbus_access (int fd, char rw, uint8_t command, int size, union i2c_smbus_data *data) +{ + struct i2c_smbus_ioctl_data args ; + + args.read_write = rw ; + args.command = command ; + args.size = size ; + args.data = data ; + return ioctl (fd, I2C_SMBUS, &args) ; +} + /* * wiringPiI2CRead: @@ -40,7 +118,12 @@ int wiringPiI2CRead (int fd) { - return i2c_smbus_read_byte (fd) ; + union i2c_smbus_data data ; + + if (i2c_smbus_access (fd, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data)) + return -1 ; + else + return data.byte & 0xFF ; } @@ -52,12 +135,22 @@ int wiringPiI2CRead (int fd) int wiringPiI2CReadReg8 (int fd, int reg) { - return i2c_smbus_read_byte_data (fd, reg) ; + union i2c_smbus_data data; + + if (i2c_smbus_access (fd, I2C_SMBUS_READ, reg, I2C_SMBUS_BYTE_DATA, &data)) + return -1 ; + else + return data.byte & 0xFF ; } int wiringPiI2CReadReg16 (int fd, int reg) { - return i2c_smbus_read_word_data (fd, reg) ; + union i2c_smbus_data data; + + if (i2c_smbus_access (fd, I2C_SMBUS_READ, reg, I2C_SMBUS_WORD_DATA, &data)) + return -1 ; + else + return data.word & 0xFFFF ; } @@ -69,7 +162,7 @@ int wiringPiI2CReadReg16 (int fd, int reg) int wiringPiI2CWrite (int fd, int data) { - return i2c_smbus_write_byte (fd, data) ; + return i2c_smbus_access (fd, I2C_SMBUS_WRITE, data, I2C_SMBUS_BYTE, NULL) ; } @@ -79,14 +172,41 @@ int wiringPiI2CWrite (int fd, int data) ********************************************************************************* */ -int wiringPiI2CWriteReg8 (int fd, int reg, int data) +int wiringPiI2CWriteReg8 (int fd, int reg, int value) { - return i2c_smbus_write_byte_data (fd, reg, data) ; + union i2c_smbus_data data ; + + data.byte = value ; + return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_BYTE_DATA, &data) ; } -int wiringPiI2CWriteReg16 (int fd, int reg, int data) +int wiringPiI2CWriteReg16 (int fd, int reg, int value) { - return i2c_smbus_write_word_data (fd, reg, data) ; + union i2c_smbus_data data ; + + data.word = value ; + return i2c_smbus_access (fd, I2C_SMBUS_WRITE, reg, I2C_SMBUS_WORD_DATA, &data) ; +} + + +/* + * wiringPiI2CSetupInterface: + * Undocumented access to set the interface explicitly - might be used + * for the Pi's 2nd I2C interface... + ********************************************************************************* + */ + +int wiringPiI2CSetupInterface (const char *device, int devId) +{ + int fd ; + + if ((fd = open (device, O_RDWR)) < 0) + return wiringPiFailure (WPI_ALMOST, "Unable to open I2C device: %s\n", strerror (errno)) ; + + if (ioctl (fd, I2C_SLAVE, devId) < 0) + return wiringPiFailure (WPI_ALMOST, "Unable to select I2C device: %s\n", strerror (errno)) ; + + return fd ; } @@ -96,27 +216,17 @@ int wiringPiI2CWriteReg16 (int fd, int reg, int data) ********************************************************************************* */ -int wiringPiI2CSetup (int devId) +int wiringPiI2CSetup (const int devId) { - int rev, fd ; - char *device ; + int rev ; + const char *device ; - if ((rev = piBoardRev ()) < 0) - { - fprintf (stderr, "wiringPiI2CSetup: Unable to determine Pi board revision\n") ; - exit (1) ; - } + rev = piBoardRev () ; if (rev == 1) device = "/dev/i2c-0" ; else device = "/dev/i2c-1" ; - if ((fd = open (device, O_RDWR)) < 0) - return -1 ; - - if (ioctl (fd, I2C_SLAVE, devId) < 0) - return -1 ; - - return fd ; + return wiringPiI2CSetupInterface (device, devId) ; } diff --git a/wiringPi/wiringPiI2C.h b/wiringPi/wiringPiI2C.h index 6710ff4..6db8c68 100644 --- a/wiringPi/wiringPiI2C.h +++ b/wiringPi/wiringPiI2C.h @@ -26,15 +26,16 @@ extern "C" { #endif -extern int wiringPiI2CRead (int fd) ; -extern int wiringPiI2CReadReg8 (int fd, int reg) ; -extern int wiringPiI2CReadReg16 (int fd, int reg) ; +extern int wiringPiI2CRead (int fd) ; +extern int wiringPiI2CReadReg8 (int fd, int reg) ; +extern int wiringPiI2CReadReg16 (int fd, int reg) ; -extern int wiringPiI2CWrite (int fd, int data) ; -extern int wiringPiI2CWriteReg8 (int fd, int reg, int data) ; -extern int wiringPiI2CWriteReg16 (int fd, int reg, int data) ; +extern int wiringPiI2CWrite (int fd, int data) ; +extern int wiringPiI2CWriteReg8 (int fd, int reg, int data) ; +extern int wiringPiI2CWriteReg16 (int fd, int reg, int data) ; -int wiringPiI2CSetup (int devId) ; +extern int wiringPiI2CSetupInterface (const char *device, int devId) ; +extern int wiringPiI2CSetup (const int devId) ; #ifdef __cplusplus } diff --git a/wiringPi/wiringPiSPI.c b/wiringPi/wiringPiSPI.c index 4441498..453df31 100644 --- a/wiringPi/wiringPiSPI.c +++ b/wiringPi/wiringPiSPI.c @@ -1,7 +1,7 @@ /* * wiringPiSPI.c: * Simplified SPI access routines - * Copyright (c) 2012 Gordon Henderson + * Copyright (c) 2012-2015 Gordon Henderson *********************************************************************** * This file is part of wiringPi: * https://projects.drogon.net/raspberry-pi/wiringpi/ @@ -25,20 +25,23 @@ #include #include +#include +#include #include #include +#include "wiringPi.h" + #include "wiringPiSPI.h" // The SPI bus parameters // Variables as they need to be passed as pointers later on -static char *spiDev0 = "/dev/spidev0.0" ; -static char *spiDev1 = "/dev/spidev0.1" ; -static uint8_t spiMode = 0 ; -static uint8_t spiBPW = 8 ; -static uint16_t spiDelay = 0; +const static char *spiDev0 = "/dev/spidev0.0" ; +const static char *spiDev1 = "/dev/spidev0.1" ; +const static uint8_t spiBPW = 8 ; +const static uint16_t spiDelay = 0 ; static uint32_t spiSpeeds [2] ; static int spiFds [2] ; @@ -71,6 +74,11 @@ int wiringPiSPIDataRW (int channel, unsigned char *data, int len) channel &= 1 ; +// Mentioned in spidev.h but not used in the original kernel documentation +// test program )-: + + memset (&spi, 0, sizeof (spi)) ; + spi.tx_buf = (unsigned long)data ; spi.rx_buf = (unsigned long)data ; spi.len = len ; @@ -83,35 +91,46 @@ int wiringPiSPIDataRW (int channel, unsigned char *data, int len) /* - * wiringPiSPISetup: - * Open the SPI device, and set it up, etc. + * wiringPiSPISetupMode: + * Open the SPI device, and set it up, with the mode, etc. ********************************************************************************* */ -int wiringPiSPISetup (int channel, int speed) +int wiringPiSPISetupMode (int channel, int speed, int mode) { int fd ; - channel &= 1 ; + mode &= 3 ; // Mode is 0, 1, 2 or 3 + channel &= 1 ; // Channel is 0 or 1 if ((fd = open (channel == 0 ? spiDev0 : spiDev1, O_RDWR)) < 0) - return -1 ; + return wiringPiFailure (WPI_ALMOST, "Unable to open SPI device: %s\n", strerror (errno)) ; spiSpeeds [channel] = speed ; spiFds [channel] = fd ; // Set SPI parameters. -// Why are we reading it afterwriting it? I've no idea, but for now I'm blindly -// copying example code I've seen online... - if (ioctl (fd, SPI_IOC_WR_MODE, &spiMode) < 0) return -1 ; - if (ioctl (fd, SPI_IOC_RD_MODE, &spiMode) < 0) return -1 ; + if (ioctl (fd, SPI_IOC_WR_MODE, &mode) < 0) + return wiringPiFailure (WPI_ALMOST, "SPI Mode Change failure: %s\n", strerror (errno)) ; + + if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0) + return wiringPiFailure (WPI_ALMOST, "SPI BPW Change failure: %s\n", strerror (errno)) ; - if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0) return -1 ; - if (ioctl (fd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0) return -1 ; - - if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) return -1 ; - if (ioctl (fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) return -1 ; + if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) + return wiringPiFailure (WPI_ALMOST, "SPI Speed Change failure: %s\n", strerror (errno)) ; return fd ; } + + +/* + * wiringPiSPISetup: + * Open the SPI device, and set it up, etc. in the default MODE 0 + ********************************************************************************* + */ + +int wiringPiSPISetup (int channel, int speed) +{ + return wiringPiSPISetupMode (channel, speed, 0) ; +} diff --git a/wiringPi/wiringPiSPI.h b/wiringPi/wiringPiSPI.h index f53697d..3980321 100644 --- a/wiringPi/wiringPiSPI.h +++ b/wiringPi/wiringPiSPI.h @@ -1,7 +1,7 @@ /* * wiringPiSPI.h: * Simplified SPI access routines - * Copyright (c) 2012 Gordon Henderson + * Copyright (c) 2012-2015 Gordon Henderson *********************************************************************** * This file is part of wiringPi: * https://projects.drogon.net/raspberry-pi/wiringpi/ @@ -26,9 +26,10 @@ extern "C" { #endif -int wiringPiSPIGetFd (int channel) ; -int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ; -int wiringPiSPISetup (int channel, int speed) ; +int wiringPiSPIGetFd (int channel) ; +int wiringPiSPIDataRW (int channel, unsigned char *data, int len) ; +int wiringPiSPISetupMode (int channel, int speed, int mode) ; +int wiringPiSPISetup (int channel, int speed) ; #ifdef __cplusplus } diff --git a/wiringPi/wiringSerial.c b/wiringPi/wiringSerial.c index 28ec598..ca976a9 100644 --- a/wiringPi/wiringSerial.c +++ b/wiringPi/wiringSerial.c @@ -41,7 +41,7 @@ ********************************************************************************* */ -int serialOpen (char *device, int baud) +int serialOpen (const char *device, const int baud) { struct termios options ; speed_t myBaud ; @@ -60,6 +60,7 @@ int serialOpen (char *device, int baud) case 1200: myBaud = B1200 ; break ; case 1800: myBaud = B1800 ; break ; case 2400: myBaud = B2400 ; break ; + case 4800: myBaud = B4800 ; break ; case 9600: myBaud = B9600 ; break ; case 19200: myBaud = B19200 ; break ; case 38400: myBaud = B38400 ; break ; @@ -116,7 +117,7 @@ int serialOpen (char *device, int baud) ********************************************************************************* */ -void serialFlush (int fd) +void serialFlush (const int fd) { tcflush (fd, TCIOFLUSH) ; } @@ -128,7 +129,7 @@ void serialFlush (int fd) ********************************************************************************* */ -void serialClose (int fd) +void serialClose (const int fd) { close (fd) ; } @@ -140,7 +141,7 @@ void serialClose (int fd) ********************************************************************************* */ -void serialPutchar (int fd, unsigned char c) +void serialPutchar (const int fd, const unsigned char c) { write (fd, &c, 1) ; } @@ -152,7 +153,7 @@ void serialPutchar (int fd, unsigned char c) ********************************************************************************* */ -void serialPuts (int fd, char *s) +void serialPuts (const int fd, const char *s) { write (fd, s, strlen (s)) ; } @@ -163,7 +164,7 @@ void serialPuts (int fd, char *s) ********************************************************************************* */ -void serialPrintf (int fd, char *message, ...) +void serialPrintf (const int fd, const char *message, ...) { va_list argp ; char buffer [1024] ; @@ -182,7 +183,7 @@ void serialPrintf (int fd, char *message, ...) ********************************************************************************* */ -int serialDataAvail (int fd) +int serialDataAvail (const int fd) { int result ; @@ -201,7 +202,7 @@ int serialDataAvail (int fd) ********************************************************************************* */ -int serialGetchar (int fd) +int serialGetchar (const int fd) { uint8_t x ; diff --git a/wiringPi/wiringSerial.h b/wiringPi/wiringSerial.h index 1a4198c..430dc73 100644 --- a/wiringPi/wiringSerial.h +++ b/wiringPi/wiringSerial.h @@ -24,14 +24,14 @@ extern "C" { #endif -extern int serialOpen (char *device, int baud) ; -extern void serialClose (int fd) ; -extern void serialFlush (int fd) ; -extern void serialPutchar (int fd, unsigned char c) ; -extern void serialPuts (int fd, char *s) ; -extern void serialPrintf (int fd, char *message, ...) ; -extern int serialDataAvail (int fd) ; -extern int serialGetchar (int fd) ; +extern int serialOpen (const char *device, const int baud) ; +extern void serialClose (const int fd) ; +extern void serialFlush (const int fd) ; +extern void serialPutchar (const int fd, const unsigned char c) ; +extern void serialPuts (const int fd, const char *s) ; +extern void serialPrintf (const int fd, const char *message, ...) ; +extern int serialDataAvail (const int fd) ; +extern int serialGetchar (const int fd) ; #ifdef __cplusplus } diff --git a/wiringPi/wiringShift.c b/wiringPi/wiringShift.c index b9b7a44..3df94e8 100644 --- a/wiringPi/wiringShift.c +++ b/wiringPi/wiringShift.c @@ -56,7 +56,6 @@ uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) return value; } - /* * shiftOut: * Shift data out to a clocked source diff --git a/wiringPi/wiringShift.h b/wiringPi/wiringShift.h index a3f4581..419ade4 100644 --- a/wiringPi/wiringShift.h +++ b/wiringPi/wiringShift.h @@ -33,8 +33,8 @@ extern "C" { #endif -extern uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) ; -extern void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ; +extern uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) ; +extern void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ; #ifdef __cplusplus } diff --git a/wiringPi/wpiExtensions.c b/wiringPi/wpiExtensions.c new file mode 100644 index 0000000..4cae9c4 --- /dev/null +++ b/wiringPi/wpiExtensions.c @@ -0,0 +1,731 @@ +/* + * extensions.c: + * Originally part of the GPIO program to test, peek, poke and otherwise + * noodle with the GPIO hardware on the Raspberry Pi. + * Now used as a general purpose library to allow systems to dynamically + * add in new devices into wiringPi at program run-time. + * Copyright (c) 2012-2015 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "mcp23008.h" +#include "mcp23016.h" +#include "mcp23017.h" +#include "mcp23s08.h" +#include "mcp23s17.h" +#include "sr595.h" +#include "pcf8574.h" +#include "pcf8591.h" +#include "mcp3002.h" +#include "mcp3004.h" +#include "mcp4802.h" +#include "mcp3422.h" +#include "max31855.h" +#include "max5322.h" +#include "sn3218.h" +#include "drcSerial.h" + +#include "wpiExtensions.h" + +extern int wiringPiDebug ; + +static int verbose ; +static char errorMessage [1024] ; + + +#ifndef TRUE +# define TRUE (1==1) +# define FALSE (1==2) +#endif + +// Local structure to hold details + +struct extensionFunctionStruct +{ + const char *name ; + int (*function)(char *progName, int pinBase, char *params) ; +} ; + + +/* + * verbError: + * Convenient error handling + ********************************************************************************* + */ + +static void verbError (const char *message, ...) +{ + va_list argp ; + va_start (argp, message) ; + vsnprintf (errorMessage, 1023, message, argp) ; + va_end (argp) ; + + if (verbose) + fprintf (stderr, "%s\n", errorMessage) ; +} + + +/* + * extractInt: + * Check & return an integer at the given location (prefixed by a :) + ********************************************************************************* + */ + +static char *extractInt (char *progName, char *p, int *num) +{ + if (*p != ':') + { + verbError ("%s: colon expected", progName) ; + return NULL ; + } + + ++p ; + + if (!isdigit (*p)) + { + verbError ("%s: digit expected", progName) ; + return NULL ; + } + + *num = strtol (p, NULL, 0) ; + while (isdigit (*p)) + ++p ; + + return p ; +} + + +/* + * extractStr: + * Check & return a string at the given location (prefixed by a :) + ********************************************************************************* + */ + +static char *extractStr (char *progName, char *p, char **str) +{ + char *q, *r ; + + if (*p != ':') + { + verbError ("%s: colon expected", progName) ; + return NULL ; + } + + ++p ; + + if (!isprint (*p)) + { + verbError ("%s: character expected", progName) ; + return NULL ; + } + + q = p ; + while ((*q != 0) && (*q != ':')) + ++q ; + + *str = r = calloc (q - p + 2, 1) ; // Zeros it + + while (p != q) + *r++ = *p++ ; + + return p ; +} + + + +/* + * doExtensionMcp23008: + * MCP23008 - 8-bit I2C GPIO expansion chip + * mcp23002:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionMcp23008 (char *progName, int pinBase, char *params) +{ + int i2c ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x01) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + mcp23008Setup (pinBase, i2c) ; + + return TRUE ; +} + + +/* + * doExtensionMcp23016: + * MCP230016- 16-bit I2C GPIO expansion chip + * mcp23016:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionMcp23016 (char *progName, int pinBase, char *params) +{ + int i2c ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x03) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + mcp23016Setup (pinBase, i2c) ; + + return TRUE ; +} + + +/* + * doExtensionMcp23017: + * MCP230017- 16-bit I2C GPIO expansion chip + * mcp23017:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionMcp23017 (char *progName, int pinBase, char *params) +{ + int i2c ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x03) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + mcp23017Setup (pinBase, i2c) ; + + return TRUE ; +} + + +/* + * doExtensionMcp23s08: + * MCP23s08 - 8-bit SPI GPIO expansion chip + * mcp23s08:base:spi:port + ********************************************************************************* + */ + +static int doExtensionMcp23s08 (char *progName, int pinBase, char *params) +{ + int spi, port ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI address (%d) out of range", progName, spi) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &port)) == NULL) + return FALSE ; + + if ((port < 0) || (port > 7)) + { + verbError ("%s: port address (%d) out of range", progName, port) ; + return FALSE ; + } + + mcp23s08Setup (pinBase, spi, port) ; + + return TRUE ; +} + + +/* + * doExtensionMcp23s17: + * MCP23s17 - 16-bit SPI GPIO expansion chip + * mcp23s17:base:spi:port + ********************************************************************************* + */ + +static int doExtensionMcp23s17 (char *progName, int pinBase, char *params) +{ + int spi, port ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI address (%d) out of range", progName, spi) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &port)) == NULL) + return FALSE ; + + if ((port < 0) || (port > 7)) + { + verbError ("%s: port address (%d) out of range", progName, port) ; + return FALSE ; + } + + mcp23s17Setup (pinBase, spi, port) ; + + return TRUE ; +} + + +/* + * doExtensionSr595: + * Shift Register 74x595 + * sr595:base:pins:data:clock:latch + ********************************************************************************* + */ + +static int doExtensionSr595 (char *progName, int pinBase, char *params) +{ + int pins, data, clock, latch ; + +// Extract pins + + if ((params = extractInt (progName, params, &pins)) == NULL) + return FALSE ; + + if ((pins < 8) || (pins > 32)) + { + verbError ("%s: pin count (%d) out of range - 8-32 expected.", progName, pins) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &data)) == NULL) + return FALSE ; + + if ((params = extractInt (progName, params, &clock)) == NULL) + return FALSE ; + + if ((params = extractInt (progName, params, &latch)) == NULL) + return FALSE ; + + sr595Setup (pinBase, pins, data, clock, latch) ; + + return TRUE ; +} + + +/* + * doExtensionPcf8574: + * Digital IO (Crude!) + * pcf8574:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionPcf8574 (char *progName, int pinBase, char *params) +{ + int i2c ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x03) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + pcf8574Setup (pinBase, i2c) ; + + return TRUE ; +} + + +/* + * doExtensionPcf8591: + * Analog IO + * pcf8591:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionPcf8591 (char *progName, int pinBase, char *params) +{ + int i2c ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x03) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + pcf8591Setup (pinBase, i2c) ; + + return TRUE ; +} + + +/* + * doExtensionMax31855: + * Analog IO + * max31855:base:spiChan + ********************************************************************************* + */ + +static int doExtensionMax31855 (char *progName, int pinBase, char *params) +{ + int spi ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI channel (%d) out of range", progName, spi) ; + return FALSE ; + } + + max31855Setup (pinBase, spi) ; + + return TRUE ; +} + + +/* + * doExtensionMcp3002: + * Analog IO + * mcp3002:base:spiChan + ********************************************************************************* + */ + +static int doExtensionMcp3002 (char *progName, int pinBase, char *params) +{ + int spi ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI channel (%d) out of range", progName, spi) ; + return FALSE ; + } + + mcp3002Setup (pinBase, spi) ; + + return TRUE ; +} + + +/* + * doExtensionMcp3004: + * Analog IO + * mcp3004:base:spiChan + ********************************************************************************* + */ + +static int doExtensionMcp3004 (char *progName, int pinBase, char *params) +{ + int spi ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI channel (%d) out of range", progName, spi) ; + return FALSE ; + } + + mcp3004Setup (pinBase, spi) ; + + return TRUE ; +} + + +/* + * doExtensionMax5322: + * Analog O + * max5322:base:spiChan + ********************************************************************************* + */ + +static int doExtensionMax5322 (char *progName, int pinBase, char *params) +{ + int spi ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI channel (%d) out of range", progName, spi) ; + return FALSE ; + } + + max5322Setup (pinBase, spi) ; + + return TRUE ; +} + + +/* + * doExtensionMcp4802: + * Analog IO + * mcp4802:base:spiChan + ********************************************************************************* + */ + +static int doExtensionMcp4802 (char *progName, int pinBase, char *params) +{ + int spi ; + + if ((params = extractInt (progName, params, &spi)) == NULL) + return FALSE ; + + if ((spi < 0) || (spi > 1)) + { + verbError ("%s: SPI channel (%d) out of range", progName, spi) ; + return FALSE ; + } + + mcp4802Setup (pinBase, spi) ; + + return TRUE ; +} + + +/* + * doExtensionSn3218: + * Analog Output (LED Driver) + * sn3218:base + ********************************************************************************* + */ + +static int doExtensionSn3218 (char *progName, int pinBase, char *params) +{ + sn3218Setup (pinBase) ; + return TRUE ; +} + + +/* + * doExtensionMcp3422: + * Analog IO + * mcp3422:base:i2cAddr + ********************************************************************************* + */ + +static int doExtensionMcp3422 (char *progName, int pinBase, char *params) +{ + int i2c, sampleRate, gain ; + + if ((params = extractInt (progName, params, &i2c)) == NULL) + return FALSE ; + + if ((i2c < 0x03) || (i2c > 0x77)) + { + verbError ("%s: i2c address (0x%X) out of range", progName, i2c) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &sampleRate)) == NULL) + return FALSE ; + + if ((sampleRate < 0) || (sampleRate > 3)) + { + verbError ("%s: sample rate (%d) out of range", progName, sampleRate) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &gain)) == NULL) + return FALSE ; + + if ((gain < 0) || (gain > 3)) + { + verbError ("%s: gain (%d) out of range", progName, gain) ; + return FALSE ; + } + + mcp3422Setup (pinBase, i2c, sampleRate, gain) ; + + return TRUE ; +} + + +/* + * doExtensionDrcS: + * Interface to a DRC Serial system + * drcs:base:pins:serialPort:baud + ********************************************************************************* + */ + +static int doExtensionDrcS (char *progName, int pinBase, char *params) +{ + char *port ; + int pins, baud ; + + if ((params = extractInt (progName, params, &pins)) == NULL) + return FALSE ; + + if ((pins < 1) || (pins > 100)) + { + verbError ("%s: pins (%d) out of range (2-100)", progName, pins) ; + return FALSE ; + } + + if ((params = extractStr (progName, params, &port)) == NULL) + return FALSE ; + + if (strlen (port) == 0) + { + verbError ("%s: serial port device name required", progName) ; + return FALSE ; + } + + if ((params = extractInt (progName, params, &baud)) == NULL) + return FALSE ; + + if ((baud < 1) || (baud > 4000000)) + { + verbError ("%s: baud rate (%d) out of range", progName, baud) ; + return FALSE ; + } + + drcSetupSerial (pinBase, pins, port, baud) ; + + return TRUE ; +} + + + +/* + * Function list + ********************************************************************************* + */ + +static struct extensionFunctionStruct extensionFunctions [] = +{ + { "mcp23008", &doExtensionMcp23008 }, + { "mcp23016", &doExtensionMcp23016 }, + { "mcp23017", &doExtensionMcp23017 }, + { "mcp23s08", &doExtensionMcp23s08 }, + { "mcp23s17", &doExtensionMcp23s17 }, + { "sr595", &doExtensionSr595 }, + { "pcf8574", &doExtensionPcf8574 }, + { "pcf8591", &doExtensionPcf8591 }, + { "mcp3002", &doExtensionMcp3002 }, + { "mcp3004", &doExtensionMcp3004 }, + { "mcp4802", &doExtensionMcp4802 }, + { "mcp3422", &doExtensionMcp3422 }, + { "max31855", &doExtensionMax31855 }, + { "max5322", &doExtensionMax5322 }, + { "sn3218", &doExtensionSn3218 }, + { "drcs", &doExtensionDrcS }, + { NULL, NULL }, +} ; + + +/* + * loadWPiExtension: + * Load in a wiringPi extension + * The extensionData always starts with the name, a colon then the pinBase + * number. Other parameters after that are decoded by the module in question. + ********************************************************************************* + */ + +int loadWPiExtension (char *progName, char *extensionData, int printErrors) +{ + char *p ; + char *extension = extensionData ; + struct extensionFunctionStruct *extensionFn ; + int pinBase = 0 ; + + verbose = printErrors ; + +// Get the extension name by finding the first colon + + p = extension ; + while (*p != ':') + { + if (!*p) // ran out of characters + { + verbError ("%s: extension name not terminated by a colon", progName) ; + return FALSE ; + } + ++p ; + } + *p++ = 0 ; + +// Simple ATOI code + + if (!isdigit (*p)) + { + verbError ("%s: pinBase number expected after extension name", progName) ; + return FALSE ; + } + + while (isdigit (*p)) + { + if (pinBase > 1000000000) // Lets be realistic here... + { + verbError ("%s: pinBase too large", progName) ; + return FALSE ; + } + + pinBase = pinBase * 10 + (*p - '0') ; + ++p ; + } + + if (pinBase < 64) + { + verbError ("%s: pinBase (%d) too small. Minimum is 64.", progName, pinBase) ; + return FALSE ; + } + +// Search for extensions: + + for (extensionFn = extensionFunctions ; extensionFn->name != NULL ; ++extensionFn) + { + if (strcmp (extensionFn->name, extension) == 0) + return extensionFn->function (progName, pinBase, p) ; + } + + verbError ("%s: extension %s not found", progName, extension) ; + return FALSE ; +} diff --git a/wiringPi/wpiExtensions.h b/wiringPi/wpiExtensions.h new file mode 100644 index 0000000..fcaec96 --- /dev/null +++ b/wiringPi/wpiExtensions.h @@ -0,0 +1,26 @@ +/* + * extensions.h: + * Part of the GPIO program to test, peek, poke and otherwise + * noodle with the GPIO hardware on the Raspberry Pi. + * Copyright (c) 2012-2015 Gordon Henderson + *********************************************************************** + * This file is part of wiringPi: + * https://projects.drogon.net/raspberry-pi/wiringpi/ + * + * wiringPi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * wiringPi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with wiringPi. If not, see . + *********************************************************************** + */ + + +extern int loadWPiExtension (char *progName, char *extensionData, int verbose) ; From a402cac9201d41128d27751df5c5a324be2f0cd0 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Sat, 27 Feb 2016 16:25:17 +0000 Subject: [PATCH 18/29] Removed redundant files --- README | 7 - examples/gertboard.c | 94 --------- examples/gertboard.png | Bin 4834 -> 0 bytes examples/piface.c | 71 ------- examples/test1.c | 111 ----------- examples/test2.c | 58 ------ examples/tone.c | 59 ------ gpio/gpio | Bin 21304 -> 0 bytes wiringPi/README | 9 - wiringPi/gertboard.c | 122 ------------ wiringPi/gertboard.h | 39 ---- wiringPi/lcd.c | 380 ------------------------------------ wiringPi/lcd.h | 46 ----- wiringPi/libwiringPi.so.1.0 | Bin 43311 -> 0 bytes wiringPi/piNes.c | 113 ----------- wiringPi/piNes.h | 45 ----- wiringPi/q2w.c | 89 --------- wiringPi/wiringPiFace.c | 362 ---------------------------------- 18 files changed, 1605 deletions(-) delete mode 100644 README delete mode 100644 examples/gertboard.c delete mode 100644 examples/gertboard.png delete mode 100644 examples/piface.c delete mode 100644 examples/test1.c delete mode 100644 examples/test2.c delete mode 100644 examples/tone.c delete mode 100755 gpio/gpio delete mode 100644 wiringPi/README delete mode 100644 wiringPi/gertboard.c delete mode 100644 wiringPi/gertboard.h delete mode 100644 wiringPi/lcd.c delete mode 100644 wiringPi/lcd.h delete mode 100755 wiringPi/libwiringPi.so.1.0 delete mode 100644 wiringPi/piNes.c delete mode 100644 wiringPi/piNes.h delete mode 100644 wiringPi/q2w.c delete mode 100644 wiringPi/wiringPiFace.c diff --git a/README b/README deleted file mode 100644 index 781510a..0000000 --- a/README +++ /dev/null @@ -1,7 +0,0 @@ - -WiringPi: An implementation of most of the Arduino Wiring - functions for the Raspberry Pi - -Full details at: - https://projects.drogon.net/raspberry-pi/wiringpi/ - diff --git a/examples/gertboard.c b/examples/gertboard.c deleted file mode 100644 index f02e27d..0000000 --- a/examples/gertboard.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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 - * copy this value to D/A port 1 and use a 'scope on both D/A ports - * to check all's well. - * - * 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 B_SIZE 200 -#undef DO_TIMING - -#include -#include - -int main (void) -{ - double angle ; - int i ; - uint32_t x1 ; - int buffer [B_SIZE] ; - -#ifdef DO_TIMING - unsigned int now, then ; -#endif - - printf ("Raspberry Pi Gertboard SPI test program\n") ; - - if (wiringPiSetupSys () < 0) - return -1 ; - - if (gertboardSPISetup () < 0) - return 1 ; - -// Generate a Sine Wave - - 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) ; - } - - - for (;;) - { -#ifdef DO_TIMING - then = millis () ; -#endif - - for (i = 0 ; i < B_SIZE ; ++i) - { - gertboardAnalogWrite (0, buffer [i]) ; - -#ifndef DO_TIMING - x1 = gertboardAnalogRead (0) ; - gertboardAnalogWrite (1, x1 >> 2) ; // 10-bit A/D, 8-bit D/A -#endif - } - -#ifdef DO_TIMING - now = millis () ; - printf ("%4d mS, %9.7f S/sample", now - then, ((double)(now - then) / 1000.0) / (double)B_SIZE) ; - printf (" -> %9.4f samples/sec \n", 1 / (((double)(now - then) / 1000.0) / (double)B_SIZE)) ; -#endif - } - - return 0 ; -} diff --git a/examples/gertboard.png b/examples/gertboard.png deleted file mode 100644 index 03c5cdd63dbb163330d19400cb9d896211e86ae7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4834 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 IM6N<$f;V*&MF0Q* diff --git a/examples/piface.c b/examples/piface.c deleted file mode 100644 index 0f00960..0000000 --- a/examples/piface.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * piFace.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 -#include - -int outputs [4] = { 0,0,0,0 } ; - -void scanButton (int button) -{ - if (digitalRead (button) == LOW) - { - outputs [button] ^= 1 ; - digitalWrite (button, outputs [button]) ; - } - - while (digitalRead (button) == LOW) - delay (1) ; -} - - -int main (void) -{ - int pin, button ; - - printf ("Raspberry Pi wiringPiFace test program\n") ; - - if (wiringPiSetupPiFace () == -1) - exit (1) ; - -// Enable internal pull-ups - - for (pin = 0 ; pin < 8 ; ++pin) - pullUpDnControl (pin, PUD_UP) ; - - - for (;;) - { - for (button = 0 ; button < 4 ; ++button) - scanButton (button) ; - delay (1) ; - } - - return 0 ; -} diff --git a/examples/test1.c b/examples/test1.c deleted file mode 100644 index 4c75711..0000000 --- a/examples/test1.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * test1.c: - * Simple test program to test the wiringPi functions - * This is a sequencer to make a patter appear on 8 LEDs - * connected to the GPIO pins. - * - * 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 - - -// Simple sequencer data -// Triplets of LED, On/Off and delay - -uint8_t 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, 1, - 7, 0, 1, - - 0, 0, 1, // Extra delay - -// Back again - - 7, 1, 1, - 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 - - 9, 9, 9, // End marker - -} ; - - -int main (void) -{ - int pin ; - int dataPtr ; - int l, s, d ; - - printf ("Raspberry Pi wiringPi test program\n") ; - - if (wiringPiSetup () == -1) - exit (1) ; - - for (pin = 0 ; pin < 8 ; ++pin) - pinMode (pin, OUTPUT) ; - - pinMode (8, INPUT) ; // Pin 8 SDA0 - Has on-board 2k2 pull-up resistor - - dataPtr = 0 ; - - for (;;) - { - l = data [dataPtr++] ; // LED - s = data [dataPtr++] ; // State - d = data [dataPtr++] ; // Duration (10ths) - - if ((l + s + d) == 27) - { - dataPtr = 0 ; - continue ; - } - - digitalWrite (l, s) ; - - if (digitalRead (8) == 0) // Pressed as our switch shorts to ground - delay (d * 10) ; // Faster! - else - delay (d * 100) ; - } - - return 0 ; -} diff --git a/examples/test2.c b/examples/test2.c deleted file mode 100644 index 580591e..0000000 --- a/examples/test2.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * test2.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 - -int main (void) -{ - int bright ; - - printf ("Raspberry Pi wiringPi PWM test program\n") ; - - if (wiringPiSetup () == -1) - exit (1) ; - - pinMode (1, PWM_OUTPUT) ; - - for (;;) - { - for (bright = 0 ; bright < 1024 ; ++bright) - { - pwmWrite (1, bright) ; - delay (1) ; - } - - for (bright = 1023 ; bright >= 0 ; --bright) - { - pwmWrite (1, bright) ; - delay (1) ; - } - } - - return 0 ; -} diff --git a/examples/tone.c b/examples/tone.c deleted file mode 100644 index 0e8a47d..0000000 --- a/examples/tone.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * tone.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 ; - - if (wiringPiSetup () == -1) - { - fprintf (stdout, "oops: %s\n", strerror (errno)) ; - return 1 ; - } - - softToneCreate (PIN) ; - - for (;;) - { - for (i = 0 ; i < 8 ; ++i) - { - printf ("%3d\n", i) ; - softToneWrite (PIN, scale [i]) ; - delay (500) ; - } - } - -} diff --git a/gpio/gpio b/gpio/gpio deleted file mode 100755 index 54df96acc4db421f20e155f5ca8ab5a32637ea97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21304 zcmd6ve|%Kcng8!30V5&=4T?zZwL*&u$)Ko+RD=9(156<*ev6w-GLvL#k{M?v{AklQ z{;ITvLIo<@(kAWFN~^7OtGj5?uUpxcwYc(a?UuG~zX@Sl*0Ni)w2Ml~zCY)l8&0Cw z-S1!D`{Lm_&yVw*=lpukxi@FdC+Ahqk3=F~_!N1QJy9iJ@x1Ba()W8_k>?GY?)hFR zvUhtEB+u-=-t%@p89=G@l*htwu<}mt48Ry9(=aP9mJE9O-2q$#El_^g20)(I8Ngo3 z5-7iT(g}DGaKzgOV**a9T**m#2hcx&Oi+qkAi2sA#Gqq$2QU{}5XwGO$R{A*@`U*- zTT=CvEs3cuskZhtQ{&mz=EjO#y5eeOkc~0`^WK6bxA1@9kMfQOBrgZl29l2`+4pk! z1Ka03H|dvOoAg&d_)5{nyDpxD>?Ys}Ky`7S%Pk>WD&qn`ZG9P_XAB_wmB7Wodw?5& zS%4mu|8C%XKt8D7OuK?rt`A%TQ~-L^FJ}W&L^#h`HvK;EWMCW+1x5lxpL1ZC#sObz zh1Xg9UW;c~ETp#5b0IL%r08Gp2;dS+PqSF)UBJ1(l_Kmz_j{vldMtP*aHFM#raEc$ zm-}1_!Lawv1Fo`yQDC)?+D!Utlg=@Tj{B;Men6v@dL^+UuVkVhsr&pkL|*6LdS&;P z-sAtI%Bxx8bw;9-U+?i2dUaLad(JLfQ}X#?ql-FaOKq?Esy)>gYAe-6<;j2br~Fqx ztButk>U*_^{8ayjeJ}sip6U;c6SarxseTFDpX5LvsLj<*delCu^FKfI=l!dH{-us{ zAOG-g{`abX{6gfi*LR#8^{Ja%F7-c=OkF>^mPz23j)G|`|EazQJ1%|k>_30z z@PAA=H0I%F&Kdp0*N^^s^MtRw**3cU>8p01`g!N9IrDyY^vaF}U;XNlPQ0=!=bkhVp9e z9B||pB46joKM9?1=v&d>^|{meZzfsd$R`(h-U^3)n*1{y{dMS1_*R&Iw6_lZ9?I8K z=Dpf~BlHwUe-om)4t*58PKQ1ldAH;LBhMo$}S;-HyBi`XxucneyEB zdmVez9sLg?KkE3i3;AS6z8rd=V{ab%&5r(jrsE7553Qke+k;H&uge|aqMk{KH=!!iJfPi@}EHdsH6XDXy4H$C*^!GdT14I1(G4huj`zAR+kM!0Kv0nkbXFyJ2tlg_q*;HFo zETu(znpa!f)S7Oq&E@0Sd~K~)`+-%p%aTp0Tt1nd(-P0+k~yy_lSd%1 z4V25!VfjX{F`Y@adAWSHt)VsJW!m#O{nyYO&wBCtbQZ;YHjf95v}8_13+jyxE$Lh` z5Vf}mH^g&E89=KkrOwMI+g2e+;G3v+m<`S8)#P1mdQuuBKX{}UP~rrj`~k>9C=d7Cfh_z#&0N!7#|O$&DYhlWUbi(aFTP>r zh^@S6K;FR|9*bOazno2<)`W64GMekK$uOGVt6@@9wvZZz-H%&@F-%nFq^7l!lOO!xG)=| z6T&p|Nnvf8$bSKw*%DzYT`J6CK2n&?a+xq2uX15FYU6}&WbGAZljRGu(Vi$=&YB>6 z8EdaF8?dM_o5tzFw95=(HsiB|+2mFUzlXJ1n9bcnVK#i#!fbqF!fX<2gxTP&5N6}M zQkV^7op2?43t=|+&BAP6TZGw2XM}m7$P2THTqDd2LTT01e>=Ct`(0`0(??2rrWQ(i zx(cIuHujVrd#14GQQGB)8xM_me*K|6C-)S>^y5zYQ765_NpE-3Tb%TICw-rj?r_q1 zC*9(t6Ha=ildf^n)lPb@lb+?Ir#tB>PI{t~p5Ua*o%Bd2UE-uqzInQRjyvh2PWrHu ze%VRCAg;RkCT4fNk8hOcR19=5ZOJhlM6On2|T1B(w$9NATf#JYPQM$QQAW4MkehxZNWvRTOd?mo}Imo30; zeSeFrq;6~BY2Fh7t0{ zf3wJYrL^q9LL_?cp^~z%70&XO_rB5J|J1S1bQRQ=k<5Za#ZlTgy3Vxe%j3HWGi>=| zi-LCD5ASNryTS7Iz^kylf3|J?D7?!pk3Hb{V)|@j5$#;o-CN>!_m+BF3&qIS&17su zH)FH1w}iI7)bn0hL*6wbx(cUG_5UspelL0>7&oe8GxU4F39t{Y178AO37!C!-du1D zdK|bKd;xeNxEwqed>&YOGr=>UM}endb6?!cXDt1HTDA4t^ah{iCG!lU8~1Q+4rZgM;vY2w!#%%g*)a zVN3JmQPL`BIJ##ce;K)WyCnDV0iAyGYA*c@+3>3F-kUPreYewgYTxzPehm4}vJHpI z{O-PC*!V8=K7Yd@uT%XSqo42T+5OQMB0Ieehy2btg(H$jHyl!)h*x#U^X~2Oqp`vW zZ+V~JSv71HHou6DY?a_w6kmdV+;HeP{8H>tuf7*ZYwXQu9E9aRDBCJK_BLh5<`n)( z@-vkks~Wbiw5#wjboP!rUFOfB!!mb~R+-rEWvLw~H!r*IQ0GS^KU2BXc?IR(fsX3@ zBb8Bg-yuG)^i@$tmE+6f$UNYDE6T7N$)>8*W#-QPdH99!}yQrF$Ll|Czl&OrYg zX^oACNdJa(3G?LGg2Mcxh{ya z>f>;}va9O52A?%XhvDa^i##))qqZJZ)MGt)!#b!w!?79C@_8h@2)qdGL|uCMUh$d8 zIkCRd3%e$LJmOt(o{?qx+VE9z{VdA4NH$0_uLsILZp$9y@SZCU{9#@X=xv85zt4hK zM7!M@@qSrKdu_iUXs?~o7YgfuH~y@78awoHtqtg%NBJL&c+anCBsQ%A<^!J!){8$z zWHZ*c!M5G2mcHB4|8D84v7tHpbJ?cestfPWCOw>VnMrr|^_=Q|Jt1_dmNB0*1bB)5`AoJSK-H&cbDb$!26-)u~jv(_`uk%v6F1ys9!Y3 z4jaE>eY?kY4ZDOgAHPOro{r5=;g{lgH+k7p4jP}E$Q#kvtn2O_MIY`kG;scR>nf}xt^WH4_KsM+VRo&mrfjWMd^dU9wQBBt>;q^AtyNm5zE3~O{y6HmL1oYu zZ1+taOYxKMO@qeYBj_BTuDwLnp<-`Y@6qzE`};iaGe_XLb^Rp19V`#V#A?}PEc{ru zsQ*2*>pstWeovySuqO}91@Mb~!z;UGn?81JwO~u}p)N~xo2qw=JWJ70y~mvDH~v+Xca8ndka|x>XXw1U3|YFfadr^i6w6y?dHdkK&+_iXr!ZE$ zZs+SH?CmV>DojOZ2lz_xHt^-b%exBOazI1S40VpJ)#7k#Ku^3|=s^){LK z*Qq=deS)&Zdn=P+zZe1AP_i8})4Wm@3LFd3Hmg z_atT5INz&S3V*oDp-+hk194=IjV*tKr@5mz_9A)TsO;`Lab8!UyB^2_Hv{){6(018 zdUn#ss@JR3In46|^6W?7N8d-^N8d-^o5VOk|6S-8&=1=!X3Hgp4Djx#_2m zfy~;29*^}Vi$o`Z0Q1uu!1G)*0d2lB%cNg!m-{YPC5dgdc*!ykX@xdjJ^9~B^1&#s7 zftSfU>+g8y2lfHSm4>$sTldK}5X0tn;0Q4NyS)Db-N0dBGA|)@z%F1N`PQJn7dQco zLtpPWGkB*xi9CT1Ex_PQ|8HUse!1UOD2{II zDT;3Xt@c2d^jAivoa}#P9e)hifqA`idj3z@Cok)Z_}#^x|J*QidJp2Kk8SgA8r_6^ zc^}^)N{zlvD}LzP#D4yct0%*IY>anP?JeJpFYC*&U8lL(Rrtl5jBn!Z`NX4hnRhYf zmg4)%;xq5gvHW4o$Kmj!ij z&vD}wPwDeM#l^|^*p3X{SHv&2{Brp6L4N)XSbobl4_jY{E-fQXoj37bCH_&`Q955i zCcfnQma(2TKgJk2pf<0gT^Jwt8l6pr2JoJ@X@B{n_WuZYoAOnuJvSRai3o*T;IAVe zbzt2L#znKua|bv&$+{$hRFGN;j@&>ZA$bY+)F9GkMpVtG5L5g#;hH9kD0(aiuWNe_$@#(>7jx%fb>h#j zkjaNN=*f@s<%bzZTg`Wq&_9jWk;t?TOa7m{SEwElc;R?bJww}5u)P=Cza<8V&wkXD zIS&3a@Yxd?{#lk^0)IFBU%@}gc<|H@jIV!%r}6bP_=v_2@nAUqmf-&|%6}2Q#-+;I z>*Nz(`5ps5PQGK<-645ZVE0E>{xEnOa@8{&w@<;7P36syrvrJohxneA?F82#OPIXD z{z7y25i9Qo4;{A}qZ*&%*h@?XW&qVd4WO~>gR6ijpfTJ7FC52vNw0)o%otEyR=itT z)-|?l&^X>wsG{73^0%(LcP?wo&Cp&fc4!#mVFrA)-97Nsc8bBDf204EiSSMQwR7{M z$W{L|cspgP9*=`H{|;E+j1QE-T;%XFSWeO ztX>pevE@y)JRjbv*Mq#8r?OuL?{&-L&ov`Tpv6Bf9_3b0kK?q1=6U#jq_#QyHax{^ z>1jT>y1OmEXb8XC@_7dvq<`NT^jpqgetL0{iIOy@2}oBz-&`p2oQLR`g#lfASgB&+D)$Ki{dJ!+l5C zMsww(PafyDH%_P_Re|0|OjyGnPFmd$}N$#~pt>+x+{5A9F$__qd-za3zW z$r*M&UNFShJIGfjU-|Z7zPFVzCd=&iwla;$5A|tJGDBn1+hWFYj66}BhjHDjd854~ zI!7kJpHQZ{2kYb}>)-v>zXP@%H~j^_uKR!R>x%z@Umvl4)mpzEwSMiwuM_k5J53$m z6JuS4h288=VjFu#bPJL_kxX}QQ77-6cewHB9XY;{_bx#DbB!JCz4iCt1G|YKKo4*PI0l>myeIh^B2Wg51AJgI5Cvuc zRlq_Z2CM+;fMy^AtN}WKb-*TI8_*5x1a<+pLH>v&&N-P5P-e|AROC9sZ)L=J@sT_Cz+G5193p{H6bn5x7~I$)+1BThod5 z77lcHUKY@?j+y=~ZSne+q@Pdw4b91hJAJF8a>+O;H`Bi@o^9j6$V`8J3dOc`-p^!{ zxnx`3(Q&QlfQQfVfn+wB}Tl(o{UaPR3=i{WP>?;@eXzelxSRQ z+HXu}jk}W)K`9(`@KSA@z`#zL{{cgQ)#S$KMQy9%Evba5qH!Q~bd46yI9(X%cJT^!RUYJ3U(7+OMHhW&d}_iTpclUjuM( zyKw}_Q>pxwWLCMn_j%KR)8*?F zkjfw7@Jv>J7Tg>CS&iA`T{jN)8S|mkj1nXEDig_7l>`b3TK zY}xE3HMduI9w*9hE+0>|U5G+B`WcX zv6yOHtGde;{C3sT&o>jJliAjs;;9Hu&->Mc;jF(PNvMst__6l-mQ;gZooYz7<&u6p z=V!#pH766sR{dI&alV>qdDu+z)7Up>(WdxGnhblkEBvd&qO8R!%+1iR$??1@Lioxk zlwOYaYyB41oq_BXrp%#jak|P0EnBKcGtry`2C3}oR7;CuV|y;y*xoWF@Vh znfZ%qmdsne+@HU6nLpc)&0bcsXwEIwvzPg?Tb9L^E}vK7`^#x5%-X)NE&dKot`(v+ z&ET^`D`F`_-^_%0Xl5~7Sk`sjq#!~~sJ8b2@Xg+Lvj$O7j1>-xfVQPn3g}!kk}k2!(-tU~`sn*7 z!680D+r5wBcpfu}rosD3Ib(S6+F^QZqEcQY1&MFxDxGZqf`88>ej31B({&n*FY!e0i!eZIxA%_#Hy_^ zdF9lB$0i3jL+C5L4(4re`kMW^>6;FJNxU`b`_PNE4e79xqXXSZ*Cvc$($!$dob#XG zp^BLE!{Fecu3K-zF`F9WJ<2SVUb?Z-TU|d$uRd%R^(dz7__(u;EeipvwUzeOur=et z_K#Vzr>+`-cX|S{c@X*GsZDp#@3c{+aiwx~y|X1!SvUF>6%|ABWQOK>tCDT@K^dJ8 zVP6|^Z!sQ(s7ghZ%259;N5wE&TWi=k;hC9~ZB4IQqQmfc< zWp5lTGm(gZrkA@x<_3o%*9pSM=^z!lslGEqioKh`?B@(-CuQ)}7EibM8jG*B_&UCB z&7Dm-;5pR>&zTpsc$&eBmo8r<`Qk;(ms-6K3fHWeYvju;Hs#H*cCQccH0#$i{93d` zxjav6y727k8oV(W?+ixUV6+W3`$6=m1>ZXl_v@!b=IQ(j^B&M6UI;qBt@L(_bzXa< zls*^y#!SB(x(HIgq2wqq-(dLg0_=n42(qEY+j6(({qa;SU^uPaFDarh`cD}@^>BcTeb_q2i6Da72xxr*8t}OrNF8F{`5Hb{b1$g zdvp4WpC$1>eDu4|@EJ*c|9^zgKjA2Umt8Pt&P;zYKgdY2x0qgWZN=47r%k^yn@LT( zJRsjrW5ytb+1l8|lkxhL7nw+M*tOp9;iZwYBO{8=D=CkRja*nfE^<+1e9^_l6CzV0 zUPW$gYd&5N=9d!&H-{;+WM{kzqJFZ1ZR6B@yvb79Pt~`l_z7$(;hEi4b3E7VRV3E7 zVK2b>Y#_0l=|My-vTU+N`avSY&t59bZ(%C($u*?SuVX5*Y4bCRirLE+SMWoS#2T+6 z*<9Pm)+`yQ*Xn&`ZJ-{eKhl78EXP|@4V0S3T406WVt5sb=X|;GjLmr7zJ9Q9|2H4a z6OAm5&FRbw{f=34D15?EcNvVc0O^_E86)sXhmYo!9!>60FLO8h0QA&x;S=gDgfR?| zJlZQp33#D@$|ATE&>UA<^PCU1UKQ!E4Z`|z=E?lVR(gsP zE6`J%2<=Hv@q#K2=qauoKu_^TdglV69wJjOlb?8?AK0Qg@Py?)07rF_o{1Ugy&P5& zp7aC{0-@d!zLy^1kJQr@Jna+O+Xfx#Dc(-FBJg{tp2D~ERNsl{O+;@CHp3^h_YD~6 zW$pp*eiC49Q9IzKc|yJKLWTC8MekYkLYWl9^!G_CuliW)z}_?H{Rp|-k)GCveP_`7 zDRPx7J)POue+IpS$koQu3x20hJ;_#!(whSgAISu70NBce{1?%y3<!kHe<}PnZ_&qQ*6Cc zd=xH;rd-{T0WTffxc=H%3J7YC3^%R>K&fMD=(!ngyJkwKbMr<&j0$ME>%$tB#uP`^BGzfj| zMuK@DTx@nF!FUg7?P7v)9nisUC){fkn_uY%`<_6q-Hyjtj2K*Oe!(A%J28p}tsJ7A z0Al19n;r`LM;%&Lb`~^AkSAi zax(&K`)h`Y4%=H1LUid6xj#_;Xmh6nD&{HS_sY@_`%jVR5=&18hvk=UGV1&{%GlrK z_@hm+=*J!Xny$h635UK3k?0+c{z*q}{O>-UU-duw)zh@((XXARCEp=q<_Y{e;n0#d zf8C0$|D6skd5=TO{&9zveCNZ1^S|uSl4o`fmalVY$;-YuSnfNtvG33-UuXM*C+Po$ zoa1w8oihxcGVg;VMAv{LL?+=5Xy4MZud|rJGtP{s?M{A4^tbKcxyZZS(()t1{HO~A z=6{VB?H|Ikfc(PL*t>5ae=wfIcOi`z?HNKk98Vq2_|Z^3NPc;s@`Sa%1y8y6WryY$ zre^%wi86>VowdHS%8IT?Xye=UQm3 z%Ypnt<9`^RwF8r6!azJY*T}>B10=6TLG@98pGSYKgbwA3#%<80-Hb7oCdpSrhw;lN ze%%8-#oCwt7U=c1J#`<#*Pz||GQI~r*U^6tTKfQ%ulqb+gm&*&=!M?q$oXTqr}_6N z`ts-Z&^n_V=6?fvrDOjb{MLNaK2Z8&pt~LYcSH9;>yf`#K)e1=gVvej(7x{TXm;!` zh1R)%P`(1%yTHS_Bir)K`VZR?KKH{pCi8xI_&>4`hPC8dmls%bdRIY zS^Powb=(i_-gog3bcx+RX#6|^{jAfTd!WO|C-Gxw_r8~3L5J~YOwl;+2=rvf-U(=} zzd?P=yt7ES_lfWWkwN#DOo4XqL%9jsz5gW!t@u!fFY1pv=!8>V2ef;i$mgKl{@x7j z-jDJP=n@;RWbfP1I!6RD^Wg~+TF=(m@}7lu?d^kJ=am01&^n6*GWmZ)!X3}ALA&>l zlne{jo8!E!sr<8{wO$1I$9bcn-TPX`L+>AuU*x?PTI*@v`Zpa~=Xb*LXG81keMm2c z4j-RH9NN9#BoFQ0PxC40y-xl98v1}ke+$|h7;huJUC{3RH2(mt^;~g7_46hsyoqtI zf$!$dy(8vNz!eQ%Z6aOGA9&11=89A<8|TUlz7%t2MeL-mrO@9Img;PY$6vBsZBt8{zg5&G^66}@Hr~F*<7-H! zh084x71vyQ^>yTU8zpm7N$_!{mMz&`39okU?Mr4aUNi@jj>KHc;?*vwUV8KF>e{9A=P#dEQ_Ej5tLNzw z4Rh~CL#{ozO+{a>(k)e0r|-~6r01DaHlDr!*^4-WJ3L%1=b8?jG?$FHVtsFSX?w5B zGT8RE5Le1wA-cpRkv4KZh;#Fb=^1k=iL04N$2epW{y8MLhsC`XB)CJwy+y_|7mv6$ zuz#DmqGZsGEcS94$JoH7HK(tFF`msaM?7dIoudg|Im5*>G;c$2bBgPMy&GjPYtRij zfrG*IDy~{^xr)n41h?$i8(CZlBh%?YE`Av-9CH7PE5vK_XWBtLbKi{18E7BpQXjYF z&HX(?ZVJ*NEY}7;=F+uH&_qj;zXzxCgM^EgGX4^&wp#wO&y6=4s_lcuDlD$6ar4;g zW?YuJmd0f`bHIE*9eTlzt4mjL-;K**LMOs2bO!N*X-9-HLpPDW#U4On&IOm%3>qt# z7<>hgGo$SNJFazeMNYd8_YuPeE+lgA8aiE|{=TTcu9<<#z|3L#g?Tp;8!g1edcn`x3hJ!$a( diff --git a/wiringPi/README b/wiringPi/README deleted file mode 100644 index c79754e..0000000 --- a/wiringPi/README +++ /dev/null @@ -1,9 +0,0 @@ - -WiringPi: An implementation of most of the Arduino Wiring - functions for the Raspberry Pi, - along with many more features and libraries to support - hardware, etc. on the Raspberry Pi - -Full details at: - https://projects.drogon.net/raspberry-pi/wiringpi/ - diff --git a/wiringPi/gertboard.c b/wiringPi/gertboard.c deleted file mode 100644 index a8795d3..0000000 --- a/wiringPi/gertboard.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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 "wiringPiSPI.h" - -#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 (int chan, 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 (int chan) -{ - uint8_t spiData [2] ; - - uint8_t chanBits ; - - if (chan == 0) - chanBits = 0b11010000 ; - else - chanBits = 0b11110000 ; - - spiData [0] = chanBits ; - spiData [1] = 0 ; - - wiringPiSPIDataRW (SPI_A2D, spiData, 2) ; - - return ((spiData [0] << 7) | (spiData [1] >> 1)) & 0x3FF ; -} - - -/* - * gertboardSPISetup: - * Initialise the SPI bus, etc. - ********************************************************************************* - */ - -int gertboardSPISetup (void) -{ - if (wiringPiSPISetup (SPI_A2D, SPI_ADC_SPEED) < 0) - return -1 ; - - if (wiringPiSPISetup (SPI_D2A, SPI_DAC_SPEED) < 0) - return -1 ; - - return 0 ; -} diff --git a/wiringPi/gertboard.h b/wiringPi/gertboard.h deleted file mode 100644 index 98fd1e7..0000000 --- a/wiringPi/gertboard.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 - -extern void gertboardAnalogWrite (int chan, int value) ; -extern int gertboardAnalogRead (int chan) ; -extern int gertboardSPISetup (void) ; - -#ifdef __cplusplus -} -#endif diff --git a/wiringPi/lcd.c b/wiringPi/lcd.c deleted file mode 100644 index f123db2..0000000 --- a/wiringPi/lcd.c +++ /dev/null @@ -1,380 +0,0 @@ -/* - * 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 "wiringPi.h" -#include "lcd.h" - -// Commands - -#define LCD_CLEAR 0x01 -#define LCD_HOME 0x02 -#define LCD_ENTRY 0x04 -#define LCD_ON_OFF 0x08 -#define LCD_CDSHIFT 0x10 -#define LCD_FUNC 0x20 -#define LCD_CGRAM 0x40 -#define LCD_DGRAM 0x80 - -#define LCD_ENTRY_SH 0x01 -#define LCD_ENTRY_ID 0x02 - -#define LCD_ON_OFF_B 0x01 -#define LCD_ON_OFF_C 0x02 -#define LCD_ON_OFF_D 0x04 - -#define LCD_FUNC_F 0x04 -#define LCD_FUNC_N 0x08 -#define LCD_FUNC_DL 0x10 - -#define LCD_CDSHIFT_RL 0x04 - -struct lcdDataStruct -{ - uint8_t bits, rows, cols ; - uint8_t rsPin, strbPin ; - uint8_t dataPins [8] ; -} ; - -struct lcdDataStruct *lcds [MAX_LCDS] ; - - -/* - * 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 (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 (struct lcdDataStruct *lcd, uint8_t data) -{ - uint8_t i, d4 ; - - if (lcd->bits == 4) - { - d4 = (data >> 4) & 0x0F; - for (i = 0 ; i < 4 ; ++i) - { - digitalWrite (lcd->dataPins [i], (d4 & 1)) ; - d4 >>= 1 ; - } - strobe (lcd) ; - - d4 = data & 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], (data & 1)) ; - data >>= 1 ; - } - } - strobe (lcd) ; -} - - -/* - * putCommand: - * Send a command byte to the display - ********************************************************************************* - */ - -static void putCommand (struct lcdDataStruct *lcd, uint8_t command) -{ - digitalWrite (lcd->rsPin, 0) ; - sendDataCmd (lcd, command) ; -} - -static void put4Command (struct lcdDataStruct *lcd, uint8_t command) -{ - uint8_t i ; - - digitalWrite (lcd->rsPin, 0) ; - - for (i = 0 ; i < 4 ; ++i) - { - digitalWrite (lcd->dataPins [i], (command & 1)) ; - command >>= 1 ; - } - strobe (lcd) ; -} - - -/* - ********************************************************************************* - * User Code below here - ********************************************************************************* - */ - -/* - * lcdHome: lcdClear: - * Home the cursor or clear the screen. - ********************************************************************************* - */ - -void lcdHome (int fd) -{ - struct lcdDataStruct *lcd = lcds [fd] ; - putCommand (lcd, LCD_HOME) ; -} - -void lcdClear (int fd) -{ - struct lcdDataStruct *lcd = lcds [fd] ; - putCommand (lcd, LCD_CLEAR) ; -} - - -/* - * lcdSendCommand: - * Send any arbitary command to the display - ********************************************************************************* - */ - -void lcdSendCommand (int fd, uint8_t command) -{ - struct lcdDataStruct *lcd = lcds [fd] ; - putCommand (lcd, command) ; -} - -/* - * lcdPosition: - * Update the position of the cursor on the display - ********************************************************************************* - */ - - -void lcdPosition (int fd, int x, int y) -{ - static uint8_t rowOff [4] = { 0x00, 0x40, 0x14, 0x54 } ; - struct lcdDataStruct *lcd = lcds [fd] ; - - putCommand (lcd, x + (LCD_DGRAM | rowOff [y])) ; -} - - -/* - * lcdPutchar: - * Send a data byte to be displayed on the display - ********************************************************************************* - */ - -void lcdPutchar (int fd, uint8_t data) -{ - struct lcdDataStruct *lcd = lcds [fd] ; - - digitalWrite (lcd->rsPin, 1) ; - sendDataCmd (lcd, data) ; -} - - -/* - * lcdPuts: - * Send a string to be displayed on the display - ********************************************************************************* - */ - -void lcdPuts (int fd, char *string) -{ - while (*string) - lcdPutchar (fd, *string++) ; -} - - -/* - * lcdPrintf: - * Printf to an LCD display - ********************************************************************************* - */ - -void lcdPrintf (int fd, 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 (int rows, int cols, int bits, int rs, int strb, - int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) -{ - static int initialised = 0 ; - - uint8_t 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 = 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->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 - - putCommand (lcd, LCD_ON_OFF | LCD_ON_OFF_D) ; delay (2) ; - putCommand (lcd, LCD_ENTRY | LCD_ENTRY_ID) ; delay (2) ; - putCommand (lcd, LCD_CDSHIFT | LCD_CDSHIFT_RL) ; delay (2) ; - putCommand (lcd, LCD_CLEAR) ; delay (5) ; - - return lcdFd ; -} diff --git a/wiringPi/lcd.h b/wiringPi/lcd.h deleted file mode 100644 index beebb75..0000000 --- a/wiringPi/lcd.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 (int fd) ; -extern void lcdClear (int fd) ; -extern void lcdSendCommand (int fd, uint8_t command) ; -extern void lcdPosition (int fd, int x, int y) ; -extern void lcdPutchar (int fd, uint8_t data) ; -extern void lcdPuts (int fd, char *string) ; -extern void lcdPrintf (int fd, char *message, ...) ; - -extern int lcdInit (int rows, int cols, int bits, int rs, int strb, - int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ; - -#ifdef __cplusplus -} -#endif diff --git a/wiringPi/libwiringPi.so.1.0 b/wiringPi/libwiringPi.so.1.0 deleted file mode 100755 index 7c87ee9e0b6a1975bca211971d0a94605bef164a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43311 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 diff --git a/wiringPi/piNes.c b/wiringPi/piNes.c deleted file mode 100644 index a115050..0000000 --- a/wiringPi/piNes.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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/wiringPi/piNes.h b/wiringPi/piNes.h deleted file mode 100644 index 897f181..0000000 --- a/wiringPi/piNes.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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/wiringPi/q2w.c b/wiringPi/q2w.c deleted file mode 100644 index 31486da..0000000 --- a/wiringPi/q2w.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * q2w.c: - *********************************************************************** - */ - -#include -#include -#include -#include -#include - -#include -#include - -// MCP23S17 Registers - -#define IOCON 0x0A - -#define IODIRA 0x00 -#define IPOLA 0x02 -#define GPINTENA 0x04 -#define DEFVALA 0x06 -#define INTCONA 0x08 -#define GPPUA 0x0C -#define INTFA 0x0E -#define INTCAPA 0x10 -#define GPIOA 0x12 -#define OLATA 0x14 - -#define IODIRB 0x01 -#define IPOLB 0x03 -#define GPINTENB 0x05 -#define DEFVALB 0x07 -#define INTCONB 0x09 -#define GPPUB 0x0D -#define INTFB 0x0F -#define INTCAPB 0x11 -#define GPIOB 0x13 -#define OLATB 0x15 - -// Bits in the IOCON register - -#define IOCON_BANK_MODE 0x80 -#define IOCON_MIRROR 0x40 -#define IOCON_SEQOP 0x20 -#define IOCON_DISSLW 0x10 -#define IOCON_HAEN 0x08 -#define IOCON_ODR 0x04 -#define IOCON_INTPOL 0x02 -#define IOCON_UNUSED 0x01 - -// Default initialisation mode - -#define IOCON_INIT (IOCON_SEQOP) - - - -/* - ********************************************************************************* - * The works - ********************************************************************************* - */ - -int main (int argc, char *argv []) -{ - int q2w ; - -// if (wiringPiSetup () == -1) -// { fprintf (stderr, "q2w: Unable to initialise wiringPi: %s\n", strerror (errno)) ; return 1 ; } - - if ((q2w = wiringPiI2CSetup (0x20)) == -1) - { fprintf (stderr, "q2w: Unable to initialise I2C: %s\n", strerror (errno)) ; return 1 ; } - -// Very simple direct control of the MCP23017: - - wiringPiI2CWriteReg8 (q2w, IOCON, IOCON_INIT) ; - wiringPiI2CWriteReg8 (q2w, IODIRA, 0x00) ; // Port A -> Outputs - wiringPiI2CWriteReg8 (q2w, IODIRB, 0x00) ; // Port B -> Outputs - - for (;;) - { - wiringPiI2CWriteReg8 (q2w, GPIOA, 0x00) ; // All Off - delay (500) ; - wiringPiI2CWriteReg8 (q2w, GPIOA, 0xFF) ; // All On - delay (500) ; - } - - return 0 ; -} diff --git a/wiringPi/wiringPiFace.c b/wiringPi/wiringPiFace.c deleted file mode 100644 index ac3c6fa..0000000 --- a/wiringPi/wiringPiFace.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - * wiringPiFace: - * Arduino compatable (ish) Wiring library for the Raspberry Pi - * Copyright (c) 2012 Gordon Henderson - * - * This file to interface with the PiFace peripheral device which - * has an MCP23S17 GPIO device connected via the SPI bus. - * - *********************************************************************** - * This file is part of wiringPi: - * https://projects.drogon.net/raspberry-pi/wiringpi/ - * - * wiringPi is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * wiringPi is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with wiringPi. - * If not, see . - *********************************************************************** - */ - - -#include -#include -#include -#include -#include -#include - -#include "wiringPi.h" - - -// The SPI bus parameters -// Variables as they need to be passed as pointers later on - -static char *spiDevice = "/dev/spidev0.0" ; -static uint8_t spiMode = 0 ; -static uint8_t spiBPW = 8 ; -static uint32_t spiSpeed = 5000000 ; -static uint16_t spiDelay = 0; - -// Locals here to keep track of everything - -static int spiFd ; - -// The MCP23S17 doesn't have bit-set operations, so it's -// cheaper to keep a copy here than to read/modify/write it - -uint8_t dataOutRegister = 0 ; -uint8_t pudRegister = 0 ; - -// MCP23S17 Registers - -#define IOCON 0x0A - -#define IODIRA 0x00 -#define IPOLA 0x02 -#define GPINTENA 0x04 -#define DEFVALA 0x06 -#define INTCONA 0x08 -#define GPPUA 0x0C -#define INTFA 0x0E -#define INTCAPA 0x10 -#define GPIOA 0x12 -#define OLATA 0x14 - -#define IODIRB 0x01 -#define IPOLB 0x03 -#define GPINTENB 0x05 -#define DEFVALB 0x07 -#define INTCONB 0x09 -#define GPPUB 0x0D -#define INTFB 0x0F -#define INTCAPB 0x11 -#define GPIOB 0x13 -#define OLATB 0x15 - -// Bits in the IOCON register - -#define IOCON_BANK_MODE 0x80 -#define IOCON_MIRROR 0x40 -#define IOCON_SEQOP 0x20 -#define IOCON_DISSLW 0x10 -#define IOCON_HAEN 0x08 -#define IOCON_ODR 0x04 -#define IOCON_INTPOL 0x02 -#define IOCON_UNUSED 0x01 - -// Default initialisation mode - -#define IOCON_INIT (IOCON_SEQOP) - -// Command codes - -#define CMD_WRITE 0x40 -#define CMD_READ 0x41 - - -/* - * writeByte: - * Write a byte to a register on the MCP23S17 on the SPI bus. - * This is using the synchronous access mechanism. - ********************************************************************************* - */ - -static void writeByte (uint8_t reg, uint8_t data) -{ - uint8_t spiBufTx [3] ; - uint8_t spiBufRx [3] ; - struct spi_ioc_transfer spi ; - - spiBufTx [0] = CMD_WRITE ; - spiBufTx [1] = reg ; - spiBufTx [2] = data ; - - spi.tx_buf = (unsigned long)spiBufTx ; - spi.rx_buf = (unsigned long)spiBufRx ; - spi.len = 3 ; - spi.delay_usecs = spiDelay ; - spi.speed_hz = spiSpeed ; - spi.bits_per_word = spiBPW ; - - ioctl (spiFd, SPI_IOC_MESSAGE(1), &spi) ; -} - -/* - * readByte: - * Read a byte from a register on the MCP23S17 on the SPI bus. - * This is the synchronous access mechanism. - * What appears to happen is that the data returned is at - * the same offset as the number of bytes written to the device. So if we - * write 2 bytes (e.g. command then register number), then the data returned - * will by at the 3rd byte... - ********************************************************************************* - */ - -static uint8_t readByte (uint8_t reg) -{ - uint8_t tx [4] ; - uint8_t rx [4] ; - struct spi_ioc_transfer spi ; - - tx [0] = CMD_READ ; - tx [1] = reg ; - tx [2] = 0 ; - - spi.tx_buf = (unsigned long)tx ; - spi.rx_buf = (unsigned long)rx ; - spi.len = 3 ; - spi.delay_usecs = spiDelay ; - spi.speed_hz = spiSpeed ; - spi.bits_per_word = spiBPW ; - - ioctl (spiFd, SPI_IOC_MESSAGE(1), &spi) ; - - return rx [2] ; -} - - -/* - * digitalWritePiFace: - * Perform the digitalWrite function on the PiFace board - ********************************************************************************* - */ - -void digitalWritePiFace (int pin, int value) -{ - uint8_t mask = 1 << pin ; - - if (value == 0) - dataOutRegister &= (~mask) ; - else - dataOutRegister |= mask ; - - writeByte (GPIOA, dataOutRegister) ; -} - -void digitalWriteBytePiFace (int value) -{ - writeByte (GPIOA, value) ; -} - - -void digitalWritePiFaceSpecial (int pin, int value) -{ - uint8_t mask = 1 << pin ; - uint8_t old ; - - old = readByte (GPIOA) ; - - if (value == 0) - old &= (~mask) ; - else - old |= mask ; - - writeByte (GPIOA, old) ; -} - - -/* - * digitalReadPiFace: - * Perform the digitalRead function on the PiFace board - ********************************************************************************* - */ - -int digitalReadPiFace (int pin) -{ - uint8_t mask = 1 << pin ; - - if ((readByte (GPIOB) & mask) != 0) - return HIGH ; - else - return LOW ; -} - - -/* - * pullUpDnControlPiFace: - * Perform the pullUpDnControl function on the PiFace board - ********************************************************************************* - */ - -void pullUpDnControlPiFace (int pin, int pud) -{ - uint8_t mask = 1 << pin ; - - if (pud == PUD_UP) - pudRegister |= mask ; - else - pudRegister &= (~mask) ; - - writeByte (GPPUB, pudRegister) ; - -} - - -void pullUpDnControlPiFaceSpecial (int pin, int pud) -{ - uint8_t mask = 1 << pin ; - uint8_t old ; - - old = readByte (GPPUB) ; - - if (pud == PUD_UP) - old |= mask ; - else - old &= (~mask) ; - - writeByte (GPPUB, old) ; - -} - - - -/* - * Dummy functions that are not used in this mode - ********************************************************************************* - */ - -void pinModePiFace (int pin, int mode) {} -void pwmWritePiFace (int pin, int value) {} -int waitForInterruptPiFace (int pin, int mS) { return 0 ; } - - -/* - * wiringPiSetupPiFace - * Setup the SPI interface and initialise the MCP23S17 chip - ********************************************************************************* - */ - -static int _wiringPiSetupPiFace (void) -{ - if ((spiFd = open (spiDevice, O_RDWR)) < 0) - return -1 ; - -// Set SPI parameters -// Why are we doing a read after write? -// I don't know - just blindliy copying an example elsewhere... -GH- - - if (ioctl (spiFd, SPI_IOC_WR_MODE, &spiMode) < 0) - return -1 ; - - if (ioctl (spiFd, SPI_IOC_RD_MODE, &spiMode) < 0) - return -1 ; - - if (ioctl (spiFd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0) - return -1 ; - - if (ioctl (spiFd, SPI_IOC_RD_BITS_PER_WORD, &spiBPW) < 0) - return -1 ; - - if (ioctl (spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed) < 0) - return -1 ; - - if (ioctl (spiFd, SPI_IOC_RD_MAX_SPEED_HZ, &spiSpeed) < 0) - return -1 ; - -// Setup the MCP23S17 - - writeByte (IOCON, IOCON_INIT) ; - - writeByte (IODIRA, 0x00) ; // Port A -> Outputs - writeByte (IODIRB, 0xFF) ; // Port B -> Inputs - - return 0 ; -} - - -int wiringPiSetupPiFace (void) -{ - int x = _wiringPiSetupPiFace () ; - - if (x != 0) - return x ; - - writeByte (GPIOA, 0x00) ; // Set all outptus off - writeByte (GPPUB, 0x00) ; // Disable any pull-ups on port B - - pinMode = pinModePiFace ; - pullUpDnControl = pullUpDnControlPiFace ; - digitalWrite = digitalWritePiFace ; - digitalWriteByte = digitalWriteBytePiFace ; - pwmWrite = pwmWritePiFace ; - digitalRead = digitalReadPiFace ; - waitForInterrupt = waitForInterruptPiFace ; - - return 0 ; -} - - -/* - * wiringPiSetupPiFaceForGpioProg: - * Setup the SPI interface and initialise the MCP23S17 chip - * Special version for the gpio program - ********************************************************************************* - */ - - -int wiringPiSetupPiFaceForGpioProg (void) -{ - int x = _wiringPiSetupPiFace () ; - - if (x != 0) - return x ; - - pinMode = pinModePiFace ; - pullUpDnControl = pullUpDnControlPiFaceSpecial ; - digitalWrite = digitalWritePiFaceSpecial ; - digitalWriteByte = digitalWriteBytePiFace ; - pwmWrite = pwmWritePiFace ; - digitalRead = digitalReadPiFace ; - waitForInterrupt = waitForInterruptPiFace ; - - return 0 ; -} From 579a7b839a5d9b5938aae8a44939c6e18a870245 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Sat, 27 Feb 2016 16:30:24 +0000 Subject: [PATCH 19/29] Removed pesky piFaceOld.c --- devLib/piFaceOld.c | 178 --------------------------------------------- 1 file changed, 178 deletions(-) delete mode 100644 devLib/piFaceOld.c diff --git a/devLib/piFaceOld.c b/devLib/piFaceOld.c deleted file mode 100644 index 1b1c0dd..0000000 --- a/devLib/piFaceOld.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * piFace.: - * Arduino compatable (ish) Wiring library for the Raspberry Pi - * Copyright (c) 2012-2013 Gordon Henderson - * - * This file to interface with the PiFace peripheral device which - * has an MCP23S17 GPIO device connected via the SPI bus. - *********************************************************************** - * This file is part of wiringPi: - * https://projects.drogon.net/raspberry-pi/wiringpi/ - * - * wiringPi is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * wiringPi is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with wiringPi. - * If not, see . - *********************************************************************** - */ - - -#include -#include - -#include -#include - -#include "../wiringPi/mcp23x0817.h" - -#include "piFace.h" - -#define PIFACE_SPEED 4000000 -#define PIFACE_DEVNO 0 - - - -/* - * writeByte: - * Write a byte to a register on the MCP23S17 on the SPI bus. - ********************************************************************************* - */ - -static void writeByte (uint8_t reg, uint8_t data) -{ - uint8_t spiData [4] ; - - spiData [0] = CMD_WRITE ; - spiData [1] = reg ; - spiData [2] = data ; - - wiringPiSPIDataRW (PIFACE_DEVNO, spiData, 3) ; -} - -/* - * readByte: - * Read a byte from a register on the MCP23S17 on the SPI bus. - ********************************************************************************* - */ - -static uint8_t readByte (uint8_t reg) -{ - uint8_t spiData [4] ; - - spiData [0] = CMD_READ ; - spiData [1] = reg ; - - wiringPiSPIDataRW (PIFACE_DEVNO, spiData, 3) ; - - return spiData [2] ; -} - - -/* - * myDigitalWrite: - * Perform the digitalWrite function on the PiFace board - ********************************************************************************* - */ - -void myDigitalWrite (struct wiringPiNodeStruct *node, int pin, int value) -{ - uint8_t mask, old ; - - pin -= node->pinBase ; - mask = 1 << pin ; - old = readByte (MCP23x17_GPIOA) ; - - if (value == 0) - old &= (~mask) ; - else - old |= mask ; - - writeByte (MCP23x17_GPIOA, old) ; -} - - -/* - * myDigitalRead: - * Perform the digitalRead function on the PiFace board - ********************************************************************************* - */ - -int myDigitalRead (struct wiringPiNodeStruct *node, int pin) -{ - uint8_t mask, reg ; - - mask = 1 << ((pin - node->pinBase) & 7) ; - - if (pin < 8) - reg = MCP23x17_GPIOB ; // Input regsiter - else - reg = MCP23x17_OLATA ; // Output latch regsiter - - if ((readByte (reg) & mask) != 0) - return HIGH ; - else - return LOW ; -} - - -/* - * myPullUpDnControl: - * Perform the pullUpDnControl function on the PiFace board - ********************************************************************************* - */ - -void myPullUpDnControl (struct wiringPiNodeStruct *node, int pin, int pud) -{ - uint8_t mask, old ; - - mask = 1 << (pin - node->pinBase) ; - old = readByte (MCP23x17_GPPUB) ; - - if (pud == 0) - old &= (~mask) ; - else - old |= mask ; - - writeByte (MCP23x17_GPPUB, old) ; -} - - -/* - * piFaceSetup - * Setup the SPI interface and initialise the MCP23S17 chip - * We create one node with 16 pins - each if the first 8 pins being read - * and write - although the operations actually go to different - * hardware ports. The top 8 let you read the state of the output register. - ********************************************************************************* - */ - -int piFaceSetup (const int pinBase) -{ - int x ; - struct wiringPiNodeStruct *node ; - - if ((x = wiringPiSPISetup (PIFACE_DEVNO, PIFACE_SPEED)) < 0) - return x ; - -// Setup the MCP23S17 - - writeByte (MCP23x17_IOCON, IOCON_INIT) ; - writeByte (MCP23x17_IODIRA, 0x00) ; // Port A -> Outputs - writeByte (MCP23x17_IODIRB, 0xFF) ; // Port B -> Inputs - - node = wiringPiNewNode (pinBase, 16) ; - node->digitalRead = myDigitalRead ; - node->digitalWrite = myDigitalWrite ; - node->pullUpDnControl = myPullUpDnControl ; - - return 0 ; -} From 0f7d03d9f04c226192c299dafe03e1d56ec219c9 Mon Sep 17 00:00:00 2001 From: Philip Howard Date: Sat, 12 Aug 2017 11:06:53 +0100 Subject: [PATCH 20/29] Update README.TXT --- README.TXT | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.TXT b/README.TXT index 7789b2e..894a31b 100644 --- a/README.TXT +++ b/README.TXT @@ -1,3 +1,13 @@ +Note +==== + +This is an unofficial mirror of WiringPi to support ports (Python/Ruby/etc). + +Please do not email Gordon if you have issues, he will not be able to help. + +Pull-requests are not currently accepted, since this is a mirror. + +For support, comments, questions, etc please join the WiringPi Discord channel: https://discord.gg/SM4WUVG wiringPi README =============== From 03204c3807e660e81209284c7f8e426e04077fb7 Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Sat, 14 Dec 2019 13:42:07 +1300 Subject: [PATCH 21/29] Sync with changes from wiringpi_2.50.orig.tar.gz Sourced from http://archive.ubuntu.com/ubuntu/pool/universe/w/wiringpi/wiringpi_2.50.orig.tar.gz --- VERSION | 2 +- gpio/readall.c | 17 ++++++++++------- version.h | 4 ++-- wiringPi/wiringPi.c | 12 ++++++++---- wiringPi/wiringPi.h | 8 +++++--- wiringPi/wiringPiSPI.c | 15 +++++++++++---- 6 files changed, 37 insertions(+), 21 deletions(-) diff --git a/VERSION b/VERSION index e72716a..f02fc20 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.46 +2.50 diff --git a/gpio/readall.c b/gpio/readall.c index 9396c6d..097755a 100644 --- a/gpio/readall.c +++ b/gpio/readall.c @@ -303,10 +303,12 @@ static void plus2header (int model) 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 if (model == PI_MODEL_3B) + printf (" +-----+-----+---------+------+---+---Pi 3B--+---+------+---------+-----+-----+\n") ; + else if (model == PI_MODEL_3BP) + printf (" +-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+\n") ; + else if (model == PI_MODEL_3AP) + printf (" +-----+-----+---------+------+---+---Pi 3A+-+---+------+---------+-----+-----+\n") ; else printf (" +-----+-----+---------+------+---+---Pi ?---+---+------+---------+-----+-----+\n") ; } @@ -351,11 +353,12 @@ void doReadall (void) /**/ 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_2) || + (model == PI_MODEL_3AP) || + (model == PI_MODEL_3B) || (model == PI_MODEL_3BP) || (model == PI_MODEL_ZERO) || (model == PI_MODEL_ZERO_W)) piPlusReadall (model) ; - else if ((model == PI_MODEL_CM) || (model == PI_MODEL_CM3)) + else if ((model == PI_MODEL_CM) || (model == PI_MODEL_CM3) || ((model == PI_MODEL_CM3P))) allReadall () ; else printf ("Oops - unable to determine board type... model: %d\n", model) ; diff --git a/version.h b/version.h index 242c62b..07e50ef 100644 --- a/version.h +++ b/version.h @@ -1,3 +1,3 @@ -#define VERSION "2.46" +#define VERSION "2.50" #define VERSION_MAJOR 2 -#define VERSION_MINOR 46 +#define VERSION_MINOR 50 diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 586b148..3db6866 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -218,7 +218,7 @@ volatile unsigned int *_wiringPiTimerIrqRaw ; static volatile unsigned int piGpioBase = 0 ; -const char *piModelNames [16] = +const char *piModelNames [20] = { "Model A", // 0 "Model B", // 1 @@ -233,9 +233,13 @@ const char *piModelNames [16] = "CM3", // 10 "Unknown11", // 11 "Pi Zero-W", // 12 - "Pi 3+", // 13 - "Unknown14", // 14 + "Pi 3B+", // 13 + "Pi 3A+", // 14 "Unknown15", // 15 + "CM3+", // 16 + "Unknown17", // 17 + "Unknown18", // 18 + "Unknown19", // 19 } ; const char *piRevisionNames [16] = @@ -2239,7 +2243,7 @@ int wiringPiSetup (void) piBoardId (&model, &rev, &mem, &maker, &overVolted) ; - if ((model == PI_MODEL_CM) || (model == PI_MODEL_CM3)) + if ((model == PI_MODEL_CM) || (model == PI_MODEL_CM3) || (model == PI_MODEL_CM3P)) wiringPiMode = WPI_MODE_GPIO ; else wiringPiMode = WPI_MODE_PINS ; diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index ae5d647..0ff0c92 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -95,11 +95,13 @@ #define PI_ALPHA 5 #define PI_MODEL_CM 6 #define PI_MODEL_07 7 -#define PI_MODEL_3 8 +#define PI_MODEL_3B 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_3BP 13 +#define PI_MODEL_3AP 14 +#define PI_MODEL_CM3P 16 #define PI_VERSION_1 0 #define PI_VERSION_1_1 1 @@ -111,7 +113,7 @@ #define PI_MAKER_EMBEST 2 #define PI_MAKER_UNKNOWN 3 -extern const char *piModelNames [16] ; +extern const char *piModelNames [20] ; extern const char *piRevisionNames [16] ; extern const char *piMakerNames [16] ; extern const int piMemorySize [ 8] ; diff --git a/wiringPi/wiringPiSPI.c b/wiringPi/wiringPiSPI.c index 022b99f..749c8fe 100644 --- a/wiringPi/wiringPiSPI.c +++ b/wiringPi/wiringPiSPI.c @@ -23,7 +23,9 @@ */ +#include #include +#include #include #include #include @@ -39,8 +41,8 @@ // The SPI bus parameters // Variables as they need to be passed as pointers later on -static const char *spiDev0 = "/dev/spidev0.0" ; -static const char *spiDev1 = "/dev/spidev0.1" ; +//static const char *spiDev0 = "/dev/spidev0.0" ; +//static const char *spiDev1 = "/dev/spidev0.1" ; static const uint8_t spiBPW = 8 ; static const uint16_t spiDelay = 0 ; @@ -100,11 +102,16 @@ int wiringPiSPIDataRW (int channel, unsigned char *data, int len) int wiringPiSPISetupMode (int channel, int speed, int mode) { int fd ; + char spiDev [32] ; mode &= 3 ; // Mode is 0, 1, 2 or 3 - channel &= 1 ; // Channel is 0 or 1 - if ((fd = open (channel == 0 ? spiDev0 : spiDev1, O_RDWR)) < 0) +// Channel can be anything - lets hope for the best +// channel &= 1 ; // Channel is 0 or 1 + + snprintf (spiDev, 31, "/dev/spidev0.%d", channel) ; + + if ((fd = open (spiDev, O_RDWR)) < 0) return wiringPiFailure (WPI_ALMOST, "Unable to open SPI device: %s\n", strerror (errno)) ; spiSpeeds [channel] = speed ; From aca883a051a32f2513b1db90a74efddd0c714ccf Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Sat, 14 Dec 2019 01:09:13 +0000 Subject: [PATCH 22/29] Add support for Raspberry Pi 4B This change make the following commands correctly detect the 4B however there may be an issue with reading GPIO inputs on the 4B as they are always returning zero. The aim of this change is to be the source-equivalent of the binary package release 2.52[1] which was the last release before upstream development ceased. [1] http://wiringpi.com/wiringpi-updated-to-2-52-for-the-raspberry-pi-4b/ --- gpio/readall.c | 7 +++++-- wiringPi/wiringPi.c | 36 ++++++++++++++++++------------------ wiringPi/wiringPi.h | 5 +++-- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/gpio/readall.c b/gpio/readall.c index 097755a..2d745a4 100644 --- a/gpio/readall.c +++ b/gpio/readall.c @@ -80,7 +80,7 @@ static char *alts [] = "IN", "OUT", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3" } ; -static int physToWpi [64] = +static int physToWpi [64] = { -1, // 0 -1, -1, // 1, 2 @@ -113,7 +113,7 @@ static int physToWpi [64] = -1, -1, -1, -1, -1, -1, -1, -1, -1 } ; -static char *physNames [64] = +static char *physNames [64] = { NULL, @@ -309,6 +309,8 @@ static void plus2header (int model) printf (" +-----+-----+---------+------+---+---Pi 3B+-+---+------+---------+-----+-----+\n") ; else if (model == PI_MODEL_3AP) printf (" +-----+-----+---------+------+---+---Pi 3A+-+---+------+---------+-----+-----+\n") ; + else if (model == PI_MODEL_4B) + printf (" +-----+-----+---------+------+---+---Pi 4B--+---+------+---------+-----+-----+\n") ; else printf (" +-----+-----+---------+------+---+---Pi ?---+---+------+---------+-----+-----+\n") ; } @@ -356,6 +358,7 @@ void doReadall (void) (model == PI_MODEL_2) || (model == PI_MODEL_3AP) || (model == PI_MODEL_3B) || (model == PI_MODEL_3BP) || + (model == PI_MODEL_4B) || (model == PI_MODEL_ZERO) || (model == PI_MODEL_ZERO_W)) piPlusReadall (model) ; else if ((model == PI_MODEL_CM) || (model == PI_MODEL_CM3) || ((model == PI_MODEL_CM3P))) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 3db6866..73ec220 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -237,7 +237,7 @@ const char *piModelNames [20] = "Pi 3A+", // 14 "Unknown15", // 15 "CM3+", // 16 - "Unknown17", // 17 + "Pi 4B", // 17 "Unknown18", // 18 "Unknown19", // 19 } ; @@ -818,7 +818,7 @@ int piGpioLayout (void) for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c) *c = 0 ; - + if (wiringPiDebug) printf ("piGpioLayout: Revision string: %s\n", line) ; @@ -887,7 +887,7 @@ int piBoardRev (void) * So the distinction between boards that I can see is: * * 0000 - Error - * 0001 - Not used + * 0001 - Not used * * Original Pi boards: * 0002 - Model B, Rev 1, 256MB, Egoman @@ -972,7 +972,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c) *c = 0 ; - + if (wiringPiDebug) printf ("piBoardId: Revision string: %s\n", line) ; @@ -1011,7 +1011,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) bMfg = (revision & (0x0F << 16)) >> 16 ; bMem = (revision & (0x07 << 20)) >> 20 ; bWarranty = (revision & (0x03 << 24)) != 0 ; - + *model = bType ; *rev = bRev ; *mem = bMem ; @@ -1038,7 +1038,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) // If longer than 4, we'll assume it's been overvolted *warranty = strlen (c) > 4 ; - + // Extract last 4 characters: c = c + strlen (c) - 4 ; @@ -1078,7 +1078,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) else { *model = 0 ; *rev = 0 ; *mem = 0 ; *maker = 0 ; } } } - + /* @@ -1264,7 +1264,7 @@ void gpioClockSet (int pin, int freq) pin = physToGpio [pin] ; else if (wiringPiMode != WPI_MODE_GPIO) return ; - + divi = 19200000 / freq ; divr = 19200000 % freq ; divf = (int)((double)divr * 4096.0 / 19200000.0) ; @@ -1510,7 +1510,7 @@ void pullUpDnControl (int pin, int pud) *(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) ; } @@ -1684,7 +1684,7 @@ void pwmWrite (int pin, int value) /* * analogRead: - * Read the analog value of a given Pin. + * 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. ********************************************************************************* @@ -1703,7 +1703,7 @@ int analogRead (int pin) /* * analogWrite: - * Write the analog value to the given Pin. + * 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. ********************************************************************************* @@ -1752,7 +1752,7 @@ void pwmToneWrite (int pin, int freq) * 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 + * 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 @@ -1808,7 +1808,7 @@ unsigned int digitalReadByte (void) data = (data << 1) | x ; } } - else + else { raw = *(gpio + gpioToGPLEV [0]) ; // First bank for these pins for (pin = 0 ; pin < 8 ; ++pin) @@ -1865,7 +1865,7 @@ unsigned int digitalReadByte2 (void) data = (data << 1) | x ; } } - else + else data = ((*(gpio + gpioToGPLEV [0])) >> 20) & 0xFF ; // First bank for these pins return data ; @@ -2277,7 +2277,7 @@ int wiringPiSetup (void) // Open the master /dev/ memory control device // Device strategy: December 2016: -// Try /dev/mem. If that fails, then +// 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) @@ -2315,13 +2315,13 @@ int wiringPiSetup (void) 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) ; @@ -2441,7 +2441,7 @@ int wiringPiSetupSys (void) // Open and scan the directory, looking for exported GPIOs, and pre-open // the 'value' interface to speed things up for later - + for (pin = 0 ; pin < 64 ; ++pin) { sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ; diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 0ff0c92..ecce383 100644 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -102,6 +102,7 @@ #define PI_MODEL_3BP 13 #define PI_MODEL_3AP 14 #define PI_MODEL_CM3P 16 +#define PI_MODEL_4B 17 #define PI_VERSION_1 0 #define PI_VERSION_1_1 1 @@ -134,7 +135,7 @@ extern const int piMemorySize [ 8] ; // 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 +// 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.... @@ -211,7 +212,7 @@ extern void pwmWrite (int pin, int value) ; extern int analogRead (int pin) ; extern void analogWrite (int pin, int value) ; -// PiFace specifics +// PiFace specifics // (Deprecated) extern int wiringPiSetupPiFace (void) ; From a49f696232809cede14f8e4de3eb118bd5fbd037 Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Sat, 14 Dec 2019 02:01:23 +0000 Subject: [PATCH 23/29] Use correct peripheral address for Pi4B --- wiringPi/wiringPi.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 73ec220..2d581e9 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -213,8 +213,9 @@ volatile unsigned int *_wiringPiTimerIrqRaw ; // piGpioBase: // The base address of the GPIO memory mapped hardware IO -#define GPIO_PERI_BASE_OLD 0x20000000 -#define GPIO_PERI_BASE_NEW 0x3F000000 +#define GPIO_PERI_BASE_OLD 0x20000000 +#define GPIO_PERI_BASE_2708 0x3F000000 +#define GPIO_PERI_BASE_2711 0xFE000000 static volatile unsigned int piGpioBase = 0 ; @@ -1533,7 +1534,6 @@ int digitalRead (int pin) { char c ; struct wiringPiNodeStruct *node = wiringPiNodes ; - if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin { /**/ if (wiringPiMode == WPI_MODE_GPIO_SYS) // Sys mode @@ -2243,7 +2243,9 @@ int wiringPiSetup (void) piBoardId (&model, &rev, &mem, &maker, &overVolted) ; - if ((model == PI_MODEL_CM) || (model == PI_MODEL_CM3) || (model == PI_MODEL_CM3P)) + if ((model == PI_MODEL_CM) || + (model == PI_MODEL_CM3) || + (model == PI_MODEL_CM3P)) wiringPiMode = WPI_MODE_GPIO ; else wiringPiMode = WPI_MODE_PINS ; @@ -2270,8 +2272,12 @@ int wiringPiSetup (void) piGpioBase = GPIO_PERI_BASE_OLD ; break ; + case PI_MODEL_4B: + piGpioBase = GPIO_PERI_BASE_2711 ; + break ; + default: - piGpioBase = GPIO_PERI_BASE_NEW ; + piGpioBase = GPIO_PERI_BASE_2708 ; break ; } From 41f941a78ee929406bcda6c3f80ea6d554e5a48b Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Sat, 14 Dec 2019 20:42:06 +0000 Subject: [PATCH 24/29] Fix GPIO pull up/down for Pi4B Based on this raspi-gpio commit[1] the 2711 chip uses a different method for pull up/down. This change implements that same method. With this change, wiringPi now works for the Pi4B with the subset of functionality used by zynthian. [1] https://github.com/RPi-Distro/raspi-gpio/commit/80fa7d04eafb3ea34fc6f2d32de5f1873b5fb369?diff=unified --- wiringPi/wiringPi.c | 48 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 2d581e9..76f5684 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -214,7 +214,7 @@ volatile unsigned int *_wiringPiTimerIrqRaw ; // The base address of the GPIO memory mapped hardware IO #define GPIO_PERI_BASE_OLD 0x20000000 -#define GPIO_PERI_BASE_2708 0x3F000000 +#define GPIO_PERI_BASE_2835 0x3F000000 #define GPIO_PERI_BASE_2711 0xFE000000 static volatile unsigned int piGpioBase = 0 ; @@ -543,6 +543,14 @@ static uint8_t gpioToFEN [] = #define GPPUD 37 +/* 2711 has a different mechanism for pin pull-up/down/enable */ +#define GPPUPPDN0 57 /* Pin pull-up/down for pins 15:0 */ +#define GPPUPPDN1 58 /* Pin pull-up/down for pins 31:16 */ +#define GPPUPPDN2 59 /* Pin pull-up/down for pins 47:32 */ +#define GPPUPPDN3 60 /* Pin pull-up/down for pins 57:48 */ + +static volatile unsigned int piGpioPupOffset = 0 ; + // gpioToPUDCLK // (Word) offset to the Pull Up Down Clock regsiter @@ -1509,11 +1517,36 @@ void pullUpDnControl (int pin, int pud) else if (wiringPiMode != WPI_MODE_GPIO) return ; - *(gpio + GPPUD) = pud & 3 ; delayMicroseconds (5) ; - *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ; delayMicroseconds (5) ; + if (piGpioPupOffset == GPPUPPDN0) + { + // Pi 4B pull up/down method + int pullreg = GPPUPPDN0 + (pin>>4); + int pullshift = (pin & 0xf) << 1; + unsigned int pullbits; + unsigned int pull; - *(gpio + GPPUD) = 0 ; delayMicroseconds (5) ; - *(gpio + gpioToPUDCLK [pin]) = 0 ; delayMicroseconds (5) ; + switch (pud) + { + case PUD_OFF: pull = 0; break; + case PUD_UP: pull = 1; break; + case PUD_DOWN: pull = 2; break; + default: return ; /* An illegal value */ + } + + pullbits = *(gpio + pullreg); + pullbits &= ~(3 << pullshift); + pullbits |= (pull << pullshift); + *(gpio + pullreg) = pullbits; + } + else + { + // legacy pull up/down method + *(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 { @@ -2270,14 +2303,17 @@ int wiringPiSetup (void) case PI_ALPHA: case PI_MODEL_CM: case PI_MODEL_ZERO: case PI_MODEL_ZERO_W: piGpioBase = GPIO_PERI_BASE_OLD ; + piGpioPupOffset = GPPUD ; break ; case PI_MODEL_4B: piGpioBase = GPIO_PERI_BASE_2711 ; + piGpioPupOffset = GPPUPPDN0 ; break ; default: - piGpioBase = GPIO_PERI_BASE_2708 ; + piGpioBase = GPIO_PERI_BASE_2835 ; + piGpioPupOffset = GPPUD ; break ; } From 9aed9a44154eb68c2461aa72e1b32d85680fc1ae Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Sat, 14 Dec 2019 20:45:00 +0000 Subject: [PATCH 25/29] Increment version to 2.60 Now that the upstream maintainer has abandoned this project without establishing another maintainer, its difficult to choose an appropriate version number. Going with 2.60 for now, as this only has incremental changes to support 4B. --- VERSION | 2 +- version.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index f02fc20..f6a4163 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.50 +2.60 diff --git a/version.h b/version.h index 07e50ef..812dbdc 100644 --- a/version.h +++ b/version.h @@ -1,3 +1,3 @@ -#define VERSION "2.50" +#define VERSION "2.60" #define VERSION_MAJOR 2 -#define VERSION_MINOR 50 +#define VERSION_MINOR 60 From 03e88aef0426408f86dd8196ec24f1a6ab5df880 Mon Sep 17 00:00:00 2001 From: Mark Liffiton Date: Sun, 29 Dec 2019 20:12:14 -0600 Subject: [PATCH 26/29] One last 2.46->2.50 file update. --- debian-template/wiringPi/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian-template/wiringPi/DEBIAN/control b/debian-template/wiringPi/DEBIAN/control index 72b3bc8..b710eaa 100644 --- a/debian-template/wiringPi/DEBIAN/control +++ b/debian-template/wiringPi/DEBIAN/control @@ -1,5 +1,5 @@ Package: wiringpi -Version: 2.46 +Version: 2.50 Section: libraries Priority: optional Architecture: armhf From 2a8e57a1c7628fe96d33bbc5494b709733ba3ac0 Mon Sep 17 00:00:00 2001 From: Mark Liffiton Date: Sun, 29 Dec 2019 20:39:00 -0600 Subject: [PATCH 27/29] Update README, convert to markdown With Gordon ending development of WiringPi, this repository needs to reflect the situation accurately and differentiate between Gordon's final code release and updates made since then. --- README.TXT | 36 ------------------------------------ README.md | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 36 deletions(-) delete mode 100644 README.TXT create mode 100644 README.md diff --git a/README.TXT b/README.TXT deleted file mode 100644 index 894a31b..0000000 --- a/README.TXT +++ /dev/null @@ -1,36 +0,0 @@ -Note -==== - -This is an unofficial mirror of WiringPi to support ports (Python/Ruby/etc). - -Please do not email Gordon if you have issues, he will not be able to help. - -Pull-requests are not currently accepted, since this is a mirror. - -For support, comments, questions, etc please join the WiringPi Discord channel: https://discord.gg/SM4WUVG - -wiringPi README -=============== - -Please note that the official way to get wiringPi is via git from -git.drogon.net and not GitHub. - -ie. - - git clone git://git.drogon.net/wiringPi - -The version of wiringPi held on GitHub by "Gadgetoid" is used to build the -wiringPython, Ruby, Perl, etc. wrappers for these other languages. This -version may lag the official Drogon release. Pull requests may not be -accepted to Github.... - -Please see - - http://wiringpi.com/ - -for the official documentation, etc. and the best way to submit bug reports, etc. -is by sending an email to projects@drogon.net - -Thanks! - - -Gordon diff --git a/README.md b/README.md new file mode 100644 index 0000000..2ee609d --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +Unofficial WiringPi Mirror +========================== + +This is an unofficial mirror of WiringPi to support ports (Python/Ruby/etc). With the +[end of official development](http://wiringpi.com/wiringpi-deprecated/), this repository +has become a mirror of the last "official" source release as well as a source for small +updates to support newer hardware (primarily for use by the ports). + + * The final "official" source release can be found at the + [`final_source_2.50`](https://github.com/WiringPi/WiringPi/tree/final_official_2.50) tag. + * The default `master` branch contains code that has been written since that final source + release to provide support for newer hardware. + +Please do not email Gordon if you have issues, he will not be able to help. + +Pull-requests may be accepted to add or fix support for newer hardware, but new features or +other changes will not be accepted. + +For support, comments, questions, etc please join the WiringPi Discord channel: https://discord.gg/SM4WUVG From 1f908c5eeda66789ad2096f8370e2a410ca81100 Mon Sep 17 00:00:00 2001 From: Mark Liffiton Date: Sun, 29 Dec 2019 20:40:42 -0600 Subject: [PATCH 28/29] Small change to reflect new version. --- debian-template/wiringPi/DEBIAN/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian-template/wiringPi/DEBIAN/control b/debian-template/wiringPi/DEBIAN/control index b710eaa..41c69a8 100644 --- a/debian-template/wiringPi/DEBIAN/control +++ b/debian-template/wiringPi/DEBIAN/control @@ -1,5 +1,5 @@ Package: wiringpi -Version: 2.50 +Version: 2.60 Section: libraries Priority: optional Architecture: armhf From 651136a110d1a63320193d4f7d39e9399762847e Mon Sep 17 00:00:00 2001 From: neuralassembly Date: Mon, 30 Dec 2019 23:40:30 +0900 Subject: [PATCH 29/29] Keeping compatibility of hardware clock of Pi 4 with earlier versions. --- wiringPi/wiringPi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index 76f5684..46c6826 100644 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -1218,6 +1218,11 @@ void pwmSetRange (unsigned int range) void pwmSetClock (int divisor) { uint32_t pwm_control ; + + if (piGpioBase == GPIO_PERI_BASE_2711) + { + divisor = 540*divisor/192; + } divisor &= 4095 ; if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))