![JAR search and dependency download from the Maven repository](/logo.png)
com.tinkerforge.BrickletCANV2 Maven / Gradle / Ivy
/* ***********************************************************
* This file was automatically generated on 2019-11-25. *
* *
* Java Bindings Version 2.1.25 *
* *
* If you have a bugfix for this file and want to commit it, *
* please fix the bug in the generator. You can find a link *
* to the generators git repository on tinkerforge.com *
*************************************************************/
package com.tinkerforge;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Communicates with CAN bus devices
*/
public class BrickletCANV2 extends Device {
public final static int DEVICE_IDENTIFIER = 2107;
public final static String DEVICE_DISPLAY_NAME = "CAN Bricklet 2.0";
public final static byte FUNCTION_WRITE_FRAME_LOW_LEVEL = (byte)1;
public final static byte FUNCTION_READ_FRAME_LOW_LEVEL = (byte)2;
public final static byte FUNCTION_SET_FRAME_READ_CALLBACK_CONFIGURATION = (byte)3;
public final static byte FUNCTION_GET_FRAME_READ_CALLBACK_CONFIGURATION = (byte)4;
public final static byte FUNCTION_SET_TRANSCEIVER_CONFIGURATION = (byte)5;
public final static byte FUNCTION_GET_TRANSCEIVER_CONFIGURATION = (byte)6;
public final static byte FUNCTION_SET_QUEUE_CONFIGURATION_LOW_LEVEL = (byte)7;
public final static byte FUNCTION_GET_QUEUE_CONFIGURATION_LOW_LEVEL = (byte)8;
public final static byte FUNCTION_SET_READ_FILTER_CONFIGURATION = (byte)9;
public final static byte FUNCTION_GET_READ_FILTER_CONFIGURATION = (byte)10;
public final static byte FUNCTION_GET_ERROR_LOG_LOW_LEVEL = (byte)11;
public final static byte FUNCTION_SET_COMMUNICATION_LED_CONFIG = (byte)12;
public final static byte FUNCTION_GET_COMMUNICATION_LED_CONFIG = (byte)13;
public final static byte FUNCTION_SET_ERROR_LED_CONFIG = (byte)14;
public final static byte FUNCTION_GET_ERROR_LED_CONFIG = (byte)15;
public final static byte FUNCTION_GET_SPITFP_ERROR_COUNT = (byte)234;
public final static byte FUNCTION_SET_BOOTLOADER_MODE = (byte)235;
public final static byte FUNCTION_GET_BOOTLOADER_MODE = (byte)236;
public final static byte FUNCTION_SET_WRITE_FIRMWARE_POINTER = (byte)237;
public final static byte FUNCTION_WRITE_FIRMWARE = (byte)238;
public final static byte FUNCTION_SET_STATUS_LED_CONFIG = (byte)239;
public final static byte FUNCTION_GET_STATUS_LED_CONFIG = (byte)240;
public final static byte FUNCTION_GET_CHIP_TEMPERATURE = (byte)242;
public final static byte FUNCTION_RESET = (byte)243;
public final static byte FUNCTION_WRITE_UID = (byte)248;
public final static byte FUNCTION_READ_UID = (byte)249;
public final static byte FUNCTION_GET_IDENTITY = (byte)255;
private final static int CALLBACK_FRAME_READ_LOW_LEVEL = 16;
private final static int CALLBACK_FRAME_READ = -16;
public final static int FRAME_TYPE_STANDARD_DATA = 0;
public final static int FRAME_TYPE_STANDARD_REMOTE = 1;
public final static int FRAME_TYPE_EXTENDED_DATA = 2;
public final static int FRAME_TYPE_EXTENDED_REMOTE = 3;
public final static int TRANSCEIVER_MODE_NORMAL = 0;
public final static int TRANSCEIVER_MODE_LOOPBACK = 1;
public final static int TRANSCEIVER_MODE_READ_ONLY = 2;
public final static int FILTER_MODE_ACCEPT_ALL = 0;
public final static int FILTER_MODE_MATCH_STANDARD_ONLY = 1;
public final static int FILTER_MODE_MATCH_EXTENDED_ONLY = 2;
public final static int FILTER_MODE_MATCH_STANDARD_AND_EXTENDED = 3;
public final static int TRANSCEIVER_STATE_ACTIVE = 0;
public final static int TRANSCEIVER_STATE_PASSIVE = 1;
public final static int TRANSCEIVER_STATE_DISABLED = 2;
public final static int COMMUNICATION_LED_CONFIG_OFF = 0;
public final static int COMMUNICATION_LED_CONFIG_ON = 1;
public final static int COMMUNICATION_LED_CONFIG_SHOW_HEARTBEAT = 2;
public final static int COMMUNICATION_LED_CONFIG_SHOW_COMMUNICATION = 3;
public final static int ERROR_LED_CONFIG_OFF = 0;
public final static int ERROR_LED_CONFIG_ON = 1;
public final static int ERROR_LED_CONFIG_SHOW_HEARTBEAT = 2;
public final static int ERROR_LED_CONFIG_SHOW_TRANSCEIVER_STATE = 3;
public final static int ERROR_LED_CONFIG_SHOW_ERROR = 4;
public final static int BOOTLOADER_MODE_BOOTLOADER = 0;
public final static int BOOTLOADER_MODE_FIRMWARE = 1;
public final static int BOOTLOADER_MODE_BOOTLOADER_WAIT_FOR_REBOOT = 2;
public final static int BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_REBOOT = 3;
public final static int BOOTLOADER_MODE_FIRMWARE_WAIT_FOR_ERASE_AND_REBOOT = 4;
public final static int BOOTLOADER_STATUS_OK = 0;
public final static int BOOTLOADER_STATUS_INVALID_MODE = 1;
public final static int BOOTLOADER_STATUS_NO_CHANGE = 2;
public final static int BOOTLOADER_STATUS_ENTRY_FUNCTION_NOT_PRESENT = 3;
public final static int BOOTLOADER_STATUS_DEVICE_IDENTIFIER_INCORRECT = 4;
public final static int BOOTLOADER_STATUS_CRC_MISMATCH = 5;
public final static int STATUS_LED_CONFIG_OFF = 0;
public final static int STATUS_LED_CONFIG_ON = 1;
public final static int STATUS_LED_CONFIG_SHOW_HEARTBEAT = 2;
public final static int STATUS_LED_CONFIG_SHOW_STATUS = 3;
private List listenerFrameReadLowLevel = new CopyOnWriteArrayList();
private List listenerFrameRead = new CopyOnWriteArrayList();
public class ReadFrameLowLevel {
public boolean success;
public int frameType;
public long identifier;
public int dataLength;
public int[] dataData = new int[15];
public String toString() {
return "[" + "success = " + success + ", " + "frameType = " + frameType + ", " + "identifier = " + identifier + ", " + "dataLength = " + dataLength + ", " + "dataData = " + Arrays.toString(dataData) + "]";
}
}
public class TransceiverConfiguration {
public long baudRate;
public int samplePoint;
public int transceiverMode;
public String toString() {
return "[" + "baudRate = " + baudRate + ", " + "samplePoint = " + samplePoint + ", " + "transceiverMode = " + transceiverMode + "]";
}
}
public class QueueConfigurationLowLevel {
public int writeBufferSize;
public int writeBufferTimeout;
public int writeBacklogSize;
public int readBufferSizesLength;
public int[] readBufferSizesData = new int[32];
public int readBacklogSize;
public String toString() {
return "[" + "writeBufferSize = " + writeBufferSize + ", " + "writeBufferTimeout = " + writeBufferTimeout + ", " + "writeBacklogSize = " + writeBacklogSize + ", " + "readBufferSizesLength = " + readBufferSizesLength + ", " + "readBufferSizesData = " + Arrays.toString(readBufferSizesData) + ", " + "readBacklogSize = " + readBacklogSize + "]";
}
}
public class ReadFilterConfiguration {
public int filterMode;
public long filterMask;
public long filterIdentifier;
public String toString() {
return "[" + "filterMode = " + filterMode + ", " + "filterMask = " + filterMask + ", " + "filterIdentifier = " + filterIdentifier + "]";
}
}
public class ErrorLogLowLevel {
public int transceiverState;
public int transceiverWriteErrorLevel;
public int transceiverReadErrorLevel;
public long transceiverStuffingErrorCount;
public long transceiverFormatErrorCount;
public long transceiverACKErrorCount;
public long transceiverBit1ErrorCount;
public long transceiverBit0ErrorCount;
public long transceiverCRCErrorCount;
public long writeBufferTimeoutErrorCount;
public long readBufferOverflowErrorCount;
public int readBufferOverflowErrorOccurredLength;
public boolean[] readBufferOverflowErrorOccurredData = new boolean[32];
public long readBacklogOverflowErrorCount;
public String toString() {
return "[" + "transceiverState = " + transceiverState + ", " + "transceiverWriteErrorLevel = " + transceiverWriteErrorLevel + ", " + "transceiverReadErrorLevel = " + transceiverReadErrorLevel + ", " + "transceiverStuffingErrorCount = " + transceiverStuffingErrorCount + ", " + "transceiverFormatErrorCount = " + transceiverFormatErrorCount + ", " + "transceiverACKErrorCount = " + transceiverACKErrorCount + ", " + "transceiverBit1ErrorCount = " + transceiverBit1ErrorCount + ", " + "transceiverBit0ErrorCount = " + transceiverBit0ErrorCount + ", " + "transceiverCRCErrorCount = " + transceiverCRCErrorCount + ", " + "writeBufferTimeoutErrorCount = " + writeBufferTimeoutErrorCount + ", " + "readBufferOverflowErrorCount = " + readBufferOverflowErrorCount + ", " + "readBufferOverflowErrorOccurredLength = " + readBufferOverflowErrorOccurredLength + ", " + "readBufferOverflowErrorOccurredData = " + Arrays.toString(readBufferOverflowErrorOccurredData) + ", " + "readBacklogOverflowErrorCount = " + readBacklogOverflowErrorCount + "]";
}
}
public class SPITFPErrorCount {
public long errorCountAckChecksum;
public long errorCountMessageChecksum;
public long errorCountFrame;
public long errorCountOverflow;
public String toString() {
return "[" + "errorCountAckChecksum = " + errorCountAckChecksum + ", " + "errorCountMessageChecksum = " + errorCountMessageChecksum + ", " + "errorCountFrame = " + errorCountFrame + ", " + "errorCountOverflow = " + errorCountOverflow + "]";
}
}
public class ReadFrame {
public boolean success;
public int frameType;
public long identifier;
public int[] data;
public ReadFrame(boolean success, int frameType, long identifier, int[] data) {
this.success = success;
this.frameType = frameType;
this.identifier = identifier;
this.data = data;
}
public String toString() {
return "[" + "success = " + success + ", " + "frameType = " + frameType + ", " + "identifier = " + identifier + ", " + "data = " + Arrays.toString(data) + "]";
}
}
public class QueueConfiguration {
public int writeBufferSize;
public int writeBufferTimeout;
public int writeBacklogSize;
public int[] readBufferSizes;
public int readBacklogSize;
public QueueConfiguration(int writeBufferSize, int writeBufferTimeout, int writeBacklogSize, int[] readBufferSizes, int readBacklogSize) {
this.writeBufferSize = writeBufferSize;
this.writeBufferTimeout = writeBufferTimeout;
this.writeBacklogSize = writeBacklogSize;
this.readBufferSizes = readBufferSizes;
this.readBacklogSize = readBacklogSize;
}
public String toString() {
return "[" + "writeBufferSize = " + writeBufferSize + ", " + "writeBufferTimeout = " + writeBufferTimeout + ", " + "writeBacklogSize = " + writeBacklogSize + ", " + "readBufferSizes = " + Arrays.toString(readBufferSizes) + ", " + "readBacklogSize = " + readBacklogSize + "]";
}
}
public class ErrorLog {
public int transceiverState;
public int transceiverWriteErrorLevel;
public int transceiverReadErrorLevel;
public long transceiverStuffingErrorCount;
public long transceiverFormatErrorCount;
public long transceiverACKErrorCount;
public long transceiverBit1ErrorCount;
public long transceiverBit0ErrorCount;
public long transceiverCRCErrorCount;
public long writeBufferTimeoutErrorCount;
public long readBufferOverflowErrorCount;
public boolean[] readBufferOverflowErrorOccurred;
public long readBacklogOverflowErrorCount;
public ErrorLog(int transceiverState, int transceiverWriteErrorLevel, int transceiverReadErrorLevel, long transceiverStuffingErrorCount, long transceiverFormatErrorCount, long transceiverACKErrorCount, long transceiverBit1ErrorCount, long transceiverBit0ErrorCount, long transceiverCRCErrorCount, long writeBufferTimeoutErrorCount, long readBufferOverflowErrorCount, boolean[] readBufferOverflowErrorOccurred, long readBacklogOverflowErrorCount) {
this.transceiverState = transceiverState;
this.transceiverWriteErrorLevel = transceiverWriteErrorLevel;
this.transceiverReadErrorLevel = transceiverReadErrorLevel;
this.transceiverStuffingErrorCount = transceiverStuffingErrorCount;
this.transceiverFormatErrorCount = transceiverFormatErrorCount;
this.transceiverACKErrorCount = transceiverACKErrorCount;
this.transceiverBit1ErrorCount = transceiverBit1ErrorCount;
this.transceiverBit0ErrorCount = transceiverBit0ErrorCount;
this.transceiverCRCErrorCount = transceiverCRCErrorCount;
this.writeBufferTimeoutErrorCount = writeBufferTimeoutErrorCount;
this.readBufferOverflowErrorCount = readBufferOverflowErrorCount;
this.readBufferOverflowErrorOccurred = readBufferOverflowErrorOccurred;
this.readBacklogOverflowErrorCount = readBacklogOverflowErrorCount;
}
public String toString() {
return "[" + "transceiverState = " + transceiverState + ", " + "transceiverWriteErrorLevel = " + transceiverWriteErrorLevel + ", " + "transceiverReadErrorLevel = " + transceiverReadErrorLevel + ", " + "transceiverStuffingErrorCount = " + transceiverStuffingErrorCount + ", " + "transceiverFormatErrorCount = " + transceiverFormatErrorCount + ", " + "transceiverACKErrorCount = " + transceiverACKErrorCount + ", " + "transceiverBit1ErrorCount = " + transceiverBit1ErrorCount + ", " + "transceiverBit0ErrorCount = " + transceiverBit0ErrorCount + ", " + "transceiverCRCErrorCount = " + transceiverCRCErrorCount + ", " + "writeBufferTimeoutErrorCount = " + writeBufferTimeoutErrorCount + ", " + "readBufferOverflowErrorCount = " + readBufferOverflowErrorCount + ", " + "readBufferOverflowErrorOccurred = " + Arrays.toString(readBufferOverflowErrorOccurred) + ", " + "readBacklogOverflowErrorCount = " + readBacklogOverflowErrorCount + "]";
}
}
/**
* @see FrameReadListener
*/
public interface FrameReadLowLevelListener extends DeviceListener {
public void frameReadLowLevel(int frameType, long identifier, int dataLength, int[] dataData);
}
/**
* This listener is triggered if a data or remote frame was received by the CAN
* transceiver.
*
* The ``identifier`` return value follows the identifier format described for
* {@link BrickletCANV2#writeFrame(int, long, int[])}.
*
* For details on the ``data`` return value see {@link BrickletCANV2#readFrame()}.
*
* A configurable read filter can be used to define which frames should be
* received by the CAN transceiver and put into the read queue (see
* {@link BrickletCANV2#setQueueConfiguration(int, int, int, int[], int)}).
*
* To enable this listener, use {@link BrickletCANV2#setFrameReadCallbackConfiguration(boolean)}.
*
* \note
* If reconstructing the value fails, the listener is triggered with null for data.
*/
public interface FrameReadListener extends DeviceListener {
public void frameRead(int frameType, long identifier, int[] data);
}
/**
* Creates an object with the unique device ID \c uid. and adds it to
* the IP Connection \c ipcon.
*/
public BrickletCANV2(String uid, IPConnection ipcon) {
super(uid, ipcon);
apiVersion[0] = 2;
apiVersion[1] = 0;
apiVersion[2] = 0;
responseExpected[IPConnection.unsignedByte(FUNCTION_WRITE_FRAME_LOW_LEVEL)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_READ_FRAME_LOW_LEVEL)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_SET_FRAME_READ_CALLBACK_CONFIGURATION)] = RESPONSE_EXPECTED_FLAG_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_GET_FRAME_READ_CALLBACK_CONFIGURATION)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_SET_TRANSCEIVER_CONFIGURATION)] = RESPONSE_EXPECTED_FLAG_FALSE;
responseExpected[IPConnection.unsignedByte(FUNCTION_GET_TRANSCEIVER_CONFIGURATION)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_SET_QUEUE_CONFIGURATION_LOW_LEVEL)] = RESPONSE_EXPECTED_FLAG_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_GET_QUEUE_CONFIGURATION_LOW_LEVEL)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_SET_READ_FILTER_CONFIGURATION)] = RESPONSE_EXPECTED_FLAG_FALSE;
responseExpected[IPConnection.unsignedByte(FUNCTION_GET_READ_FILTER_CONFIGURATION)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_GET_ERROR_LOG_LOW_LEVEL)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_SET_COMMUNICATION_LED_CONFIG)] = RESPONSE_EXPECTED_FLAG_FALSE;
responseExpected[IPConnection.unsignedByte(FUNCTION_GET_COMMUNICATION_LED_CONFIG)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_SET_ERROR_LED_CONFIG)] = RESPONSE_EXPECTED_FLAG_FALSE;
responseExpected[IPConnection.unsignedByte(FUNCTION_GET_ERROR_LED_CONFIG)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_GET_SPITFP_ERROR_COUNT)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_SET_BOOTLOADER_MODE)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_GET_BOOTLOADER_MODE)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_SET_WRITE_FIRMWARE_POINTER)] = RESPONSE_EXPECTED_FLAG_FALSE;
responseExpected[IPConnection.unsignedByte(FUNCTION_WRITE_FIRMWARE)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_SET_STATUS_LED_CONFIG)] = RESPONSE_EXPECTED_FLAG_FALSE;
responseExpected[IPConnection.unsignedByte(FUNCTION_GET_STATUS_LED_CONFIG)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_GET_CHIP_TEMPERATURE)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_RESET)] = RESPONSE_EXPECTED_FLAG_FALSE;
responseExpected[IPConnection.unsignedByte(FUNCTION_WRITE_UID)] = RESPONSE_EXPECTED_FLAG_FALSE;
responseExpected[IPConnection.unsignedByte(FUNCTION_READ_UID)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
responseExpected[IPConnection.unsignedByte(FUNCTION_GET_IDENTITY)] = RESPONSE_EXPECTED_FLAG_ALWAYS_TRUE;
highLevelCallbacks[-CALLBACK_FRAME_READ] = new IPConnection.DeviceHighLevelCallback();
callbacks[CALLBACK_FRAME_READ_LOW_LEVEL] = new IPConnection.DeviceCallbackListener() {
public void callback(byte[] packet) {
ByteBuffer bb = ByteBuffer.wrap(packet, 8, packet.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
int frameType = IPConnection.unsignedByte(bb.get());
long identifier = IPConnection.unsignedInt(bb.getInt());
int dataLength = IPConnection.unsignedByte(bb.get());
int[] dataData = new int[15];
for (int i = 0; i < 15; i++) {
dataData[i] = IPConnection.unsignedByte(bb.get());
}
int[] data = new int[dataLength];
System.arraycopy(dataData, 0, data, 0, dataLength);
for (FrameReadListener listener: listenerFrameRead) {
listener.frameRead(frameType, identifier, data);
}
for (FrameReadLowLevelListener listener: listenerFrameReadLowLevel) {
listener.frameReadLowLevel(frameType, identifier, dataLength, dataData);
}
}
};
}
/**
* Writes a data or remote frame to the write queue to be transmitted over the
* CAN transceiver.
*
* The Bricklet supports the standard 11-bit (CAN 2.0A) and the additional extended
* 29-bit (CAN 2.0B) identifiers. For standard frames the Bricklet uses bit 0 to 10
* from the ``identifier`` parameter as standard 11-bit identifier. For extended
* frames the Bricklet uses bit 0 to 28 from the ``identifier`` parameter as
* extended 29-bit identifier.
*
* The ``data`` parameter can be up to 15 bytes long. For data frames up to 8 bytes
* will be used as the actual data. The length (DLC) field in the data or remote
* frame will be set to the actual length of the ``data`` parameter. This allows
* to transmit data and remote frames with excess length. For remote frames only
* the length of the ``data`` parameter is used. The actual ``data`` bytes are
* ignored.
*
* Returns *true* if the frame was successfully added to the write queue. Returns
* *false* if the frame could not be added because write queue is already full or
* because the write buffer or the write backlog are configured with a size of
* zero (see {@link BrickletCANV2#setQueueConfiguration(int, int, int, int[], int)}).
*
* The write queue can overflow if frames are written to it at a higher rate
* than the Bricklet can transmitted them over the CAN transceiver. This may
* happen if the CAN transceiver is configured as read-only or is using a low baud
* rate (see {@link BrickletCANV2#setTransceiverConfiguration(long, int, int)}). It can also happen if the CAN
* bus is congested and the frame cannot be transmitted because it constantly loses
* arbitration or because the CAN transceiver is currently disabled due to a high
* write error level (see {@link BrickletCANV2#getErrorLog()}).
*/
public boolean writeFrameLowLevel(int frameType, long identifier, int dataLength, int[] dataData) throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)29, FUNCTION_WRITE_FRAME_LOW_LEVEL, this);
bb.put((byte)frameType);
bb.putInt((int)identifier);
bb.put((byte)dataLength);
for (int i = 0; i < 15; i++) {
bb.put((byte)dataData[i]);
}
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
boolean success = (bb.get()) != 0;
return success;
}
/**
* Tries to read the next data or remote frame from the read queue and returns it.
* If a frame was successfully read, then the ``success`` return value is set to
* *true* and the other return values contain the frame. If the read queue is
* empty and no frame could be read, then the ``success`` return value is set to
* *false* and the other return values contain invalid data.
*
* The ``identifier`` return value follows the identifier format described for
* {@link BrickletCANV2#writeFrame(int, long, int[])}.
*
* The ``data`` return value can be up to 15 bytes long. For data frames up to the
* first 8 bytes are the actual received data. All bytes after the 8th byte are
* always zero and only there to indicate the length of a data or remote frame
* with excess length. For remote frames the length of the ``data`` return value
* represents the requested length. The actual ``data`` bytes are always zero.
*
* A configurable read filter can be used to define which frames should be
* received by the CAN transceiver and put into the read queue (see
* {@link BrickletCANV2#setReadFilterConfiguration(int, int, long, long)}).
*
* Instead of polling with this function, you can also use listeners. See the
* {@link BrickletCANV2#setFrameReadCallbackConfiguration(boolean)} function and the {@link BrickletCANV2.FrameReadListener}
* callback.
*/
public ReadFrameLowLevel readFrameLowLevel() throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)8, FUNCTION_READ_FRAME_LOW_LEVEL, this);
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
ReadFrameLowLevel obj = new ReadFrameLowLevel();
obj.success = (bb.get()) != 0;
obj.frameType = IPConnection.unsignedByte(bb.get());
obj.identifier = IPConnection.unsignedInt(bb.getInt());
obj.dataLength = IPConnection.unsignedByte(bb.get());
for (int i = 0; i < 15; i++) {
obj.dataData[i] = IPConnection.unsignedByte(bb.get());
}
return obj;
}
/**
* Enables and disables the {@link BrickletCANV2.FrameReadListener} listener.
*
* By default the listener is disabled.
*/
public void setFrameReadCallbackConfiguration(boolean enabled) throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)9, FUNCTION_SET_FRAME_READ_CALLBACK_CONFIGURATION, this);
bb.put((byte)(enabled ? 1 : 0));
sendRequest(bb.array());
}
/**
* Returns *true* if the {@link BrickletCANV2.FrameReadListener} listener is enabled, *false* otherwise.
*/
public boolean getFrameReadCallbackConfiguration() throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)8, FUNCTION_GET_FRAME_READ_CALLBACK_CONFIGURATION, this);
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
boolean enabled = (bb.get()) != 0;
return enabled;
}
/**
* Sets the transceiver configuration for the CAN bus communication.
*
* The CAN transceiver has three different modes:
*
* * Normal: Reads from and writes to the CAN bus and performs active bus
* error detection and acknowledgement.
* * Loopback: All reads and writes are performed internally. The transceiver
* is disconnected from the actual CAN bus.
* * Read-Only: Only reads from the CAN bus, but does neither active bus error
* detection nor acknowledgement. Only the receiving part of the transceiver
* is connected to the CAN bus.
*/
public void setTransceiverConfiguration(long baudRate, int samplePoint, int transceiverMode) throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)15, FUNCTION_SET_TRANSCEIVER_CONFIGURATION, this);
bb.putInt((int)baudRate);
bb.putShort((short)samplePoint);
bb.put((byte)transceiverMode);
sendRequest(bb.array());
}
/**
* Returns the configuration as set by {@link BrickletCANV2#setTransceiverConfiguration(long, int, int)}.
*/
public TransceiverConfiguration getTransceiverConfiguration() throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)8, FUNCTION_GET_TRANSCEIVER_CONFIGURATION, this);
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
TransceiverConfiguration obj = new TransceiverConfiguration();
obj.baudRate = IPConnection.unsignedInt(bb.getInt());
obj.samplePoint = IPConnection.unsignedShort(bb.getShort());
obj.transceiverMode = IPConnection.unsignedByte(bb.get());
return obj;
}
/**
* Sets the write and read queue configuration.
*
* The CAN transceiver has 32 buffers in total in hardware for transmitting and
* receiving frames. Additionally, the Bricklet has a backlog for 768 frames in
* total in software. The buffers and the backlog can be freely assigned to the
* write and read queues.
*
* {@link BrickletCANV2#writeFrame(int, long, int[])} writes a frame into the write backlog. The Bricklet moves
* the frame from the backlog into a free write buffer. The CAN transceiver then
* transmits the frame from the write buffer to the CAN bus. If there are no
* write buffers (``write_buffer_size`` is zero) or there is no write backlog
* (``write_backlog_size`` is zero) then no frames can be transmitted and
* {@link BrickletCANV2#writeFrame(int, long, int[])} returns always *false*.
*
* The CAN transceiver receives a frame from the CAN bus and stores it into a
* free read buffer. The Bricklet moves the frame from the read buffer into the
* read backlog. {@link BrickletCANV2#readFrame()} reads the frame from the read backlog and
* returns it. If there are no read buffers (``read_buffer_sizes`` is empty) or
* there is no read backlog (``read_backlog_size`` is zero) then no frames can be
* received and {@link BrickletCANV2#readFrame()} returns always *false*.
*
* There can be multiple read buffers, because the CAN transceiver cannot receive
* data and remote frames into the same read buffer. A positive read buffer size
* represents a data frame read buffer and a negative read buffer size represents
* a remote frame read buffer. A read buffer size of zero is not allowed. By
* default the first read buffer is configured for data frames and the second read
* buffer is configured for remote frame. There can be up to 32 different read
* buffers, assuming that no write buffer is used. Each read buffer has its own
* filter configuration (see {@link BrickletCANV2#setReadFilterConfiguration(int, int, long, long)}).
*
* A valid queue configuration fulfills these conditions::
*
* write_buffer_size + abs(read_buffer_size_0) + abs(read_buffer_size_1) + ... + abs(read_buffer_size_31) <= 32
* write_backlog_size + read_backlog_size <= 768
*
* The write buffer timeout has three different modes that define how a failed
* frame transmission should be handled:
*
* * Single-Shot (< 0): Only one transmission attempt will be made. If the
* transmission fails then the frame is discarded.
* * Infinite (= 0): Infinite transmission attempts will be made. The frame will
* never be discarded.
* * Milliseconds (> 0): A limited number of transmission attempts will be made.
* If the frame could not be transmitted successfully after the configured
* number of milliseconds then the frame is discarded.
*
* The current content of the queues is lost when this function is called.
*/
public void setQueueConfigurationLowLevel(int writeBufferSize, int writeBufferTimeout, int writeBacklogSize, int readBufferSizesLength, int[] readBufferSizesData, int readBacklogSize) throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)50, FUNCTION_SET_QUEUE_CONFIGURATION_LOW_LEVEL, this);
bb.put((byte)writeBufferSize);
bb.putInt(writeBufferTimeout);
bb.putShort((short)writeBacklogSize);
bb.put((byte)readBufferSizesLength);
for (int i = 0; i < 32; i++) {
bb.put((byte)readBufferSizesData[i]);
}
bb.putShort((short)readBacklogSize);
sendRequest(bb.array());
}
/**
* Returns the queue configuration as set by {@link BrickletCANV2#setQueueConfiguration(int, int, int, int[], int)}.
*/
public QueueConfigurationLowLevel getQueueConfigurationLowLevel() throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)8, FUNCTION_GET_QUEUE_CONFIGURATION_LOW_LEVEL, this);
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
QueueConfigurationLowLevel obj = new QueueConfigurationLowLevel();
obj.writeBufferSize = IPConnection.unsignedByte(bb.get());
obj.writeBufferTimeout = (bb.getInt());
obj.writeBacklogSize = IPConnection.unsignedShort(bb.getShort());
obj.readBufferSizesLength = IPConnection.unsignedByte(bb.get());
for (int i = 0; i < 32; i++) {
obj.readBufferSizesData[i] = (bb.get());
}
obj.readBacklogSize = IPConnection.unsignedShort(bb.getShort());
return obj;
}
/**
* Set the read filter configuration for the given read buffer index. This can be
* used to define which frames should be received by the CAN transceiver and put
* into the read buffer.
*
* The read filter has four different modes that define if and how the filter mask
* and the filter identifier are applied:
*
* * Accept-All: All frames are received.
* * Match-Standard-Only: Only standard frames with a matching identifier are
* received.
* * Match-Extended-Only: Only extended frames with a matching identifier are
* received.
* * Match-Standard-And-Extended: Standard and extended frames with a matching
* identifier are received.
*
* The filter mask and filter identifier are used as bit masks. Their usage
* depends on the mode:
*
* * Accept-All: Mask and identifier are ignored.
* * Match-Standard-Only: Bit 0 to 10 (11 bits) of filter mask and filter
* identifier are used to match the 11-bit identifier of standard frames.
* * Match-Extended-Only: Bit 0 to 28 (29 bits) of filter mask and filter
* identifier are used to match the 29-bit identifier of extended frames.
* * Match-Standard-And-Extended: Bit 18 to 28 (11 bits) of filter mask and filter
* identifier are used to match the 11-bit identifier of standard frames, bit 0
* to 17 (18 bits) are ignored in this case. Bit 0 to 28 (29 bits) of filter
* mask and filter identifier are used to match the 29-bit identifier of extended
* frames.
*
* The filter mask and filter identifier are applied in this way: The filter mask
* is used to select the frame identifier bits that should be compared to the
* corresponding filter identifier bits. All unselected bits are automatically
* accepted. All selected bits have to match the filter identifier to be accepted.
* If all bits for the selected mode are accepted then the frame is accepted and
* is added to the read buffer.
*
* \verbatim
* "Filter Mask Bit", "Filter Identifier Bit", "Frame Identifier Bit", "Result"
*
* 0, X, X, Accept
* 1, 0, 0, Accept
* 1, 0, 1, Reject
* 1, 1, 0, Reject
* 1, 1, 1, Accept
* \endverbatim
*
* For example, to receive standard frames with identifier 0x123 only, the mode
* can be set to Match-Standard-Only with 0x7FF as mask and 0x123 as identifier.
* The mask of 0x7FF selects all 11 identifier bits for matching so that the
* identifier has to be exactly 0x123 to be accepted.
*
* To accept identifier 0x123 and identifier 0x456 at the same time, just set
* filter 2 to 0x456 and keep mask and filter 1 unchanged.
*
* There can be up to 32 different read filters configured at the same time,
* because there can be up to 32 read buffer (see {@link BrickletCANV2#setQueueConfiguration(int, int, int, int[], int)}).
*
* The default mode is accept-all for all read buffers.
*/
public void setReadFilterConfiguration(int bufferIndex, int filterMode, long filterMask, long filterIdentifier) throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)18, FUNCTION_SET_READ_FILTER_CONFIGURATION, this);
bb.put((byte)bufferIndex);
bb.put((byte)filterMode);
bb.putInt((int)filterMask);
bb.putInt((int)filterIdentifier);
sendRequest(bb.array());
}
/**
* Returns the read filter configuration as set by {@link BrickletCANV2#setReadFilterConfiguration(int, int, long, long)}.
*/
public ReadFilterConfiguration getReadFilterConfiguration(int bufferIndex) throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)9, FUNCTION_GET_READ_FILTER_CONFIGURATION, this);
bb.put((byte)bufferIndex);
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
ReadFilterConfiguration obj = new ReadFilterConfiguration();
obj.filterMode = IPConnection.unsignedByte(bb.get());
obj.filterMask = IPConnection.unsignedInt(bb.getInt());
obj.filterIdentifier = IPConnection.unsignedInt(bb.getInt());
return obj;
}
/**
* Returns information about different kinds of errors.
*
* The write and read error levels indicate the current level of stuffing, form,
* acknowledgement, bit and checksum errors during CAN bus write and read
* operations. For each of this error kinds there is also an individual counter.
*
* When the write error level extends 255 then the CAN transceiver gets disabled
* and no frames can be transmitted or received anymore. The CAN transceiver will
* automatically be activated again after the CAN bus is idle for a while.
*
* The write buffer timeout, read buffer and backlog overflow counts represents the
* number of these errors:
*
* * A write buffer timeout occurs if a frame could not be transmitted before the
* configured write buffer timeout expired (see {@link BrickletCANV2#setQueueConfiguration(int, int, int, int[], int)}).
* * A read buffer overflow occurs if a read buffer of the CAN transceiver
* still contains the last received frame when the next frame arrives. In this
* case the last received frame is lost. This happens if the CAN transceiver
* receives more frames than the Bricklet can handle. Using the read filter
* (see {@link BrickletCANV2#setReadFilterConfiguration(int, int, long, long)}) can help to reduce the amount of
* received frames. This count is not exact, but a lower bound, because the
* Bricklet might not able detect all overflows if they occur in rapid succession.
* * A read backlog overflow occurs if the read backlog of the Bricklet is already
* full when the next frame should be read from a read buffer of the CAN
* transceiver. In this case the frame in the read buffer is lost. This
* happens if the CAN transceiver receives more frames to be added to the read
* backlog than are removed from the read backlog using the {@link BrickletCANV2#readFrame()}
* function. Using the {@link BrickletCANV2.FrameReadListener} listener ensures that the read backlog
* can not overflow.
*
* The read buffer overflow counter counts the overflows of all configured read
* buffers. Which read buffer exactly suffered from an overflow can be figured
* out from the read buffer overflow occurrence list
* (``read_buffer_overflow_error_occurred``).
*/
public ErrorLogLowLevel getErrorLogLowLevel() throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)8, FUNCTION_GET_ERROR_LOG_LOW_LEVEL, this);
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
ErrorLogLowLevel obj = new ErrorLogLowLevel();
obj.transceiverState = IPConnection.unsignedByte(bb.get());
obj.transceiverWriteErrorLevel = IPConnection.unsignedByte(bb.get());
obj.transceiverReadErrorLevel = IPConnection.unsignedByte(bb.get());
obj.transceiverStuffingErrorCount = IPConnection.unsignedInt(bb.getInt());
obj.transceiverFormatErrorCount = IPConnection.unsignedInt(bb.getInt());
obj.transceiverACKErrorCount = IPConnection.unsignedInt(bb.getInt());
obj.transceiverBit1ErrorCount = IPConnection.unsignedInt(bb.getInt());
obj.transceiverBit0ErrorCount = IPConnection.unsignedInt(bb.getInt());
obj.transceiverCRCErrorCount = IPConnection.unsignedInt(bb.getInt());
obj.writeBufferTimeoutErrorCount = IPConnection.unsignedInt(bb.getInt());
obj.readBufferOverflowErrorCount = IPConnection.unsignedInt(bb.getInt());
obj.readBufferOverflowErrorOccurredLength = IPConnection.unsignedByte(bb.get());
byte[] readBufferOverflowErrorOccurredDataBits = new byte[4];
bb.get(readBufferOverflowErrorOccurredDataBits);
for (int i = 0; i < 32; i++) {
obj.readBufferOverflowErrorOccurredData[i] = (readBufferOverflowErrorOccurredDataBits[i / 8] & (1 << (i % 8))) != 0;
}
obj.readBacklogOverflowErrorCount = IPConnection.unsignedInt(bb.getInt());
return obj;
}
/**
* Sets the communication LED configuration. By default the LED shows
* CAN-Bus traffic, it flickers once for every 40 transmitted or received frames.
*
* You can also turn the LED permanently on/off or show a heartbeat.
*
* If the Bricklet is in bootloader mode, the LED is off.
*/
public void setCommunicationLEDConfig(int config) throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)9, FUNCTION_SET_COMMUNICATION_LED_CONFIG, this);
bb.put((byte)config);
sendRequest(bb.array());
}
/**
* Returns the configuration as set by {@link BrickletCANV2#setCommunicationLEDConfig(int)}
*/
public int getCommunicationLEDConfig() throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)8, FUNCTION_GET_COMMUNICATION_LED_CONFIG, this);
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
int config = IPConnection.unsignedByte(bb.get());
return config;
}
/**
* Sets the error LED configuration.
*
* By default (show-transceiver-state) the error LED turns on if the CAN
* transceiver is passive or disabled state (see {@link BrickletCANV2#getErrorLog()}). If
* the CAN transceiver is in active state the LED turns off.
*
* If the LED is configured as show-error then the error LED turns on if any error
* occurs. If you call this function with the show-error option again, the LED will
* turn off until the next error occurs.
*
* You can also turn the LED permanently on/off or show a heartbeat.
*
* If the Bricklet is in bootloader mode, the LED is off.
*/
public void setErrorLEDConfig(int config) throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)9, FUNCTION_SET_ERROR_LED_CONFIG, this);
bb.put((byte)config);
sendRequest(bb.array());
}
/**
* Returns the configuration as set by {@link BrickletCANV2#setErrorLEDConfig(int)}.
*/
public int getErrorLEDConfig() throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)8, FUNCTION_GET_ERROR_LED_CONFIG, this);
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
int config = IPConnection.unsignedByte(bb.get());
return config;
}
/**
* Returns the error count for the communication between Brick and Bricklet.
*
* The errors are divided into
*
* * ACK checksum errors,
* * message checksum errors,
* * framing errors and
* * overflow errors.
*
* The errors counts are for errors that occur on the Bricklet side. All
* Bricks have a similar function that returns the errors on the Brick side.
*/
public SPITFPErrorCount getSPITFPErrorCount() throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)8, FUNCTION_GET_SPITFP_ERROR_COUNT, this);
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
SPITFPErrorCount obj = new SPITFPErrorCount();
obj.errorCountAckChecksum = IPConnection.unsignedInt(bb.getInt());
obj.errorCountMessageChecksum = IPConnection.unsignedInt(bb.getInt());
obj.errorCountFrame = IPConnection.unsignedInt(bb.getInt());
obj.errorCountOverflow = IPConnection.unsignedInt(bb.getInt());
return obj;
}
/**
* Sets the bootloader mode and returns the status after the requested
* mode change was instigated.
*
* You can change from bootloader mode to firmware mode and vice versa. A change
* from bootloader mode to firmware mode will only take place if the entry function,
* device identifier and CRC are present and correct.
*
* This function is used by Brick Viewer during flashing. It should not be
* necessary to call it in a normal user program.
*/
public int setBootloaderMode(int mode) throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)9, FUNCTION_SET_BOOTLOADER_MODE, this);
bb.put((byte)mode);
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
int status = IPConnection.unsignedByte(bb.get());
return status;
}
/**
* Returns the current bootloader mode, see {@link BrickletCANV2#setBootloaderMode(int)}.
*/
public int getBootloaderMode() throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)8, FUNCTION_GET_BOOTLOADER_MODE, this);
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
int mode = IPConnection.unsignedByte(bb.get());
return mode;
}
/**
* Sets the firmware pointer for {@link BrickletCANV2#writeFirmware(int[])}. The pointer has
* to be increased by chunks of size 64. The data is written to flash
* every 4 chunks (which equals to one page of size 256).
*
* This function is used by Brick Viewer during flashing. It should not be
* necessary to call it in a normal user program.
*/
public void setWriteFirmwarePointer(long pointer) throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)12, FUNCTION_SET_WRITE_FIRMWARE_POINTER, this);
bb.putInt((int)pointer);
sendRequest(bb.array());
}
/**
* Writes 64 Bytes of firmware at the position as written by
* {@link BrickletCANV2#setWriteFirmwarePointer(long)} before. The firmware is written
* to flash every 4 chunks.
*
* You can only write firmware in bootloader mode.
*
* This function is used by Brick Viewer during flashing. It should not be
* necessary to call it in a normal user program.
*/
public int writeFirmware(int[] data) throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)72, FUNCTION_WRITE_FIRMWARE, this);
for (int i = 0; i < 64; i++) {
bb.put((byte)data[i]);
}
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
int status = IPConnection.unsignedByte(bb.get());
return status;
}
/**
* Sets the status LED configuration. By default the LED shows
* communication traffic between Brick and Bricklet, it flickers once
* for every 10 received data packets.
*
* You can also turn the LED permanently on/off or show a heartbeat.
*
* If the Bricklet is in bootloader mode, the LED is will show heartbeat by default.
*/
public void setStatusLEDConfig(int config) throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)9, FUNCTION_SET_STATUS_LED_CONFIG, this);
bb.put((byte)config);
sendRequest(bb.array());
}
/**
* Returns the configuration as set by {@link BrickletCANV2#setStatusLEDConfig(int)}
*/
public int getStatusLEDConfig() throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)8, FUNCTION_GET_STATUS_LED_CONFIG, this);
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
int config = IPConnection.unsignedByte(bb.get());
return config;
}
/**
* Returns the temperature in °C as measured inside the microcontroller. The
* value returned is not the ambient temperature!
*
* The temperature is only proportional to the real temperature and it has bad
* accuracy. Practically it is only useful as an indicator for
* temperature changes.
*/
public int getChipTemperature() throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)8, FUNCTION_GET_CHIP_TEMPERATURE, this);
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
int temperature = (bb.getShort());
return temperature;
}
/**
* Calling this function will reset the Bricklet. All configurations
* will be lost.
*
* After a reset you have to create new device objects,
* calling functions on the existing ones will result in
* undefined behavior!
*/
public void reset() throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)8, FUNCTION_RESET, this);
sendRequest(bb.array());
}
/**
* Writes a new UID into flash. If you want to set a new UID
* you have to decode the Base58 encoded UID string into an
* integer first.
*
* We recommend that you use Brick Viewer to change the UID.
*/
public void writeUID(long uid) throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)12, FUNCTION_WRITE_UID, this);
bb.putInt((int)uid);
sendRequest(bb.array());
}
/**
* Returns the current UID as an integer. Encode as
* Base58 to get the usual string version.
*/
public long readUID() throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)8, FUNCTION_READ_UID, this);
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
long uid = IPConnection.unsignedInt(bb.getInt());
return uid;
}
/**
* Returns the UID, the UID where the Bricklet is connected to,
* the position, the hardware and firmware version as well as the
* device identifier.
*
* The position can be 'a', 'b', 'c' or 'd'.
*
* The device identifier numbers can be found :ref:`here <device_identifier>`.
* |device_identifier_constant|
*/
public Identity getIdentity() throws TinkerforgeException {
ByteBuffer bb = ipcon.createRequestPacket((byte)8, FUNCTION_GET_IDENTITY, this);
byte[] response = sendRequest(bb.array());
bb = ByteBuffer.wrap(response, 8, response.length - 8);
bb.order(ByteOrder.LITTLE_ENDIAN);
Identity obj = new Identity();
obj.uid = IPConnection.string(bb, 8);
obj.connectedUid = IPConnection.string(bb, 8);
obj.position = (char)(bb.get());
for (int i = 0; i < 3; i++) {
obj.hardwareVersion[i] = IPConnection.unsignedByte(bb.get());
}
for (int i = 0; i < 3; i++) {
obj.firmwareVersion[i] = IPConnection.unsignedByte(bb.get());
}
obj.deviceIdentifier = IPConnection.unsignedShort(bb.getShort());
return obj;
}
/**
* Writes a data or remote frame to the write queue to be transmitted over the
* CAN transceiver.
*
* The Bricklet supports the standard 11-bit (CAN 2.0A) and the additional extended
* 29-bit (CAN 2.0B) identifiers. For standard frames the Bricklet uses bit 0 to 10
* from the ``identifier`` parameter as standard 11-bit identifier. For extended
* frames the Bricklet uses bit 0 to 28 from the ``identifier`` parameter as
* extended 29-bit identifier.
*
* The ``data`` parameter can be up to 15 bytes long. For data frames up to 8 bytes
* will be used as the actual data. The length (DLC) field in the data or remote
* frame will be set to the actual length of the ``data`` parameter. This allows
* to transmit data and remote frames with excess length. For remote frames only
* the length of the ``data`` parameter is used. The actual ``data`` bytes are
* ignored.
*
* Returns *true* if the frame was successfully added to the write queue. Returns
* *false* if the frame could not be added because write queue is already full or
* because the write buffer or the write backlog are configured with a size of
* zero (see {@link BrickletCANV2#setQueueConfiguration(int, int, int, int[], int)}).
*
* The write queue can overflow if frames are written to it at a higher rate
* than the Bricklet can transmitted them over the CAN transceiver. This may
* happen if the CAN transceiver is configured as read-only or is using a low baud
* rate (see {@link BrickletCANV2#setTransceiverConfiguration(long, int, int)}). It can also happen if the CAN
* bus is congested and the frame cannot be transmitted because it constantly loses
* arbitration or because the CAN transceiver is currently disabled due to a high
* write error level (see {@link BrickletCANV2#getErrorLog()}).
*/
public boolean writeFrame(int frameType, long identifier, int[] data) throws TinkerforgeException {
if (data.length > 15) {
throw new IllegalArgumentException("Data can be at most 15 items long");
}
int dataLength = data.length;
int[] dataData = new int[15];
boolean ret;
System.arraycopy(data, 0, dataData, 0, dataLength);
Arrays.fill(dataData, dataLength, 15, 0);
ret = writeFrameLowLevel(frameType, identifier, dataLength, dataData);
return ret;
}
/**
* Tries to read the next data or remote frame from the read queue and returns it.
* If a frame was successfully read, then the ``success`` return value is set to
* *true* and the other return values contain the frame. If the read queue is
* empty and no frame could be read, then the ``success`` return value is set to
* *false* and the other return values contain invalid data.
*
* The ``identifier`` return value follows the identifier format described for
* {@link BrickletCANV2#writeFrame(int, long, int[])}.
*
* The ``data`` return value can be up to 15 bytes long. For data frames up to the
* first 8 bytes are the actual received data. All bytes after the 8th byte are
* always zero and only there to indicate the length of a data or remote frame
* with excess length. For remote frames the length of the ``data`` return value
* represents the requested length. The actual ``data`` bytes are always zero.
*
* A configurable read filter can be used to define which frames should be
* received by the CAN transceiver and put into the read queue (see
* {@link BrickletCANV2#setReadFilterConfiguration(int, int, long, long)}).
*
* Instead of polling with this function, you can also use listeners. See the
* {@link BrickletCANV2#setFrameReadCallbackConfiguration(boolean)} function and the {@link BrickletCANV2.FrameReadListener}
* callback.
*/
public ReadFrame readFrame() throws TinkerforgeException {
ReadFrameLowLevel ret = readFrameLowLevel();
int[] data = new int[ret.dataLength];
System.arraycopy(ret.dataData, 0, data, 0, ret.dataLength);
return new ReadFrame(ret.success, ret.frameType, ret.identifier, data);
}
/**
* Sets the write and read queue configuration.
*
* The CAN transceiver has 32 buffers in total in hardware for transmitting and
* receiving frames. Additionally, the Bricklet has a backlog for 768 frames in
* total in software. The buffers and the backlog can be freely assigned to the
* write and read queues.
*
* {@link BrickletCANV2#writeFrame(int, long, int[])} writes a frame into the write backlog. The Bricklet moves
* the frame from the backlog into a free write buffer. The CAN transceiver then
* transmits the frame from the write buffer to the CAN bus. If there are no
* write buffers (``write_buffer_size`` is zero) or there is no write backlog
* (``write_backlog_size`` is zero) then no frames can be transmitted and
* {@link BrickletCANV2#writeFrame(int, long, int[])} returns always *false*.
*
* The CAN transceiver receives a frame from the CAN bus and stores it into a
* free read buffer. The Bricklet moves the frame from the read buffer into the
* read backlog. {@link BrickletCANV2#readFrame()} reads the frame from the read backlog and
* returns it. If there are no read buffers (``read_buffer_sizes`` is empty) or
* there is no read backlog (``read_backlog_size`` is zero) then no frames can be
* received and {@link BrickletCANV2#readFrame()} returns always *false*.
*
* There can be multiple read buffers, because the CAN transceiver cannot receive
* data and remote frames into the same read buffer. A positive read buffer size
* represents a data frame read buffer and a negative read buffer size represents
* a remote frame read buffer. A read buffer size of zero is not allowed. By
* default the first read buffer is configured for data frames and the second read
* buffer is configured for remote frame. There can be up to 32 different read
* buffers, assuming that no write buffer is used. Each read buffer has its own
* filter configuration (see {@link BrickletCANV2#setReadFilterConfiguration(int, int, long, long)}).
*
* A valid queue configuration fulfills these conditions::
*
* write_buffer_size + abs(read_buffer_size_0) + abs(read_buffer_size_1) + ... + abs(read_buffer_size_31) <= 32
* write_backlog_size + read_backlog_size <= 768
*
* The write buffer timeout has three different modes that define how a failed
* frame transmission should be handled:
*
* * Single-Shot (< 0): Only one transmission attempt will be made. If the
* transmission fails then the frame is discarded.
* * Infinite (= 0): Infinite transmission attempts will be made. The frame will
* never be discarded.
* * Milliseconds (> 0): A limited number of transmission attempts will be made.
* If the frame could not be transmitted successfully after the configured
* number of milliseconds then the frame is discarded.
*
* The current content of the queues is lost when this function is called.
*/
public void setQueueConfiguration(int writeBufferSize, int writeBufferTimeout, int writeBacklogSize, int[] readBufferSizes, int readBacklogSize) throws TinkerforgeException {
if (readBufferSizes.length > 32) {
throw new IllegalArgumentException("Read Buffer Sizes can be at most 32 items long");
}
int readBufferSizesLength = readBufferSizes.length;
int[] readBufferSizesData = new int[32];
System.arraycopy(readBufferSizes, 0, readBufferSizesData, 0, readBufferSizesLength);
Arrays.fill(readBufferSizesData, readBufferSizesLength, 32, 0);
setQueueConfigurationLowLevel(writeBufferSize, writeBufferTimeout, writeBacklogSize, readBufferSizesLength, readBufferSizesData, readBacklogSize);
}
/**
* Returns the queue configuration as set by {@link BrickletCANV2#setQueueConfiguration(int, int, int, int[], int)}.
*/
public QueueConfiguration getQueueConfiguration() throws TinkerforgeException {
QueueConfigurationLowLevel ret = getQueueConfigurationLowLevel();
int[] readBufferSizes = new int[ret.readBufferSizesLength];
System.arraycopy(ret.readBufferSizesData, 0, readBufferSizes, 0, ret.readBufferSizesLength);
return new QueueConfiguration(ret.writeBufferSize, ret.writeBufferTimeout, ret.writeBacklogSize, readBufferSizes, ret.readBacklogSize);
}
/**
* Returns information about different kinds of errors.
*
* The write and read error levels indicate the current level of stuffing, form,
* acknowledgement, bit and checksum errors during CAN bus write and read
* operations. For each of this error kinds there is also an individual counter.
*
* When the write error level extends 255 then the CAN transceiver gets disabled
* and no frames can be transmitted or received anymore. The CAN transceiver will
* automatically be activated again after the CAN bus is idle for a while.
*
* The write buffer timeout, read buffer and backlog overflow counts represents the
* number of these errors:
*
* * A write buffer timeout occurs if a frame could not be transmitted before the
* configured write buffer timeout expired (see {@link BrickletCANV2#setQueueConfiguration(int, int, int, int[], int)}).
* * A read buffer overflow occurs if a read buffer of the CAN transceiver
* still contains the last received frame when the next frame arrives. In this
* case the last received frame is lost. This happens if the CAN transceiver
* receives more frames than the Bricklet can handle. Using the read filter
* (see {@link BrickletCANV2#setReadFilterConfiguration(int, int, long, long)}) can help to reduce the amount of
* received frames. This count is not exact, but a lower bound, because the
* Bricklet might not able detect all overflows if they occur in rapid succession.
* * A read backlog overflow occurs if the read backlog of the Bricklet is already
* full when the next frame should be read from a read buffer of the CAN
* transceiver. In this case the frame in the read buffer is lost. This
* happens if the CAN transceiver receives more frames to be added to the read
* backlog than are removed from the read backlog using the {@link BrickletCANV2#readFrame()}
* function. Using the {@link BrickletCANV2.FrameReadListener} listener ensures that the read backlog
* can not overflow.
*
* The read buffer overflow counter counts the overflows of all configured read
* buffers. Which read buffer exactly suffered from an overflow can be figured
* out from the read buffer overflow occurrence list
* (``read_buffer_overflow_error_occurred``).
*/
public ErrorLog getErrorLog() throws TinkerforgeException {
ErrorLogLowLevel ret = getErrorLogLowLevel();
boolean[] readBufferOverflowErrorOccurred = new boolean[ret.readBufferOverflowErrorOccurredLength];
System.arraycopy(ret.readBufferOverflowErrorOccurredData, 0, readBufferOverflowErrorOccurred, 0, ret.readBufferOverflowErrorOccurredLength);
return new ErrorLog(ret.transceiverState, ret.transceiverWriteErrorLevel, ret.transceiverReadErrorLevel, ret.transceiverStuffingErrorCount, ret.transceiverFormatErrorCount, ret.transceiverACKErrorCount, ret.transceiverBit1ErrorCount, ret.transceiverBit0ErrorCount, ret.transceiverCRCErrorCount, ret.writeBufferTimeoutErrorCount, ret.readBufferOverflowErrorCount, readBufferOverflowErrorOccurred, ret.readBacklogOverflowErrorCount);
}
/**
* Adds a FrameReadLowLevel listener.
*/
public void addFrameReadLowLevelListener(FrameReadLowLevelListener listener) {
listenerFrameReadLowLevel.add(listener);
}
/**
* Removes a FrameReadLowLevel listener.
*/
public void removeFrameReadLowLevelListener(FrameReadLowLevelListener listener) {
listenerFrameReadLowLevel.remove(listener);
}
/**
* Adds a FrameRead listener.
*/
public void addFrameReadListener(FrameReadListener listener) {
listenerFrameRead.add(listener);
}
/**
* Removes a FrameRead listener.
*/
public void removeFrameReadListener(FrameReadListener listener) {
listenerFrameRead.remove(listener);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy