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

com.pi4j.plugin.linuxfs.provider.i2c.LinuxFsI2C Maven / Gradle / Ivy

The newest version!
package com.pi4j.plugin.linuxfs.provider.i2c;

/*-
 * #%L
 * **********************************************************************
 * ORGANIZATION  :  Pi4J
 * PROJECT       :  Pi4J :: PLUGIN   :: LinuxFS I/O Providers
 * FILENAME      :  PiGpioI2C.java
 *
 * This file is part of the Pi4J project. More information about
 * this project can be found here:  https://pi4j.com/
 * **********************************************************************
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.*
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import com.pi4j.io.i2c.I2C;
import com.pi4j.io.i2c.I2CBase;
import com.pi4j.io.i2c.I2CConfig;
import com.pi4j.io.i2c.I2CProvider;
import com.pi4j.plugin.linuxfs.util.SystemUtil;

import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.Objects;

/**
 * 

PiGpioI2C class.

* * @author Robert Savage (http://www.savagehomeautomation.com) * @version $Id: $Id */ public class LinuxFsI2C extends I2CBase implements I2C { private final LinuxFsI2CBus i2CBus; /** *

Constructor for PiGpioI2C.

* * @param provider * a {@link I2CProvider} object. * @param config * a {@link I2CConfig} object. */ public LinuxFsI2C(LinuxFsI2CBus i2CBus, I2CProvider provider, I2CConfig config) { super(provider, config, i2CBus); this.i2CBus = i2CBus; } // ------------------------------------------------------------------- // RAW DEVICE WRITE FUNCTIONS // ------------------------------------------------------------------- /** * {@inheritDoc} */ @Override public int write(byte b) { return this.i2CBus.execute(this, file -> { file.write(b); return 1; }); } /** * {@inheritDoc} */ @Override public int write(byte[] data, int offset, int length) { Objects.checkFromIndexSize(offset, length, data.length); return this.i2CBus.execute(this, file -> { file.write(data, offset, length); return length; }); } // ------------------------------------------------------------------- // RAW DEVICE READ FUNCTIONS // ------------------------------------------------------------------- /** * {@inheritDoc} */ @Override public int read() { return this.i2CBus.execute(this, RandomAccessFile::read); } /** * {@inheritDoc} */ @Override public int read(byte[] buffer, int offset, int length) { Objects.checkFromIndexSize(offset, length, buffer.length); return this.i2CBus.execute(this, file -> file.read(buffer, offset, length)); } // ------------------------------------------------------------------- // DEVICE REGISTER WRITE FUNCTIONS // ------------------------------------------------------------------- /** * {@inheritDoc} */ @Override public int writeRegister(int register, byte b) { return write((byte) register, b); } /** * {@inheritDoc} */ @Override public int writeRegister(int register, byte[] data, int offset, int length) { Objects.checkFromIndexSize(offset, length, data.length); byte[] tmp = new byte[length + 1]; tmp[0] = (byte) register; System.arraycopy(data, offset, tmp, 1, length); return write(tmp); } /** * {@inheritDoc} */ @Override public int writeRegister(byte[] register, byte[] data, int offset, int length) { Objects.checkFromIndexSize(offset, length, data.length); byte[] tmp = new byte[length + register.length]; System.arraycopy(register,0, tmp, 0, register.length); System.arraycopy(data, offset, tmp, register.length, length); int rc = write(tmp); return (rc - register.length); // do not include the register bytes as what was written... } // ------------------------------------------------------------------- // DEVICE REGISTER READ FUNCTIONS // ------------------------------------------------------------------- /** * {@inheritDoc} */ @Override public int readRegister(int register) { byte reg[] = new byte[1]; reg[0] = (byte) (register & 0xff); byte buffer[] = new byte[1]; this.readRegister(reg, buffer,0,buffer.length); int rVal = buffer[0] & 0xff; return rVal; } /** * {@inheritDoc} */ @Override public int readRegister(int register, byte[] buffer, int offset, int length) { Objects.checkFromIndexSize(offset, length, buffer.length); byte reg[] = new byte[1]; reg[0] = (byte) (register & 0xff); int rCode = this.readRegister(reg, buffer, offset, length); return rCode; } /** * {@inheritDoc} * *

This function uses the IOCTL interface to the LinuxFS. This * is required so the I2C transaction uses an I2C RESTART. * The following details explain creating the ByteBuffers used * to create the 'C" structures for the IOCTL.

*

i2c_msg: The space *buf will be used to set a pointer to the data buffer. * This pointer must be aligned to the machines 4 or 8 byte alignment. *

*

* This alignment is accomplished when the pointer is 'put' into the * ByteBuffer *

* *
    *
  • struct i2c_msg {
  • *
  • __u16 addr;
  • *
  • __u16 flags;
  • *
  • __u16 len;
  • *
  • __u8 *buf; wordSize
  • *
  • u8 buffer
  • *
  • };
  • *
*

* The ioctl command is I2CConstants.I2C_RDWR, this command requires * two i2c_msg entries. *

*

The following describes the ByteBuffer, ioctlData, contents:

* *
    *
  • two byte address entry one
  • *
  • two byte len entry one
  • *
  • Possible padding for alignment
  • *
  • word size area for pointer to write data buffer
  • *
  • two byte address entry two
  • *
  • two byte flags entry two
  • *
  • two byte len entry two
  • *
  • Possible padding for alignment
  • *
  • word size area for pointer to read data buffer
  • *
  • Bytes required to contain write buffer contents
  • *
  • Bytes required to contain read data buffer
  • *
* *

There is a second byte buffer, offsets, this specifies the * ByteBuffer offset of any pointer paired with the ByteBuffer offset * of the data pointed to.

* * This ByteBuffer contents *
    *
  • ByteBuffer position start of pointer to write data buffer
  • *
  • ByteBuffer position start of write buffer contents
  • *
  • ByteBuffer position start of pointer to read data buffer
  • *
  • ByteBuffer position start of read buffer contents
  • *
* */ @Override public int readRegister(byte[] register, byte[] buffer, int offset, int length) { Objects.checkFromIndexSize(offset, length, buffer.length); // command I2C_RDWR long command = I2CConstants.I2C_RDWR; // create byte buffer containing the i2c messages // address,flags, number of bytes data, pointer // First message to write device register short deviceAddr = (short) (this.config.device()& 0xff); short writeFlags = (short) (I2CConstants.I2C_SMBUS_WRITE & 0xff); short writeLength = (short) register.length; // two pointers will be used so 2 pairs of offset entries IntBuffer offsets = IntBuffer.allocate(4); // create ByteBuffer, load with the write details Matches i2c provider ByteBuffer ioctlData = ByteBuffer.allocate(2048); // Ensures Pi BCM little_endian ioctlData.order(ByteOrder.nativeOrder()); ioctlData.putShort(deviceAddr); ioctlData.putShort(writeFlags); ioctlData.putShort(writeLength); // Before creating the pointer entry space, see if we are properly aligned int wrtAlignValue = ioctlData.position()%SystemUtil.getWordSize(); // test if current position is less than word size, if less move position to word boundary // If greater than word size set position to next word boundary if(ioctlData.position() > 8) & 0xff); byte buff[] = new byte[2]; word = (buff[1] << 8) | buff[0]; return word; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy