ioio.lib.api
Interface SpiMaster

All Superinterfaces:
Closeable

public interface SpiMaster
extends Closeable

An interface for controlling an SPI module, in SPI bus-master mode, enabling communication with multiple SPI-enabled slave modules.

SPI is a common hardware communication protocol, enabling full-duplex, synchronous point-to-multi-point data transfer. It requires MOSI, MISO and CLK lines shared by all nodes, as well as a SS line per slave, connected between this slave and a respective pin on the master. The MISO line should operate in pull-up mode, using either the internal pull-up or an external resistor. SpiMaster instances are obtained by calling IOIO#openSpiMaster(Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[], Config).

The SPI protocol is comprised of simultaneous sending and receiving of data between the bus master and a single slave. By the very nature of this protocol, the amount of bytes sent is equal to the amount of bytes received. However, by padding the sent data with garbage data, and by ignoring the leading bytes of the received data arbitrarily-sized packets can be sent and received.

A very common practice for SPI-based slave devices (although not always the case), is to have a fixed request and response length and a fixed lag between them, based on the request type. For example, an SPI-based sensor may define the the protocol for obtaining its measured value is by sending a 2-byte message, whereas the returned 3-byte value has its first byte overlapping the second value of the response, as illustrated below:

 Master: M1   M2   GG   GG
 Slave:  GG   S1   S2   S3
 
M1, M2: the master's request
S1, S2, S3: the slave's response
GG: garbage bytes used for padding.

The IOIO SPI interface supports such fixed length message protocols using a single method, writeRead(int, byte[], int, int, byte[], int), which gets the request data, and the lengths of the request, the response and the total transaction bytes.

The instance is alive since its creation. If the connection with the IOIO drops at any point, the instance transitions to a disconnected state, in which every attempt to use it (except Closeable.close()) will throw a ConnectionLostException. Whenever Closeable.close() is invoked the instance may no longer be used. Any resources associated with it are freed and can be reused.

Typical usage (single slave, as per the example above):

 // MISO, MOSI, CLK, SS on pins 3, 4, 5, 6, respectively.
 SpiMaster spi = ioio.openSpiMaster(3, 4, 5, 6, SpiMaster.Rate.RATE_125K);
 final byte[] request = new byte[]{ 0x23, 0x45 };
 final byte[] response = new byte[3];
 spi.writeRead(request, 2, 4, response, 3);
 ...
 spi.close();  // free SPI module and pins
 

See Also:
IOIO#openSpiMaster(Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[], Config)

Nested Class Summary
static class SpiMaster.Config
          SPI configuration structure.
static class SpiMaster.Rate
          Possible data rates for SPI, in Hz.
static interface SpiMaster.Result
          An object that can be waited on for asynchronous calls.
 
Method Summary
 void writeRead(byte[] writeData, int writeSize, int totalSize, byte[] readData, int readSize)
          Shorthand for writeRead(int, byte[], int, int, byte[], int) for the single-slave case.
 void writeRead(int slave, byte[] writeData, int writeSize, int totalSize, byte[] readData, int readSize)
          Perform a single SPI transaction which includes optional transmission and optional reception of data to a single slave.
 SpiMaster.Result writeReadAsync(int slave, byte[] writeData, int writeSize, int totalSize, byte[] readData, int readSize)
          The same as writeRead(int, byte[], int, int, byte[], int), but returns immediately and returns a SpiMaster.Result object that can be waited on.
 
Methods inherited from interface ioio.lib.api.Closeable
close
 

Method Detail

writeRead

void writeRead(int slave,
               byte[] writeData,
               int writeSize,
               int totalSize,
               byte[] readData,
               int readSize)
               throws ConnectionLostException,
                      java.lang.InterruptedException
Perform a single SPI transaction which includes optional transmission and optional reception of data to a single slave. This is a blocking operation that can take a few milliseconds to a few tens of milliseconds. To abort this operation, client can interrupt the blocked thread. If readSize is 0, the call returns immediately.

Parameters:
slave - The slave index. It is determined by the index of its slave-select pin, as per the array passed to IOIO#openSpiMaster(Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[], Config) .
writeData - A byte array of data to write. May be null if writeSize is 0.
writeSize - Number of bytes to write. Valid values are 0 to totalSize.
totalSize - Total transaction length, in bytes. Valid values are 1 to 64.
readData - An array where the response is to be stored. May be null if readSize is 0.
readSize - The number of expected response bytes. Valid values are 0 to totalSize.
Throws:
ConnectionLostException - Connection to the IOIO has been lost.
java.lang.InterruptedException - Calling thread has been interrupted.

writeRead

void writeRead(byte[] writeData,
               int writeSize,
               int totalSize,
               byte[] readData,
               int readSize)
               throws ConnectionLostException,
                      java.lang.InterruptedException
Shorthand for writeRead(int, byte[], int, int, byte[], int) for the single-slave case.

Throws:
ConnectionLostException
java.lang.InterruptedException
See Also:
writeRead(int, byte[], int, int, byte[], int)

writeReadAsync

SpiMaster.Result writeReadAsync(int slave,
                                byte[] writeData,
                                int writeSize,
                                int totalSize,
                                byte[] readData,
                                int readSize)
                                throws ConnectionLostException
The same as writeRead(int, byte[], int, int, byte[], int), but returns immediately and returns a SpiMaster.Result object that can be waited on. If readSize is 0, the result object is ready immediately.

Throws:
ConnectionLostException
See Also:
writeRead(int, byte[], int, int, byte[], int)