All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.oracle.dio.i2cbus.impl.I2CCombinedMessage Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.oracle.dio.i2cbus.impl;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import com.oracle.dio.utils.ExceptionMessage;
import com.oracle.dio.utils.Logging;

import jdk.dio.ClosedDeviceException;
import jdk.dio.DeviceConfig;
import jdk.dio.UnavailableDeviceException;
import jdk.dio.i2cbus.I2CDevice;
import jdk.dio.i2cbus.I2CDeviceConfig;

class I2CCombinedMessage implements jdk.dio.i2cbus.I2CCombinedMessage {
    ArrayList> messageList = new ArrayList>();
    int messageBus = DeviceConfig.DEFAULT;
    boolean isAlreadyTransferedOnce;
    int rxMessageCount;
    int stopConditionIndex = -1;

    private class Message

{ public P device; public ByteBuffer buf; public int skip; public boolean isRx; public Message(P device, ByteBuffer buf, int skip, boolean isRx) { this.device = device; this.buf = buf; this.skip = skip; this.isRx = isRx; } } void validateAndAppend(Message message) throws ClosedDeviceException { synchronized (messageList) { if (isAlreadyTransferedOnce) { throw new IllegalStateException( ExceptionMessage.format(ExceptionMessage.I2CBUS_ALREADY_TRANSFERRED_MESSAGE) ); } if (0 > message.skip) { throw new IllegalArgumentException( ExceptionMessage.format(ExceptionMessage.I2CBUS_NEGATIVE_SKIP_ARG) ); } if (!message.device.isOpen()) { throw new ClosedDeviceException(); } /* check that can get '-1' here */ int busNumber = ((I2CDeviceConfig) message.device.getDescriptor().getConfiguration()).getControllerNumber(); if (DeviceConfig.DEFAULT == messageBus) { messageBus = busNumber; } else { if (messageBus != busNumber) { throw new IllegalArgumentException( ExceptionMessage.format(ExceptionMessage.I2CBUS_DIFFERENT_BUS_SLAVE_OPERATION) ); } } // null check and mark for stopCondition. if (message.buf.remaining() != 0 || message.skip > 0) { boolean alreadyAppended = false; for (Message already : messageList) { if (already.buf == message.buf) { alreadyAppended = true; break; } } // if the buffer is used several times, stop condition must occur only once, // on first use, if (!alreadyAppended) stopConditionIndex = messageList.size(); } messageList.add(message); if (message.isRx) { ++rxMessageCount; } } } /** * Creates a new {@code I2CCombinedMessage} instance. */ I2CCombinedMessage() { } /** * Appends a read message/operation from the provided I2C slave device. Reads up to * {@code rwBuf.remaining()} bytes of data from this slave device into the buffer {@code rxBuf}. * * @param slave the I2C slave device to read from. * @param rxBuf the buffer into which the data is read. * @return a reference to this {@code I2CCombinedMessage} object. * @throws NullPointerException If {@code rxBuf} is {@code null}. * @throws IllegalStateException if this message has already been transferred once. * @throws ClosedDeviceException if the device has been closed. * @throws IllegalArgumentException if appending the read operation to a slave on a different bus. */ public I2CCombinedMessage appendRead(I2CDevice slave, ByteBuffer rxBuf) throws ClosedDeviceException { validateAndAppend(new Message(slave, rxBuf, 0, true)); return this; } /** * Appends a read message/operation from the provided I2C slave device. Reads up to * {@code rwBuf.remaining()} bytes of data from this slave device into the buffer skipping * {@code rxBuf} the first {@code rxSkip} bytes read. * * @param slave the I2C slave device to read from. * @param rxSkip the number of read bytes that must be ignored/skipped before filling in the * {@code rxBuf} buffer. * @param rxBuf the buffer into which the data is read. * @return a reference to this {@code I2CCombinedMessage} object. * @throws IOException if some other I/O error occurs. * @throws NullPointerException If {@code rxBuf} is {@code null}. * @throws IllegalStateException if this message has already been transferred once. * @throws ClosedDeviceException if the device has been closed. * @throws IllegalArgumentException if {@code rxSkip} is negative or if appending the read operation to a slave on a * different bus. */ public I2CCombinedMessage appendRead(I2CDevice slave, int rxSkip, ByteBuffer rxBuf) throws IOException, ClosedDeviceException { validateAndAppend(new Message(slave, rxBuf, rxSkip, true)); return this; } /** * Appends a write message/operation from the provided I2C slave device. Writes to this slave * device {@code txBuff.remaining()} bytes from the buffer {@code txBuf}. * * @param slave the I2C slave device to write to. * @param txBuf the buffer containing the bytes to write. * @return a reference to this {@code I2CCombinedMessage} object. * @throws IOException if some other I/O error occurs. * @throws NullPointerException If {@code txBuf} is {@code null}. * @throws IndexOutOfBoundsException {@code txOff} or {@code txLen} points or results in pointing outside * {@code txBuf}. * @throws IllegalStateException if this message has already been transferred once. * @throws ClosedDeviceException if the device has been closed. * @throws IllegalArgumentException if appending the write operation to a slave on a different bus. */ public I2CCombinedMessage appendWrite(I2CDevice slave, ByteBuffer txBuf) throws IOException, ClosedDeviceException { validateAndAppend(new Message(slave, txBuf, 0, false)); return this; } /** * Transfers this combined message. This will result in each of the contained * messages/operations to be sent/executed in the same order they have been appended to this * combined message. *

* Once transfer no additional operation can be appended anymore to this combined message. Any * such attempt will result in a {@link IllegalStateException} to be thrown.
* This combined message can be transferred several times. * * @return an array containing the number of bytes read for each of the read operations of this * combined message; the results of each read operations appear in the very same order * the read operations have been appended to this combined message. * @throws IOException if an I/O error occurred * @throws UnavailableDeviceException if this device is not currently available - such as it is locked by another * application. * @throws ClosedDeviceException if any of the targeted devices is not currently available (has been closed). */ public int[] transfer() throws IOException, UnavailableDeviceException, ClosedDeviceException { int bytesRead[]; synchronized (messageList) { /* Forbid adding more messages to this combined message */ isAlreadyTransferedOnce = true; if (0 == messageList.size()) { return null; } bytesRead = new int[rxMessageCount]; int bytesReadIdx = 0; final int size = messageList.size(); if (1 == size) { Message message = messageList.get(0); int skip = (message.isRx) ? message.skip : -1; Logging.reportInformation(ExceptionMessage.format(ExceptionMessage.I2CBUS_LAST_MESSAGE)); int res = ((I2CSlaveImpl) message.device).transfer(I2CSlaveImpl.I2C_REGULAR, skip, message.buf); if (rxMessageCount > 0) { bytesRead[0] = res; } } else { int flag = I2CSlaveImpl.I2C_COMBINED_START; Logging.reportInformation(ExceptionMessage.format(ExceptionMessage.I2CBUS_FIRST_MESSAGE)); Set slavesInUse = new HashSet(); for (int i = 0; i < messageList.size(); i++) { Message message = messageList.get(i); I2CSlaveImpl slave = (I2CSlaveImpl) message.device; slavesInUse.add(slave); int skip = (message.isRx) ? message.skip : -1; if (i == stopConditionIndex) { Logging.reportInformation(ExceptionMessage.format(ExceptionMessage.I2CBUS_LAST_MESSAGE)); flag = I2CSlaveImpl.I2C_COMBINED_END; } int res = slave.transfer(flag, skip, message.buf); if (message.isRx) { bytesRead[bytesReadIdx++] = res; } flag = I2CSlaveImpl.I2C_COMBINED_BODY; } for (I2CSlaveImpl usedSlave : slavesInUse) { usedSlave.applyDelayedConversions(); } } } return bytesRead; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy