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