This package provides interfaces and classes for SPI (Serial Peripheral Interface Bus) device access.
The Serial Peripheral Interface (SPI) bus is a synchronous serial data link standard that operates in full duplex mode. Devices communicate in master or slave mode, where the master device initiates the communication data frame. Multiple slave devices are allowed with individual slave select lines.
The functionalities supported by this API are those of an SPI master. In order to communicate with a specific slave, an application should first open and obtain an SPIDevice
instance for the SPI slave device the application wants to exchange data with, using its numerical ID, name, type (interface), or properties. The following example demonstrates how to obtain an SPI device using its ID.
SPIDevice slave = (SPIDevice) PeripheralManager.open(3);
This example demonstrates how to access a device using its name and interface.
SPIDevice slave = (SPIDevice) PeripheralManager.open("RTC1", SPIDevice.class, null);
Once the peripheral opened, the application can exchange data with the SPI slave device using methods of the SPIDevice
interface such as the writeAndRead()
method.
slave.writeAndRead(sndBuf, 0, 1, rcvBuf, 0, 1);
When the data exchange is over, the application should call the Peripheral.close()
method to release the SPI slave device.
slave.close();
Example 12-1 shows how to use the SPI API to communicate with SPI slaves.
Example 12-1 Using the SPI APIs to Communicate with SPI Slaves
import com.oracle.deviceaccess.PeripheralException; import com.oracle.deviceaccess.PeripheralManager; import com.oracle.deviceaccess.spibus.SPIDevice; import java.io.IOException; public class SPIExample { SPIDevice slave = null; public SPIExample() { try { slave = (SPIDevice) PeripheralManager.open("SPI1", SPIDevice.class, (String[]) null); byte[] sndBuf1 = {0x01}; byte[] sndBuf2 = {0x02}; byte[] rcvBuf = new byte[3]; slave.writeAndRead(sndBuf1, 0, sndBuf1.length, rcvBuf, 0, 1); // received data will be stored in rcvBuf[0] slave.writeAndRead(sndBuf2, 0, sndBuf2.length, rcvBuf, 1, 2); // received data will be stored in rcvBuf[1] and rcvBuf[2] } catch (PeripheralException pe) { // Handle exception } catch (IOException ioe) { // Handle exception } finally { if (slave != null) { try { slave.close(); } catch (IOException ex) { } } } } }
Information about the SPI-bus specification can be found at http://www.freescale.com/files/microcontrollers/doc/ref_manual/M68HC11RM.pdf
.
SPI slave devices are opened by invoking one of the com.oracle.deviceaccess.PeripheralManager.open()
methods. The com.oracle.deviceaccess.spi
permission allows access to be granted to SPI slave devices as a whole. This permission must be requested in the JAD file under MIDlet-Permissions
or MIDlet-Permissions-Opt
, and the application must be digitally signed by a trusted authority to gain access to the APIs. Alternatively, the permission may be allowed for all applications in the untrusted
domain of the security policy file (policy.txt
).
The SPIDevice
interface provides methods for transmitting and receiving data to and from an SPI slave device. Each SPI slave device is identified by a numerical ID and by a name.
An SPIDevice
instance can be opened by a call to one of the PeripheralManager.open()
methods. On an SPI bus, data is transferred between the SPI master device and an SPI slave device in full duplex. That is, data is transmitted by the SPI master to the SPI slave device at the same time data is received from the SPI slave device by the SPI master.
To perform such a bidirectional exchange of data with an SPI slave device, an application may use one of the writeAndRead()
methods. When an application only wants to send data to or receive data from an SPI slave device, it may use a write()
or read()
method, respectively. When writing only, the data received from the SPI slave device will be ignored and discarded. When reading only, dummy data will be sent to the slave.
A data exchange consists of words of a certain length which may vary from one SPI slave device to another. Words in the sending and receiving byte buffers are not packed bit-wise and must be byte-aligned. The most significant bits of a word are stored at the lower index (first). If a word's bit length is not a multiple of eight, then the most significant bits will be undefined when receiving or unused when sending. If the designated portion of a sending or receiving byte buffer cannot contain a positive integral number of words then an InvalidWordLengthException
is thrown. For example, if the word length is 16 bits and the designated portion of buffer is only 1-byte long or 3-bytes long, an InvalidWordLengthException
is thrown.
Assuming a word length w
, the length l
of the designated portion of the sending or receiving byte buffer must be such that:
((l % (((w - 1) / 8) + 1)) == 0)
When the data exchange is over, an application should call the SPIDevice.close()
method to release the SPI slave device. Any attempt to read or write to an SPI slave device which has been closed will thow a PeripheralNotAvailableException
.
The following methods are contained in the SPIDevice
interface.
This method demarcates the beginning of an SPI transaction so that this slave's Select line (SS) will be remain asserted during the subsequent read and write operations and until the transaction ends.
This method demarcates the end of a transaction, hence ending the assertion of this slave's Select line (SS).
int getWordLength() throws java.io.IOException, PeripheralNotAvailableException
This method retrieves the transfer word length in bits supported by this slave device. If the length of data to be exchanged is not a multiple of this word length, an InvalidWordLengthException
is thrown.
int read() throws java.io.IOException, PeripheralNotAvailableException
This method reads one data word of up to 32 bits from this slave device.
int read(byte[] rxBuf, int rxOff, int rxLen) throws java.io.IOException, PeripheralNotAvailableException
This method reads data from this slave device. During the duplex, dummy data is sent to this slave device by the platform. The length of the designated portion of the sending byte buffers must correspond to a (positive) integral number of words. This slave's Select line (SS) is asserted for the duration of the reception.
int read(int rxSkip, byte[] rxBuf, int rxOff, int rxLen) throws java.io.IOException, PeripheralNotAvailableException
This method reads up to rxLen
bytes of data from this slave device into an array of bytes skipping the first rxSkip
bytes read.
void write(int txData) throws java.io.IOException, PeripheralNotAvailableException
This method writes one data word of up to 32 bits to this slave device.
void write(byte[] txBuf, int txOff, int txLen) throws java.io.IOException, PeripheralNotAvailableException
This method writes to the slave device txLen
bytes from buffer txBuf
.
int writeAndRead(int txData) throws java.io.IOException, PeripheralNotAvailableException
This method exchanges (send and receives) one data word of up to 32 bits with this slave device. This slave's Select line (SS) is asserted for the duration of the exchange.
int writeAndRead(byte[] txBuf, int txOff, int txLen, byte[] rxBuf, int rxOff, int rxLen) throws java.io.IOException, PeripheralNotAvailableException
This method exchanges (send and receives) data with this slave device. The designated portions of the sending and receiving byte buffers might not have the same length. When sending more than is being received, the extra received bytes are ignored and discarded. Conversely, when sending less than is being received, extra dummy data are sent. This slave's Select line (SS) is asserted for the duration of the exchange
int writeAndRead(byte[] txBuf, int txOff, int txLen, int rxSkip, byte[] rxBuf, int rxOff, int rxLen) throws java.io.IOException, PeripheralNotAvailableException
This method exchanges (send and receives) data with this slave device skipping the specified number of bytes received. The designated portions of the sending and receiving byte buffers might not have the same length. When sending more than is being received, the extra received bytes are ignored and discarded. Conversely, when sending less than is being received, extra dummy data are sent. This slave's Select line (SS) is asserted for the duration of the exchange.
The SPIDeviceConfig
class encapsulates the configuration parameters of an SPI slave device.
Each SPI slave device has a clock mode. The clock mode is a number from 0 to 3 which represents the combination of the CPOL (SPI Clock Polarity Bit) and CPHA (SPI Clock Phase Bit) signals, where CPOL is the high order bit and CPHA is the low order bit, as shown in Table 12-1.
Table 12-1 Clock Modes in the SPIDeviceConfig Class
Mode | CPOL | CPHA |
---|---|---|
0 |
0 = Active-high clocks selected. |
0 = Sampling of data occurs at odd edges of the SCK clock |
1 |
0 = Active-high clocks selected. |
1 = Sampling of data occurs at even edges of the SCK clock |
2 |
1 = Active-low clocks selected. |
0 = Sampling of data occurs at odd edges of the SCK clock |
3 |
1 = Active-low clocks selected. |
1 = Sampling of data occurs at even edges of the SCK clock |
An instance of SPIDeviceConfig
can be passed to the PeripheralManager.open(PeripheralConfig)
method to open the designated SPI slave device with the specified configuration.
The SPIDeviceConfig
class consists of one constructor and the following methods
SPIDeviceConfig(int busNumber, int address, int clockFrequency, int clockMode, int wordLength, int bitOrdering)
This constructor creates a new SPIDeviceConfig
with the provided parameters. Note that unused or not applicable numerical parameters should be set to PeripheralConfig.DEFAULT
.
This method returns the configured SPI bus number the slave is connected to.
This method returns the configured address of the SPI slave device.
public int getClockFrequency()
This method returns the clock frequency (in Hertz) supported by the SPI slave device.
This method returns the configured clock mode (combining clock polarity and phase) for communicating with the SPI slave device. See Table 12-1 for more information on possible values for the clock mode.
This method returns the configured word length for communicating with the SPI slave device.
This method returns the configured bit (shifting) ordering of the SPI slave device, one of: Peripheral.BIG_ENDIAN
, Peripheral.LITTLE_ENDIAN
or PeripheralConfig.DEFAULT
.