001package com.pi4j.io.gpio; 002 003import com.pi4j.io.gpio.event.PinListener; 004import com.pi4j.wiringpi.GpioInterruptEvent; 005import com.pi4j.wiringpi.GpioInterruptListener; 006 007/* 008 * #%L 009 * ********************************************************************** 010 * ORGANIZATION : Pi4J 011 * PROJECT : Pi4J :: Java Library (Core) 012 * FILENAME : RaspiGpioProvider.java 013 * 014 * This file is part of the Pi4J project. More information about 015 * this project can be found here: http://www.pi4j.com/ 016 * ********************************************************************** 017 * %% 018 * Copyright (C) 2012 - 2013 Pi4J 019 * %% 020 * Licensed under the Apache License, Version 2.0 (the "License"); 021 * you may not use this file except in compliance with the License. 022 * You may obtain a copy of the License at 023 * 024 * http://www.apache.org/licenses/LICENSE-2.0 025 * 026 * Unless required by applicable law or agreed to in writing, software 027 * distributed under the License is distributed on an "AS IS" BASIS, 028 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 029 * See the License for the specific language governing permissions and 030 * limitations under the License. 031 * #L% 032 */ 033 034/** 035 * Raspberry PI {@link GpioProvider} implementation. 036 * 037 * @author Robert Savage (<a 038 * href="http://www.savagehomeautomation.com">http://www.savagehomeautomation.com</a>) 039 */ 040public class RaspiGpioProvider extends GpioProviderBase implements GpioProvider, GpioInterruptListener { 041 042 public static final String NAME = "RaspberryPi GPIO Provider"; 043 044 public RaspiGpioProvider() { 045 // set wiringPi interface for internal use 046 // we will use the WiringPi pin number scheme with the wiringPi library 047 com.pi4j.wiringpi.Gpio.wiringPiSetup(); 048 } 049 050 @Override 051 public String getName() { 052 return NAME; 053 } 054 055 @Override 056 public boolean hasPin(Pin pin) { 057 return (com.pi4j.wiringpi.Gpio.wpiPinToGpio(pin.getAddress()) >= 0); 058 } 059 060 @Override 061 public void export(Pin pin, PinMode mode) { 062 super.export(pin, mode); 063 064 //System.out.println("-- EXPORTING PIN [" + pin.getAddress() + "] to mode [" + mode.getName() + "]"); 065 066 // export the pin and set the mode 067 com.pi4j.wiringpi.GpioUtil.export(pin.getAddress(), mode.getDirection().getValue()); 068 setMode(pin, mode); 069 } 070 071 @Override 072 public boolean isExported(Pin pin) { 073 super.isExported(pin); 074 075 // return the pin exported state 076 return com.pi4j.wiringpi.GpioUtil.isExported(pin.getAddress()); 077 } 078 079 @Override 080 public void unexport(Pin pin) { 081 super.unexport(pin); 082 083 // unexport the pins 084 com.pi4j.wiringpi.GpioUtil.unexport(pin.getAddress()); 085 } 086 087 @Override 088 public void setMode(Pin pin, PinMode mode) { 089 super.setMode(pin, mode); 090 091 com.pi4j.wiringpi.Gpio.pinMode(pin.getAddress(), mode.getValue()); 092 093 // if this is an input pin, then configure edge detection 094 if (PinMode.allInputs().contains(mode)) { 095 com.pi4j.wiringpi.GpioUtil.setEdgeDetection(pin.getAddress(), PinEdge.BOTH.getValue()); 096 } 097 } 098 099 @Override 100 public PinMode getMode(Pin pin) { 101 // TODO : get actual pin mode from native impl 102 return super.getMode(pin); 103 } 104 105 @Override 106 public void setPullResistance(Pin pin, PinPullResistance resistance) { 107 super.setPullResistance(pin, resistance); 108 109 com.pi4j.wiringpi.Gpio.pullUpDnControl(pin.getAddress(), resistance.getValue()); 110 } 111 112 @Override 113 public PinPullResistance getPullResistance(Pin pin) { 114 // TODO : get actual pin pull resistance from native impl 115 return super.getPullResistance(pin); 116 } 117 118 @Override 119 public void setState(Pin pin, PinState state) { 120 super.setState(pin, state); 121 122 com.pi4j.wiringpi.Gpio.digitalWrite(pin.getAddress(), state.getValue()); 123 } 124 125 @Override 126 public PinState getState(Pin pin) { 127 super.getState(pin); 128 129 // return pin state 130 PinState state = null; 131 int ret = com.pi4j.wiringpi.Gpio.digitalRead(pin.getAddress()); 132 if (ret >= 0) { 133 state = PinState.getState(ret); 134 } 135 return state; 136 } 137 138 @Override 139 public void setValue(Pin pin, double value) { 140 super.setValue(pin, value); 141 throw new RuntimeException("This GPIO provider does not support analog pins."); 142 } 143 144 @Override 145 public double getValue(Pin pin) { 146 super.getValue(pin); 147 throw new RuntimeException("This GPIO provider does not support analog pins."); 148 } 149 150 @Override 151 public void setPwm(Pin pin, int value) { 152 super.setPwm(pin, value); 153 154 if (getMode(pin) == PinMode.PWM_OUTPUT) { 155 setPwmValue(pin, value); 156 } 157 } 158 159 @Override 160 public int getPwm(Pin pin) { 161 return super.getPwm(pin); 162 } 163 164 // internal 165 private void setPwmValue(Pin pin, int value) { 166 // set pin PWM value 167 com.pi4j.wiringpi.Gpio.pwmWrite(pin.getAddress(), value); 168 } 169 170 @Override 171 public void pinStateChange(GpioInterruptEvent event) { 172 // iterate over the pin listeners map 173 for (Pin pin : listeners.keySet()) { 174 // dispatch this event to the listener 175 // if a matching pin address is found 176 if (pin.getAddress() == event.getPin()) { 177 dispatchPinDigitalStateChangeEvent(pin, PinState.getState(event.getState())); 178 } 179 } 180 } 181 182 @Override 183 public void addListener(Pin pin, PinListener listener) { 184 super.addListener(pin, listener); 185 186 // update the native interrupt listener thread for callbacks 187 updateInterruptListener(pin); 188 } 189 190 @Override 191 public void removeListener(Pin pin, PinListener listener) { 192 super.removeListener(pin, listener); 193 194 // update the native interrupt listener thread for callbacks 195 updateInterruptListener(pin); 196 } 197 198 // internal 199 private void updateInterruptListener(Pin pin) { 200 if (listeners.size() > 0) { 201 // setup interrupt listener native thread and enable callbacks 202 if (!com.pi4j.wiringpi.GpioInterrupt.hasListener(this)) { 203 com.pi4j.wiringpi.GpioInterrupt.addListener(this); 204 } 205 com.pi4j.wiringpi.GpioInterrupt.enablePinStateChangeCallback(pin.getAddress()); 206 } else { 207 // remove interrupt listener, disable native thread and callbacks 208 com.pi4j.wiringpi.GpioInterrupt.disablePinStateChangeCallback(pin.getAddress()); 209 if (com.pi4j.wiringpi.GpioInterrupt.hasListener(this)) { 210 com.pi4j.wiringpi.GpioInterrupt.removeListener(this); 211 } 212 } 213 } 214}