package com.pi4j.io.i2c.impl; /* * #%L * ********************************************************************** * ORGANIZATION : Pi4J * PROJECT : Pi4J :: Java Library (Core) * FILENAME : I2CDeviceImpl.java * * This file is part of the Pi4J project. More information about * this project can be found here: http://www.pi4j.com/ * ********************************************************************** * %% * Copyright (C) 2012 - 2013 Pi4J * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import java.io.IOException; import com.pi4j.io.i2c.I2CDevice; import com.pi4j.jni.I2C; /** * Implementation of i2c device. This class only holds reference to i2c bus (so it can use its handle) and * device address. * * @author Daniel Sendula * */ public class I2CDeviceImpl implements I2CDevice { /** Reference to i2c bus */ private I2CBusImpl bus; /** I2c device address */ private int deviceAddress; /** * Constructor. * * @param bus i2c bus * @param address i2c device address */ public I2CDeviceImpl(I2CBusImpl bus, int address) { this.bus = bus; this.deviceAddress = address; } /** * This method writes one byte to i2c device. * * @param b byte to be written * * @throws IOException thrown in case byte cannot be written to the i2c device or i2c bus */ @Override public void write(byte data) throws IOException { int ret = I2C.i2cWriteByteDirect(bus.fd, deviceAddress, data); if (ret < 0) { throw new IOException("Error writing to " + makeDescription() + ". Got " + ret + "."); } } /** * This method writes several bytes to the i2c device from given buffer at given offset. * * @param buffer buffer of data to be written to the i2c device in one go * @param offset offset in buffer * @param size number of bytes to be written * * @throws IOException thrown in case byte cannot be written to the i2c device or i2c bus */ @Override public void write(byte[] buffer, int offset, int size) throws IOException { int ret = I2C.i2cWriteBytesDirect(bus.fd, deviceAddress, size, offset, buffer); if (ret < 0) { throw new IOException("Error writing to " + makeDescription() + ". Got " + ret + "."); } } /** * This method writes one byte to i2c device. * * @param address local address in the i2c device * @param b byte to be written * * @throws IOException thrown in case byte cannot be written to the i2c device or i2c bus */ @Override public void write(int address, byte data) throws IOException { int ret = I2C.i2cWriteByte(bus.fd, deviceAddress, address, data); if (ret < 0) { throw new IOException("Error writing to " + makeDescription(address) + ". Got " + ret + "."); } } /** * This method writes several bytes to the i2c device from given buffer at given offset. * * @param address local address in the i2c device * @param buffer buffer of data to be written to the i2c device in one go * @param offset offset in buffer * @param size number of bytes to be written * * @throws IOException thrown in case byte cannot be written to the i2c device or i2c bus */ @Override public void write(int address, byte[] buffer, int offset, int size) throws IOException { int ret = I2C.i2cWriteBytes(bus.fd, deviceAddress, address, size, offset, buffer); if (ret < 0) { throw new IOException("Error writing to " + makeDescription(address) + ". Got " + ret + "."); } } /** * This method reads one byte from the i2c device. Result is between -128 and 127. * * @return * * @throws IOException thrown in case byte cannot be read from the i2c device or i2c bus */ @Override public int read() throws IOException { int ret = I2C.i2cReadByteDirect(bus.fd, deviceAddress); if (ret < 0) { throw new IOException("Error reading from " + makeDescription() + ". Got " + ret + "."); } return ret; } /** * <p>This method reads bytes from the i2c device to given buffer at asked offset. </p> * * <p>Note: Current implementation calls {@link #read(int)}. That means for each read byte * i2c bus will send (next) address to i2c device. * </p> * * @param buffer buffer of data to be read from the i2c device in one go * @param offset offset in buffer * @param size number of bytes to be read * * @return number of bytes read * * @throws IOException thrown in case byte cannot be read from the i2c device or i2c bus */ @Override public int read(byte[] buffer, int offset, int size) throws IOException { // It doesn't work for some reason. int ret = I2C.i2cReadBytesDirect(bus.fd, deviceAddress, size, offset, buffer); if (ret < 0) { throw new IOException("Error reading from " + makeDescription() + ". Got " + ret + "."); } return ret; } /** * This method reads one byte from the i2c device. Result is between -128 and 127. * * @param address local address in the i2c device * @return * * @throws IOException thrown in case byte cannot be read from the i2c device or i2c bus */ @Override public int read(int address) throws IOException { int ret = I2C.i2cReadByte(bus.fd, deviceAddress, address); if (ret < 0) { throw new IOException("Error reading from " + makeDescription(address) + ". Got " + ret + "."); } return ret; } /** * <p>This method reads bytes from the i2c device to given buffer at asked offset. </p> * * <p>Note: Current implementation calls {@link #read(int)}. That means for each read byte * i2c bus will send (next) address to i2c device. * </p> * * @param address local address in the i2c device * @param buffer buffer of data to be read from the i2c device in one go * @param offset offset in buffer * @param size number of bytes to be read * * @return number of bytes read * * @throws IOException thrown in case byte cannot be read from the i2c device or i2c bus */ @Override public int read(int address, byte[] buffer, int offset, int size) throws IOException { // It doesn't work for some reason. int ret = I2C.i2cReadBytes(bus.fd, deviceAddress, address, size, offset, buffer); if (ret < 0) { throw new IOException("Error reading from " + makeDescription(address) + ". Got " + ret + "."); } return ret; } /** * This helper method creates a string describing bus file name and device address (in hex). * * @return string with all details */ protected String makeDescription() { return bus.filename + " at address 0x" + Integer.toHexString(deviceAddress); } /** * This helper method creates a string describing bus file name, device address (in hex) * and local i2c address. * * @param address local address in i2c device * @return string with all details */ protected String makeDescription(int address) { return bus.filename + " at address 0x" + Integer.toHexString(deviceAddress) + " to address 0x" + Integer.toHexString(address); } }