001package com.pi4j.wiringpi; 002 003/* 004 * #%L 005 * ********************************************************************** 006 * ORGANIZATION : Pi4J 007 * PROJECT : Pi4J :: Java Library (Core) 008 * FILENAME : GpioInterrupt.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 - 2015 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.Vector; 036 037/** 038 * <p> 039 * This class provides static methods to configure the native Pi4J library to listen to GPIO 040 * interrupts and invoke callbacks into this class. Additionally, this class provides a listener 041 * registration allowing Java consumers to subscribe to GPIO pin state changes. 042 * </p> 043 * 044 * <p> 045 * Before using the Pi4J library, you need to ensure that the Java VM in configured with access to 046 * the following system libraries: 047 * <ul> 048 * <li>pi4j</li> 049 * <li>wiringPi</li> 050 * </ul> 051 * <blockquote> This library depends on the wiringPi native system library.</br> (developed by 052 * Gordon Henderson @ <a href="http://wiringpi.com/">http://wiringpi.com/</a>) 053 * </blockquote> 054 * </p> 055 * 056 * @see <a href="http://www.pi4j.com/">http://www.pi4j.com/</a> 057 * @author Robert Savage (<a 058 * href="http://www.savagehomeautomation.com">http://www.savagehomeautomation.com</a>) 059 */ 060public class GpioInterrupt { 061 062 private static Vector<GpioInterruptListener> listeners = new Vector<>(); 063 private Object lock; 064 065 // private constructor 066 private GpioInterrupt() { 067 // forbid object construction 068 } 069 070 static { 071 // Load the platform library 072 NativeLibraryLoader.load("libpi4j.so"); 073 } 074 075 /** 076 * <p> 077 * This method is used to instruct the native code to setup a monitoring thread to monitor 078 * interrupts that represent changes to the selected GPIO pin. 079 * </p> 080 * 081 * <p> 082 * <b>The GPIO pin must first be exported before it can be monitored.</b> 083 * </p> 084 * 085 * @param pin GPIO pin number (not header pin number; not wiringPi pin number) 086 * @return A return value of a negative number represents an error. A return value of '0' 087 * represents success and that the GPIO pin is already being monitored. A return value 088 * of '1' represents success and that a new monitoring thread was created to handle the 089 * requested GPIO pin number. 090 */ 091 public static native int enablePinStateChangeCallback(int pin); 092 093 /** 094 * <p> 095 * This method is used to instruct the native code to stop the monitoring thread monitoring 096 * interrupts on the selected GPIO pin. 097 * </p> 098 * 099 * @param pin GPIO pin number (not header pin number; not wiringPi pin number) 100 101 * @return A return value of a negative number represents an error. A return value of '0' 102 * represents success and that no existing monitor was previously running. A return 103 * value of '1' represents success and that an existing monitoring thread was stopped 104 * for the requested GPIO pin number. 105 */ 106 public static native int disablePinStateChangeCallback(int pin); 107 108 /** 109 * <p> 110 * This method is provided as the callback handler for the Pi4J native library to invoke when a 111 * GPIO interrupt is detected. This method should not be called from any Java consumers. (Thus 112 * is is marked as a private method.) 113 * </p> 114 * 115 * @param pin GPIO pin number (not header pin number; not wiringPi pin number) 116 * @param state New GPIO pin state. 117 */ 118 @SuppressWarnings("unchecked") 119 private static void pinStateChangeCallback(int pin, boolean state) { 120 121 Vector<GpioInterruptListener> dataCopy; 122 dataCopy = (Vector<GpioInterruptListener>) listeners.clone(); 123 124 for (int i = 0; i < dataCopy.size(); i++) { 125 GpioInterruptEvent event = new GpioInterruptEvent(listeners, pin, state); 126 (dataCopy.elementAt(i)).pinStateChange(event); 127 } 128 129 // System.out.println("GPIO PIN [" + pin + "] = " + state); 130 } 131 132 /** 133 * <p> 134 * Java consumer code can all this method to register itself as a listener for pin state 135 * changes. 136 * </p> 137 * 138 * @see com.pi4j.wiringpi.GpioInterruptListener 139 * @see com.pi4j.wiringpi.GpioInterruptEvent 140 * 141 * @param listener A class instance that implements the GpioInterruptListener interface. 142 */ 143 public static synchronized void addListener(GpioInterruptListener listener) { 144 if (!listeners.contains(listener)) { 145 listeners.addElement(listener); 146 } 147 } 148 149 /** 150 * <p> 151 * Java consumer code can all this method to unregister itself as a listener for pin state 152 * changes. 153 * </p> 154 * 155 * @see com.pi4j.wiringpi.GpioInterruptListener 156 * @see com.pi4j.wiringpi.GpioInterruptEvent 157 * 158 * @param listener A class instance that implements the GpioInterruptListener interface. 159 */ 160 public static synchronized void removeListener(GpioInterruptListener listener) { 161 if (listeners.contains(listener)) { 162 listeners.removeElement(listener); 163 } 164 } 165 166 167 /** 168 * <p> 169 * Returns true if the listener is already registered for event callbacks. 170 * </p> 171 * 172 * @see com.pi4j.wiringpi.GpioInterruptListener 173 * @see com.pi4j.wiringpi.GpioInterruptEvent 174 * 175 * @param listener A class instance that implements the GpioInterruptListener interface. 176 */ 177 public static synchronized boolean hasListener(GpioInterruptListener listener) { 178 return listeners.contains(listener); 179 } 180}