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

com.ociweb.iot.hardware.impl.grovepi.GrovePiPinManager Maven / Gradle / Ivy

package com.ociweb.iot.hardware.impl.grovepi;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.nio.file.spi.FileSystemProvider;
import java.util.HashSet;
import java.util.Set;

/**
 * @author Brandon Sanders [[email protected]]
 */
public class GrovePiPinManager {

    public final Path[] gpio;
    public final Path[] gpioDirection;
    public final Path[] gpioValue;
    public final Path[] gpioDebugCurrentPinMux;

    public final short[] gpioPinInt;
    public final String[] gpioPinString;
    public FileSystemProvider provider;
    
    private static final Path PATH_GPIO_EXPORT = Paths.get("/sys/class/gpio/export");
    private static final Path PATH_GPIO_UNEXPORT = Paths.get("/sys/class/gpio/unexport");

    public static final byte[] OUT = "out".getBytes();
    public static final byte[] IN = "in".getBytes();
    public static final byte[] DRECTION_HIGH = "out".getBytes();
    public static final byte[] DIRECTION_LOW = "in".getBytes();
    public static final byte[] VALUE_HIGH = "1".getBytes();
    public static final byte[] VALUE_LOW = "0".getBytes();

    public static final ByteBuffer I2C_LOW = ByteBuffer.wrap(VALUE_LOW);
    public static final ByteBuffer I2C_HIGH = ByteBuffer.wrap(VALUE_HIGH);
    public static final ByteBuffer[] BIT_BYTES = new ByteBuffer[]{I2C_LOW, I2C_HIGH};
    public static final int I2C_CLOCK = 1;
    public static final int I2C_DATA = 0;

    private static final Set readOptions = new HashSet();
    private static final Set i2cOptions = new HashSet();

    private static ByteBuffer[] readBitBuffer;

    static {
        i2cOptions.add(StandardOpenOption.READ);
        i2cOptions.add(StandardOpenOption.WRITE);

        readOptions.add(StandardOpenOption.READ);
        readOptions.add(StandardOpenOption.SYNC);

        int b = GrovePiConstants.GPIO_PINS.length;
        readBitBuffer = new ByteBuffer[b];
        while (--b >= 0)
            readBitBuffer[b] = ByteBuffer.allocate(1);
    }

    public GrovePiPinManager(final short[] pins) {

        gpioPinInt = pins;
        gpio = new Path[pins.length];
        gpioDirection = new Path[pins.length];
        gpioValue = new Path[pins.length];
        gpioPinString = new String[pins.length];
        gpioDebugCurrentPinMux = new Path[pins.length];

        final FileSystem fileSystem = FileSystems.getDefault();
        provider = fileSystem.provider();

        int i = pins.length;
        final StringBuilder sb = new StringBuilder();

        sb.append("/sys/class/gpio/gpio");

        final int baseLen = sb.length();
        while (--i >= 0) {
            if (pins[i] >= 0) {
                gpioPinString[i] = Integer.toString(pins[i]);

                gpioDebugCurrentPinMux[i] = fileSystem.getPath("/sys/kernel/debug/gpio_debug/gpio" + gpioPinString[i] + "/current_pinmux");

                sb.setLength(baseLen);
                sb.append(gpioPinString[i]);
                gpio[i] = fileSystem.getPath(sb.toString());

                final int withIdLen = sb.length();

                sb.append("/direction");
                gpioDirection[i] = fileSystem.getPath(sb.toString());

                sb.setLength(withIdLen);

                sb.append("/value");
                gpioValue[i] = fileSystem.getPath(sb.toString());
            }
        }
    }

    public void setDirectionLow(final int i) {
        if (null != gpioDirection[i]) try {
            Files.write(gpioDirection[i], DIRECTION_LOW);
        }
        catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void setDirectionHigh(final int i) {
        if (null != gpioDirection[i]) try {
            Files.write(gpioDirection[i], DRECTION_HIGH);
        }
        catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void setDirectionIn(final int i) {
        try {
            Files.write(gpioDirection[i], IN);
        }
        catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void setDirectionOut(final int i) {
        try {
            Files.write(gpioDirection[i], OUT);
        }
        catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void setValueHigh(final int i) {
        try {
            Files.write(gpioValue[i], VALUE_HIGH);
        }
        catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void setValueLow(final int i) {
        try {
            Files.write(gpioValue[i], VALUE_LOW);
        }
        catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void ensureDevice(final int i) {

        if ((null != gpio[i]) && !gpio[i].toFile().exists()) try {
            Files.write(PATH_GPIO_EXPORT, gpioPinString[i].getBytes());
        }
        catch (final IOException e) {
            throw new RuntimeException(e);
        }

    }

    public void removeDevice(final int i) {
        if ((null != gpio[i]) && !gpio[i].toFile().exists()) try {
            Files.write(PATH_GPIO_UNEXPORT, gpioPinString[i].getBytes());
        }
        catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void writeValue(final int port, final ByteBuffer data, final GrovePiPinManager d) {
        try {
            final SeekableByteChannel channel = d.provider.newByteChannel(d.gpioValue[port],
                                                                          i2cOptions);
            do channel.write(data);
            while (data.hasRemaining()); //Caution, TODO: this is blocking.
            data.flip();
            channel.close();
        }
        catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }
    
    public static int digitalRead(final int idx) {
        GrovePiGPIO.gpioLinuxPins.removeDevice(idx);
        GrovePiGPIO.gpioLinuxPins.ensureDevice(idx);

        try {
            final ByteBuffer buffer = readBitBuffer[idx];
            final SeekableByteChannel bc = GrovePiGPIO.gpioLinuxPins.provider.newByteChannel(GrovePiGPIO.gpioLinuxPins.gpioValue[idx],
                                                                                             readOptions);
            buffer.clear();
            while (bc.read(buffer) == 0) {}//only need 1
            bc.close();
            buffer.flip();
            return buffer.get() & 0x1;
        }
        catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }

	public static void digitalWrite(int connector, int value, final GrovePiPinManager d) {
		writeValue(connector, BIT_BYTES[value],d);
		
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy