From cdffd77a38c8340a5f4a8ffba4d6538bb32f3854 Mon Sep 17 00:00:00 2001 From: Christopher Vagnetoft Date: Sat, 14 Jun 2014 03:10:07 +0200 Subject: [PATCH] Added software spi stuff --- examples/softwarespi.php | 25 +++++++++++ lib/Bus/Bus.php | 64 ++++++++++++++++++++++++++ lib/Bus/BusInterface.php | 42 +++++++++++++++++ lib/Bus/SoftwareSpiBus.php | 92 ++++++++++++++++++++++++++++++++++++++ lib/GpioPin.php | 3 +- lib/Util/BitmappedGpio.php | 17 +++++++ 6 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 examples/softwarespi.php create mode 100644 lib/Bus/Bus.php create mode 100644 lib/Bus/BusInterface.php create mode 100644 lib/Bus/SoftwareSpiBus.php diff --git a/examples/softwarespi.php b/examples/softwarespi.php new file mode 100644 index 0000000..cbd777d --- /dev/null +++ b/examples/softwarespi.php @@ -0,0 +1,25 @@ +sclk = $gpio[1]; +$spi->mosi = $gpio[2]; +$spi->miso = $gpio[3]; +// write to the spi bus +$spi->write("\xBE\xEF"); +// read the two bytes exchanged with the write() +$read = $spi->read(2); + +// +Dumper::dump($read); diff --git a/lib/Bus/Bus.php b/lib/Bus/Bus.php new file mode 100644 index 0000000..3d46374 --- /dev/null +++ b/lib/Bus/Bus.php @@ -0,0 +1,64 @@ + + */ + +namespace NoccyLabs\Gpio\Bus; + +abstract class Bus implements BusInterface +{ + protected $pins = array(); + + public function __construct() + { + $this->configure(); + } + + public function addPin($name) + { + $this->pins[$name] = null; + } + + public function __set($name, $value) + { + if (!array_key_exists($name,$this->pins)) { + throw new \Exception("No such pin: {$name}"); + } + $this->pins[$name] = $value; + } + + public function __get($name) + { + if (!array_key_exists($name,$this->pins)) { + throw new \Exception("No such pin: {$name}"); + } + return $this->pins[$name]; + } + + public function __isSet($name) + { + return array_key_exists($name,$this->pins); + } + + public function __unset($name) + { + if (!array_key_exists($name,$this->pins)) { + return; + } + $this->pins[$name] = null; + } +} diff --git a/lib/Bus/BusInterface.php b/lib/Bus/BusInterface.php new file mode 100644 index 0000000..c81cf80 --- /dev/null +++ b/lib/Bus/BusInterface.php @@ -0,0 +1,42 @@ + + */ + +namespace NoccyLabs\Gpio\Bus; + +interface BusInterface +{ + /** + * Write data to the bus. The data will be written immediately. + * + */ + public function write($data); + + /** + * Read data from the buffer, or perform additional null reads over the + * (SPI) bus to acquire the data. + * + */ + public function read($bytes); + + /** + * Return the number of bytes in the read buffer + * + */ + public function getBufferFill(); +} diff --git a/lib/Bus/SoftwareSpiBus.php b/lib/Bus/SoftwareSpiBus.php new file mode 100644 index 0000000..167d719 --- /dev/null +++ b/lib/Bus/SoftwareSpiBus.php @@ -0,0 +1,92 @@ + + */ + +namespace NoccyLabs\Gpio\Bus; + +class SoftwareSpiBus extends Bus +{ + protected $buffer = null; + + protected function configure() + { + $this->addPin("sclk"); + $this->addPin("mosi"); + $this->addPin("miso"); + } + + protected function spiExchangeByte($byte) + { + $in = 0; + if (is_string($byte)) { $byte = ord($byte); } + for($bit=0; $bit<8; $bit++) { + $this->setValue("sclk", 0); + $this->setValue("mosi", (($byte & 1<<$bit)>0)); + usleep(5000); + $this->setValue("sclk", 1); + usleep(5000); + if ($this->getValue("miso")) { + $in |= 1<<$bit; + } + } + return chr($in); + } + + protected function setValue($pin,$value) + { + echo "{$pin}→{$value}\n"; + } + protected function getValue($pin) + { + echo "{$pin}←0\n"; + return 0; + } + + public function write($data) + { + for($n = 0; $n < strlen($data); $n++) { + $this->buffer .= $this->spiExchangeByte($data[$n]); + } + } + + public function read($bytes) + { + $ret = null; + if (strlen($this->buffer)>0) { + if (strlen($this->buffer)<$bytes) { + $ret = $this->buffer; + $bytes -= strlen($this->buffer); + $this->buffer = null; + } else { + $ret = substr($this->buffer,0,$bytes); + $this->buffer = substr($this->buffer,$bytes); + return $ret; + } + } + for($n = 0; $n < $bytes; $n++) { + $ret.= $this->spiExchangeByte(0x00); + } + return $ret; + } + + public function getBufferFill() + { + return strlen($this->buffer); + } + +} diff --git a/lib/GpioPin.php b/lib/GpioPin.php index 7ac8d35..df4363a 100644 --- a/lib/GpioPin.php +++ b/lib/GpioPin.php @@ -52,8 +52,6 @@ class GpioPin { $this->pin = (int)$pin; $this->gpio = $gpio; - $this->export(); - $this->hardware = $this->findHardware(); } private function findHardware() @@ -139,6 +137,7 @@ class GpioPin if (!file_exists("/sys/class/gpio/gpio{$this->pin}")) { throw new HardwareException("Unable to export pin {$this->pin}"); } + $this->hardware = $this->findHardware(); return $this; } diff --git a/lib/Util/BitmappedGpio.php b/lib/Util/BitmappedGpio.php index 6d7971e..7d072ca 100644 --- a/lib/Util/BitmappedGpio.php +++ b/lib/Util/BitmappedGpio.php @@ -1,5 +1,22 @@ + */ + namespace NoccyLabs\Gpio\Util; use NoccyLabs\Gpio\GpioPin;