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 - 2021 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 GpioPin gpioPin; 545 546 // if the provider does not match the pin's provider then throw an error 547 if (!Objects.equals(provider.getName(), pin.getProvider())) { 548 throw new PinProviderException(provider, pin); 549 } 550 551 synchronized(this) { 552 // if an existing pin has been previously created, then throw an error 553 for (GpioPin p : pins) { 554 if (Objects.equals(p.getProvider(), provider) && Objects.equals(p.getPin(), pin)) { 555 throw new GpioPinExistsException(pin); 556 } 557 } 558 559 // create new GPIO pin instance 560 gpioPin = new GpioPinImpl(this, provider, pin); 561 562 // set the gpio pin name 563 if (name != null) { 564 gpioPin.setName(name); 565 } 566 567 // export this pin 568 gpioPin.export(mode, defaultState); 569 570 // add this new pin instance to the managed collection 571 pins.add(gpioPin); 572 } 573 574 // return new new pin instance 575 return gpioPin; 576 } 577 578 @Override 579 public GpioPin provisionPin(Pin pin, String name, PinMode mode) { 580 return provisionPin(defaultProvider, pin, name, mode); 581 } 582 583 @Override 584 public GpioPin provisionPin(Pin pin, PinMode mode) { 585 return provisionPin(defaultProvider, pin, mode); 586 } 587 588 @Override 589 public GpioPinDigitalMultipurpose provisionDigitalMultipurposePin(GpioProvider provider, Pin pin, String name, PinMode mode) { 590 // return new new pin instance 591 return (GpioPinDigitalMultipurpose)provisionPin(provider, pin, name, mode); 592 } 593 594 @Override 595 public GpioPinDigitalMultipurpose provisionDigitalMultipurposePin(GpioProvider provider, Pin pin, PinMode mode) { 596 // return new new pin instance 597 return (GpioPinDigitalMultipurpose)provisionPin(provider, pin, mode); 598 } 599 600 @Override 601 public GpioPinDigitalMultipurpose provisionDigitalMultipurposePin(Pin pin, String name, PinMode mode) { 602 return provisionDigitalMultipurposePin(defaultProvider, pin, name, mode); 603 } 604 605 @Override 606 public GpioPinDigitalMultipurpose provisionDigitalMultipurposePin(Pin pin, PinMode mode) { 607 return provisionDigitalMultipurposePin(defaultProvider, pin, mode); 608 } 609 610 @Override 611 public GpioPinDigitalMultipurpose provisionDigitalMultipurposePin(GpioProvider provider, Pin pin, PinMode mode, PinPullResistance resistance) { 612 // create new GPIO pin instance 613 return provisionDigitalMultipurposePin(provider, pin, pin.getName(), mode, resistance); 614 } 615 616 @Override 617 public GpioPinDigitalMultipurpose provisionDigitalMultipurposePin(GpioProvider provider, Pin pin, String name, PinMode mode, PinPullResistance resistance) { 618 // create new GPIO pin instance 619 GpioPinDigitalMultipurpose gpioPin = provisionDigitalMultipurposePin(provider, pin, name, mode); 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 GpioPinDigitalMultipurpose provisionDigitalMultipurposePin(Pin pin, String name, PinMode mode, PinPullResistance resistance) { 631 return provisionDigitalMultipurposePin(defaultProvider, pin, name, mode, resistance); 632 } 633 634 @Override 635 public GpioPinDigitalMultipurpose provisionDigitalMultipurposePin(Pin pin, PinMode mode, PinPullResistance resistance) { 636 return provisionDigitalMultipurposePin(defaultProvider, pin, mode, resistance); 637 } 638 639 640 @Override 641 public GpioPinDigitalInput provisionDigitalInputPin(GpioProvider provider, Pin pin, String name) { 642 // return new new pin instance 643 return (GpioPinDigitalInput)provisionPin(provider, pin, name, PinMode.DIGITAL_INPUT); 644 } 645 646 @Override 647 public GpioPinDigitalInput provisionDigitalInputPin(GpioProvider provider, Pin pin) { 648 // return new new pin instance 649 return (GpioPinDigitalInput)provisionPin(provider, pin, PinMode.DIGITAL_INPUT); 650 } 651 652 @Override 653 public GpioPinDigitalInput provisionDigitalInputPin(Pin pin, String name) { 654 return provisionDigitalInputPin(defaultProvider, pin, name); 655 } 656 657 @Override 658 public GpioPinDigitalInput provisionDigitalInputPin(Pin pin) { 659 return provisionDigitalInputPin(defaultProvider, pin); 660 } 661 662 @Override 663 public GpioPinDigitalInput provisionDigitalInputPin(GpioProvider provider, Pin pin, PinPullResistance resistance) { 664 // create new GPIO pin instance 665 return provisionDigitalInputPin(provider, pin, pin.getName(), resistance); 666 } 667 668 @Override 669 public GpioPinDigitalInput provisionDigitalInputPin(GpioProvider provider, Pin pin, String name, PinPullResistance resistance) { 670 // create new GPIO pin instance 671 GpioPinDigitalInput gpioPin = provisionDigitalInputPin(provider, pin, name); 672 673 // set the gpio pull resistor 674 if (resistance != null) { 675 gpioPin.setPullResistance(resistance); 676 } 677 // return new new pin instance 678 return gpioPin; 679 } 680 681 @Override 682 public GpioPinDigitalInput provisionDigitalInputPin(Pin pin, String name, PinPullResistance resistance) { 683 return provisionDigitalInputPin(defaultProvider, pin, name, resistance); 684 } 685 686 @Override 687 public GpioPinDigitalInput provisionDigitalInputPin(Pin pin, PinPullResistance resistance) { 688 return provisionDigitalInputPin(defaultProvider, pin, resistance); 689 } 690 691 @Override 692 public GpioPinDigitalOutput provisionDigitalOutputPin(GpioProvider provider, Pin pin, String name) { 693 // return new new pin instance 694 return (GpioPinDigitalOutput)provisionPin(provider, pin, name, PinMode.DIGITAL_OUTPUT); 695 } 696 697 @Override 698 public GpioPinDigitalOutput provisionDigitalOutputPin(GpioProvider provider, Pin pin) { 699 // return new new pin instance 700 return (GpioPinDigitalOutput)provisionPin(provider, pin, PinMode.DIGITAL_OUTPUT); 701 } 702 703 @Override 704 public GpioPinDigitalOutput provisionDigitalOutputPin(Pin pin, String name) { 705 return provisionDigitalOutputPin(defaultProvider, pin, name); 706 } 707 708 @Override 709 public GpioPinDigitalOutput provisionDigitalOutputPin(Pin pin) { 710 return provisionDigitalOutputPin(defaultProvider, pin); 711 } 712 713 @Override 714 public GpioPinDigitalOutput provisionDigitalOutputPin(GpioProvider provider, Pin pin, PinState defaultState) { 715 return provisionDigitalOutputPin(provider, pin, pin.getName(), defaultState); 716 } 717 718 @Override 719 public GpioPinDigitalOutput provisionDigitalOutputPin(GpioProvider provider, Pin pin, String name, PinState defaultState) { 720 // create new GPIO pin instance 721 GpioPinDigitalOutput gpioPin = (GpioPinDigitalOutput)provisionPin(provider, pin, name, PinMode.DIGITAL_OUTPUT, defaultState); 722 723 // apply default state 724 if (defaultState != null) { 725 gpioPin.setState(defaultState); 726 } 727 // return new new pin instance 728 return gpioPin; 729 } 730 731 @Override 732 public GpioPinDigitalOutput provisionDigitalOutputPin(Pin pin, String name, PinState defaultState) { 733 return provisionDigitalOutputPin(defaultProvider, pin, name, defaultState); 734 } 735 736 @Override 737 public GpioPinDigitalOutput provisionDigitalOutputPin(Pin pin, PinState defaultState) { 738 return provisionDigitalOutputPin(defaultProvider, pin, defaultState); 739 } 740 741 @Override 742 public GpioPinAnalogInput provisionAnalogInputPin(GpioProvider provider, Pin pin, String name) { 743 // return new new pin instance 744 return (GpioPinAnalogInput)provisionPin(provider, pin, name, PinMode.ANALOG_INPUT); 745 } 746 747 @Override 748 public GpioPinAnalogInput provisionAnalogInputPin(GpioProvider provider, Pin pin) { 749 // return new new pin instance 750 return (GpioPinAnalogInput)provisionPin(provider, pin, PinMode.ANALOG_INPUT); 751 } 752 753 @Override 754 public GpioPinAnalogInput provisionAnalogInputPin(Pin pin, String name) { 755 return provisionAnalogInputPin(defaultProvider, pin, name); 756 } 757 758 @Override 759 public GpioPinAnalogInput provisionAnalogInputPin(Pin pin) { 760 return provisionAnalogInputPin(defaultProvider, pin); 761 } 762 763 @Override 764 public GpioPinAnalogOutput provisionAnalogOutputPin(GpioProvider provider, Pin pin, String name) { 765 // return new new pin instance 766 return (GpioPinAnalogOutput)provisionPin(provider, pin, name, PinMode.ANALOG_OUTPUT); 767 } 768 769 @Override 770 public GpioPinAnalogOutput provisionAnalogOutputPin(GpioProvider provider, Pin pin) { 771 // return new new pin instance 772 return (GpioPinAnalogOutput)provisionPin(provider, pin, PinMode.ANALOG_OUTPUT); 773 } 774 775 @Override 776 public GpioPinAnalogOutput provisionAnalogOutputPin(Pin pin, String name) { 777 return provisionAnalogOutputPin(defaultProvider, pin, name); 778 } 779 780 @Override 781 public GpioPinAnalogOutput provisionAnalogOutputPin(Pin pin) { 782 return provisionAnalogOutputPin(defaultProvider, pin); 783 } 784 785 @Override 786 public GpioPinAnalogOutput provisionAnalogOutputPin(GpioProvider provider, Pin pin, double defaultValue) { 787 return provisionAnalogOutputPin(provider, pin, pin.getName(), defaultValue); 788 } 789 790 @Override 791 public GpioPinAnalogOutput provisionAnalogOutputPin(GpioProvider provider, Pin pin, String name, double defaultValue) { 792 // create new GPIO pin instance 793 GpioPinAnalogOutput gpioPin = provisionAnalogOutputPin(provider, pin, name); 794 795 // apply default value 796 gpioPin.setValue(defaultValue); 797 798 // return new new pin instance 799 return gpioPin; 800 } 801 802 @Override 803 public GpioPinAnalogOutput provisionAnalogOutputPin(Pin pin, String name, double defaultValue) { 804 return provisionAnalogOutputPin(defaultProvider, pin, name, defaultValue); 805 } 806 807 @Override 808 public GpioPinAnalogOutput provisionAnalogOutputPin(Pin pin, double defaultValue) { 809 return provisionAnalogOutputPin(defaultProvider, pin, defaultValue); 810 } 811 812 @Override 813 public GpioPinPwmOutput provisionPwmOutputPin(GpioProvider provider, Pin pin, String name) { 814 // return new new pin instance 815 return (GpioPinPwmOutput)provisionPin(provider, pin, name, PinMode.PWM_OUTPUT); 816 } 817 818 @Override 819 public GpioPinPwmOutput provisionPwmOutputPin(GpioProvider provider, Pin pin) { 820 // return new new pin instance 821 return (GpioPinPwmOutput)provisionPin(provider, pin, PinMode.PWM_OUTPUT); 822 } 823 824 @Override 825 public GpioPinPwmOutput provisionPwmOutputPin(Pin pin, String name) { 826 return provisionPwmOutputPin(defaultProvider, pin, name); 827 } 828 829 @Override 830 public GpioPinPwmOutput provisionPwmOutputPin(Pin pin) { 831 return provisionPwmOutputPin(defaultProvider, pin); 832 } 833 834 @Override 835 public GpioPinPwmOutput provisionPwmOutputPin(GpioProvider provider, Pin pin, int defaultValue) { 836 return provisionPwmOutputPin(provider, pin, pin.getName(), defaultValue); 837 } 838 839 @Override 840 public GpioPinPwmOutput provisionPwmOutputPin(GpioProvider provider, Pin pin, String name, int defaultValue) { 841 // create new GPIO pin instance 842 GpioPinPwmOutput gpioPin = provisionPwmOutputPin(provider, pin, name); 843 844 // apply default value 845 gpioPin.setPwm(defaultValue); 846 847 // return new new pin instance 848 return gpioPin; 849 } 850 851 @Override 852 public GpioPinPwmOutput provisionPwmOutputPin(Pin pin, String name, int defaultValue) { 853 return provisionPwmOutputPin(defaultProvider, pin, name, defaultValue); 854 } 855 856 @Override 857 public GpioPinPwmOutput provisionPwmOutputPin(Pin pin, int defaultValue) { 858 return provisionPwmOutputPin(defaultProvider, pin, defaultValue); 859 } 860 861 @Override 862 public GpioPinPwmOutput provisionSoftPwmOutputPin(GpioProvider provider, Pin pin, String name) { 863 // return new new pin instance 864 return (GpioPinPwmOutput)provisionPin(provider, pin, name, PinMode.SOFT_PWM_OUTPUT); 865 } 866 867 @Override 868 public GpioPinPwmOutput provisionSoftPwmOutputPin(GpioProvider provider, Pin pin) { 869 // return new new pin instance 870 return (GpioPinPwmOutput)provisionPin(provider, pin, PinMode.SOFT_PWM_OUTPUT); 871 } 872 873 @Override 874 public GpioPinPwmOutput provisionSoftPwmOutputPin(Pin pin, String name) { 875 return provisionSoftPwmOutputPin(defaultProvider, pin, name); 876 } 877 878 @Override 879 public GpioPinPwmOutput provisionSoftPwmOutputPin(Pin pin) { 880 return provisionSoftPwmOutputPin(defaultProvider, pin); 881 } 882 883 @Override 884 public GpioPinPwmOutput provisionSoftPwmOutputPin(GpioProvider provider, Pin pin, int defaultValue) { 885 return provisionSoftPwmOutputPin(provider, pin, pin.getName(), defaultValue); 886 } 887 888 @Override 889 public GpioPinPwmOutput provisionSoftPwmOutputPin(GpioProvider provider, Pin pin, String name, int defaultValue) { 890 // create new GPIO pin instance 891 GpioPinPwmOutput gpioPin = provisionSoftPwmOutputPin(provider, pin, name); 892 893 // apply default value 894 gpioPin.setPwm(defaultValue); 895 896 // return new new pin instance 897 return gpioPin; 898 } 899 900 @Override 901 public GpioPinPwmOutput provisionSoftPwmOutputPin(Pin pin, String name, int defaultValue) { 902 return provisionSoftPwmOutputPin(defaultProvider, pin, name, defaultValue); 903 } 904 905 @Override 906 public GpioPinPwmOutput provisionSoftPwmOutputPin(Pin pin, int defaultValue) { 907 return provisionSoftPwmOutputPin(defaultProvider, pin, defaultValue); 908 } 909 910 @Override 911 public void unprovisionPin(GpioPin... pin) { 912 if (pin == null || pin.length == 0) { 913 throw new IllegalArgumentException("Missing pin argument."); 914 } 915 for (int index = (pin.length-1); index >= 0; index--) { 916 GpioPin p = pin[index]; 917 918 // ensure the requested pin has been provisioned 919 if (!pins.contains(p)) { 920 throw new GpioPinNotProvisionedException(p.getPin()); 921 } 922 923 synchronized (this) { 924 // remove all listeners and triggers 925 if (p instanceof GpioPinInput) { 926 ((GpioPinInput) p).removeAllListeners(); 927 ((GpioPinInput) p).removeAllTriggers(); 928 } 929 930 // remove this pin instance from the managed collection 931 pins.remove(p); 932 } 933 } 934 } 935 936 public void setShutdownOptions(GpioPinShutdown options, GpioPin... pin) { 937 for (GpioPin p : pin) { 938 if (!pins.contains(p)) { 939 throw new GpioPinNotProvisionedException(p.getPin()); 940 } 941 p.setShutdownOptions(options); 942 } 943 } 944 945 public void setShutdownOptions(Boolean unexport, GpioPin... pin) { 946 for (GpioPin p : pin) { 947 if (!pins.contains(p)) { 948 throw new GpioPinNotProvisionedException(p.getPin()); 949 } 950 p.setShutdownOptions(unexport); 951 } 952 } 953 954 public void setShutdownOptions(Boolean unexport, PinState state, GpioPin... pin) { 955 for (GpioPin p : pin) { 956 if (!pins.contains(p)) { 957 throw new GpioPinNotProvisionedException(p.getPin()); 958 } 959 p.setShutdownOptions(unexport, state); 960 } 961 } 962 963 public void setShutdownOptions(Boolean unexport, PinState state, PinPullResistance resistance, GpioPin... pin) { 964 for (GpioPin p : pin) { 965 if (!pins.contains(p)) { 966 throw new GpioPinNotProvisionedException(p.getPin()); 967 } 968 p.setShutdownOptions(unexport, state, resistance); 969 } 970 } 971 972 public void setShutdownOptions(Boolean unexport, PinState state, PinPullResistance resistance, PinMode mode, GpioPin... pin) { 973 for (GpioPin p : pin) { 974 if (!pins.contains(p)) { 975 throw new GpioPinNotProvisionedException(p.getPin()); 976 } 977 p.setShutdownOptions(unexport, state, resistance, mode); 978 } 979 } 980 981 982 /** 983 * This class is used to perform any configured shutdown actions 984 * on the provisioned GPIO pins 985 * 986 * @author Robert Savage 987 * 988 */ 989 private class ShutdownHook extends Thread { 990 public void run() { 991 // perform shutdown 992 shutdown(); 993 } 994 } 995 996 /** 997 * This method returns TRUE if the GPIO controller has been shutdown. 998 * 999 * @return shutdown state 1000 */ 1001 @Override 1002 public boolean isShutdown(){ 1003 return isshutdown; 1004 } 1005 1006 1007 /** 1008 * This method can be called to forcefully shutdown all GPIO controller 1009 * monitoring, listening, and task threads/executors. 1010 */ 1011 @Override 1012 public synchronized void shutdown() 1013 { 1014 // prevent reentrant invocation 1015 if(isShutdown()) 1016 return; 1017 1018 // create a temporary set of providers to shutdown after completing all the pin instance shutdowns 1019 Set<GpioProvider> gpioProvidersToShutdown = new HashSet<>(); 1020 1021 // shutdown explicit configured GPIO pins 1022 for (GpioPin pin : pins) { 1023 1024 // add each GPIO provider to the shutdown set 1025 if(!gpioProvidersToShutdown.contains(pin.getProvider())){ 1026 gpioProvidersToShutdown.add(pin.getProvider()); 1027 } 1028 1029 // perform the shutdown options if configured for the pin 1030 GpioPinShutdown shutdownOptions = pin.getShutdownOptions(); 1031 if (shutdownOptions != null) { 1032 // get shutdown option configuration 1033 PinState state = shutdownOptions.getState(); 1034 PinMode mode = shutdownOptions.getMode(); 1035 PinPullResistance resistance = shutdownOptions.getPullResistor(); 1036 Boolean unexport = shutdownOptions.getUnexport(); 1037 1038 // perform shutdown actions 1039 if ((state != null) && pin.isMode(PinMode.DIGITAL_OUTPUT)) { 1040 ((GpioPinDigitalOutput)pin).setState(state); 1041 } 1042 if (resistance != null) { 1043 pin.setPullResistance(resistance); 1044 } 1045 if (mode != null) { 1046 pin.setMode(mode); 1047 } 1048 if (unexport != null && unexport == Boolean.TRUE) { 1049 pin.unexport(); 1050 } 1051 } 1052 } 1053 1054 // perform a shutdown on each GPIO provider 1055 for(GpioProvider gpioProvider : gpioProvidersToShutdown){ 1056 if(!gpioProvider.isShutdown()){ 1057 gpioProvider.shutdown(); 1058 } 1059 } 1060 1061 // shutdown all executor services 1062 // 1063 // NOTE: we are not permitted to access the shutdown() method of the individual 1064 // executor services, we must perform the shutdown with the factory 1065 GpioFactory.getExecutorServiceFactory().shutdown(); 1066 1067 // set is shutdown tracking variable 1068 isshutdown = true; 1069 } 1070}