@Override public void setState(Pin pin, PinState state) { // validate if (hasPin(pin) == false) { throw new InvalidPinException(pin); } // only permit invocation on pins set to DIGITAL_OUTPUT modes if (getPinCache(pin).getMode() != PinMode.DIGITAL_OUTPUT) { throw new InvalidPinModeException( pin, "Invalid pin mode on pin [" + pin.getName() + "]; cannot setState() when pin mode is [" + getPinCache(pin).getMode().getName() + "]"); } try { // determine A or B port based on pin address if (pin.getAddress() < GPIO_B_OFFSET) { setStateA(pin, state); } else { setStateB(pin, state); } } catch (IOException ex) { throw new RuntimeException(ex); } // cache pin state getPinCache(pin).setState(state); }
public void run() { while (!shuttingDown) { try { // only process for interrupts if a pin on port A is configured as an input pin if (currentDirectionA > 0) { // process interrupts for port A byte pinInterruptA = provider.read(REGISTER_INTF_A); // validate that there is at least one interrupt active on port A if (pinInterruptA > 0) { // read the current pin states on port A byte pinInterruptState = provider.read(REGISTER_GPIO_A); // loop over the available pins on port B for (Pin pin : MCP23S17Pin.ALL_A_PINS) { int pinAddressA = pin.getAddress() - GPIO_A_OFFSET; // is there an interrupt flag on this pin? if ((pinInterruptA & pinAddressA) > 0) { // System.out.println("INTERRUPT ON PIN [" + pin.getName() + "]"); evaluatePinForChangeA(pin, pinInterruptState); } } } } // only process for interrupts if a pin on port B is configured as an input pin if (currentDirectionB > 0) { // process interrupts for port B int pinInterruptB = (int) provider.read(REGISTER_INTF_B); // validate that there is at least one interrupt active on port B if (pinInterruptB > 0) { // read the current pin states on port B int pinInterruptState = (int) provider.read(REGISTER_GPIO_B); // loop over the available pins on port B for (Pin pin : MCP23S17Pin.ALL_B_PINS) { int pinAddressB = pin.getAddress() - GPIO_B_OFFSET; // is there an interrupt flag on this pin? if ((pinInterruptB & pinAddressB) > 0) { // System.out.println("INTERRUPT ON PIN [" + pin.getName() + "]"); evaluatePinForChangeB(pin, pinInterruptState); } } } } // ... lets take a short breather ... Thread.currentThread(); Thread.sleep(50); } catch (Exception ex) { ex.printStackTrace(); } } }
private void dispatchPinChangeEvent(int pinAddress, PinState state) { // iterate over the pin listeners map for (Pin pin : listeners.keySet()) { // System.out.println("<<< DISPATCH >>> " + pin.getName() + " : " + // state.getName()); // dispatch this event to the listener // if a matching pin address is found if (pin.getAddress() == pinAddress) { // dispatch this event to all listener handlers for (PinListener listener : listeners.get(pin)) { listener.handlePinEvent(new PinDigitalStateChangeEvent(this, pin, state)); } } } }
@Override public void setMode(Pin pin, PinMode mode) { // validate if (!pin.getSupportedPinModes().contains(mode)) { throw new InvalidPinModeException( pin, "Invalid pin mode [" + mode.getName() + "]; pin [" + pin.getName() + "] does not support this mode."); } // validate if (!pin.getSupportedPinModes().contains(mode)) { throw new UnsupportedPinModeException(pin, mode); } // determine A or B port based on pin address try { if (pin.getAddress() < GPIO_B_OFFSET) { setModeA(pin, mode); } else { setModeB(pin, mode); } } catch (IOException ex) { throw new RuntimeException(ex); } // cache mode getPinCache(pin).setMode(mode); // if any pins are configured as input pins, then we need to start the interrupt monitoring // thread if (currentDirectionA > 0 || currentDirectionB > 0) { // if the monitor has not been started, then start it now if (monitor == null) { // start monitoring thread monitor = new GpioStateMonitor(this); monitor.start(); } } else { // shutdown and destroy monitoring thread since there are no input pins configured if (monitor != null) { monitor.shutdown(); monitor = null; } } }
private PinState getStateB(Pin pin) { // determine pin address int pinAddress = pin.getAddress() - GPIO_B_OFFSET; // determine pin state PinState state = (currentStatesB & pinAddress) == pinAddress ? PinState.HIGH : PinState.LOW; // cache state getPinCache(pin).setState(state); return state; }
private void setStateB(Pin pin, PinState state) throws IOException { // determine pin address int pinAddress = pin.getAddress() - GPIO_B_OFFSET; // determine state value for pin bit if (state.isHigh()) { currentStatesB |= pinAddress; } else { currentStatesB &= ~pinAddress; } // update state value write(REGISTER_GPIO_B, (byte) currentStatesB); }
private void setPullResistanceB(Pin pin, PinPullResistance resistance) throws IOException { // determine pin address int pinAddress = pin.getAddress() - GPIO_B_OFFSET; // determine pull up value for pin bit if (resistance == PinPullResistance.PULL_UP) { currentPullupB |= pinAddress; } else { currentPullupB &= ~pinAddress; } // next update pull up resistor value write(REGISTER_GPPU_B, (byte) currentPullupB); }
private void evaluatePinForChangeB(Pin pin, int state) { if (getPinCache(pin).isExported()) { // determine pin address int pinAddress = pin.getAddress() - GPIO_B_OFFSET; if ((state & pinAddress) != (currentStatesB & pinAddress)) { PinState newState = (state & pinAddress) == pinAddress ? PinState.HIGH : PinState.LOW; // cache state getPinCache(pin).setState(newState); // determine and cache state value for pin bit if (newState.isHigh()) { currentStatesB |= pinAddress; } else { currentStatesB &= ~pinAddress; } // change detected for INPUT PIN // System.out.println("<<< CHANGE >>> " + pin.getName() + " : " + state); dispatchPinChangeEvent(pin.getAddress(), newState); } } }
@Override public void setPullResistance(Pin pin, PinPullResistance resistance) { // validate if (hasPin(pin) == false) { throw new InvalidPinException(pin); } // validate if (!pin.getSupportedPinPullResistance().contains(resistance)) { throw new UnsupportedPinPullResistanceException(pin, resistance); } try { // determine A or B port based on pin address if (pin.getAddress() < GPIO_B_OFFSET) { setPullResistanceA(pin, resistance); } else { setPullResistanceB(pin, resistance); } } catch (IOException ex) { throw new RuntimeException(ex); } // cache resistance getPinCache(pin).setResistance(resistance); }
@Override public PinState getState(Pin pin) { // call super method to perform validation on pin PinState result = super.getState(pin); // determine A or B port based on pin address if (pin.getAddress() < GPIO_B_OFFSET) { result = getStateA(pin); // get pin state } else { result = getStateB(pin); // get pin state } // return pin state return result; }
private void setModeB(Pin pin, PinMode mode) throws IOException { // determine register and pin address int pinAddress = pin.getAddress() - GPIO_B_OFFSET; // determine update direction value based on mode if (mode == PinMode.DIGITAL_INPUT) { currentDirectionB |= pinAddress; } else if (mode == PinMode.DIGITAL_OUTPUT) { currentDirectionB &= ~pinAddress; } // next update direction (mode) value write(REGISTER_IODIR_B, (byte) currentDirectionB); // enable interrupts; interrupt on any change from previous state write(REGISTER_GPINTEN_B, (byte) currentDirectionB); }
@Override public GpioPinPwmOutput provisionPwmOutputPin(GpioProvider provider, Pin pin, int defaultValue) { return provisionPwmOutputPin(provider, pin, pin.getName(), defaultValue); }
@Override public GpioPinAnalogOutput provisionAnalogOutputPin( GpioProvider provider, Pin pin, double defaultValue) { return provisionAnalogOutputPin(provider, pin, pin.getName(), defaultValue); }
@Override public GpioPinDigitalOutput provisionDigitalOutputPin( GpioProvider provider, Pin pin, PinState defaultState) { return provisionDigitalOutputPin(provider, pin, pin.getName(), defaultState); }
@Override public GpioPinDigitalInput provisionDigitalInputPin( GpioProvider provider, Pin pin, PinPullResistance resistance) { // create new GPIO pin instance return provisionDigitalInputPin(provider, pin, pin.getName(), resistance); }
@Override public GpioPinDigitalMultipurpose provisionDigitalMultipurposePin( GpioProvider provider, Pin pin, PinMode mode, PinPullResistance resistance) { // create new GPIO pin instance return provisionDigitalMultipurposePin(provider, pin, pin.getName(), mode, resistance); }
@Override public GpioPin provisionPin(GpioProvider provider, Pin pin, PinMode mode) { return provisionPin(provider, pin, pin.getName(), mode); }