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