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:  https://www.pi4j.com/
012 * **********************************************************************
013 * %%
014 * Copyright (C) 2012 - 2021 Pi4J
015 * %%
016 * This program is free software: you can redistribute it and/or modify
017 * it under the terms of the GNU Lesser General Public License as
018 * published by the Free Software Foundation, either version 3 of the
019 * License, or (at your option) any later version.
020 *
021 * This program is distributed in the hope that it will be useful,
022 * but WITHOUT ANY WARRANTY; without even the implied warranty of
023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
024 * GNU General Lesser Public License for more details.
025 *
026 * You should have received a copy of the GNU General Lesser Public
027 * License along with this program.  If not, see
028 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
029 * #L%
030 */
031
032
033import com.pi4j.util.NativeLibraryLoader;
034
035import java.util.ArrayList;
036import java.util.List;
037
038/**
039 * <[>WiringPi GPIO Control</[>
040 *
041 * <p>
042 * Some of the functions in the WiringPi library are designed to mimic those in the Arduino Wiring
043 * system. There are relatively easy to use and should present no problems for anyone used to the
044 * Arduino system, or C programming in-general.
045 * </p>
046 *
047 * <p>
048 * The main difference is that unlike the Arduino system, the main loop of the program is not
049 * provided for you and you need to write it yourself. This is often desirable in a Linux system
050 * anyway as it can give you access to command-line arguments and so on. See the examples page for
051 * some simple examples and a Makefile to use.
052 * </p>
053 *
054 * <p>
055 * Before using the Pi4J library, you need to ensure that the Java VM in configured with access to
056 * the following system libraries:
057 * <ul>
058 * <li>pi4j</li>
059 * <li>wiringPi</li>
060 * </ul>
061 * <blockquote> This library depends on the wiringPi native system library.</br> (developed by
062 * Gordon Henderson @ <a href="http://wiringpi.com/">http://wiringpi.com/</a>)
063 * </blockquote>
064 * </p>
065 *
066 * @see <a href="https://www.pi4j.com/">https://www.pi4j.com/</a>
067 * @see <a
068 *      href="http://wiringpi.com/reference/">http://wiringpi.com/reference/</a>
069 * @author Robert Savage (<a
070 *         href="http://www.savagehomeautomation.com">http://www.savagehomeautomation.com</a>)
071 */
072public class Gpio {
073
074    // private constructor
075    private Gpio()  {
076        // forbid object construction
077    }
078
079    /**
080     * The total number of GPIO pins available in the WiringPi library.
081     * <i>(Note this is not the maximum pin count on the Pi GPIO header.)</i>
082     */
083    public static final int NUM_PINS = 46;
084
085    /**
086     * GPIO pin constant for INPUT direction for reading pin states
087     *
088     * @see #pinMode(int,int)
089     */
090    public static final int INPUT = 0;
091
092    /**
093     * GPIO pin constant for OUTPUT direction for writing digital pin states (0/1)
094     *
095     * @see #pinMode(int,int)
096     */
097    public static final int OUTPUT = 1;
098
099    /**
100     * GPIO pin constant for PWM_OUTPUT direction for writing analog pin states
101     *
102     * @see #pinMode(int,int)
103     */
104    public static final int PWM_OUTPUT = 2;
105
106    /**
107     * GPIO pin constant for GPIO_CLOCK pin mode
108     *
109     * @see #pinMode(int,int)
110     */
111    public static final int GPIO_CLOCK = 3;
112
113    /**
114     * GPIO pin state constant for LOW/OFF/0VDC
115     *
116     * @see #digitalWrite(int,int)
117     */
118    public static final int LOW = 0;
119
120    /**
121     * GPIO pin state constant for HIGH/ON/+3.3VDC
122     *
123     * @see #digitalWrite(int,int)
124     */
125    public static final int HIGH = 1;
126
127    /**
128     * GPIO constant to disable the pull-up or pull-down resistor mode on a GPIO pin.
129     *
130     * @see #waitForInterrupt(int,int)
131     */
132    public static final int PUD_OFF = 0;
133
134    /**
135     * GPIO constant to enable the pull-down resistor mode on a GPIO pin.
136     *
137     * @see #waitForInterrupt(int,int)
138     */
139    public static final int PUD_DOWN = 1;
140
141    /**
142     * GPIO constant to enable the pull-up resistor mode on a GPIO pin.
143     *
144     * @see #waitForInterrupt(int,int)
145     */
146    public static final int PUD_UP = 2;
147
148
149    /**
150     * GPIO constant to define PWM balanced mode.
151     *
152     * @see #pwmSetMode(int)
153     */
154    public static final int PWM_MODE_BAL = 1;
155
156
157    /**
158     * GPIO constant to define PWM mark:space mode.
159     *
160     * @see #pwmSetMode(int)
161     */
162    public static final int PWM_MODE_MS = 0;
163
164
165    /**
166     * GPIO constant to define pin ALT modes
167     *
168     * @see #pinModeAlt(int,int)
169     */
170    public static final int ALT0 = 4;
171    public static final int ALT1 = 5;
172    public static final int ALT2 = 6;
173    public static final int ALT3 = 7;
174    public static final int ALT4 = 3;
175    public static final int ALT5 = 2;
176
177    /**
178     * GPIO constants to define interrupt levels
179     *
180     * @see #wiringPiISR(int,int,com.pi4j.wiringpi.GpioInterruptCallback)
181     */
182    public static final int INT_EDGE_SETUP = 0;
183    public static final int INT_EDGE_FALLING = 1;
184    public static final int INT_EDGE_RISING = 2;
185    public static final int INT_EDGE_BOTH = 3;
186
187    static {
188        // Load the platform library
189        NativeLibraryLoader.load("libpi4j.so", "pi4j");
190    }
191
192    /**
193     * <p>Setup Functions</p>
194     *
195     * <p>
196     * This initializes the wiringPi system and assumes that the calling program is going to be
197     * using the wiringPi pin numbering scheme. This is a simplified numbering scheme which provides
198     * a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin
199     * numbers. See the pins page for a table which maps the wiringPi pin number to the Broadcom
200     * GPIO pin number to the physical location on the edge connector.
201     * </p>
202     *
203     * <p><b><i>This function needs to be called with root privileges.</i></b></p>
204     *
205     * @see <a
206     *      href="http://wiringpi.com/reference/setup/">http://wiringpi.com/reference/setup/</a>
207     * @return If this function returns a value of '-1' then an error has occurred and the
208     *         initialization of the GPIO has failed. A return value of '0' indicates a successful
209     *         GPIO initialization.
210     */
211    public static native int wiringPiSetup();
212
213    /**
214     * <p>Setup Functions</p>
215     *
216     * <p>
217     * This initializes the wiringPi system but uses the /sys/class/gpio interface rather than
218     * accessing the hardware directly. This can be called as a non-root user provided the GPIO pins
219     * have been exported before-hand using the gpio program. Pin number in this mode is the native
220     * Broadcom GPIO numbers.
221     * </p>
222     *
223     * <p>
224     * <ul>
225     * Note:
226     * </ul>
227     * In this mode you can only use the pins which have been exported via the /sys/class/gpio
228     * interface. You must export these pins before you call your program. You can do this in a
229     * separate shell-script, or by using the system() function from inside your program.
230     * </p>
231     *
232     * <p>
233     * <b><i>Also note that some functions (noted below) have no effect when using this mode as
234     * they're not currently possible to action unless called with root privileges.</i></b>
235     * </p>
236     *
237     * @see <a
238     *      href="http://wiringpi.com/reference/setup/">http://wiringpi.com/reference/setup/</a>
239     * @return If this function returns a value of '-1' then an error has occurred and the
240     *         initialization of the GPIO has failed. A return value of '0' indicates a successful
241     *         GPIO initialization.
242     */
243    public static native int wiringPiSetupSys();
244
245    /**
246     * <p>Setup Functions</p>
247     *
248     * <p>
249     * This setup function is identical to wiringPiSetup(), however it allows the calling programs
250     * to use the Broadcom GPIO pin numbers directly with no re-mapping.
251     * </p>
252     *
253     * <p> <b><i>This function needs to be called with root privileges.</i></b></p>
254     *
255     * @see <a
256     *      href="http://wiringpi.com/reference/setup/">http://wiringpi.com/reference/setup/</a>
257     * @return If this function returns a value of '-1' then an error has occurred and the
258     *         initialization of the GPIO has failed. A return value of '0' indicates a successful
259     *         GPIO initialization.
260     */
261    public static native int wiringPiSetupGpio();
262
263
264    /**
265     * <p>Setup Functions</p>
266     *
267     * <p>
268     * This setup function is identical to wiringPiSetup(), however it allows the calling programs
269     * to use the physical header pin numbers on the board GPIO header.
270     * </p>
271     *
272     * <p> <b><i>This function needs to be called with root privileges.</i></b></p>
273     *
274     * @see <a
275     *      href="http://wiringpi.com/reference/setup/">http://wiringpi.com/reference/setup/</a>
276     * @return If this function returns a value of '-1' then an error has occurred and the
277     *         initialization of the GPIO has failed. A return value of '0' indicates a successful
278     *         GPIO initialization.
279     */
280    public static native int wiringPiSetupPhys();
281
282
283    /**
284     * <p>Core Functions</p>
285     *
286     * <p>
287     * This sets the mode of a pin to either INPUT, OUTPUT, PWM_OUTPUT or GPIO_CLOCK. Note that only wiringPi pin 1
288     * (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes.
289     * </p>
290     *
291     * <p> <b><i>This function has no effect when in Sys mode.</i></b></p>
292     *
293     * @see #INPUT
294     * @see #OUTPUT
295     * @see #PWM_OUTPUT
296     * @see <a
297     *      href="http://wiringpi.com/reference/core-functions/">http://wiringpi.com/reference/core-functions/</a>
298     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
299     *            be the wiringPi pin number, the Broadcom GPIO pin number, or the board header pin number.)</i>
300     * @param mode  Pin mode/direction to apply to the selected pin.</br>The following constants are
301     *            provided for use with this parameter:
302     *            <ul>
303     *            <li>INPUT</li>
304     *            <li>OUTPUT</li>
305     *            <li>PWM_OUTPUT</li>
306     *            <li>GPIO_CLOCK</li>
307     *            </ul>
308     */
309    public static native void pinMode(int pin, int mode);
310
311
312    /**
313     * <p>Core Functions</p>
314     *
315     * <p>
316     * This method is an undocumented method in the WiringPi library that allows
317     * you to configure any PIN to any MODE.
318     * </p>
319     *
320     * @param pin pin number
321     * @param mode  Pin mode/direction to apply to the selected pin.</br>The following constants are
322     *            provided for use with this parameter:
323     *            <ul>
324     *            <li>INPUT</li>
325     *            <li>OUTPUT</li>
326     *            <li>ALT0</li>
327     *            <li>ALT1</li>
328     *            <li>ALT2</li>
329     *            <li>ALT3</li>
330     *            <li>ALT4</li>
331     *            <li>ALT5</li>
332     *            </ul>
333     */
334    public static native void pinModeAlt(int pin, int mode);
335
336
337
338    /**
339     * <p>Core Functions</p>
340     *
341     * This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an
342     * input. Unlike the Arduino, the BCM2835 has both pull-up an down internal resistors. The
343     * parameter pud should be; PUD_OFF, (no pull up/down), PUD_DOWN (pull to ground) or PUD_UP
344     * (pull to 3.3v)
345     *
346     * This function has no effect when in Sys mode (see above) If you need to activate a
347     * pull-up/pull-down, then you can do it with the gpio program in a script before you start your
348     * program.
349     *
350     * @see #PUD_OFF
351     * @see #PUD_DOWN
352     * @see #PUD_UP
353     * @see <a
354     *      href="http://wiringpi.com/reference/core-functions/">http://wiringpi.com/reference/core-functions/</a>
355     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
356     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
357     * @param pud Pull Up/Down internal pin resistance.</br>The following constants are provided for
358     *            use with this parameter:
359     *            <ul>
360     *            <li>PUD_OFF</li>
361     *            <li>PUD_DOWN</li>
362     *            <li>PUD_UP</li>
363     *            </ul>
364     */
365    public static native void pullUpDnControl(int pin, int pud);
366
367
368    /**
369     * <p>Core Functions</p>
370     *
371     * <p>
372     * Writes the value HIGH or LOW (1 or 0) to the given pin which must have been previously set as
373     * an output.  WiringPi treats any non-zero number as HIGH, however 0 is the only representation of LOW.
374     * </p>
375     *
376     * @see #HIGH
377     * @see #LOW
378     * @see <a
379     *      href="http://wiringpi.com/reference/core-functions/">http://wiringpi.com/reference/core-functions/</a>
380     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
381     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
382     * @param value The pin state to write to the selected pin.</br>The following constants are
383     *            provided for use with this parameter:
384     *            <ul>
385     *            <li>HIGH</li>
386     *            <li>LOW</li>
387     *            </ul>
388     */
389    public static native void digitalWrite(int pin, int value);
390
391
392    /**
393     * <p>Core Functions</p>
394     *
395     * <p>
396     * Writes the value HIGH or LOW ('true' or 'false') to the given pin which must have been
397     * previously set as an output.
398     * </p>
399     *
400     * @see <a
401     *      href="http://wiringpi.com/reference/core-functions/">http://wiringpi.com/reference/core-functions/</a>
402     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
403     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
404     * @param value The pin boolean state to write to the selected pin.
405     */
406    public static void digitalWrite(int pin, boolean value) {
407        digitalWrite(pin, (value) ? 1 : 0);
408    }
409
410
411    /**
412     * <p>Core Functions</p>
413     *
414     * <p>
415     * Writes the value to the PWM register for the given pin. The value must be between 0 and 1024.
416     * (Again, note that only pin 1 supports PWM: )
417     * </p>
418     *
419     * <p><b>This function has no effect when in Sys mode</b></p>
420     *
421     * @see <a
422     *      href="http://wiringpi.com/reference/core-functions/">http://wiringpi.com/reference/core-functions/</a>
423     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
424     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
425     * @param value The analog value to write to the selected pin. </br><i>(The value must be between
426     *            0 and 1024.)</i>
427     */
428    public static native void pwmWrite(int pin, int value);
429
430
431    /**
432     * <p>Core Functions</p>
433     *
434     * <p>
435     * This function returns the value read at the given pin. It will be HIGH or LOW (1 or 0)
436     * depending on the logic level at the pin.
437     * </p>
438     *
439     * @see <a
440     *      href="http://wiringpi.com/reference/core-functions/">http://wiringpi.com/reference/core-functions/</a>
441     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
442     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
443     * @return If the selected GPIO pin is HIGH, then a value of '1' is returned; else of the pin is
444     *         LOW, then a value of '0' is returned.
445     */
446    public static native int digitalRead(int pin);
447
448
449    /**
450     * <p>Core Functions</p>
451     *
452     * <p>
453     * This returns the value read on the supplied analog input pin. You will need to register additional analog
454     * modules to enable this function for devices such as the Gertboard, quick2Wire analog board, etc.
455     * </p>
456     *
457     * @see <a
458     *      href="http://wiringpi.com/reference/core-functions/">http://wiringpi.com/reference/core-functions/</a>
459     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
460     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
461     * @return Analog value of selected pin.
462     */
463    public static native int analogRead(int pin);
464
465
466    /**
467     * <p>Core Functions</p>
468     *
469     * <p>
470     * This writes the given value to the supplied analog pin. You will need to register additional analog modules to
471     * enable this function for devices such as the Gertboard.
472     * </p>
473     *
474     * @see <a
475     *      href="http://wiringpi.com/reference/core-functions/">http://wiringpi.com/reference/core-functions/</a>
476     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
477     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
478     * @param value The analog value to assign to the selected pin number.
479     */
480    public static native void analogWrite(int pin, int value);
481
482
483    /**
484     * <p>Timing Functions</p>
485     *
486     * <p>
487     * This causes program execution to pause for at least howLong milliseconds. Due to the
488     * multi-tasking nature of Linux it could be longer. Note that the maximum delay is an unsigned
489     * 32-bit integer or approximately 49 days.
490     * </p>
491     *
492     * @see <a
493     *      href="http://wiringpi.com/reference/timing/">http://wiringpi.com/reference/timing/</a>
494     * @param howLong The number of milliseconds to delay the main program thread.
495     */
496    public static native void delay(long howLong);
497
498
499    /**
500     * <p>Timing Functions</p>
501     *
502     * <p>
503     * This returns a number representing the number if milliseconds since your program called one
504     * of the wiringPiSetup functions. It returns an unsigned 32-bit number which wraps after 49
505     * days.
506     * </p>
507     *
508     * @see <a
509     *      href="http://wiringpi.com/reference/timing/">http://wiringpi.com/reference/timing/</a>
510     * @return The number if milliseconds since the program called one of the wiringPi setup
511     *         functions.
512     */
513    public static native long millis();
514
515
516    /**
517     * <p>Timing Functions</p>
518     *
519     * <p>
520     * This returns a number representing the number of microseconds since your program called one of the
521     * wiringPiSetup functions. It returns an unsigned 32-bit number which wraps after approximately 71 minutes.
522     * </p>
523     *
524     * @see <a
525     *      href="http://wiringpi.com/reference/timing/">http://wiringpi.com/reference/timing/</a>
526     * @return The number if microseconds since the program called one of the wiringPi setup
527     *         functions.
528     */
529    public static native long micros();
530
531
532    /**
533     * <p>Timing Functions</p>
534     *
535     * <p>
536     * This causes program execution to pause for at least howLong microseconds. Due to the
537     * multi-tasking nature of Linux it could be longer. Note that the maximum delay is an unsigned
538     * 32-bit integer microseconds or approximately 71 minutes.
539     *
540     * Delays under 100 microseconds are timed using a hard-coded loop continually polling the system time,
541     * Delays over 100 microseconds are done using the system nanosleep() function – You may need to consider
542     * the implications of very short delays on the overall performance of the system, especially if using
543     * threads.
544     * </p>
545     *
546     * @see <a
547     *      href="http://wiringpi.com/reference/timing/">http://wiringpi.com/reference/timing/</a>
548     * @param howLong The number of microseconds to delay the main program thread.
549     */
550    public static native void delayMicroseconds(long howLong);
551
552
553    /**
554     * <p>Priority, Interrupt and Thread Functions</p>
555     *
556     * <p>
557     * This attempts to shift your program (or thread in a multi-threaded program) to a higher
558     * priority and enables a real-time scheduling. The priority parameter should be from 0 (the
559     * Default) to 99 (the maximum). This won't make your program go any faster, but it will give it
560     * a bigger slice of time when other programs are running. The priority parameter works relative
561     * to others and so you can make one program priority 1 and another priority 2 and it will have
562     * the same effect as setting one to 10 and the other to 90 (as long as no other programs are
563     * running with elevated priorities)
564     * </p>
565     *
566     * <p>
567     * The return value is 0 for success and -1 for error. If an error is returned, the program
568     * should then consult the errno global variable, as per the usual conventions.
569     * </p>
570     *
571     * <p>
572     * Note: Only programs running as root can change their priority. If called from a non-root
573     * program then nothing happens.
574     * </p>
575     *
576     * @see <a
577     *      href="http://wiringpi.com/reference/priority-interrupts-and-threads/">http://wiringpi.com/reference/priority-interrupts-and-threads/</a>
578     * @param priority  The priority parameter should be from 0 (the Default) to 99 (the maximum)
579     * @return The return value is 0 for success and -1 for error. If an error is returned, the
580     *         program should then consult the errno global variable, as per the usual conventions.
581     */
582    public static native int piHiPri(int priority);
583
584
585    /**
586     * <p>Priority, Interrupt and Thread Functions</p>
587     *
588     * <p>
589     * With a newer kernel patched with the GPIO interrupt handling code, you can now wait for an
590     * interrupt in your program. This frees up the processor to do other tasks while you're waiting
591     * for that interrupt. The GPIO can be set to interrupt on a rising, falling or both edges of
592     * the incoming signal.
593     * </p>
594     * <p> <b> int waitForInterrupt (int pin, int timeOut) </b> </p>
595     *
596     * <p>
597     * When called, it will wait for an interrupt event to happen on that pin and your program will
598     * be stalled. The timeOut parameter is given in milliseconds, or can be -1 which means to wait
599     * forever.
600     * </p>
601     *
602     * <p>
603     * Before you call waitForInterrupt, you must first initialize the GPIO pin and at present the
604     * only way to do this is to use the gpio program, either in a script, or using the system()
605     * call from inside your program.
606     * </p>
607     *
608     * <p>
609     * e.g. We want to wait for a falling-edge interrupt on GPIO pin 0, so to setup the hardware, we
610     * need to run:
611     *
612     * <pre>
613     * gpio edge 0 falling
614     * </pre>
615     *
616     * </p>
617     *
618     * @deprecated Note: Jan 2013: The waitForInterrupt() function is deprecated – you should use the newer
619     *             and easier to use wiringPiISR() function.
620     *
621     * @see <a
622     *      href="http://wiringpi.com/reference/priority-interrupts-and-threads/">http://wiringpi.com/reference/priority-interrupts-and-threads/</a>
623     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
624     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
625     * @param timeout The number of milliseconds to wait before timing out. </br>A value of '-1' will
626     *            disable the timeout.
627     * @return The return value is -1 if an error occurred (and errno will be set appropriately), 0
628     *         if it timed out, or 1 on a successful interrupt event.
629     */
630    public static native int waitForInterrupt(int pin, int timeout);
631
632
633    /**
634     * <p>Priority, Interrupt and Thread Functions</p>
635     *
636     * <p>
637     * This function registers a function to received interrupts on the specified pin. The edgeType parameter is either
638     * INT_EDGE_FALLING, INT_EDGE_RISING, INT_EDGE_BOTH or INT_EDGE_SETUP. If it is INT_EDGE_SETUP then no
639     * initialisation of the pin will happen – it’s assumed that you have already setup the pin elsewhere
640     * (e.g. with the gpio program), but if you specify one of the other types, then the pin will be exported and
641     * initialised as specified. This is accomplished via a suitable call to the gpio utility program, so it need to
642     * be available
643     * </p>
644     *
645     * <p>
646     * The pin number is supplied in the current mode – native wiringPi, BCM_GPIO, physical or Sys modes.
647     * </p>
648     *
649     * <p>
650     * This function will work in any mode, and does not need root privileges to work.
651     * </p>
652     *
653     * <p>
654     * The function will be called when the interrupt triggers. When it is triggered, it’s cleared in the dispatcher
655     * before calling your function, so if a subsequent interrupt fires before you finish your handler, then it won’t
656     * be missed. (However it can only track one more interrupt, if more than one interrupt fires while one is being
657     * handled then they will be ignored)
658     * </p>
659     *
660     * <p>
661     * This function is run at a high priority (if the program is run using sudo, or as root) and executes
662     * concurrently with the main program. It has full access to all the global variables, open file handles
663     * and so on.
664     * </p>
665     *
666     * @see <a
667     *      href="http://wiringpi.com/reference/priority-interrupts-and-threads/">http://wiringpi.com/reference/priority-interrupts-and-threads/</a>
668     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
669     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
670     * @param edgeType The type of pin edge event to watch for: INT_EDGE_FALLING, INT_EDGE_RISING, INT_EDGE_BOTH or INT_EDGE_SETUP.
671     * @param callback The callback interface implemented by the consumer.  The 'callback' method of this interface
672     *                 will be invoked when the wiringPiISR issues a callback signal.
673     * @return The return value is -1 if an error occurred (and errno will be set appropriately), 0
674     *         if it timed out, or 1 on a successful interrupt event.
675     */
676    public static int wiringPiISR(int pin, int edgeType, GpioInterruptCallback callback){
677        // if there is not collection in the array at this pin location, then initialize an array list
678        if(isrCallbacks[pin] == null){
679            isrCallbacks[pin] = new ArrayList<>();
680        }
681
682        // add provided callback interface to ISR callbacks collection
683        isrCallbacks[pin].add(callback);
684        return _wiringPiISR(pin, edgeType);
685    }
686
687    // internal collection for use subscribed IRS callbacks
688    private static List<GpioInterruptCallback> isrCallbacks[] = new List[NUM_PINS];
689
690    // delegated native method for 'wiringPiISR'
691    private static native int _wiringPiISR(int pin, int edgeType);
692
693    /**
694     * Clear all WiringPiISR callbacks for this GPIO pin.
695     *
696     * @param pin The GPIO pin number. </br><i>(Depending on how wiringPi was initialized, this may
697     *            be the wiringPi pin number or the Broadcom GPIO pin number.)</i>
698     */
699    public static void wiringPiClearISR(int pin){
700        // ensure there is a callbacks at this pin location
701        if(isrCallbacks[pin] != null){
702            // remove all ISR callbacks
703            isrCallbacks[pin].clear();
704        }
705    }
706
707    /**
708     * <p>
709     * This method is provided as the callback handler for the Pi4J native library to invoke when a
710     * GPIO ISR is detected. This method should not be called from any Java consumers. (Thus
711     * is is marked as a private method.)
712     * </p>
713     *
714     * @param pin GPIO pin number
715     */
716    private static void isrCallback(int pin) {
717        // dispatch callback to the subscribers for this pin
718        List<GpioInterruptCallback> callbacks = isrCallbacks[pin];
719
720        // ensure callbacks collection exists for this pins number
721        if(callbacks != null && !callbacks.isEmpty()){
722            // iterate over each callback delegate and invoke the callback if the pin and edge type match
723            for(GpioInterruptCallback callback : callbacks){
724                callback.callback(pin);
725            }
726        }
727    }
728
729    //    /**
730    //     * --------------------------------------------------------------------------------------------
731    //     * lets not use native code for threading in Java; that could get you into some trouble.
732    //     * --------------------------------------------------------------------------------------------
733    //     * <h1>Concurrent Processing (multi-threading)</h1>
734    //     *
735    //     * wiringPi has a simplified interface to the Linux implementation of Posix threads, as well as
736    //     * a (simplified) mechanisms to access mutexs (Mutual exclusions)
737    //     *
738    //     * Using these functions you can create a new process (a function inside your main program)
739    //     * which runs concurrently with your main program and using the mutex mechanisms, safely pass
740    //     * variables between them.
741    //     *
742    //     * @see <a
743    //     *      href="http://wiringpi.com/reference/priority-interrupts-and-threads/">http://wiringpi.com/reference/priority-interrupts-and-threads/</a>
744    //     */
745    // public static native int piThreadCreate(void fn, int timeout);
746    // public static native void piLock(int key);
747    // public static native void piUnlock(int key);
748
749
750    /**
751     * <p>[Hardware]</p>
752     *
753     * <p> This method provides the board revision as determined by the wiringPi library.  </p>
754     *
755     * @see <a
756     *      href="http://wiringpi.com/reference/raspberry-pi-specifics/">http://wiringpi.com/reference/raspberry-pi-specifics/</a>
757     * @return The return value represents the major board revision version.
758     *         A -1 will be returned if the board revision cannot be determined.
759     */
760    public static native int piBoardRev();
761
762
763    /**
764     * <p>[Hardware]</p>
765     *
766     * <p> This method provides the edge GPIO pin number for the requested wiringPi pin number.  </p>
767     *
768     * @see <a
769     *      href="http://wiringpi.com/reference/raspberry-pi-specifics/">http://wiringpi.com/reference/raspberry-pi-specifics/</a>
770     * @return The return value represents the RaspberryPi GPIO (edge) pin number.
771     *         A -1 will be returned for an invalid pin number.
772     */
773    public static native int wpiPinToGpio(int wpiPin);
774
775
776    /**
777     * <p>[Hardware]</p>
778     *
779     * <p> This returns the BCM_GPIO pin number of the supplied physical pin on the board header connector. </p>
780     *
781     * @see <a
782     *      href="http://wiringpi.com/reference/raspberry-pi-specifics/">http://wiringpi.com/reference/raspberry-pi-specifics/</a>
783     * @return The return value represents the RaspberryPi GPIO (edge) pin number.
784     *         A -1 will be returned for an invalid pin number.
785     */
786    public static native int physPinToGpio(int physPin);
787
788
789    /**
790     * <p> This writes the 8-bit byte supplied to the first 8 GPIO pins. It’s the fastest way to set all 8 bits at once to a particular value,
791     *     although it still takes two write operations to the Pi’s GPIO hardware.  </p>
792     *
793     * @see <a
794     *      href="http://wiringpi.com/reference/raspberry-pi-specifics/">http://wiringpi.com/reference/raspberry-pi-specifics/</a>
795     */
796    public static native void digitalWriteByte(int value);
797
798
799    /**
800     * <p>[PWM]</p>
801     *
802     * <p> The PWM generator can run in 2 modes – balanced and mark:space. The mark:space mode is traditional, however
803     *     the default mode in the Pi is balanced. You can switch modes by supplying the parameter: PWM_MODE_BAL or PWM_MODE_MS.</p>
804     *
805     * @see <a
806     *      href="http://wiringpi.com/reference/raspberry-pi-specifics/">http://wiringpi.com/reference/raspberry-pi-specifics/</a>
807     */
808    public static native void pwmSetMode(int mode);
809
810
811    /**
812     * <p>[PWM]</p>
813     *
814     * <p> This sets the range register in the PWM generator. The default is 1024.</p>
815     *
816     * @see <a
817     *      href="http://wiringpi.com/reference/raspberry-pi-specifics/">http://wiringpi.com/reference/raspberry-pi-specifics/</a>
818     */
819    public static native void pwmSetRange(int range);
820
821
822    /**
823     * <p>[PWM]</p>
824     *
825     * <p> This sets the divisor for the PWM clock.</p>
826     *
827     * @see <a
828     *      href="http://wiringpi.com/reference/raspberry-pi-specifics/">http://wiringpi.com/reference/raspberry-pi-specifics/</a>
829     */
830    public static native void pwmSetClock(int divisor);
831
832
833    /**
834     * <p>[Hardware]</p>
835     *
836     * <p> This sets the strength of the pad drivers for a particular group of pins. There are 3 groups of pins and the drive strength is from 0 to 7. Do not use this unless you know what you are doing. </p>
837     *
838     * @see <a
839     *      href="http://wiringpi.com/reference/raspberry-pi-specifics/">http://wiringpi.com/reference/raspberry-pi-specifics/</a>
840     */
841    public static native void setPadDrive(int group, int value);
842
843
844    /**
845     * <p>[Hardware]</p>
846     *
847     * <p> This gets the ALT function level of the requested pin number </p>
848     *
849     * @see <a
850     *      href="http://wiringpi.com/reference/raspberry-pi-specifics/">http://wiringpi.com/reference/raspberry-pi-specifics/</a>
851     */
852    public static native int getAlt(int pin);
853
854
855    /**
856     * <p>[Hardware]</p>
857     *
858     * <p> This sets the frequency of a GPIO pin </p>
859     *
860     * @see <a
861     *      href="http://wiringpi.com/reference/raspberry-pi-specifics/">http://wiringpi.com/reference/raspberry-pi-specifics/</a>
862     */
863    public static native void gpioClockSet(int pin, int frequency);
864}