NAME

Device::Chip::Adapter - an abstraction of a hardware communication device

DESCRIPTION

This package describes an interfaces tha classes can use to implement a driver to provide access to some means of connecting an electronic chip or hardware module to a computer. An instance implementing this interface provides some means to send electrical signals to a connected chip or module, and receive replies back from it; this device is called the adapter. This is provided as a service to some instance of the related interface, Device::Chip.

It is suggested that a driver for a particular adapter provides a concrete class named within the Device::Chip::Adapter heirarchy, adding the basic name of the product or means of communication as a suffix; for example the driver for communication device based on the FDTI range of devices would be called:

package Device::Chip::Adapter::FTDI;

This package provides a base class that such a specific implementation class could use as a superclass, but it is not required to. The important detail is that it provides the interface described by this documentation.

UTILITY CONSTRUCTOR

new_from_description

$adapter = Device::Chip::Adapter->new_from_description( $DESC )

This utility method is provided to allow end-user programs a convenient way to construct a useable Device::Chip::Adapter instance from a given single string value. This string takes the form of a the main name of the adapter class (minus the leading Device::Chip::Adapter:: prefix), optionally followed by a single colon and some comma-separated options. Each option takes the form of a name and value, separated by equals sign. For example:

FTDI
FTDI:
FTDI:product=0x0601
BusPirate:serial=/dev/ttyUSB3,baud=57600

This utility method splits off the base name from the optional suffix, and splits the options into an even-sized name/value list. It loads the class implied by the base name and invokes a method called new_from_description on it. This is passed the even-sized name/value list obtained by splitting the option string. Any option named without a value will be passed having the value 1, as a convenience for options that are simple boolean flags.

If the class does not provide the new_from_description method (and of course, simply inheriting the base class one from here does not count), then if there are no other options given, the plain new constructor is invoked instead. If this is not possible because there are user-specified options that must be honoured, then an exception is thrown instead.

Note for example that in the case above, the product option would be passed to the FTDI adapter class still as a string value; it is likely that this class would want to implement a new_from_description method to parse that using the oct operator into a plain integer.

It is intended that this method is used for creating an adapter that a standalone program can use from a description string specified by the user; likely in a commandline option or environment variable.

METHODS

The following methods documented with a trailing call to ->get return Future instances.

make_protocol

$protocol = $adapter->make_protocol( $pname )->get

Returns an object that satisfies one of the interfaces documented below in "PROTOCOLS", depending on the protocol name given by $pname. This should be one of the following values:

GPIO
SPI
I2C

It is unspecified what class these objects should belong to. In particular, it is permitted that an adapter could even return itself as the protocol implementation, provided it has the methods to satisfy the interface for that particular protocol. This is especially convenient in the case that the adapter is only capable of one kind of protocol.

shutdown

$adapter->shutdown

Shuts down the adapter in whatever manner is appropriate at the end of the lifetime of the containing program; or at least, at the point when the program has finished using the connected device.

This method is allowed to block; it does not yield a Future. It is suitable to call from a DESTROY method or END block.

PROTOCOLS

The following methods are common to all protocol instances:

configure

$protocol->configure( %args )->get

Sets configuration options for the protocol. The actual set of options available will depend on the type of the protocol.

Chip drivers should attempt to bundle their changes together into as few configure calls as possible, because adapters may find it most efficient to apply multiple changes in one go.

power

$protocol->power( $on )->get

Switches on or off the power to the actual chip or module, if such ability is provided by the adapter.

list_gpios

@pin_names = $protocol->list_gpios

Returns a list of the names of GPIO pins that are available for the chip driver to use. This list would depend on the pins available on the adapter itself, minus any pins that are in use by the protocol itself.

Adapters should name GPIO pins in a way that makes sense from the hardware; for example MOSI, SDA, DTR, Q0, etc...

write_gpios

$protocol->write_gpios( \%pin_values )->get

Sets the named GPIO pins as driven outputs, and gives their new values. Any GPIO pins not named are left as they are; either driving outputs at the current state, or high-impedence inputs.

Pins are specified as a HASH reference, mapping pin names (as returned by the "list_gpios" method) to boolean logic levels.

read_gpios

\%pin_values = $protocol->read_gpios( \@pin_names )->get;

Sets the named GPIO pins as high-impedence inputs, and reads their current state. Any GPIO pins not named here are left as they are; either driving outputs at the current state, or other inputs.

Pins are specified in an ARRAY reference giving the names of pins (as returned by the "list_gpios" method); read values are given in the returned HASH reference which maps pin names to boolean logic levels.

GPIO PROTOCOL

The GPIO protocol adds no new abilities or methods; it is the most basic form of protocol that simply provides access to the generic GPIO pins of the device.

SPI PROTOCOL

Configuration Options

The following configuration options are recognised:

mode => 0 | 1 | 2 | 3

The numbered SPI mode used to communicate with the chip.

max_bitrate => INT

The highest speed, in bits per second, that the chip can accept. The adapter must pick a rate that is no higher than this. Note specifically that not all adapters are able to choose a rate arbitrarily, and so the actually communication may happen at some rate slower than this.

readwrite

$bytes_in = $spi->readwrite( $bytes_out )->get

Performs a complete SPI transaction; synchronously clocking the data given by the plain byte string $bytes_out out of the MOSI pin of the adapter, while simultaneously capturing the data coming in to the MISO pin, which is eventually returned as the result of the returned future.

write

$spi->write( $bytes )->get

A variant of readwrite where the caller does not intend to make use of the data returned by the device, and so the adapter does not need to return it. This may or may not make a material difference to the actual communication with the adapter or device; it could be implemented simply by calling the readwrite method and ignoring the return value.

I2C PROTOCOL

Configuration Options

The following configuration options are recognised:

addr => INT

The (7-bit) slave address for the chip this protocol is communicating with.

max_bitrate => INT

The highest speed, in bits per second, that the chip can accept. The adapter must pick a rate that is no higher than this. Note specifically that not all adapters are able to choose a rate arbitrarily, and so the actually communication may happen at some rate slower than this.

write

$i2c->write( $bytes_out )->get

Performs a complete I²C transaction to send the given bytes to the slave chip. This includes the start condition, sending the addressing byte (which is implied; it should not be included in $bytes_out) and ending in the stop condition.

write_then_read

$bytes_in = $i2c->write_then_read( $bytes_out, $len_in )->get

Performs a complete I²C transaction to first send the given bytes to the slave chip then reads the give number of bytes back, returning them. These two operations must be performed within a single I²C transaction using a repeated start condition.

AUTHOR

Paul Evans <leonerd@leonerd.org.uk>