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