jdk.dio.gpio.GPIOPortConfig Maven / Gradle / Ivy
Show all versions of org.openjdk.dio Show documentation
/*
* 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 jdk.dio.gpio;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Objects;
import com.oracle.dio.impl.Platform;
import com.oracle.dio.utils.ExceptionMessage;
import jdk.dio.DeviceConfig;
import jdk.dio.DeviceManager;
import jdk.dio.InvalidDeviceConfigException;
import romizer.DontRenameMethod;
import serializator.*;
/**
* The {@code GPIOPortConfig} class encapsulates the hardware addressing information, and static and
* dynamic configuration parameters of a GPIO port.
*
* Some hardware addressing, static or dynamic configuration parameters may be
* set to {@link #UNASSIGNED UNASSIGNED} or {@code null} (see
* Unassigned, Default or Unused Parameter Values).
*
* An instance of {@code GPIOPortConfig} can be passed to the
* {@link DeviceManager#open(DeviceConfig) open(DeviceConfig, ...)} and
* {@link DeviceManager#open(Class, DeviceConfig) open(Class, DeviceConfig, ...)}
* methods of the {@link DeviceManager} to open the designated GPIO port
* with the specified configuration. A {@link InvalidDeviceConfigException} is thrown when
* attempting to open a device with an invalid or unsupported configuration.
*
* The value change notification trigger of a GPIO port is defined by the interrupt trigger(s) configured
* for its pins (see {@link GPIOPinConfig#getTrigger GPIOPinConfig.getTrigger}). Any of
* the {@code GPIOPin}s configured with an interrupt trigger (other than {@link GPIOPinConfig#TRIGGER_NONE})
* that compose a {@code GPIOPort} may trigger a notification for that {@code GPIOPort}.
*
* The following sample code illustrates how a 4-pin GPIO port configuration may be built
* with pins from the same GPIO controller:
*
*
* GPIOPinConfig.Builder builder = new GPIOPinConfig.Builder()
* .setControllerNumber(1)
* .setDirection(GPIOPinConfig.DIR_OUTPUT_ONLY)
* .setDriveMode(GPIOPinConfig.MODE_OUTPUT_PUSH_PULL);
* GPIOPortConfig config = new GPIOPortConfig(GPIOPortConfig.DIR_OUTPUT_ONLY, 0x0,
* builder.setPinNumber(0).build(),
* builder.setPinNumber(1).build(),
* builder.setPinNumber(2).build(),
* builder.setPinNumber(3).build()
* );
*
*
*
* @see DeviceManager#open(DeviceConfig)
* @see DeviceManager#open(DeviceConfig, int)
* @see DeviceManager#open(Class, DeviceConfig)
* @see DeviceManager#open(Class, DeviceConfig, int)
* @since 1.0
*/
@SerializeMe
@apimarker.API("device-io_1.1_gpio")
public final class GPIOPortConfig implements DeviceConfig {
/**
* Bidirectional port direction with initial input direction.
*/
public static final int DIR_BOTH_INIT_INPUT = 2;
/**
* Bidirectional port direction with initial output direction.
*/
public static final int DIR_BOTH_INIT_OUTPUT = 3;
/**
* Input port direction.
*/
public static final int DIR_INPUT_ONLY = 0;
/**
* Output port direction.
*/
public static final int DIR_OUTPUT_ONLY = 1;
private int direction;
private int initValue;
private GPIOPinConfig[] pinConfigs;
// hidden constructor for serializer
@DontRenameMethod
GPIOPortConfig() {}
/**
* Creates a new {@code GPIOPortConfig} with the specified hardware addressing information and
* configuration parameters.
*
* If the access modes (exclusive or shared) supported by the designated
* {@code GPIOPin}s are incompatible with those required by the underlying {@code GPIOPort}
* device or device driver, attempting to open
* the {@code GPIOPort} device using this configuration may result in a
* {@link InvalidDeviceConfigException} to be thrown.
*
*
* @param direction
* the allowed and initial direction of the port, one of: {@link #DIR_INPUT_ONLY},
* {@link #DIR_OUTPUT_ONLY}, {@link #DIR_BOTH_INIT_INPUT},
* {@link #DIR_BOTH_INIT_OUTPUT}.
* @param initValue
* the initial value of the port when initially set for output.
* @param pins
* the pin configurations in the exact same order they compose the port.
* @throws IllegalArgumentException
* if any of the following is true:
*
* - {@code direction} is not one of the defined values;
* - {@code pins.length} is {@code 0};
* - if any of the provided pin configurations does not support the specified
* direction; more precisely:
*
* - if {@code direction} is {@link #DIR_BOTH_INIT_INPUT} or
* {@link #DIR_BOTH_INIT_OUTPUT} and any of the provided pin
* configurations' direction is {@link GPIOPinConfig#DIR_INPUT_ONLY} or {@link GPIOPinConfig#DIR_OUTPUT_ONLY};
* - if {@code direction} is {@link #DIR_INPUT_ONLY} and any of the provided pin
* configurations' direction is {@link GPIOPinConfig#DIR_OUTPUT_ONLY};
* - if {@code direction} is {@link #DIR_OUTPUT_ONLY} and any of the provided pin
* configurations' direction is {@link GPIOPinConfig#DIR_INPUT_ONLY};
*
*
*
* @throws NullPointerException
* if {@code pins} is {@code null}.
*/
public GPIOPortConfig(int direction, int initValue, GPIOPinConfig... pins) {
this.direction = direction;
this.initValue = initValue;
this.pinConfigs = new GPIOPinConfig[pins.length];
System.arraycopy(pins, 0, this.pinConfigs, 0, pins.length);
checkValues();
}
private void checkValues() {
if (DIR_INPUT_ONLY > direction ||
DIR_BOTH_INIT_OUTPUT < direction) {
throw new IllegalArgumentException(ExceptionMessage.format(ExceptionMessage.GPIO_INVALID_DIRECTION));
}
if (pinConfigs.length == 0) {
throw new IllegalArgumentException();
}
for (GPIOPinConfig pin : pinConfigs) {
if (pin.getDirection() != direction &&
pin.getDirection() < DIR_BOTH_INIT_INPUT) {
throw new IllegalArgumentException(
ExceptionMessage.format(ExceptionMessage.GPIO_DIR_UNSUPPORTED_BY_PIN_CONFIG)
);
}
}
}
/**
* Creates a new {@code GPIOPortConfig} whose state is deserialized from the specified {@code InputStream}.
* This method may be invoked to restore the state of a {@code GPIOPortConfig}
* object from a persistent store.
*
* @param in the stream to read from.
* @return a new {@code GPIOPortConfig} instance.
* @throws IOException if an I/O error occurs or if the provided stream does not
* contain a representation of a {@code GPIOPortConfig} object.
*
* @since 1.1
*/
public static GPIOPortConfig deserialize(InputStream in) throws IOException {
return (GPIOPortConfig) Platform.deserialize(in);
}
/**
* Serializes the state of this {@code GPIOPortConfig} object to the specified {@code OutputStream}.
* This method may be invoked by the {@link jdk.dio.DeviceManager DeviceManager}
* to save the state of this {@code GPIOPortConfig} object to a persistent store.
*
* @param out the stream to write to.
* @throws IOException if an I/O error occurs.
*
* @since 1.1
*/
@Override
public int serialize(OutputStream out) throws IOException {
return Platform.serialize(this, out);
}
/**
* Gets the configured port direction.
*
* @return the port direction, one of: {@link #DIR_INPUT_ONLY}, {@link #DIR_OUTPUT_ONLY},
* {@link #DIR_BOTH_INIT_INPUT}, {@link #DIR_BOTH_INIT_OUTPUT}.
*/
public int getDirection() {
return direction;
}
/**
* Gets the configured initial value of the port, if configured for output.
*
* @return the port's initial output value.
*/
public int getInitValue() {
return initValue;
}
/**
* Gets the configured configurations of the pins composing the port (in the exact same order
* they compose the port).
*
* @return the pins composing the port (a defensive copy is returned).
*/
public GPIOPinConfig[] getPinConfigs() {
if (pinConfigs != null) {
GPIOPinConfig[] clone = new GPIOPinConfig[pinConfigs.length];
System.arraycopy(pinConfigs, 0, clone, 0, pinConfigs.length);
return clone;
}
return null;
}
/**
* Gets the pins composing the port (in the exact same order they compose the port).
*
* A concurrent runtime change of the
* dynamic configuration parameters of any of the pins composing the port (such as of its direction) may result in
* {@code IOException} being thrown by port operations.
*
*
* @return the pins composing the port (a defensive copy is returned); or {@code null}
* if this {@code GPIOPortConfig} instance is not associated to an actual {@code GPIOPort} instance -
* that is the {@code GPIOPortConfig} instance was not retrieved from a call to
* {@code getDescriptor().getConfiguration()} on the {@code GPIOPort} instance.
*
* @deprecated As of 1.1, replaced by {@link GPIOPort#getPins GPIOPort.getPins}.
*/
@Deprecated
public GPIOPin[] getPins() {
return null;
}
/**
* Returns the hash code value for this object.
*
* @return a hash code value for this object.
*/
@Override
public int hashCode() {
return Platform.hash(this, 3, 97);
}
/**
* Checks two {@code GPIOPortConfig} objects for equality.
*
* @param obj
* the object to test for equality with this object.
*
* @return {@code true} if {@code obj} is a {@code GPIOPortConfig} and has
* the same configuration parameter values as this {@code GPIOPortConfig} object; {@code false} otherwise.
*/
@Override
public boolean equals(Object obj) {
return Platform.equals(this, obj);
}
}