001package com.pi4j.wiringpi;
002
003/*
004 * #%L
005 * **********************************************************************
006 * ORGANIZATION  :  Pi4J
007 * PROJECT       :  Pi4J :: Java Library (Core)
008 * FILENAME      :  Gpio.java  
009 * 
010 * This file is part of the Pi4J project. More information about 
011 * this project can be found here:  http://www.pi4j.com/
012 * **********************************************************************
013 * %%
014 * Copyright (C) 2012 - 2013 Pi4J
015 * %%
016 * Licensed under the Apache License, Version 2.0 (the "License");
017 * you may not use this file except in compliance with the License.
018 * You may obtain a copy of the License at
019 * 
020 *      http://www.apache.org/licenses/LICENSE-2.0
021 * 
022 * Unless required by applicable law or agreed to in writing, software
023 * distributed under the License is distributed on an "AS IS" BASIS,
024 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
025 * See the License for the specific language governing permissions and
026 * limitations under the License.
027 * #L%
028 */
029
030
031import com.pi4j.util.NativeLibraryLoader;
032
033/**
034 * <[>WiringPi GPIO Control</[>
035 * 
036 * <p>
037 * Some of the functions in the WiringPi library are designed to mimic those in the Arduino Wiring
038 * system. There are relatively easy to use and should present no problems for anyone used to the
039 * Arduino system, or C programming in-general.
040 * </p>
041 * 
042 * <p>
043 * The main difference is that unlike the Arduino system, the main loop of the program is not
044 * provided for you and you need to write it yourself. This is often desirable in a Linux system
045 * anyway as it can give you access to command-line arguments and so on. See the examples page for
046 * some simple examples and a Makefile to use.
047 * </p>
048 * 
049 * <p>
050 * Before using the Pi4J library, you need to ensure that the Java VM in configured with access to
051 * the following system libraries:
052 * <ul>
053 * <li>pi4j</li>
054 * <li>wiringPi</li>
055 * </ul>
056 * <blockquote> This library depends on the wiringPi native system library.</br> (developed by
057 * Gordon Henderson @ <a href="https://projects.drogon.net/">https://projects.drogon.net/</a>)
058 * </blockquote>
059 * </p>
060 * 
061 * @see <a href="http://www.pi4j.com/">http://www.pi4j.com/</a>
062 * @see <a
063 *      href="https://projects.drogon.net/raspberry-pi/wiringpi/">https://projects.drogon.net/raspberry-pi/wiringpi/</a>
064 * @author Robert Savage (<a
065 *         href="http://www.savagehomeautomation.com">http://www.savagehomeautomation.com</a>)
066 */
067public class Gpio {
068
069    // private constructor 
070    private Gpio()  {
071        // forbid object construction 
072    }
073    
074    /**
075     * The total number of GPIO pins available in the WiringPi library.
076     * <i>(Note this is not the maximum pin count on the Pi GPIO header.)</i>
077     */
078    public static final int NUM_PINS = 20;
079
080    /**
081     * GPIO pin constant for INPUT direction for reading pin states
082     * 
083     * @see #pinMode(int,int)
084     */
085    public static final int INPUT = 0;
086
087    /**
088     * GPIO pin constant for OUTPUT direction for writing digital pin states (0/1)
089     * 
090     * @see #pinMode(int,int)
091     */
092    public static final int OUTPUT = 1;
093
094    /**
095     * GPIO pin constant for PWM_OUTPUT direction for writing analog pin states
096     * 
097     * @see #pinMode(int,int)
098     */
099    public static final int PWM_OUTPUT = 2;
100
101    /**
102     * GPIO pin state constant for LOW/OFF/0VDC
103     * 
104     * @see #digitalWrite(int,int)
105     */
106    public static final int LOW = 0;
107
108    /**
109     * GPIO pin state constant for HIGH/ON/+3.3VDC
110     * 
111     * @see #digitalWrite(int,int)
112     */
113    public static final int HIGH = 1;
114
115    /**
116     * GPIO constant to disable the pull-up or pull-down resistor mode on a GPIO pin.
117     * 
118     * @see #waitForInterrupt(int,int)
119     */
120    public static final int PUD_OFF = 0;
121
122    /**
123     * GPIO constant to enable the pull-down resistor mode on a GPIO pin.
124     * 
125     * @see #waitForInterrupt(int,int)
126     */
127    public static final int PUD_DOWN = 1;
128
129    /**
130     * GPIO constant to enable the pull-up resistor mode on a GPIO pin.
131     * 
132     * @see #waitForInterrupt(int,int)
133     */
134    public static final int PUD_UP = 2;
135
136    static {
137        // Load the platform library
138        NativeLibraryLoader.load("pi4j", "libpi4j.so");
139    }
140
141    /**
142     * <p>
143     * This initializes the wiringPi system and assumes that the calling program is going to be
144     * using the wiringPi pin numbering scheme. This is a simplified numbering scheme which provides
145     * a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin
146     * numbers. See the pins page for a table which maps the wiringPi pin number to the Broadcom
147     * GPIO pin number to the physical location on the edge connector.
148     * </p>
149     * 
150     * <p><b><i>This function needs to be called with root privileges.</i></b></p>
151     * 
152     * @see <a
153     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
154     * @return If this function returns a value of '-1' then an error has occurred and the
155     *         initialization of the GPIO has failed. A return value of '0' indicates a successful
156     *         GPIO initialization.
157     */
158    public static native int wiringPiSetup();
159
160    /**
161     * <p>
162     * This initializes the wiringPi system but uses the /sys/class/gpio interface rather than
163     * accessing the hardware directly. This can be called as a non-root user provided the GPIO pins
164     * have been exported before-hand using the gpio program. Pin number in this mode is the native
165     * Broadcom GPIO numbers.
166     * </p>
167     * 
168     * <p>
169     * <ul>
170     * Note:
171     * </ul>
172     * In this mode you can only use the pins which have been exported via the /sys/class/gpio
173     * interface. You must export these pins before you call your program. You can do this in a
174     * separate shell-script, or by using the system() function from inside your program.
175     * </p>
176     * 
177     * <p>
178     * <b><i>Also note that some functions (noted below) have no effect when using this mode as
179     * they're not currently possible to action unless called with root privileges.</i></b>
180     * </p>
181     * 
182     * @see <a
183     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
184     * @return If this function returns a value of '-1' then an error has occurred and the
185     *         initialization of the GPIO has failed. A return value of '0' indicates a successful
186     *         GPIO initialization.
187     */
188    public static native int wiringPiSetupSys();
189
190    /**
191     * <p>
192     * This setup function is identical to wiringPiSetup(), however it allows the calling programs
193     * to use the Broadcom GPIO pin numbers directly with no re-mapping.
194     * </p>
195     * 
196     * <p> <b><i>This function needs to be called with root privileges.</i></b></p>
197     * 
198     * @see <a
199     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
200     * @return If this function returns a value of '-1' then an error has occurred and the
201     *         initialization of the GPIO has failed. A return value of '0' indicates a successful
202     *         GPIO initialization.
203     */
204    public static native int wiringPiSetupGpio();
205
206    /**
207     * <p>
208     * This sets the mode of a pin to either INPUT, OUTPUT, or PWM_OUTPUT. Note that only wiringPi
209     * pin 1 (GPIO-18) supports PWM output. The pin number is the number obtained from the pins
210     * table.
211     * </p>
212     * 
213     * <p> <b><i>This function has no effect when in Sys mode.</i></b></p>
214     * 
215     * @see #INPUT
216     * @see #OUTPUT
217     * @see #PWM_OUTPUT
218     * @see <a
219     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
220     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
221     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
222     * @param mode  Pin mode/direction to apply to the selected pin.</br>The following constants are
223     *            provided for use with this parameter:
224     *            <ul>
225     *            <li>INPUT</li>
226     *            <li>OUTPUT</li>
227     *            <li>PWM_OUTPUT</li>
228     *            </ul>
229     */
230    public static native void pinMode(int pin, int mode);
231
232    /**
233     * This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an
234     * input. Unlike the Arduino, the BCM2835 has both pull-up an down internal resistors. The
235     * parameter pud should be; PUD_OFF, (no pull up/down), PUD_DOWN (pull to ground) or PUD_UP
236     * (pull to 3.3v)
237     * 
238     * This function has no effect when in Sys mode (see above) If you need to activate a
239     * pull-up/pull-down, then you can do it with the gpio program in a script before you start your
240     * program.
241     * 
242     * @see #PUD_OFF
243     * @see #PUD_DOWN
244     * @see #PUD_UP
245     * @see <a
246     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
247     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
248     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
249     * @param pud Pull Up/Down internal pin resistance.</br>The following constants are provided for
250     *            use with this parameter:
251     *            <ul>
252     *            <li>PUD_OFF</li>
253     *            <li>PUD_DOWN</li>
254     *            <li>PUD_UP</li>
255     *            </ul>
256     */
257    public static native void pullUpDnControl(int pin, int pud);
258
259    /**
260     * <p>
261     * Writes the value HIGH or LOW (1 or 0) to the given pin which must have been previously set as
262     * an output.
263     * </p>
264     * 
265     * @see #HIGH
266     * @see #LOW
267     * @see <a
268     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
269     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
270     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
271     * @param value The pin state to write to the selected pin.</br>The following constants are
272     *            provided for use with this parameter:
273     *            <ul>
274     *            <li>HIGH</li>
275     *            <li>LOW</li>
276     *            </ul>
277     */
278    public static native void digitalWrite(int pin, int value);
279
280    /**
281     * <p>
282     * Writes the value HIGH or LOW ('true' or 'false') to the given pin which must have been
283     * previously set as an output.
284     * </p>
285     * 
286     * @see <a
287     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
288     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
289     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
290     * @param value The pin boolean state to write to the selected pin.
291     */
292    public static void digitalWrite(int pin, boolean value) {
293        digitalWrite(pin, (value == true) ? 1 : 0);
294    }
295
296    /**
297     * <p>
298     * Writes the value to the PWM register for the given pin. The value must be between 0 and 1024.
299     * (Again, note that only pin 1 supports PWM)
300     * </p>
301     * 
302     * <p><b>This function has no effect when in Sys mode</b></p>
303     * 
304     * @see <a
305     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
306     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
307     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
308     * @param value The analog value to write to the selected pin. </br><i>(The value must be between
309     *            0 and 1024.)</i>
310     */
311    public static native void pwmWrite(int pin, int value);
312
313    /**
314     * <p>
315     * This function returns the value read at the given pin. It will be HIGH or LOW (1 or 0)
316     * depending on the logic level at the pin.
317     * </p>
318     * 
319     * @see <a
320     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
321     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
322     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
323     * @return If the selected GPIO pin is HIGH, then a value of '1' is returned; else of the pin is
324     *         LOW, then a value of '0' is returned.
325     */
326    public static native int digitalRead(int pin);
327
328    /**
329     * <p>
330     * This causes program execution to pause for at least howLong milliseconds. Due to the
331     * multi-tasking nature of Linux it could be longer. Note that the maximum delay is an unsigned
332     * 32-bit integer or approximately 49 days.
333     * </p>
334     * 
335     * @see <a
336     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
337     * @param howLong The number of milliseconds to delay the main program thread.
338     */
339    public static native void delay(long howLong);
340
341    /**
342     * <p>
343     * This returns a number representing the number if milliseconds since your program called one
344     * of the wiringPiSetup functions. It returns an unsigned 32-bit number which wraps after 49
345     * days.
346     * </p>
347     * 
348     * @see <a
349     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
350     * @return The number if milliseconds since the program called one of the wiringPi setup
351     *         functions.
352     */
353    public static native long millis();
354
355    /**
356     * <p>
357     * This causes program execution to pause for at least howLong microseconds. Due to the
358     * multi-tasking nature of Linux it could be longer. Note that the maximum delay is an unsigned
359     * 32-bit integer microseconds or approximately 71 minutes.
360     * </p>
361     * 
362     * @see <a
363     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
364     * @param howLong The number of microseconds to delay the main program thread.
365     */
366    public static native void delayMicroseconds(long howLong);
367
368    /**
369     * <p>
370     * This attempts to shift your program (or thread in a multi-threaded program) to a higher
371     * priority and enables a real-time scheduling. The priority parameter should be from 0 (the
372     * Default) to 99 (the maximum). This won't make your program go any faster, but it will give it
373     * a bigger slice of time when other programs are running. The priority parameter works relative
374     * to others and so you can make one program priority 1 and another priority 2 and it will have
375     * the same effect as setting one to 10 and the other to 90 (as long as no other programs are
376     * running with elevated priorities)
377     * </p>
378     * 
379     * <p>
380     * The return value is 0 for success and -1 for error. If an error is returned, the program
381     * should then consult the errno global variable, as per the usual conventions.
382     * </p>
383     * 
384     * <p>
385     * Note: Only programs running as root can change their priority. If called from a non-root
386     * program then nothing happens.
387     * </p>
388     * 
389     * @see <a
390     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
391     * @param priority  The priority parameter should be from 0 (the Default) to 99 (the maximum)
392     * @return The return value is 0 for success and -1 for error. If an error is returned, the
393     *         program should then consult the errno global variable, as per the usual conventions.
394     */
395    public static native int piHiPri(int priority);
396
397    /**
398     * <p>[Interrupts]</p>
399     * 
400     * <p>
401     * With a newer kernel patched with the GPIO interrupt handling code, you can now wait for an
402     * interrupt in your program. This frees up the processor to do other tasks while you're waiting
403     * for that interrupt. The GPIO can be set to interrupt on a rising, falling or both edges of
404     * the incoming signal.
405     * </p>
406     * <p> <b> int waitForInterrupt (int pin, int timeOut) </b> </p>
407     * 
408     * <p>
409     * When called, it will wait for an interrupt event to happen on that pin and your program will
410     * be stalled. The timeOut parameter is given in milliseconds, or can be -1 which means to wait
411     * forever.
412     * </p>
413     * 
414     * <p>
415     * Before you call waitForInterrupt, you must first initialize the GPIO pin and at present the
416     * only way to do this is to use the gpio program, either in a script, or using the system()
417     * call from inside your program.
418     * </p>
419     * 
420     * <p>
421     * e.g. We want to wait for a falling-edge interrupt on GPIO pin 0, so to setup the hardware, we
422     * need to run:
423     * 
424     * <pre>
425     * gpio edge 0 falling
426     * </pre>
427     * 
428     * </p>
429     * 
430     * @see <a
431     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
432     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
433     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
434     * @param timeout The number of milliseconds to wait before timing out. </br>A value of '-1' will
435     *            disable the timeout.
436     * @return The return value is -1 if an error occurred (and errno will be set appropriately), 0
437     *         if it timed out, or 1 on a successful interrupt event.
438     */
439    public static native int waitForInterrupt(int pin, int timeout);
440
441    /**
442     * <p>[Hardware]</p>
443     * 
444     * <p> This method provides the board revision as determined by the wiringPi library.  </p>
445     * 
446     * @see <a
447     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
448     * @return The return value represents the major board revision version. 
449     *         A -1 will be returned if the board revision cannot be determined.
450     */
451    public static native int piBoardRev();
452
453    
454    /**
455     * <p>[Hardware]</p>
456     * 
457     * <p> This method provides the edge GPIO pin number for the requested wiringPi pin number.  </p>
458     * 
459     * @see <a
460     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
461     * @return The return value represents the RaspberryPi GPIO (edge) pin number. 
462     *         A -1 will be returned for an invalid pin number.
463     */
464    public static native int wpiPinToGpio(int wpiPin);
465                                                     
466    
467    //    /**
468    //     * --------------------------------------------------------------------------------------------
469    //     * lets not use native code for threading in Java; that could get you into some trouble.
470    //     * --------------------------------------------------------------------------------------------
471    //     * <h1>Concurrent Processing (multi-threading)</h1>
472    //     * 
473    //     * wiringPi has a simplified interface to the Linux implementation of Posix threads, as well as
474    //     * a (simplified) mechanisms to access mutexs (Mutual exclusions)
475    //     * 
476    //     * Using these functions you can create a new process (a function inside your main program)
477    //     * which runs concurrently with your main program and using the mutex mechanisms, safely pass
478    //     * variables between them.
479    //     * 
480    //     * @see <a
481    //     *      href="https://projects.drogon.net/raspberry-pi/wiringpi/functions/">https://projects.drogon.net/raspberry-pi/wiringpi/functions/</a>
482    //     */
483    // public static native int piThreadCreate(void fn, int timeout);
484    // public static native void piLock(int key);
485    // public static native void piUnlock(int key);
486
487    // private static class Hook extends Thread
488    // {
489    // File libfile;
490    //
491    // public Hook(File libfile)
492    // {
493    // this.libfile = libfile;
494    // }
495    // public void run()
496    // {
497    // if(libfile.exists())
498    // libfile.deleteOnExit()
499    // System.out.println( "Running Clean Up..." );
500    // }
501    // }
502}