2014-06-06 14:00:34 +00:00
|
|
|
Linux Userspace GPIO Library
|
|
|
|
============================
|
|
|
|
|
2014-06-14 22:34:33 +00:00
|
|
|
Current and planned features:
|
|
|
|
|
|
|
|
* Export and Unexport GPIO pins via sysfs
|
2014-06-06 14:00:34 +00:00
|
|
|
* Interrupt support (*)
|
2014-06-12 12:22:37 +00:00
|
|
|
* Hardware-neutral rewrite of NoccyLabs RaspIO
|
|
|
|
* Compatible with psr/logs LoggerInterface for logging
|
2014-06-14 22:34:33 +00:00
|
|
|
* Bit-banged SPI/I2C/1Wire
|
|
|
|
|
|
|
|
|
|
|
|
## Gpio
|
|
|
|
|
|
|
|
Without a mapper active, the GPIOs adressed are the direct exported GPIO numbers,
|
|
|
|
not necessarily in any logical order. Requesting `$gpio[22]` gives you `GPIO22`.
|
|
|
|
|
|
|
|
$gpio = new Gpio();
|
|
|
|
$gpio1 = $gpio[1];
|
|
|
|
|
|
|
|
|
|
|
|
### With a Mapper
|
|
|
|
|
|
|
|
With a mapper the pins are arranged logically starting at 0. For example, with
|
|
|
|
the WiringPi mapper, `$gpio[0]` would return `GPIO17` and so on. The `GpioPin#getPin()`
|
|
|
|
method will still return the actual GPIO (i.e. *17* rather than *0*).
|
|
|
|
|
|
|
|
$gpio = new Gpio();
|
|
|
|
$mapper = new WiringPiMapper(2);
|
|
|
|
$gpio->setMapper($mapper);
|
|
|
|
|
|
|
|
$gpio17 = $gpio[0];
|
|
|
|
|
2014-06-06 14:00:34 +00:00
|
|
|
|
|
|
|
## Interrupts
|
|
|
|
|
2014-06-12 12:22:37 +00:00
|
|
|
*NOTE: Not implemented!*
|
|
|
|
|
2014-06-06 14:00:34 +00:00
|
|
|
For interrupts to work, you need to first bind the interrupt handler, and then
|
|
|
|
make sure to call on `Gpio#refresh()` every cycle to poll the interrupt flag on
|
2014-06-12 12:22:37 +00:00
|
|
|
the selected pins. This is because the `select()` function is used.
|
2014-06-06 14:00:34 +00:00
|
|
|
|
|
|
|
$gpio = new Gpio();
|
|
|
|
|
2014-06-12 12:22:37 +00:00
|
|
|
// Set the handler on the Gpio object
|
|
|
|
$gpio->setInterruptHandler($gpio[4], function() { ... });
|
|
|
|
// Or like this on the GpioPin.
|
|
|
|
$gpio[4]
|
|
|
|
->setEdge("rising")
|
|
|
|
->setHandler(function() { ... });
|
2014-06-06 14:00:34 +00:00
|
|
|
|
|
|
|
while (..) {
|
|
|
|
..
|
|
|
|
$gpio->refresh();
|
|
|
|
}
|
|
|
|
|
2014-06-12 12:22:37 +00:00
|
|
|
You can also be risky and use php ticks and timerfuncs (although that might not
|
|
|
|
be portable/supported/efficient/a good idea):
|
|
|
|
|
|
|
|
declare(ticks=5);
|
|
|
|
|
|
|
|
$gpio = new Gpio();
|
|
|
|
|
|
|
|
$gpiotick = new GpioTickHandler();
|
|
|
|
$gpiotick->registerGpio($gpio);
|
|
|
|
|
|
|
|
// The interrupts will now be polled approx every 5th php vm "tick"
|
|
|
|
|
2014-06-14 22:34:33 +00:00
|
|
|
|
|
|
|
## Parallel addressing of pins
|
|
|
|
|
|
|
|
*Implemented in* ***0.1.x***
|
|
|
|
|
|
|
|
$gpio = new Gpio();
|
|
|
|
$gpio->setMapper( new WiringPiMapper(2) );
|
|
|
|
|
|
|
|
$par = new BitmappedGpio();
|
|
|
|
for($n = 0; $n < 7; $n++) {
|
|
|
|
$pin = $gpio[$n]->setDirection("out");
|
|
|
|
$par->setGpioPin($n,$pin);
|
|
|
|
}
|
|
|
|
$par->write(0x55); // turn on 1, 3, 5, 7.
|
|
|
|
|
|
|
|
|
|
|
|
## Buses
|
|
|
|
|
|
|
|
*Not yet implemented*
|
|
|
|
|
|
|
|
$bus = new NoccyLabs\Gpio\Bus\SoftwareSpiBus;
|
|
|
|
$bus->mosi = $gpio[2];
|
|
|
|
$bus->sclk = $gpio[9];
|
|
|
|
$bus->write("\0x10\0x20\0x40");
|
|
|
|
$r = $bus->read(3);
|
|
|
|
|
|
|
|
|
2014-06-12 16:14:51 +00:00
|
|
|
## Devices
|
2014-06-12 12:22:37 +00:00
|
|
|
|
2014-06-12 16:14:51 +00:00
|
|
|
$lcd = new NoccyLabs\Gpio\Device\Display\Pcd8544Device;
|
|
|
|
// Set I/O pins
|
|
|
|
$lcd->res = $gpio[4];
|
|
|
|
$lcd->dc = $gpio[8];
|
|
|
|
...
|
|
|
|
// Activate the device
|
|
|
|
$lcd->activate();
|
|
|
|
// Clear and draw text
|
|
|
|
$lcd->clear();
|
|
|
|
$lcd->writeAt(0,0,"Hello World");
|
|
|
|
echo $lcd->getRows(); // 5
|
|
|
|
echo $lcd->getCols(); // 19
|
|
|
|
|
2014-06-14 22:34:33 +00:00
|
|
|
|
2014-06-12 16:14:51 +00:00
|
|
|
### LCD Bridge
|
|
|
|
|
|
|
|
The LCD bridge will be able to bridge any device class implementing `LcdDeviceInterface`
|
|
|
|
to stdin or a named pipe. This basically creates a user-space daemon to interface with
|
|
|
|
the display without having to fiddle with bits.
|
|
|
|
|
|
|
|
$ lcdbridge -t pcd8544 --stdin
|
|
|
|
CLR
|
|
|
|
LOC 0 0
|
|
|
|
FONT 0
|
2014-06-14 22:34:33 +00:00
|
|
|
MODE +BR
|
|
|
|
OUT "Hello World"
|
2014-06-12 16:14:51 +00:00
|
|
|
^C
|
|
|
|
$
|
|
|
|
|
|
|
|
Commands should include:
|
|
|
|
|
2014-06-14 22:34:33 +00:00
|
|
|
* `CLR` - clears the display (`LcdDeviceInterface#clear()`)
|
|
|
|
* `LOC n m` - moves the cursor to line n column m (0-indexed) (`LcdDeviceInterface#setCursorPos(n,m)`)
|
|
|
|
* `FONT n` - loads the default font (0) or a custom font file (`LcdDeviceInterface#setFont()`)
|
|
|
|
* `OUT s` - Write text to the display (`LcdDeviceInterface#write()`)
|
|
|
|
* `MODE s` - Set text modes (`LcdDeviceInterface#setTextMode()`)
|
|
|
|
|
|
|
|
|
|
|
|
#### Modes
|
|
|
|
|
|
|
|
As supported:
|
|
|
|
|
|
|
|
* `+R`/`-R` - Set/clear inverse
|
|
|
|
* `+B`/`-B` - Set/clear bold
|
|
|
|
|
|
|
|
|
|
|
|
#### Fonts
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### Location and write
|
|
|
|
|
|
|
|
Location is maintained and incremented after writes.
|
|
|
|
|
|
|
|
LOC 0 0
|
|
|
|
OUT "12345"
|
|
|
|
OUT "67890" <-- continued at 0 5
|
|
|
|
|
|
|
|
|