diff --git a/pi4j-core/src/main/java/com/pi4j/io/SerialCircuitIO.java b/pi4j-core/src/main/java/com/pi4j/io/SerialCircuitIO.java new file mode 100644 index 00000000..8c49b441 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/io/SerialCircuitIO.java @@ -0,0 +1,77 @@ +package com.pi4j.io; + +/** + * A shared interface for SPI and I2C serial communication, centered around the + * "writeThenRead" method that performs "connected" write and read operations. + * + *
For SPI, this means that the chip select keeps active between the write and + * the read operation. + * + *
For I2C, this means that the operation is treated as an atomic + * multibyte-register read. + * + *
If this strong connection between write and read is not intended, please use + * separate write and read calls. + * + *
The write and read calls here delegate to writeThenRead with the write or + * read buffer null in order to require only one native implementation for + * all cases. + */ +public interface SerialCircuitIO extends AutoCloseable { + + /** Reads the full data array. Returns the size of the buffer for historic reasons. */ + default int read(byte[] data) { + return read(data, 0, data.length); + } + + /** + * Read 'length' bytes into 'buffer' at offset 'offset'. + * Returns 'length' for historical reasons. + */ + default int read(byte[] buffer, int offset, int length) { + writeThenRead(null, 0, 0, 0, buffer, offset, length); + return length; + } + + /** Writes the full byte array. Returns the buffer size for historical reasons. */ + default int write(byte[] buffer) { + return write(buffer, 0, buffer.length); + } + + /** + * Writes 'length' bytes from the 'buffer' at offset 'offset'. + * Returns 'length' for historical reasons. + */ + default int write(byte[] buffer, int offset, int length) { + writeThenRead(buffer, offset, length, 0, null, 0, 0); + return length; + } + + default void writeThenRead(byte[] writeBuffer, byte[] readBuffer) { + writeThenRead(writeBuffer, 0, writeBuffer.length, 0, readBuffer, 0, readBuffer.length); + } + + /** + * This function writes bytes to the device and then reads bytes from the device. + * Write data is taken from the 'writeBuffer' byte array from the given 'writeOffset' index to + * the specified 'writeLength' (number of bytes). + * + *
Data read back from the device is then copied to the 'readBuffer' byte array starting + * at the given 'readOffset' using the 'readLength' (number of bytes). + * The 'buffer' and 'read' byte array must be at least the size of their defined 'length' + 'offset'. + *
+ * In addition. both the write and read operation can provide a configurable delay
+ * allowing the effected chip to complete any processing. The write operation and the read
+ * operation each have an individual delay value.
+ * *
+ *
+ * @param writeBuffer The write buffer. If null, only a read operation is performed.
+ * @param writeOffset The start offset in the write buffer
+ * @param writeLength The number of bytes to write.
+ * @param readDelayNanos Delay between write and read in usecs
+ * @param readBuffer The read buffer. If null, only a write operation is performed
+ * @param readOffset The start offset in the read buffer.
+ * @param readLength The number of bytes to read.
+ */
+ void writeThenRead(byte[] writeBuffer, int writeOffset, int writeLength, int readDelayNanos, byte[] readBuffer, int readOffset, int readLength);
+}
diff --git a/pi4j-core/src/main/java/com/pi4j/io/i2c/I2C.java b/pi4j-core/src/main/java/com/pi4j/io/i2c/I2C.java
index 842792f7..427666ad 100644
--- a/pi4j-core/src/main/java/com/pi4j/io/i2c/I2C.java
+++ b/pi4j-core/src/main/java/com/pi4j/io/i2c/I2C.java
@@ -29,8 +29,9 @@
import com.pi4j.io.IO;
import com.pi4j.io.IODataReader;
import com.pi4j.io.IODataWriter;
+import com.pi4j.io.SerialCircuitIO;
-import java.nio.ByteBuffer;
+import java.util.Arrays;
import java.util.concurrent.Callable;
/**
@@ -43,7 +44,7 @@
* @version $Id: $Id
*/
public interface I2C
- extends IO close.DEFAULT_BUS
*/
@@ -384,6 +385,30 @@ default int transfer(ByteBuffer buffer, int offset, int length) {
return length;
}
+ // --------------------
+ // Disambiguation
+ // ---------------------
+
+ @Override
+ default int read(byte[] data) {
+ return SerialCircuitIO.super.read(data);
+ }
+
+ @Override
+ default int read(byte[] data, int offset, int length) {
+ return SerialCircuitIO.super.read(data, offset, length);
+ }
+
+ @Override
+ default int write(byte[] data) {
+ return SerialCircuitIO.super.write(data);
+ }
+
+ @Override
+ default int write(byte[] data, int offset, int length) {
+ return SerialCircuitIO.super.write(data, offset, length);
+ }
+
// ------------------------------------------------------------------------------------
// writeThenRead
// ------------------------------------------------------------------------------------
@@ -397,21 +422,7 @@ default int transfer(ByteBuffer buffer, int offset, int length) {
* @param read Buffer to contain read data
*/
default void writeThenRead(byte[] write, byte[] read) {
- writeThenRead(write, 0, write.length, (short) 0, read, 0, read.length, (short) 0);
- }
-
- /**
- * This function writes bytes to the SPI device and then reads bytes from the device
- * Write data is taken from the 'buffer' byte array, data
- * read back from the SPI device is then copied to the 'read' byte array
- *
- * @param write the array of bytes to write to the SPI device
- * @param writeLength Number bytes written from buffer to the SPI
- * @param read Buffer to contain read data
- * @param readlength the number of bytes to read (read & read))
- */
- default void writeThenRead(byte[] write, int writeLength, byte[] read, int readlength) {
- writeThenRead(write, 0, writeLength, (short) 0, read, 0, readlength, (short) 0);
+ writeThenRead(write, 0, write.length, (short) 0, read, 0, read.length);
}
@@ -427,22 +438,20 @@ default void writeThenRead(byte[] write, int writeLength, byte[] read, int readl
* allowing the effected SPI chip to complete any processing. The write operation and the read
* operation each have an individual delay value.
*
- * @param write the array of bytes to write to the SPI device and to store read data
- * back from the SPI device
- * @param writeOffset the starting offset position in the provided buffer to
- * start writing to the SPI device from and the position
- * used as the starting offset position to place data bytes
- * read back from the SPI device.
- * @param writeLength Number of bytes written from write buffer
- * @param writeDelayUsecs Delay after SPI write record processed by kernel before the
- * read SPI record is processed. Value in usecs.
- * @param read Buffer to contain read data
- * @param readOffset Offset within the read buffer to begin placing read data
- * @param readLength The number of bytes to transfer/exchange (read & read))
- * @param readDelayUsecs Delay after SPI read record processed by kernel before the
- * read SPI record is processed. Value in usecs.
+ * @param write the array of bytes to write to the SPI device and to store read data
+ * back from the SPI device
+ * @param writeOffset the starting offset position in the provided buffer to
+ * start writing to the SPI device from and the position
+ * used as the starting offset position to place data bytes
+ * read back from the SPI device.
+ * @param writeLength Number of bytes written from write buffer
+ * @param readDelayNanos Delay after SPI write record processed by kernel before the
+ * read SPI record is processed. Value in nanoseconds.
+ * @param read Buffer to contain read data
+ * @param readOffset Offset within the read buffer to begin placing read data
+ * @param readLength The number of bytes to transfer/exchange (read & read))
*/
- default void writeThenRead(byte[] write, int writeOffset, int writeLength, short writeDelayUsecs, byte[] read, int readOffset, int readLength, short readDelayUsecs) {
+ default void writeThenRead(byte[] write, int writeOffset, int writeLength, int readDelayNanos, byte[] read, int readOffset, int readLength) {
throw new IllegalStateException("writeThenRead Not supported in this provider. \n See https://www.pi4j.com/documentation/providers/");
}
}
diff --git a/plugins/pi4j-plugin-linuxfs/src/main/java/com/pi4j/plugin/linuxfs/provider/spi/LinuxFsSpi.java b/plugins/pi4j-plugin-linuxfs/src/main/java/com/pi4j/plugin/linuxfs/provider/spi/LinuxFsSpi.java
index a8e719b6..43d2e016 100644
--- a/plugins/pi4j-plugin-linuxfs/src/main/java/com/pi4j/plugin/linuxfs/provider/spi/LinuxFsSpi.java
+++ b/plugins/pi4j-plugin-linuxfs/src/main/java/com/pi4j/plugin/linuxfs/provider/spi/LinuxFsSpi.java
@@ -397,7 +397,7 @@ public int write(byte[] data, int offset, int length) {
}
@Override
- public void writeThenRead(byte[] write, int writeOffset, int writeLength, short writeDelayUsec, byte[] read, int readOffset, int readNumberOfBytes, short readDelayUsec) {
+ public void writeThenRead(byte[] write, int writeOffset, int writeLength, int readDelayNanos, byte[] read, int readOffset, int readNumberOfBytes) {
final int firstRecord = 0;
final int secondRecord = 1;
final int totalRecords = 2;
@@ -419,7 +419,7 @@ public void writeThenRead(byte[] write, int writeOffset, int writeLength, short
txEntry.rx_buf = 0;
txEntry.bits_per_word = BITS8;
txEntry.speed_hz = config.baud();
- txEntry.delay_usecs = writeDelayUsec;
+ txEntry.delay_usecs = (short) ((readDelayNanos * 500) / 1000);
txEntry.cs_change = 0;
txEntry.len = writeLength;
@@ -429,7 +429,7 @@ public void writeThenRead(byte[] write, int writeOffset, int writeLength, short
rxEntry.tx_buf = 0;
rxEntry.bits_per_word = BITS8;
rxEntry.speed_hz = config.baud();
- rxEntry.delay_usecs = readDelayUsec;
+ rxEntry.delay_usecs = (short) (readDelayNanos / 1000);
rxEntry.cs_change = 0;
rxEntry.len = readNumberOfBytes;