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