001package com.pi4j.io.gpio.impl; 002 003/* 004 * #%L 005 * ********************************************************************** 006 * ORGANIZATION : Pi4J 007 * PROJECT : Pi4J :: Java Library (Core) 008 * FILENAME : GpioControllerImpl.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 - 2016 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 032import com.pi4j.io.gpio.*; 033import com.pi4j.io.gpio.event.GpioPinListener; 034import com.pi4j.io.gpio.exception.GpioPinExistsException; 035import com.pi4j.io.gpio.exception.GpioPinNotProvisionedException; 036import com.pi4j.io.gpio.exception.PinProviderException; 037import com.pi4j.io.gpio.exception.UnsupportedPinEventsException; 038import com.pi4j.io.gpio.trigger.GpioTrigger; 039 040import java.util.ArrayList; 041import java.util.Collection; 042import java.util.Collections; 043import java.util.List; 044 045public class GpioControllerImpl implements GpioController { 046 047 private final List<GpioPin> pins = Collections.synchronizedList(new ArrayList<GpioPin>()); 048 private final GpioProvider defaultProvider; 049 private boolean isshutdown = false; 050 051 /** 052 * Default Constructor 053 */ 054 public GpioControllerImpl() { 055 // set the local default provider reference 056 this(GpioFactory.getDefaultProvider()); 057 } 058 059 /** 060 * Default Constructor 061 */ 062 public GpioControllerImpl(GpioProvider provider) { 063 // set the local default provider reference 064 defaultProvider = provider; 065 066 // register shutdown callback hook class 067 Runtime.getRuntime().addShutdownHook(new ShutdownHook()); 068 } 069 070 @Override 071 public Collection<GpioPin> getProvisionedPins() { 072 // make an unmodifiable copy of the pins collection 073 return Collections.unmodifiableList(pins); 074 } 075 076 @Override 077 public GpioPin getProvisionedPin(Pin pin){ 078 for(GpioPin gpio_pin : pins){ 079 if(gpio_pin.getPin().equals(pin)){ 080 return gpio_pin; 081 } 082 } 083 return null; 084 } 085 086 @Override 087 public GpioPin getProvisionedPin(String name){ 088 for(GpioPin pin : pins){ 089 if(pin.getName().equals(name)){ 090 return pin; 091 } 092 } 093 return null; 094 } 095 096 @Override 097 public void unexportAll() { 098 // un-export all GPIO pins that are currently exported 099 for (GpioPin pin : pins) { 100 if (pin.isExported()) { 101 pin.unexport(); 102 } 103 } 104 } 105 106 @Override 107 public void export(PinMode mode, GpioPin... pin) { 108 export(mode, null, pin); 109 } 110 111 @Override 112 public void export(PinMode mode, PinState defaultState, GpioPin... pin){ 113 if (pin == null || pin.length == 0) { 114 throw new IllegalArgumentException("Missing pin argument."); 115 } 116 for (GpioPin p : pin) { 117 // ensure the requested pin has been provisioned 118 if (!pins.contains(p)) { 119 throw new GpioPinNotProvisionedException(p.getPin()); 120 } 121 // export the pin 122 p.export(mode, defaultState); 123 } 124 } 125 126 /** 127 * 128 * @param pin 129 * @return <p> 130 * A value of 'true' is returned if the requested pin is exported. 131 * </p> 132 */ 133 @Override 134 public boolean isExported(GpioPin... pin) { 135 if (pin == null || pin.length == 0) { 136 throw new IllegalArgumentException("Missing pin argument."); 137 } 138 for (GpioPin p : pin) { 139 // ensure the requested pin has been provisioned 140 if (!pins.contains(p)) { 141 throw new GpioPinNotProvisionedException(p.getPin()); 142 } 143 if (!p.isExported()) { 144 return false; 145 } 146 } 147 148 // return the pin exported state 149 return true; 150 } 151 152 @Override 153 public void unexport(GpioPin... pin) { 154 if (pin == null || pin.length == 0) { 155 throw new IllegalArgumentException("Missing pin argument."); 156 } 157 for (GpioPin p : pin) { 158 // ensure the requested pin has been provisioned 159 if (!pins.contains(p)) { 160 throw new GpioPinNotProvisionedException(p.getPin()); 161 } 162 // unexport the pin 163 p.unexport(); 164 } 165 } 166 167 @Override 168 public void unexport(Pin... pin) { 169 if (pin == null || pin.length == 0) { 170 throw new IllegalArgumentException("Missing pin argument."); 171 } 172 for (Pin p : pin) { 173 // unexport the pin 174 defaultProvider.unexport(p); 175 } 176 } 177 178 @Override 179 public PinMode getMode(GpioPin pin) { 180 // ensure the requested pin has been provisioned 181 if (!pins.contains(pin)) { 182 throw new GpioPinNotProvisionedException(pin.getPin()); 183 } 184 // return pin edge setting 185 return pin.getMode(); 186 } 187 188 @Override 189 public boolean isMode(PinMode mode, GpioPin... pin) { 190 if (pin == null || pin.length == 0) { 191 throw new IllegalArgumentException("Missing pin argument."); 192 } 193 for (GpioPin p : pin) { 194 if (!p.isMode(mode)) { 195 return false; 196 } 197 } 198 return true; 199 } 200 201 @Override 202 public void setMode(PinMode mode, GpioPin... pin) { 203 if (pin == null || pin.length == 0) { 204 throw new IllegalArgumentException("Missing pin argument."); 205 } 206 for (GpioPin p : pin) { 207 // ensure the requested pin has been provisioned 208 if (!pins.contains(p)) { 209 throw new GpioPinNotProvisionedException(p.getPin()); 210 } 211 // set pin mode 212 p.setMode(mode); 213 } 214 } 215 216 @Override 217 public void setPullResistance(PinPullResistance resistance, GpioPin... pin) { 218 if (pin == null || pin.length == 0) { 219 throw new IllegalArgumentException("Missing pin argument."); 220 } 221 for (GpioPin p : pin) { 222 // ensure the requested pin has been provisioned 223 if (!pins.contains(p)) { 224 throw new GpioPinNotProvisionedException(p.getPin()); 225 } 226 // set pin pull resistance 227 p.setPullResistance(resistance); 228 } 229 } 230 231 @Override 232 public PinPullResistance getPullResistance(GpioPin pin) { 233 // ensure the requested pin has been provisioned 234 if (!pins.contains(pin)) { 235 throw new GpioPinNotProvisionedException(pin.getPin()); 236 } 237 // get pin pull resistance 238 return pin.getPullResistance(); 239 } 240 241 @Override 242 public boolean isPullResistance(PinPullResistance resistance, GpioPin... pin) { 243 if (pin == null || pin.length == 0) { 244 throw new IllegalArgumentException("Missing pin argument."); 245 } 246 for (GpioPin p : pin) { 247 // ensure the requested pin has been provisioned 248 if (!pins.contains(p)) { 249 throw new GpioPinNotProvisionedException(p.getPin()); 250 } 251 // set pin pull resistance 252 if(!p.isPullResistance(resistance)) 253 return false; 254 } 255 256 return true; 257 } 258 259 @Override 260 public void high(GpioPinDigitalOutput... pin) { 261 if (pin == null || pin.length == 0) { 262 throw new IllegalArgumentException("Missing pin argument."); 263 } 264 // ensure the requested pin has been provisioned 265 for (GpioPinDigitalOutput p : pin) { 266 if (!pins.contains(p)) { 267 throw new GpioPinNotProvisionedException(p.getPin()); 268 } 269 // set pin state high 270 p.high(); 271 } 272 } 273 274 @Override 275 public void low(GpioPinDigitalOutput... pin) { 276 if (pin == null || pin.length == 0) { 277 throw new IllegalArgumentException("Missing pin argument."); 278 } 279 // ensure the requested pin has been provisioned 280 for (GpioPinDigitalOutput p : pin) { 281 if (!pins.contains(p)) { 282 throw new GpioPinNotProvisionedException(p.getPin()); 283 } 284 // set pin state low 285 p.low(); 286 } 287 } 288 289 @Override 290 public boolean isHigh(GpioPinDigital... pin) { 291 if (pin == null || pin.length == 0) { 292 throw new IllegalArgumentException("Missing pin argument."); 293 } 294 for (GpioPinDigital p : pin) { 295 if (p.isLow()) { 296 return false; 297 } 298 } 299 return true; 300 } 301 302 @Override 303 public boolean isLow(GpioPinDigital... pin) { 304 if (pin == null || pin.length == 0) { 305 throw new IllegalArgumentException("Missing pin argument."); 306 } 307 for (GpioPinDigital p : pin) { 308 if (p.isHigh()) { 309 return false; 310 } 311 } 312 return true; 313 } 314 315 @Override 316 public void toggle(GpioPinDigitalOutput... pin) { 317 if (pin == null || pin.length == 0) { 318 throw new IllegalArgumentException("Missing pin argument."); 319 } 320 for (GpioPinDigitalOutput p : pin) { 321 // ensure the requested pin has been provisioned 322 if (!pins.contains(p)) { 323 throw new GpioPinNotProvisionedException(p.getPin()); 324 } 325 // toggle pin state 326 p.toggle(); 327 } 328 } 329 330 @Override 331 public void pulse(long milliseconds, GpioPinDigitalOutput... pin) { 332 if (pin == null || pin.length == 0) { 333 throw new IllegalArgumentException("Missing pin argument."); 334 } 335 for (GpioPinDigitalOutput p : pin) { 336 // ensure the requested pin has been provisioned 337 if (!pins.contains(p)) { 338 throw new GpioPinNotProvisionedException(p.getPin()); 339 } 340 // toggle pin state 341 p.pulse(milliseconds); 342 } 343 } 344 345 @Override 346 public void setState(PinState state, GpioPinDigitalOutput... pin) { 347 if (pin == null || pin.length == 0) { 348 throw new IllegalArgumentException("Missing pin argument."); 349 } 350 for (GpioPinDigitalOutput p : pin) { 351 // ensure the requested pin has been provisioned 352 if (!pins.contains(p)) { 353 throw new GpioPinNotProvisionedException(p.getPin()); 354 } 355 // set pin state 356 p.setState(state); 357 } 358 } 359 360 @Override 361 public void setState(boolean state, GpioPinDigitalOutput... pin) { 362 setState((state) ? PinState.HIGH : PinState.LOW, pin); 363 } 364 365 @Override 366 public PinState getState(GpioPinDigital pin) { 367 // ensure the requested pin has been provisioned 368 if (!pins.contains(pin)) { 369 throw new GpioPinNotProvisionedException(pin.getPin()); 370 } 371 // return pin state 372 return pin.getState(); 373 } 374 375 @Override 376 public boolean isState(PinState state, GpioPinDigital... pin) { 377 if (pin == null || pin.length == 0) { 378 throw new IllegalArgumentException("Missing pin argument."); 379 } 380 for (GpioPinDigital p : pin) { 381 if (!p.isState(state)) { 382 return false; 383 } 384 } 385 return true; 386 } 387 388 @Override 389 public void setValue(double value, GpioPinAnalogOutput... pin) { 390 if (pin == null || pin.length == 0) { 391 throw new IllegalArgumentException("Missing pin argument."); 392 } 393 for (GpioPinAnalogOutput p : pin) { 394 // ensure the requested pin has been provisioned 395 if (!pins.contains(p)) { 396 throw new GpioPinNotProvisionedException(p.getPin()); 397 } 398 // set pin PWM value 399 p.setValue(value); 400 } 401 } 402 403 @Override 404 public double getValue(GpioPinAnalog pin) { 405 return pin.getValue(); 406 } 407 408 @Override 409 public synchronized void addListener(GpioPinListener listener, GpioPinInput... pin) { 410 if (pin == null || pin.length == 0) { 411 throw new IllegalArgumentException("Missing pin argument."); 412 } 413 for (GpioPinInput p : pin) { 414 // ensure the requested pin has been provisioned 415 if (!pins.contains(p)) { 416 throw new GpioPinNotProvisionedException(p.getPin()); 417 } 418 // ensure the requested pin supports events (interrupts) 419 if (!p.getPin().supportsPinEvents()) { 420 throw new UnsupportedPinEventsException(p.getPin()); 421 } 422 p.addListener(listener); 423 } 424 } 425 426 @Override 427 public synchronized void addListener(GpioPinListener[] listeners, GpioPinInput... pin) { 428 if (pin == null || pin.length == 0) { 429 throw new IllegalArgumentException("Missing pin argument."); 430 } 431 for (GpioPinListener listener: listeners) { 432 addListener(listener, pin); 433 } 434 } 435 436 437 @Override 438 public synchronized void removeListener(GpioPinListener listener, GpioPinInput... pin) { 439 if (pin == null || pin.length == 0) { 440 throw new IllegalArgumentException("Missing pin argument."); 441 } 442 for (GpioPinInput p : pin) { 443 // ensure the requested pin has been provisioned 444 if (!pins.contains(p)) { 445 throw new GpioPinNotProvisionedException(p.getPin()); 446 } 447 // ensure the requested pin supports events (interrupts) 448 if (!p.getPin().supportsPinEvents()) { 449 throw new UnsupportedPinEventsException(p.getPin()); 450 } 451 p.removeListener(listener); 452 } 453 } 454 455 @Override 456 public synchronized void removeListener(GpioPinListener[] listeners, GpioPinInput... pin) { 457 if(pin == null || pin.length == 0) { 458 throw new IllegalArgumentException("Missing pin argument."); 459 } 460 for (GpioPinListener listener : listeners) { 461 removeListener(listener, pin); 462 } 463 } 464 465 @Override 466 public synchronized void removeAllListeners() { 467 for (GpioPin pin : this.pins) { 468 if (pin instanceof GpioPinInput) { 469 ((GpioPinInput)pin).removeAllListeners(); 470 } 471 } 472 } 473 474 @Override 475 public synchronized void addTrigger(GpioTrigger trigger, GpioPinInput... pin) { 476 if (pin == null || pin.length == 0) { 477 throw new IllegalArgumentException("Missing pin argument."); 478 } 479 for (GpioPinInput p : pin) { 480 // ensure the requested pin has been provisioned 481 if (!pins.contains(p)) { 482 throw new GpioPinNotProvisionedException(p.getPin()); 483 } 484 p.addTrigger(trigger); 485 } 486 } 487 488 @Override 489 public synchronized void addTrigger(GpioTrigger[] triggers, GpioPinInput... pin) { 490 if (pin == null || pin.length == 0) { 491 throw new IllegalArgumentException("Missing pin argument."); 492 } 493 for (GpioTrigger trigger : triggers) { 494 addTrigger(trigger, pin); 495 } 496 } 497 498 @Override 499 public synchronized void removeTrigger(GpioTrigger trigger, GpioPinInput... pin) { 500 if (pin == null || pin.length == 0) { 501 throw new IllegalArgumentException("Missing pin argument."); 502 } 503 for (GpioPinInput p : pin) { 504 // ensure the requested pin has been provisioned 505 if (!pins.contains(p)) { 506 throw new GpioPinNotProvisionedException(p.getPin()); 507 } 508 p.removeTrigger(trigger); 509 } 510 } 511 512 @Override 513 public synchronized void removeTrigger(GpioTrigger[] triggers, GpioPinInput... pin) { 514 if (pin == null || pin.length == 0) { 515 throw new IllegalArgumentException("Missing pin argument."); 516 } 517 for (GpioTrigger trigger : triggers) { 518 removeTrigger(trigger, pin); 519 } 520 } 521 522 @Override 523 public synchronized void removeAllTriggers() { 524 for (GpioPin pin : this.pins) { 525 if (pin instanceof GpioPinInput) { 526 ((GpioPinInput)pin).removeAllTriggers(); 527 } 528 } 529 } 530 531 @Override 532 public GpioPin provisionPin(GpioProvider provider, Pin pin, PinMode mode) { 533 return provisionPin(provider, pin, pin.getName(), mode); 534 } 535 536 @Override 537 public GpioPin provisionPin(GpioProvider provider, Pin pin, String name, PinMode mode) { 538 return provisionPin(provider, pin, name, mode, null); 539 } 540 541 @Override 542 public GpioPin provisionPin(GpioProvider provider, Pin pin, String name, PinMode mode, PinState defaultState) { 543 544 // if the provider does not match the pin's provider then throw an error 545 if(!provider.getName().equals(pin.getProvider())){ 546 throw new PinProviderException(provider, pin); 547 } 548 549 // if an existing pin has been previously created, then throw an error 550 for(GpioPin p : pins) { 551 if (p.getProvider().equals(provider) && p.getPin().equals(pin)) { 552 throw new GpioPinExistsException(pin); 553 } 554 } 555 556 // create new GPIO pin instance 557 GpioPin gpioPin = new GpioPinImpl(this, provider, pin); 558 559 // set the gpio pin name 560 if (name != null) { 561 gpioPin.setName(name); 562 } 563 564 // export this pin 565 gpioPin.export(mode, defaultState); 566 567 // add this new pin instance to the managed collection 568 pins.add(gpioPin); 569 570 // return new new pin instance 571 return gpioPin; 572 } 573 574 @Override 575 public GpioPin provisionPin(Pin pin, String name, PinMode mode) { 576 return provisionPin(defaultProvider, pin, name, mode); 577 } 578 579 @Override 580 public GpioPin provisionPin(Pin pin, PinMode mode) { 581 return provisionPin(defaultProvider, pin, mode); 582 } 583 584 @Override 585 public GpioPinDigitalMultipurpose provisionDigitalMultipurposePin(GpioProvider provider, Pin pin, String name, PinMode mode) { 586 // return new new pin instance 587 return (GpioPinDigitalMultipurpose)provisionPin(provider, pin, name, mode); 588 } 589 590 @Override 591 public GpioPinDigitalMultipurpose provisionDigitalMultipurposePin(GpioProvider provider, Pin pin, PinMode mode) { 592 // return new new pin instance 593 return (GpioPinDigitalMultipurpose)provisionPin(provider, pin, mode); 594 } 595 596 @Override 597 public GpioPinDigitalMultipurpose provisionDigitalMultipurposePin(Pin pin, String name, PinMode mode) { 598 return provisionDigitalMultipurposePin(defaultProvider, pin, name, mode); 599 } 600 601 @Override 602 public GpioPinDigitalMultipurpose provisionDigitalMultipurposePin(Pin pin, PinMode mode) { 603 return provisionDigitalMultipurposePin(defaultProvider, pin, mode); 604 } 605 606 @Override 607 public GpioPinDigitalMultipurpose provisionDigitalMultipurposePin(GpioProvider provider, Pin pin, PinMode mode, PinPullResistance resistance) { 608 // create new GPIO pin instance 609 return provisionDigitalMultipurposePin(provider, pin, pin.getName(), mode, resistance); 610 } 611 612 @Override 613 public GpioPinDigitalMultipurpose provisionDigitalMultipurposePin(GpioProvider provider, Pin pin, String name, PinMode mode, PinPullResistance resistance) { 614 // create new GPIO pin instance 615 GpioPinDigitalMultipurpose gpioPin = provisionDigitalMultipurposePin(provider, pin, name, mode); 616 617 // set the gpio pull resistor 618 if (resistance != null) { 619 gpioPin.setPullResistance(resistance); 620 } 621 // return new new pin instance 622 return gpioPin; 623 } 624 625 @Override 626 public GpioPinDigitalMultipurpose provisionDigitalMultipurposePin(Pin pin, String name, PinMode mode, PinPullResistance resistance) { 627 return provisionDigitalMultipurposePin(defaultProvider, pin, name, mode, resistance); 628 } 629 630 @Override 631 public GpioPinDigitalMultipurpose provisionDigitalMultipurposePin(Pin pin, PinMode mode, PinPullResistance resistance) { 632 return provisionDigitalMultipurposePin(defaultProvider, pin, mode, resistance); 633 } 634 635 636 @Override 637 public GpioPinDigitalInput provisionDigitalInputPin(GpioProvider provider, Pin pin, String name) { 638 // return new new pin instance 639 return (GpioPinDigitalInput)provisionPin(provider, pin, name, PinMode.DIGITAL_INPUT); 640 } 641 642 @Override 643 public GpioPinDigitalInput provisionDigitalInputPin(GpioProvider provider, Pin pin) { 644 // return new new pin instance 645 return (GpioPinDigitalInput)provisionPin(provider, pin, PinMode.DIGITAL_INPUT); 646 } 647 648 @Override 649 public GpioPinDigitalInput provisionDigitalInputPin(Pin pin, String name) { 650 return provisionDigitalInputPin(defaultProvider, pin, name); 651 } 652 653 @Override 654 public GpioPinDigitalInput provisionDigitalInputPin(Pin pin) { 655 return provisionDigitalInputPin(defaultProvider, pin); 656 } 657 658 @Override 659 public GpioPinDigitalInput provisionDigitalInputPin(GpioProvider provider, Pin pin, PinPullResistance resistance) { 660 // create new GPIO pin instance 661 return provisionDigitalInputPin(provider, pin, pin.getName(), resistance); 662 } 663 664 @Override 665 public GpioPinDigitalInput provisionDigitalInputPin(GpioProvider provider, Pin pin, String name, PinPullResistance resistance) { 666 // create new GPIO pin instance 667 GpioPinDigitalInput gpioPin = provisionDigitalInputPin(provider, pin, name); 668 669 // set the gpio pull resistor 670 if (resistance != null) { 671 gpioPin.setPullResistance(resistance); 672 } 673 // return new new pin instance 674 return gpioPin; 675 } 676 677 @Override 678 public GpioPinDigitalInput provisionDigitalInputPin(Pin pin, String name, PinPullResistance resistance) { 679 return provisionDigitalInputPin(defaultProvider, pin, name, resistance); 680 } 681 682 @Override 683 public GpioPinDigitalInput provisionDigitalInputPin(Pin pin, PinPullResistance resistance) { 684 return provisionDigitalInputPin(defaultProvider, pin, resistance); 685 } 686 687 @Override 688 public GpioPinDigitalOutput provisionDigitalOutputPin(GpioProvider provider, Pin pin, String name) { 689 // return new new pin instance 690 return (GpioPinDigitalOutput)provisionPin(provider, pin, name, PinMode.DIGITAL_OUTPUT); 691 } 692 693 @Override 694 public GpioPinDigitalOutput provisionDigitalOutputPin(GpioProvider provider, Pin pin) { 695 // return new new pin instance 696 return (GpioPinDigitalOutput)provisionPin(provider, pin, PinMode.DIGITAL_OUTPUT); 697 } 698 699 @Override 700 public GpioPinDigitalOutput provisionDigitalOutputPin(Pin pin, String name) { 701 return provisionDigitalOutputPin(defaultProvider, pin, name); 702 } 703 704 @Override 705 public GpioPinDigitalOutput provisionDigitalOutputPin(Pin pin) { 706 return provisionDigitalOutputPin(defaultProvider, pin); 707 } 708 709 @Override 710 public GpioPinDigitalOutput provisionDigitalOutputPin(GpioProvider provider, Pin pin, PinState defaultState) { 711 return provisionDigitalOutputPin(provider, pin, pin.getName(), defaultState); 712 } 713 714 @Override 715 public GpioPinDigitalOutput provisionDigitalOutputPin(GpioProvider provider, Pin pin, String name, PinState defaultState) { 716 // create new GPIO pin instance 717 GpioPinDigitalOutput gpioPin = (GpioPinDigitalOutput)provisionPin(provider, pin, name, PinMode.DIGITAL_OUTPUT, defaultState); 718 719 // apply default state 720 if (defaultState != null) { 721 gpioPin.setState(defaultState); 722 } 723 // return new new pin instance 724 return gpioPin; 725 } 726 727 @Override 728 public GpioPinDigitalOutput provisionDigitalOutputPin(Pin pin, String name, PinState defaultState) { 729 return provisionDigitalOutputPin(defaultProvider, pin, name, defaultState); 730 } 731 732 @Override 733 public GpioPinDigitalOutput provisionDigitalOutputPin(Pin pin, PinState defaultState) { 734 return provisionDigitalOutputPin(defaultProvider, pin, defaultState); 735 } 736 737 @Override 738 public GpioPinAnalogInput provisionAnalogInputPin(GpioProvider provider, Pin pin, String name) { 739 // return new new pin instance 740 return (GpioPinAnalogInput)provisionPin(provider, pin, name, PinMode.ANALOG_INPUT); 741 } 742 743 @Override 744 public GpioPinAnalogInput provisionAnalogInputPin(GpioProvider provider, Pin pin) { 745 // return new new pin instance 746 return (GpioPinAnalogInput)provisionPin(provider, pin, PinMode.ANALOG_INPUT); 747 } 748 749 @Override 750 public GpioPinAnalogInput provisionAnalogInputPin(Pin pin, String name) { 751 return provisionAnalogInputPin(defaultProvider, pin, name); 752 } 753 754 @Override 755 public GpioPinAnalogInput provisionAnalogInputPin(Pin pin) { 756 return provisionAnalogInputPin(defaultProvider, pin); 757 } 758 759 @Override 760 public GpioPinAnalogOutput provisionAnalogOutputPin(GpioProvider provider, Pin pin, String name) { 761 // return new new pin instance 762 return (GpioPinAnalogOutput)provisionPin(provider, pin, name, PinMode.ANALOG_OUTPUT); 763 } 764 765 @Override 766 public GpioPinAnalogOutput provisionAnalogOutputPin(GpioProvider provider, Pin pin) { 767 // return new new pin instance 768 return (GpioPinAnalogOutput)provisionPin(provider, pin, PinMode.ANALOG_OUTPUT); 769 } 770 771 @Override 772 public GpioPinAnalogOutput provisionAnalogOutputPin(Pin pin, String name) { 773 return provisionAnalogOutputPin(defaultProvider, pin, name); 774 } 775 776 @Override 777 public GpioPinAnalogOutput provisionAnalogOutputPin(Pin pin) { 778 return provisionAnalogOutputPin(defaultProvider, pin); 779 } 780 781 @Override 782 public GpioPinAnalogOutput provisionAnalogOutputPin(GpioProvider provider, Pin pin, double defaultValue) { 783 return provisionAnalogOutputPin(provider, pin, pin.getName(), defaultValue); 784 } 785 786 @Override 787 public GpioPinAnalogOutput provisionAnalogOutputPin(GpioProvider provider, Pin pin, String name, double defaultValue) { 788 // create new GPIO pin instance 789 GpioPinAnalogOutput gpioPin = provisionAnalogOutputPin(provider, pin, name); 790 791 // apply default value 792 gpioPin.setValue(defaultValue); 793 794 // return new new pin instance 795 return gpioPin; 796 } 797 798 @Override 799 public GpioPinAnalogOutput provisionAnalogOutputPin(Pin pin, String name, double defaultValue) { 800 return provisionAnalogOutputPin(defaultProvider, pin, name, defaultValue); 801 } 802 803 @Override 804 public GpioPinAnalogOutput provisionAnalogOutputPin(Pin pin, double defaultValue) { 805 return provisionAnalogOutputPin(defaultProvider, pin, defaultValue); 806 } 807 808 @Override 809 public GpioPinPwmOutput provisionPwmOutputPin(GpioProvider provider, Pin pin, String name) { 810 // return new new pin instance 811 return (GpioPinPwmOutput)provisionPin(provider, pin, name, PinMode.PWM_OUTPUT); 812 } 813 814 @Override 815 public GpioPinPwmOutput provisionPwmOutputPin(GpioProvider provider, Pin pin) { 816 // return new new pin instance 817 return (GpioPinPwmOutput)provisionPin(provider, pin, PinMode.PWM_OUTPUT); 818 } 819 820 @Override 821 public GpioPinPwmOutput provisionPwmOutputPin(Pin pin, String name) { 822 return provisionPwmOutputPin(defaultProvider, pin, name); 823 } 824 825 @Override 826 public GpioPinPwmOutput provisionPwmOutputPin(Pin pin) { 827 return provisionPwmOutputPin(defaultProvider, pin); 828 } 829 830 @Override 831 public GpioPinPwmOutput provisionPwmOutputPin(GpioProvider provider, Pin pin, int defaultValue) { 832 return provisionPwmOutputPin(provider, pin, pin.getName(), defaultValue); 833 } 834 835 @Override 836 public GpioPinPwmOutput provisionPwmOutputPin(GpioProvider provider, Pin pin, String name, int defaultValue) { 837 // create new GPIO pin instance 838 GpioPinPwmOutput gpioPin = provisionPwmOutputPin(provider, pin, name); 839 840 // apply default value 841 gpioPin.setPwm(defaultValue); 842 843 // return new new pin instance 844 return gpioPin; 845 } 846 847 @Override 848 public GpioPinPwmOutput provisionPwmOutputPin(Pin pin, String name, int defaultValue) { 849 return provisionPwmOutputPin(defaultProvider, pin, name, defaultValue); 850 } 851 852 @Override 853 public GpioPinPwmOutput provisionPwmOutputPin(Pin pin, int defaultValue) { 854 return provisionPwmOutputPin(defaultProvider, pin, defaultValue); 855 } 856 857 @Override 858 public GpioPinPwmOutput provisionSoftPwmOutputPin(GpioProvider provider, Pin pin, String name) { 859 // return new new pin instance 860 return (GpioPinPwmOutput)provisionPin(provider, pin, name, PinMode.SOFT_PWM_OUTPUT); 861 } 862 863 @Override 864 public GpioPinPwmOutput provisionSoftPwmOutputPin(GpioProvider provider, Pin pin) { 865 // return new new pin instance 866 return (GpioPinPwmOutput)provisionPin(provider, pin, PinMode.SOFT_PWM_OUTPUT); 867 } 868 869 @Override 870 public GpioPinPwmOutput provisionSoftPwmOutputPin(Pin pin, String name) { 871 return provisionSoftPwmOutputPin(defaultProvider, pin, name); 872 } 873 874 @Override 875 public GpioPinPwmOutput provisionSoftPwmOutputPin(Pin pin) { 876 return provisionSoftPwmOutputPin(defaultProvider, pin); 877 } 878 879 @Override 880 public GpioPinPwmOutput provisionSoftPwmOutputPin(GpioProvider provider, Pin pin, int defaultValue) { 881 return provisionSoftPwmOutputPin(provider, pin, pin.getName(), defaultValue); 882 } 883 884 @Override 885 public GpioPinPwmOutput provisionSoftPwmOutputPin(GpioProvider provider, Pin pin, String name, int defaultValue) { 886 // create new GPIO pin instance 887 GpioPinPwmOutput gpioPin = provisionSoftPwmOutputPin(provider, pin, name); 888 889 // apply default value 890 gpioPin.setPwm(defaultValue); 891 892 // return new new pin instance 893 return gpioPin; 894 } 895 896 @Override 897 public GpioPinPwmOutput provisionSoftPwmOutputPin(Pin pin, String name, int defaultValue) { 898 return provisionSoftPwmOutputPin(defaultProvider, pin, name, defaultValue); 899 } 900 901 @Override 902 public GpioPinPwmOutput provisionSoftPwmOutputPin(Pin pin, int defaultValue) { 903 return provisionSoftPwmOutputPin(defaultProvider, pin, defaultValue); 904 } 905 906 @Override 907 public void unprovisionPin(GpioPin... pin) { 908 if (pin == null || pin.length == 0) { 909 throw new IllegalArgumentException("Missing pin argument."); 910 } 911 for (int index = (pin.length-1); index >= 0; index--) { 912 GpioPin p = pin[index]; 913 914 // ensure the requested pin has been provisioned 915 if (!pins.contains(p)) { 916 throw new GpioPinNotProvisionedException(p.getPin()); 917 } 918 // remove all listeners and triggers 919 if (p instanceof GpioPinInput) { 920 ((GpioPinInput)p).removeAllListeners(); 921 ((GpioPinInput)p).removeAllTriggers(); 922 } 923 924 // remove this pin instance from the managed collection 925 pins.remove(p); 926 } 927 } 928 929 public void setShutdownOptions(GpioPinShutdown options, GpioPin... pin) { 930 for (GpioPin p : pin) { 931 if (!pins.contains(p)) { 932 throw new GpioPinNotProvisionedException(p.getPin()); 933 } 934 p.setShutdownOptions(options); 935 } 936 } 937 938 public void setShutdownOptions(Boolean unexport, GpioPin... pin) { 939 for (GpioPin p : pin) { 940 if (!pins.contains(p)) { 941 throw new GpioPinNotProvisionedException(p.getPin()); 942 } 943 p.setShutdownOptions(unexport); 944 } 945 } 946 947 public void setShutdownOptions(Boolean unexport, PinState state, GpioPin... pin) { 948 for (GpioPin p : pin) { 949 if (!pins.contains(p)) { 950 throw new GpioPinNotProvisionedException(p.getPin()); 951 } 952 p.setShutdownOptions(unexport, state); 953 } 954 } 955 956 public void setShutdownOptions(Boolean unexport, PinState state, PinPullResistance resistance, GpioPin... pin) { 957 for (GpioPin p : pin) { 958 if (!pins.contains(p)) { 959 throw new GpioPinNotProvisionedException(p.getPin()); 960 } 961 p.setShutdownOptions(unexport, state, resistance); 962 } 963 } 964 965 public void setShutdownOptions(Boolean unexport, PinState state, PinPullResistance resistance, PinMode mode, GpioPin... pin) { 966 for (GpioPin p : pin) { 967 if (!pins.contains(p)) { 968 throw new GpioPinNotProvisionedException(p.getPin()); 969 } 970 p.setShutdownOptions(unexport, state, resistance, mode); 971 } 972 } 973 974 975 /** 976 * This class is used to perform any configured shutdown actions 977 * on the provisioned GPIO pins 978 * 979 * @author Robert Savage 980 * 981 */ 982 private class ShutdownHook extends Thread { 983 public void run() { 984 // perform shutdown 985 shutdown(); 986 } 987 } 988 989 /** 990 * This method returns TRUE if the GPIO controller has been shutdown. 991 * 992 * @return shutdown state 993 */ 994 @Override 995 public boolean isShutdown(){ 996 return isshutdown; 997 } 998 999 1000 /** 1001 * This method can be called to forcefully shutdown all GPIO controller 1002 * monitoring, listening, and task threads/executors. 1003 */ 1004 @Override 1005 public synchronized void shutdown() 1006 { 1007 // prevent reentrant invocation 1008 if(isShutdown()) 1009 return; 1010 1011 // shutdown all executor services 1012 // 1013 // NOTE: we are not permitted to access the shutdown() method of the individual 1014 // executor services, we must perform the shutdown with the factory 1015 GpioFactory.getExecutorServiceFactory().shutdown(); 1016 1017 // shutdown explicit configured GPIO pins 1018 for (GpioPin pin : pins) { 1019 1020 // perform a shutdown on the GPIO provider for this pin 1021 if(!pin.getProvider().isShutdown()){ 1022 pin.getProvider().shutdown(); 1023 } 1024 1025 // perform the shutdown options if configured for the pin 1026 GpioPinShutdown shutdownOptions = pin.getShutdownOptions(); 1027 if (shutdownOptions != null) { 1028 // get shutdown option configuration 1029 PinState state = shutdownOptions.getState(); 1030 PinMode mode = shutdownOptions.getMode(); 1031 PinPullResistance resistance = shutdownOptions.getPullResistor(); 1032 Boolean unexport = shutdownOptions.getUnexport(); 1033 1034 // perform shutdown actions 1035 if ((state != null) && pin.isMode(PinMode.DIGITAL_OUTPUT)) { 1036 ((GpioPinDigitalOutput)pin).setState(state); 1037 } 1038 if (resistance != null) { 1039 pin.setPullResistance(resistance); 1040 } 1041 if (mode != null) { 1042 pin.setMode(mode); 1043 } 1044 if (unexport != null && unexport == Boolean.TRUE) { 1045 pin.unexport(); 1046 } 1047 } 1048 } 1049 1050 // set is shutdown tracking variable 1051 isshutdown = true; 1052 } 1053}