cleaned up gpio and device code, implemented dummy/dry run mode
This commit is contained in:
		
							
								
								
									
										4
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							@@ -15,7 +15,7 @@
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "http://satis.noccylabs.info/packages/php-crap.git",
 | 
			
		||||
                "reference": "33d3929fb5fab4056ea9993b8d148aa3ba44e4c3"
 | 
			
		||||
                "reference": "aede74280244c61564d648139f5fa2318834471e"
 | 
			
		||||
            },
 | 
			
		||||
            "type": "library",
 | 
			
		||||
            "extra": {
 | 
			
		||||
@@ -38,7 +38,7 @@
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "description": "Crap is an exception/error/assertion handling library",
 | 
			
		||||
            "time": "2014-06-14 01:11:31"
 | 
			
		||||
            "time": "2014-06-18 19:21:45"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "noccylabs/sansi",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								examples/pcd8544.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								examples/pcd8544.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
require_once __DIR__."/../vendor/autoload.php";
 | 
			
		||||
 | 
			
		||||
NoccyLabs\Crap\Crap::activate();
 | 
			
		||||
 | 
			
		||||
use NoccyLabs\Gpio\Gpio;
 | 
			
		||||
use NoccyLabs\Gpio\Device\Display\Pcd8544Device;
 | 
			
		||||
 | 
			
		||||
$gpio = new Gpio(true);
 | 
			
		||||
$lcd = new Pcd8544Device;
 | 
			
		||||
 | 
			
		||||
$lcd
 | 
			
		||||
    // we can rename devices as we like, to help in debugging
 | 
			
		||||
    ->setName("pcd8544_1")
 | 
			
		||||
    ->setPin("sda", $gpio[0])
 | 
			
		||||
    ->setPin("scl", $gpio[1])
 | 
			
		||||
    ->setPin("res", $gpio[2])
 | 
			
		||||
    ->setPin("sce", $gpio[3])
 | 
			
		||||
    ->setPin("dc",  $gpio[4])
 | 
			
		||||
    ->initialize()
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -18,16 +18,22 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace NoccyLabs\Gpio\Device;
 | 
			
		||||
use NoccyLabs\Gpio\GpioPin;
 | 
			
		||||
 | 
			
		||||
abstract class Device implements GpioAwareInterface
 | 
			
		||||
abstract class Device
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    protected $name;
 | 
			
		||||
 | 
			
		||||
    protected $gpio;
 | 
			
		||||
    protected $description;
 | 
			
		||||
 | 
			
		||||
    protected $pins = array();
 | 
			
		||||
 | 
			
		||||
    public function __construct()
 | 
			
		||||
    {
 | 
			
		||||
        $this->configure();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function configure()
 | 
			
		||||
    {
 | 
			
		||||
        // call on ->addGpioPin etc here
 | 
			
		||||
@@ -44,39 +50,33 @@ abstract class Device implements GpioAwareInterface
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function setName($name)
 | 
			
		||||
    {}
 | 
			
		||||
    {
 | 
			
		||||
        $this->name = $name;
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function getName()
 | 
			
		||||
    {}
 | 
			
		||||
    {
 | 
			
		||||
        return $this->name;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function setDescription($description)
 | 
			
		||||
    {}
 | 
			
		||||
    {
 | 
			
		||||
        $this->description = $description;
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function getDescription()
 | 
			
		||||
    {}
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Allocate a GPIO (as defined in hardware) pin to the device.
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    public function addGpioPin($gpio, $name, $description=null)
 | 
			
		||||
    {
 | 
			
		||||
        $pin = new GpioPin($gpio);
 | 
			
		||||
        $pin->setLabel($description);
 | 
			
		||||
        $this->pins[$name] = $pin;
 | 
			
		||||
        return $this->description;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function addPin($name, $description=null)
 | 
			
		||||
    {
 | 
			
		||||
        $this->pins[$name] = null;
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Allocate a logical (wiring-pi 0-based pin number) pin to the device.
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    public function addLogicalPin($logical, $name, $description=null)
 | 
			
		||||
    {
 | 
			
		||||
        $pin = $this->gpio[$logical];
 | 
			
		||||
        $pin->setLabel($description);
 | 
			
		||||
        $this->pins[$name] = $pin;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Get all allocated pins
 | 
			
		||||
     *
 | 
			
		||||
@@ -94,20 +94,49 @@ abstract class Device implements GpioAwareInterface
 | 
			
		||||
    {
 | 
			
		||||
        return $this->pins[$name];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function setPin($pin_name, $pin)
 | 
			
		||||
    {
 | 
			
		||||
        if (array_key_exists($pin_name, $this->pins)) {
 | 
			
		||||
            $pin->setLabel($this->name.".".$pin_name);
 | 
			
		||||
            $this->pins[$pin_name] = $pin;
 | 
			
		||||
            return $this;
 | 
			
		||||
        }
 | 
			
		||||
        throw new \Exception();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a pin as a property from its name
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    protected function __get($pin_name)
 | 
			
		||||
    public function __get($pin_name)
 | 
			
		||||
    {
 | 
			
		||||
        return $this->getPin($pin_name);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function delayMillis($ms)
 | 
			
		||||
    {}
 | 
			
		||||
    public function __set($pin_name, GpioPin $pin)
 | 
			
		||||
    {
 | 
			
		||||
        $this->setPin($pin_name, $pin);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function delayMicros($us)
 | 
			
		||||
    {}
 | 
			
		||||
    protected function delayMillis($ms)
 | 
			
		||||
    {
 | 
			
		||||
        usleep($ms*1000);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    protected function delayMicros($us)
 | 
			
		||||
    {
 | 
			
		||||
        usleep($us);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    protected function shiftOut(GpioPin $pdata, GpioPin $pclk, $byte)
 | 
			
		||||
    {
 | 
			
		||||
        for ($bit = 0; $bit < 8; $bit++) {
 | 
			
		||||
            $bval = 1<<$bit;
 | 
			
		||||
            $pclk->setValue(0);
 | 
			
		||||
            $pdata->setValue(($byte & $bval) == $bval);
 | 
			
		||||
            $pclk->setValue(1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -28,12 +28,12 @@ class Pcd8544Device extends Device
 | 
			
		||||
        $this
 | 
			
		||||
            ->setName("pcd8544")
 | 
			
		||||
            ->setDescription("Philips PCD8544 LCD Display Driver")
 | 
			
		||||
            ->addLogicalPin(0, "dc", "data/command")
 | 
			
		||||
            ->addLogicalPin(1, "sce", "chip select")
 | 
			
		||||
            ->addLogicalPin(2, "scl", "clock")
 | 
			
		||||
            ->addLogicalPin(3, "sda", "data")
 | 
			
		||||
            ->addLogicalPin(4, "res", "reset")
 | 
			
		||||
            ->addLogicalPin(9, "bl", "backlight")
 | 
			
		||||
            ->addPin("dc", "data/command")
 | 
			
		||||
            ->addPin("sce", "chip select")
 | 
			
		||||
            ->addPin("scl", "clock")
 | 
			
		||||
            ->addPin("sda", "data")
 | 
			
		||||
            ->addPin("res", "reset")
 | 
			
		||||
            ->addPin("bl", "backlight")
 | 
			
		||||
            ;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
@@ -46,4 +46,70 @@ class Pcd8544Device extends Device
 | 
			
		||||
    {
 | 
			
		||||
        $this->bl->setValue((bool)$state);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function initialize()
 | 
			
		||||
    {
 | 
			
		||||
        $this->lcdInit();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function lcdSend($byte, $command=false)
 | 
			
		||||
    {
 | 
			
		||||
        // assume clk is hi
 | 
			
		||||
        // Enable display controller (active low).
 | 
			
		||||
        $this->sce->setValue(0);
 | 
			
		||||
 | 
			
		||||
        $this->dc->setValue((int)$command); // command or data
 | 
			
		||||
 | 
			
		||||
        $this->shiftOut($this->sda, $this->scl, $byte);
 | 
			
		||||
 | 
			
		||||
        // Disable display controller.
 | 
			
		||||
        $this->sce->setValue(1);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
        if (!$command) {
 | 
			
		||||
	        $this->cx++;
 | 
			
		||||
	        if ($this->cx > (LCD_X_RES - 1)) {
 | 
			
		||||
		        cx = 0; cy++;
 | 
			
		||||
		        #ifdef PCD8544_FIX_YALIGN
 | 
			
		||||
		        // Soft wrapping when FIX_YALIGN is defined
 | 
			
		||||
		        lcd_cursor(cx,cy);
 | 
			
		||||
		        #endif
 | 
			
		||||
	        }
 | 
			
		||||
        }
 | 
			
		||||
*/       
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function lcdInit()
 | 
			
		||||
    {
 | 
			
		||||
        $this->sce->setDirection("out");
 | 
			
		||||
        $this->res->setDirection("out");
 | 
			
		||||
        $this->dc->setDirection("out");
 | 
			
		||||
        $this->scl->setDirection("out");
 | 
			
		||||
        $this->sda->setDirection("out");
 | 
			
		||||
        
 | 
			
		||||
        $this->res->setValue(1); // set RES
 | 
			
		||||
        $this->sce->setValue(0); // reset SCE
 | 
			
		||||
        $this->res->setValue(0); // pull RES low
 | 
			
		||||
        $this->res->setValue(0); // and back hick
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // Send sequence of command
 | 
			
		||||
        $this->lcdSend( 0x21, true );  // LCD Extended Commands.
 | 
			
		||||
        // lcd_send( 0xC8, true );  // Set LCD Vop (Contrast).
 | 
			
		||||
        $this->lcdSend( 0x80 | 0x70, true );  // Set LCD Vop (Contrast).
 | 
			
		||||
        $this->lcdSend( 0x06, true );  // Set Temp coefficent to 2.
 | 
			
		||||
        $this->lcdSend( 0x13, true );  // LCD bias mode 1:100.
 | 
			
		||||
        #ifdef PCD8544_FIX_YALIGN
 | 
			
		||||
        $this->lcdSend( 0x45, true );  // LCD blank - Shift LCD 5 up (row starts at 1)
 | 
			
		||||
        #endif
 | 
			
		||||
        $this->lcdSend( 0x20, true );  // LCD Standard Commands, Horizontal addressing mode.
 | 
			
		||||
        $this->lcdSend( 0x40, true );  // LCD blank
 | 
			
		||||
        $this->lcdSend( 0x08, true );  // LCD blank
 | 
			
		||||
        $this->lcdSend( 0x0C, true );  // LCD in inverse mode.
 | 
			
		||||
 | 
			
		||||
        //$this->lcdClear();
 | 
			
		||||
    
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										209
									
								
								lib/DummyGpioPin.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								lib/DummyGpioPin.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,209 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2014, NoccyLabs
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace NoccyLabs\Gpio;
 | 
			
		||||
 | 
			
		||||
use NoccyLabs\Gpio\Exception\HardwareException;
 | 
			
		||||
 | 
			
		||||
use NoccyLabs\Sansi\Charset as CS;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * GPIO pin implementation. This class wraps all interaction with a GPIO pin,
 | 
			
		||||
 * thus decoupling it from the main Gpio class.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class DummyGpioPin extends GpioPin
 | 
			
		||||
{
 | 
			
		||||
    public function getPin()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->pin;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private function findHardware()
 | 
			
		||||
    {
 | 
			
		||||
   		return "dummy";
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function __destruct()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function setDirection($direction)
 | 
			
		||||
    {
 | 
			
		||||
        if (!in_array($direction, array("in", "out"))) {
 | 
			
		||||
            throw new \Exception;
 | 
			
		||||
        }
 | 
			
		||||
        $this->direction = $direction;
 | 
			
		||||
        $this->sysfsWrite($this->pin, "direction", $direction);
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function getDirection()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->sysfsRead($this->pin, "direction");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function setValue($value)
 | 
			
		||||
    {
 | 
			
		||||
        $this->value = (bool)$value;
 | 
			
		||||
        $this->sysfsWrite("{$this->pin}", "value", (int)$this->value);
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function getValue()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->sysfsRead($this->pin, "value");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set a descriptive label for the pin, used for debugging and troubleshooting.
 | 
			
		||||
     *
 | 
			
		||||
     * @param string $label
 | 
			
		||||
     * @return NoccyLabs\Gpio\GpioPin 
 | 
			
		||||
     */    
 | 
			
		||||
    public function setLabel($label)
 | 
			
		||||
    {
 | 
			
		||||
        $this->label = (string)$label;
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the assigned label for this pin.
 | 
			
		||||
     *
 | 
			
		||||
     * @return string The label
 | 
			
		||||
     */    
 | 
			
		||||
    public function getLabel()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->label;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function export()
 | 
			
		||||
    {
 | 
			
		||||
        if (file_exists("/sys/class/gpio/gpio{$this->pin}")) {
 | 
			
		||||
        	return $this;
 | 
			
		||||
        }
 | 
			
		||||
        $this->sysfsWrite(null, "export", $this->pin);
 | 
			
		||||
        if (!file_exists("/sys/class/gpio/gpio{$this->pin}")) {
 | 
			
		||||
            throw new HardwareException("Unable to export pin {$this->pin}");
 | 
			
		||||
        }
 | 
			
		||||
        $this->hardware = $this->findHardware();
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function unexport()
 | 
			
		||||
    {
 | 
			
		||||
    	$this->sysfsWrite(null, "unexport", $this->pin);
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function sysfsWrite($pin, $file, $value)
 | 
			
		||||
    {
 | 
			
		||||
        if ($pin!==null) {
 | 
			
		||||
            $path = "/sys/class/gpio/gpio{$pin}/{$file}";
 | 
			
		||||
        } else {
 | 
			
		||||
            $path = "/sys/class/gpio/{$file}";
 | 
			
		||||
        }
 | 
			
		||||
        printf("%16.4f  \e[32;1m%-5s\e[0m  \e[1m%-15s\e[0m (\e[33m%s\e[0m) => \e[36;1m%-10s\e[0m \n",
 | 
			
		||||
            microtime(true),
 | 
			
		||||
            "write",
 | 
			
		||||
            $this->label,
 | 
			
		||||
            $file,
 | 
			
		||||
            $value
 | 
			
		||||
            );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function sysfsRead($pin, $file)
 | 
			
		||||
    {
 | 
			
		||||
        $path = "/sys/class/gpio/gpio{$pin}/{$file}";
 | 
			
		||||
        printf("%16.4f  \e[31;1m%-5s\e[0m  \e[1m%-15s\e[0m (\e[33m%s\e[0m)\n",
 | 
			
		||||
            microtime(true),
 | 
			
		||||
            "read",
 | 
			
		||||
            $this->label,
 | 
			
		||||
            $file
 | 
			
		||||
            );
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function setEdge($edge)
 | 
			
		||||
    {
 | 
			
		||||
        if (!in_array($edge, array("rising", "falling", "both", "none"))) {
 | 
			
		||||
            throw new \Exception;
 | 
			
		||||
        }
 | 
			
		||||
        $this->edge = $edge;
 | 
			
		||||
        $this->sysfsWrite($this->pin, "edge", $edge);
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function getEdge()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->sysfsRead($this->pin, "edge");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function setHandler(callable $handler=null)
 | 
			
		||||
    {
 | 
			
		||||
        $this->gpio->setInterruptHandler($this->pin, $this->fd);
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function doInterrupt()
 | 
			
		||||
    {
 | 
			
		||||
        fseek($this->fd,0,SEEK_SET);
 | 
			
		||||
        $val = fgets($this->fd);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function dumpStatus($ansi=false)
 | 
			
		||||
    {
 | 
			
		||||
        if ($ansi) {
 | 
			
		||||
            $status = "\e[44;37;1m          GPIO{$this->pin}          \e[0m\n";
 | 
			
		||||
            $direction = 
 | 
			
		||||
                ($this->direction=="input"?(CS::chr(0x2190)):(CS::chr(0x2192))).
 | 
			
		||||
                " ".$this->direction;
 | 
			
		||||
            $edge = $this->edge; //"";
 | 
			
		||||
            /*if ($this->edge == "rising") {
 | 
			
		||||
                $edge.= CS::chr(0x21A5)." rising";
 | 
			
		||||
            } elseif ($this->edge == "falling") {
 | 
			
		||||
                $edge.= CS::chr(0x21A7)." falling";
 | 
			
		||||
            } else {
 | 
			
		||||
                $edge.= "\e[0m".$this->edge;
 | 
			
		||||
            }*/
 | 
			
		||||
        } else {
 | 
			
		||||
            $status = "********** GPIO{$this->pin} **********\n";
 | 
			
		||||
            $direction = $this->direction;
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
        foreach(array(    
 | 
			
		||||
            "Direction" => $this->getDirection(),
 | 
			
		||||
            "Value" => ($this->getValue()?1:0),
 | 
			
		||||
            "Edge" => $this->getEdge(),
 | 
			
		||||
            "Label" => $this->label,
 | 
			
		||||
            "Hardware" => $this->hardware,
 | 
			
		||||
            "Int count" => 0
 | 
			
		||||
        ) as $k=>$v) {
 | 
			
		||||
            if ($ansi) {
 | 
			
		||||
                $status.= sprintf("  \e[32;1m%10s\e[0m: \e[0m%s\e[0m\n", $k, $v);
 | 
			
		||||
            } else {
 | 
			
		||||
                $status.= sprintf("  %-10s: %s\n", $k, $v);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        error_log($status);
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
   
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								lib/Gpio.php
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								lib/Gpio.php
									
									
									
									
									
								
							@@ -40,9 +40,11 @@ class Gpio implements \ArrayAccess
 | 
			
		||||
    /** @var NoccyLabs\Gpio\GpioMapperInterface */
 | 
			
		||||
    protected $mapper;
 | 
			
		||||
    
 | 
			
		||||
    public function __construct($force=false)
 | 
			
		||||
    protected $dummy;
 | 
			
		||||
    
 | 
			
		||||
    public function __construct($dummy=false)
 | 
			
		||||
    {
 | 
			
		||||
        if (!$force) {
 | 
			
		||||
        if (!$dummy) {
 | 
			
		||||
            if (!file_exists("/sys/class/gpio")) {
 | 
			
		||||
                throw new HardwareException("gpio sysfs is not available");
 | 
			
		||||
            }
 | 
			
		||||
@@ -50,44 +52,7 @@ class Gpio implements \ArrayAccess
 | 
			
		||||
                throw new HardwareException("gpio sysfs is not writable");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function refresh()
 | 
			
		||||
    {
 | 
			
		||||
        $read = $this->fd_gpio;
 | 
			
		||||
        $write = array();
 | 
			
		||||
        $except = $read;
 | 
			
		||||
        if (count($read)>0) {
 | 
			
		||||
            stream_select($read, $write, $except, 0);
 | 
			
		||||
            foreach($except as $fd) {
 | 
			
		||||
                $pin = $this->getPinFromFd($fd);
 | 
			
		||||
                $pin->doInterrupt();
 | 
			
		||||
            
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function getPinFromFd($fd)
 | 
			
		||||
    {
 | 
			
		||||
        foreach($this->fd_pins as $pinfd=>$pin) {
 | 
			
		||||
            if ($pinfd == $fd) { return $pin; }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    protected $fd_gpio = array();
 | 
			
		||||
    protected $fd_pins = array();
 | 
			
		||||
    
 | 
			
		||||
    public function enableInterrupt(GpioPin $pin, $fd)
 | 
			
		||||
    {
 | 
			
		||||
        $this->fd_gpio[] = $fd;
 | 
			
		||||
        
 | 
			
		||||
        $this->fd_pins[$fd] = $pin;
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function disableInterrupt(GpioPin $pin)
 | 
			
		||||
    {
 | 
			
		||||
        $this->dummy = $dummy;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function setMapper(GpioMapperInterface $mapper=null)
 | 
			
		||||
@@ -96,26 +61,59 @@ class Gpio implements \ArrayAccess
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a pin, optionally via previously specified mapper.
 | 
			
		||||
     *
 | 
			
		||||
     * @interface ArrayAccess
 | 
			
		||||
     * @param int
 | 
			
		||||
     */    
 | 
			
		||||
    public function offsetGet($index)
 | 
			
		||||
    {
 | 
			
		||||
        if ($this->mapper) { $index = $this->mapper->mapLogicalToGpioPin($index); }
 | 
			
		||||
        if ($this->mapper) {
 | 
			
		||||
            $index = $this->mapper->mapLogicalToGpioPin($index);
 | 
			
		||||
        }
 | 
			
		||||
        if (empty($this->gpio[$index])) {
 | 
			
		||||
            $this->gpio[$index] = new GpioPin($index, $this);
 | 
			
		||||
            if ($this->dummy) {
 | 
			
		||||
                $gpio = new DummyGpioPin($index, $this);
 | 
			
		||||
            } else {
 | 
			
		||||
                $gpio = new GpioPin($index, $this);
 | 
			
		||||
            }
 | 
			
		||||
            $this->gpio[$index] = $gpio;
 | 
			
		||||
        }
 | 
			
		||||
        return $this->gpio[$index];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if a GPIO is exported
 | 
			
		||||
     *
 | 
			
		||||
     * @interface ArrayAccess
 | 
			
		||||
     * @param int
 | 
			
		||||
     */    
 | 
			
		||||
    public function offsetExists($index)
 | 
			
		||||
    {
 | 
			
		||||
        return array_key_exists($index, $this->gpio);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Not callable, get the requested pin via offsetGet() instead.
 | 
			
		||||
     *
 | 
			
		||||
     * @interface ArrayAccess
 | 
			
		||||
     * @throws Exception
 | 
			
		||||
     * @param int
 | 
			
		||||
     * @param mixed
 | 
			
		||||
     */    
 | 
			
		||||
    public function offsetSet($index,$value)
 | 
			
		||||
    {   throw new \Exception(); }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Unlink and unexport an exported GPIO
 | 
			
		||||
     *
 | 
			
		||||
     * @interface ArrayAccess
 | 
			
		||||
     * @param int
 | 
			
		||||
     */    
 | 
			
		||||
    public function offsetUnset($index)
 | 
			
		||||
    {   
 | 
			
		||||
        $this->gpio[$index]->unexport();
 | 
			
		||||
        unset($this->gpio[$index]);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 
 | 
			
		||||
@@ -154,7 +154,7 @@ class GpioPin
 | 
			
		||||
    
 | 
			
		||||
    public function sysfsWrite($pin, $file, $value)
 | 
			
		||||
    {
 | 
			
		||||
        if ($pin) {
 | 
			
		||||
        if ($pin!==null) {
 | 
			
		||||
            $path = "/sys/class/gpio/gpio{$pin}/{$file}";
 | 
			
		||||
        } else {
 | 
			
		||||
            $path = "/sys/class/gpio/{$file}";
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										71
									
								
								lib/GpioWatcher.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								lib/GpioWatcher.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2014, NoccyLabs
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace NoccyLabs\Gpio;
 | 
			
		||||
 | 
			
		||||
use NoccyLabs\Gpio\Exception\HardwareException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Watch GPIO for interrupts (hardware or software)
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class GpioWatcher 
 | 
			
		||||
{
 | 
			
		||||
    protected $fd_gpio = array();
 | 
			
		||||
    protected $fd_pins = array();
 | 
			
		||||
    
 | 
			
		||||
    public function refresh()
 | 
			
		||||
    {
 | 
			
		||||
        $read = $this->fd_gpio;
 | 
			
		||||
        $write = array();
 | 
			
		||||
        $except = $read;
 | 
			
		||||
        if (count($read)>0) {
 | 
			
		||||
            stream_select($read, $write, $except, 0);
 | 
			
		||||
            foreach($except as $fd) {
 | 
			
		||||
                $pin = $this->getPinFromFd($fd);
 | 
			
		||||
                $pin->doInterrupt();
 | 
			
		||||
            
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function getPinFromFd($fd)
 | 
			
		||||
    {
 | 
			
		||||
        foreach($this->fd_pins as $pinfd=>$pin) {
 | 
			
		||||
            if ($pinfd == $fd) { return $pin; }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function enableInterrupt(GpioPin $pin, $fd)
 | 
			
		||||
    {
 | 
			
		||||
        $this->fd_gpio[] = $fd;
 | 
			
		||||
        
 | 
			
		||||
        $this->fd_pins[$fd] = $pin;
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public function disableInterrupt(GpioPin $pin)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
   
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user