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

jdk.dio.gpio.GPIOPinConfig 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 jdk.dio.gpio;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Objects;

import com.oracle.dio.impl.Platform;
import com.oracle.dio.utils.ExceptionMessage;
import com.oracle.dio.utils.Utils;

import jdk.dio.DeviceConfig;
import jdk.dio.DeviceManager;
import jdk.dio.InvalidDeviceConfigException;

import romizer.*;

import serializator.*;
/**
 * The {@code GPIOPinConfig} class encapsulates the hardware addressing information, and static and
 * dynamic configuration parameters of a GPIO pin.
 * 

* 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 GPIOPinConfig} 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 pin * with the specified configuration. A {@link InvalidDeviceConfigException} is thrown when * attempting to open a device with an invalid or unsupported configuration. *

* * @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 GPIOPinConfig implements DeviceConfig, DeviceConfig.HardwareAddressing { /** * Bidirectional pin direction with initial input direction. */ public static final int DIR_BOTH_INIT_INPUT = 2; /** * Bidirectional pin direction with initial output direction. */ public static final int DIR_BOTH_INIT_OUTPUT = 3; /** * Input pin direction. */ public static final int DIR_INPUT_ONLY = 0; /** * Output pin direction. */ public static final int DIR_OUTPUT_ONLY = 1; /** * Input pull-down drive mode. *

* This bit flag can be bitwise-combined (OR) with other drive mode bit flags. *

*/ public static final int MODE_INPUT_PULL_DOWN = 2; /** * Input pull-up drive mode. *

* This bit flag can be bitwise-combined (OR) with other drive mode bit flags. *

*/ public static final int MODE_INPUT_PULL_UP = 1; /** * Output open-drain drive mode. *

* This bit flag can be bitwise-combined (OR) with other drive mode bit flags. *

*/ public static final int MODE_OUTPUT_OPEN_DRAIN = 8; /** * Output push-pull drive mode. *

* This bit flag can be bitwise-combined (OR) with other drive mode bit flags. *

*/ public static final int MODE_OUTPUT_PUSH_PULL = 4; /** * Rising edge trigger. */ public static final int TRIGGER_BOTH_EDGES = 3; /** * Both levels trigger. */ public static final int TRIGGER_BOTH_LEVELS = 6; /** * Falling edge trigger. */ public static final int TRIGGER_FALLING_EDGE = 1; /** * High level trigger. */ public static final int TRIGGER_HIGH_LEVEL = 4; /** * Low level trigger. */ public static final int TRIGGER_LOW_LEVEL = 5; /** * No interrupt trigger. */ public static final int TRIGGER_NONE = 0; /** * Rising edge trigger. */ public static final int TRIGGER_RISING_EDGE = 2; private String controllerName; private int direction = UNASSIGNED; private boolean initValue; private int mode = UNASSIGNED; private int pinNumber = UNASSIGNED; private int controllerNumber = UNASSIGNED; private int trigger; /** * The {@code Builder} class allows for creating and initializing * {@code GPIOPinConfig} objects. Calls can be chained in the following * manner: *
*
     *   GPIOPinConfig config = new GPIOPinConfig.Builder()
     *           .setControllerNumber(1)
     *           .setPinNumber(1)
     *           .setDirection(DIR_OUTPUT_ONLY)
     *           .setDriveMode(MODE_OUTPUT_PUSH_PULL)
     *           .setInitValue(true)
     *           .build();
     * 
*
* * @since 1.1 */ @apimarker.API("device-io_1.1_gpio") public static final class Builder { private final GPIOPinConfig instance = new GPIOPinConfig(); /** * Creates a new {@code Builder} instance. */ public Builder() { } /** * Creates a new {@code GPIOPinConfig} instance initialized with the * values set for each configuration parameters. If a configuration * parameter was not explictly set its default value will be used. * * @return a new initialized {@code GPIOPinConfig} instance. * @throws IllegalArgumentException if any of the following is true: *
    *
  • the interrupt trigger event setting is incompatible with the direction setting: * if the direction is set to output-only then the trigger mode must be * {@link #TRIGGER_NONE}.
  • *
  • the drive mode setting is incompatible with the direction setting: if * the direction is set to both input and output then the drive mode * must specify both an input drive mode and an output drive mode.
  • *
* @throws IllegalStateException if any of the following is true: *
    *
  • the allowed and initial pin direction is not set.
  • *
*/ public GPIOPinConfig build() { if (instance.direction == UNASSIGNED) { throw new IllegalStateException(ExceptionMessage.format(ExceptionMessage.GPIO_INVALID_DIRECTION)); } instance.checkConsistency(); return instance; } /** * Sets the controller name (default value is {@code null} if not set). * * @param controllerName the controller name (such as its device * file name on UNIX systems) or {@code null}. * @return this {@code Builder} instance. */ public Builder setControllerName(String controllerName) { instance.controllerName = controllerName; return this; } /** * Sets the pin number (default value is {@code UNASSIGNED} if not set). * * @param pinNumber the pin number (a positive or zero integer) or * {@link #UNASSIGNED UNASSIGNED}. * @return this {@code Builder} instance. * @throws IllegalArgumentException if {@code pinNumber} is not in the * defined range. */ public Builder setPinNumber(int pinNumber) { Utils.checkIntValue(pinNumber); instance.pinNumber = pinNumber; return this; } /** * Sets the controller number (default value is {@code UNASSIGNED} if * not set). * * @param controllerNumber the controller number (a positive or zero * integer) or {@link #UNASSIGNED UNASSIGNED}. * @return this {@code Builder} instance. * @throws IllegalArgumentException if {@code controllerNumber} is not * in the defined range. */ public Builder setControllerNumber(int controllerNumber) { Utils.checkIntValue(controllerNumber); instance.controllerNumber = controllerNumber; return this; } /** * Sets the allowed and initial pin direction. * * @param direction the allowed and initial direction of the pin, one * of: {@link #DIR_INPUT_ONLY}, * {@link #DIR_OUTPUT_ONLY}, {@link #DIR_BOTH_INIT_INPUT}, * {@link #DIR_BOTH_INIT_OUTPUT}. * @return this {@code Builder} instance. * @throws IllegalArgumentException if {@code direction} is not in the * defined range. */ public Builder setDirection(int direction) { checkDirection(direction); instance.direction = direction; return this; } /** * Sets the initial value of the pin when initially set for output * (default value is {@code false} if not set). * * @param initValue the initial value of the pin when initially set for * output. * @return this {@code Builder} instance. */ public Builder setInitValue(boolean initValue) { instance.initValue = initValue; return this; } /** * Sets the pin drive mode (default value is {@code UNASSIGNED} if not * set). * * @param mode the pin drive mode: either {@link #UNASSIGNED UNASSIGNED} or a * bitwise OR of at least one of: {@link #MODE_INPUT_PULL_UP}, {@link #MODE_INPUT_PULL_DOWN} , * {@link #MODE_OUTPUT_PUSH_PULL}, {@link #MODE_OUTPUT_OPEN_DRAIN}. * @return this {@code Builder} instance. * @throws IllegalArgumentException if any of the following is true: *
    *
  • {@code mode} does not designate any mode (i.e. equals * {@code 0});
  • *
  • {@code mode} designates more than one input or output drive * mode.
  • *
*/ public Builder setDriveMode(int mode) { checkMode(mode); instance.mode = mode; return this; } /** * Sets the initial interrupt trigger events (default value is * {@code TRIGGER_NONE} if not set). * * @param trigger the initial interrupt trigger events, one of: {@link #TRIGGER_NONE}, * {@link #TRIGGER_FALLING_EDGE}, {@link #TRIGGER_RISING_EDGE}, * {@link #TRIGGER_BOTH_EDGES}, {@link #TRIGGER_HIGH_LEVEL}, * {@link #TRIGGER_LOW_LEVEL}, {@link #TRIGGER_BOTH_LEVELS}. * @return this {@code Builder} instance. * @throws IllegalArgumentException if {@code trigger} is not in the * defined range. */ public Builder setTrigger(int trigger) { checkTrigger(trigger); instance.trigger = trigger; return this; } } // hidden constructor for serializer @DontRenameMethod GPIOPinConfig() {} /** * Creates a new {@code GPIOPinConfig} with the specified hardware addressing information and * configuration parameters. *

* The controller name is set to {@code null}. *

* * @param controllerNumber * the hardware port's number (a positive or zero integer) or {@link #UNASSIGNED UNASSIGNED}. * @param pinNumber * the hardware pin's number (a positive or zero integer) or {@link #UNASSIGNED UNASSIGNED}. * @param direction * the allowed and initial direction of the pin, one of: {@link #DIR_INPUT_ONLY}, * {@link #DIR_OUTPUT_ONLY}, {@link #DIR_BOTH_INIT_INPUT}, * {@link #DIR_BOTH_INIT_OUTPUT}. * @param mode * the drive mode of the pin: either {@link #UNASSIGNED UNASSIGNED} or a bitwise OR of at least one * of: {@link #MODE_INPUT_PULL_UP}, {@link #MODE_INPUT_PULL_DOWN} , * {@link #MODE_OUTPUT_PUSH_PULL}, {@link #MODE_OUTPUT_OPEN_DRAIN}; if the pin can be * set in both input and output direction then the mode must specify both an input * drive mode and an output drive mode (bit mask). * @param trigger * the initial interrupt trigger events, one of: {@link #TRIGGER_NONE}, * {@link #TRIGGER_FALLING_EDGE}, {@link #TRIGGER_RISING_EDGE}, * {@link #TRIGGER_BOTH_EDGES}, {@link #TRIGGER_HIGH_LEVEL}, * {@link #TRIGGER_LOW_LEVEL}, {@link #TRIGGER_BOTH_LEVELS}; if the pin is * set for output-only then {@code trigger} must be {@link #TRIGGER_NONE}. * @param initValue * the initial value of the pin when initially set for output; ignored otherwise. * @throws IllegalArgumentException * if any of the following is true: *
    *
  • {@code controllerNumber} is not in the defined range;
  • *
  • {@code pinNumber} is not in the defined range;
  • *
  • {@code direction} is not one of the defined values;
  • *
  • {@code trigger} is not one of the defined values;
  • *
  • {@code trigger} is incompatible with the direction(s) designated by {@code direction};
  • *
  • {@code mode} does not designate any mode (i.e. equals {@code 0});
  • *
  • {@code mode} designates more than one input or output drive mode;
  • *
  • {@code mode} does not designates a drive mode for or designates a drive mode * incompatible with the direction(s) designated by {@code direction}.
  • *
* * @deprecated As of 1.1, use {@link Builder} instead. */ @Deprecated public GPIOPinConfig(int controllerNumber, int pinNumber, int direction, int mode, int trigger, boolean initValue) { this.controllerNumber = controllerNumber; this.pinNumber = pinNumber; if (controllerNumber < DeviceConfig.UNASSIGNED || pinNumber < DeviceConfig.UNASSIGNED ) { throw new IllegalArgumentException(); } this.direction = direction; this.trigger = trigger; this.mode = mode; this.initValue = initValue; checkAll(); } /** * Creates a new {@code GPIOPinConfig} with the specified hardware addressing information and * configuration parameters. *

* The controller number is set to {@code UNASSIGNED}. *

* * @param controllerName * the controller name (such as its device file name on UNIX systems). * @param pinNumber * the hardware pin's number (a positive or zero integer) or {@link #UNASSIGNED UNASSIGNED}. * @param direction * the allowed and initial direction of the pin, one of: {@link #DIR_INPUT_ONLY}, * {@link #DIR_OUTPUT_ONLY}, {@link #DIR_BOTH_INIT_INPUT}, * {@link #DIR_BOTH_INIT_OUTPUT}. * @param mode * the drive mode of the pin: either {@link #UNASSIGNED UNASSIGNED} or a bitwise OR of at least one * of: {@link #MODE_INPUT_PULL_UP}, {@link #MODE_INPUT_PULL_DOWN} , * {@link #MODE_OUTPUT_PUSH_PULL}, {@link #MODE_OUTPUT_OPEN_DRAIN}; if the pin can be * set in both input and output direction then the mode must specify both an input * drive mode and an output drive mode (bit mask). * @param trigger * the initial interrupt trigger events, one of: {@link #TRIGGER_NONE}, * {@link #TRIGGER_FALLING_EDGE}, {@link #TRIGGER_RISING_EDGE}, * {@link #TRIGGER_BOTH_EDGES}, {@link #TRIGGER_HIGH_LEVEL}, * {@link #TRIGGER_LOW_LEVEL}, {@link #TRIGGER_BOTH_LEVELS}; if the pin is * set for output-only then {@code trigger} must be {@link #TRIGGER_NONE}. * @param initValue * the initial value of the pin when initially set for output; ignored otherwise. * @throws IllegalArgumentException * if any of the following is true: *
    *
  • {@code pinNumber} is not in the defined range;
  • *
  • {@code direction} is not one of the defined values;
  • *
  • {@code trigger} is not one of the defined values;
  • *
  • {@code trigger} is incompatible with the direction(s) designated by {@code direction};
  • *
  • {@code mode} does not designate any mode (i.e. equals {@code 0});
  • *
  • {@code mode} designates more than one input or output drive mode;
  • *
  • {@code mode} does not designates a drive mode for or designates a drive mode * incompatible with the direction(s) designated by {@code direction}.
  • *
* @throws NullPointerException * if {@code controllerName} is {@code null}. * * @deprecated As of 1.1, use {@link Builder} instead. */ @Deprecated public GPIOPinConfig(String controllerName, int pinNumber, int direction, int mode, int trigger, boolean initValue) { this(UNASSIGNED, pinNumber, direction, mode, trigger, initValue); controllerName.length();// NPE check this.controllerName = controllerName; } /** * Creates a new {@code GPIOPinConfig} whose state is deserialized from the specified {@code InputStream}. * This method may be invoked to restore the state of a {@code GPIOPinConfig} * object from a persistent store. * * @param in the stream to read from. * @return a new {@code GPIOPinConfig} instance. * @throws IOException if an I/O error occurs or if the provided stream does not * contain a representation of a {@code GPIOPinConfig} object. * * @since 1.1 */ public static GPIOPinConfig deserialize(InputStream in) throws IOException { return (GPIOPinConfig) Platform.deserialize(in); } /** * Serializes the state of this {@code GPIOPinConfig} 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 GPIOPinConfig} 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 pin direction. * * @return the pin 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 pin drive mode. * * @return the pin drive mode: either {@link #UNASSIGNED UNASSIGNED} or a bitwise OR of at least one of : * {@link #MODE_INPUT_PULL_UP}, {@link #MODE_INPUT_PULL_DOWN}, * {@link #MODE_OUTPUT_PUSH_PULL}, {@link #MODE_OUTPUT_OPEN_DRAIN}. */ public int getDriveMode() { return mode; } /** * Gets the configured initial value of the pin, if configured for output. * * @return the pin's initial output value; {@code false} if configured for input. */ public boolean getInitValue() { return initValue; } /** * Gets the configured pin number. * * @return the hardware pin's number (a positive or zero integer) or {@link #UNASSIGNED UNASSIGNED}. */ public int getPinNumber() { return pinNumber; } /** * Gets the configured controller number for the pin. * * @return the hardware port's number (a positive or zero integer) or {@link #UNASSIGNED UNASSIGNED}. */ @Override public int getControllerNumber() { return controllerNumber; } /** * Gets the configured controller name (such as its device file name on UNIX systems). * * @return the controller name or {@code null}. */ @Override public String getControllerName() { return controllerName; } /** * Gets the configured initial pin interrupt trigger. * * @return the pin interrupt trigger, one of: {@link #TRIGGER_NONE}, * {@link #TRIGGER_FALLING_EDGE}, {@link #TRIGGER_RISING_EDGE}, * {@link #TRIGGER_BOTH_EDGES}, {@link #TRIGGER_HIGH_LEVEL}, {@link #TRIGGER_LOW_LEVEL}, * {@link #TRIGGER_BOTH_LEVELS}. */ public int getTrigger() { return trigger; } /** * Returns the hash code value for this object. * * @return a hash code value for this object. */ @Override public int hashCode() { return Platform.hash(this, 7, 59); } /** * Checks two {@code GPIOPinConfig} objects for equality. * * @param obj * the object to test for equality with this object. * @return {@code true} if {@code obj} is a {@code GPIOPinConfig} and has the same hardware * addressing information and configuration parameter values as this * {@code GPIOPinConfig} object; {@code false} otherwise. */ @Override public boolean equals(Object obj) { return Platform.equals(this, obj); } private static void checkDirection(int direction) { if (direction < DIR_INPUT_ONLY || direction > DIR_BOTH_INIT_OUTPUT) { throw new IllegalArgumentException(ExceptionMessage.format(ExceptionMessage.GPIO_INVALID_DIRECTION)); } } private static void checkMode(int mode) { if (UNASSIGNED != mode && (0 == mode || 0 != (mode & ~(GPIOPinConfig.MODE_INPUT_PULL_UP | GPIOPinConfig.MODE_INPUT_PULL_DOWN | GPIOPinConfig.MODE_OUTPUT_PUSH_PULL | GPIOPinConfig.MODE_OUTPUT_OPEN_DRAIN)) || (GPIOPinConfig.MODE_INPUT_PULL_UP | GPIOPinConfig.MODE_INPUT_PULL_DOWN) == (mode & (GPIOPinConfig.MODE_INPUT_PULL_UP | GPIOPinConfig.MODE_INPUT_PULL_DOWN)) || (GPIOPinConfig.MODE_OUTPUT_PUSH_PULL | GPIOPinConfig.MODE_OUTPUT_OPEN_DRAIN) == (mode & (GPIOPinConfig.MODE_OUTPUT_PUSH_PULL | GPIOPinConfig.MODE_OUTPUT_OPEN_DRAIN)))) { throw new IllegalArgumentException(ExceptionMessage.format(ExceptionMessage.GPIO_INVALID_MODE)); } } private static void checkTrigger(int trigger) { if (trigger < TRIGGER_NONE || trigger > TRIGGER_BOTH_LEVELS) { throw new IllegalArgumentException(ExceptionMessage.format(ExceptionMessage.GPIO_INVALID_TRIGGER)); } } /** check if @see GPIOPinConfig.Builder.build() passed successfully. * It differs from checking for setters such as setPinNumber etc. */ private void checkConsistency() { if (direction == DIR_OUTPUT_ONLY && trigger != TRIGGER_NONE) { throw new IllegalArgumentException( ExceptionMessage.format(ExceptionMessage.GPIO_INCOMPATIBLE_DIR) ); } switch (direction) { case GPIOPinConfig.DIR_INPUT_ONLY: if (UNASSIGNED != mode && 0 != (mode & ~(GPIOPinConfig.MODE_INPUT_PULL_DOWN | GPIOPinConfig.MODE_INPUT_PULL_UP))) { throw new IllegalArgumentException( ExceptionMessage.format(ExceptionMessage.GPIO_INCOMPATIBLE_MODE) ); } break; case GPIOPinConfig.DIR_OUTPUT_ONLY: if (UNASSIGNED != mode && 0 != (mode & ~(GPIOPinConfig.MODE_OUTPUT_OPEN_DRAIN | GPIOPinConfig.MODE_OUTPUT_PUSH_PULL ))) { throw new IllegalArgumentException( ExceptionMessage.format(ExceptionMessage.GPIO_INCOMPATIBLE_MODE) ); } break; case GPIOPinConfig.DIR_BOTH_INIT_INPUT: case GPIOPinConfig.DIR_BOTH_INIT_OUTPUT: if (UNASSIGNED != mode && ((mode != (MODE_INPUT_PULL_DOWN | MODE_OUTPUT_OPEN_DRAIN)) && (mode != (MODE_INPUT_PULL_DOWN | MODE_OUTPUT_PUSH_PULL)) && (mode != (MODE_INPUT_PULL_UP | MODE_OUTPUT_OPEN_DRAIN)) && (mode != (MODE_INPUT_PULL_UP | MODE_OUTPUT_PUSH_PULL))) ) { throw new IllegalArgumentException( ExceptionMessage.format(ExceptionMessage.GPIO_INCOMPATIBLE_MODE) ); } break; default: throw new IllegalArgumentException( ExceptionMessage.format(ExceptionMessage.GPIO_INCOMPATIBLE_MODE) ); } } /** check everything for deprecated @see GPIOPinConfig call */ private void checkAll() { Utils.checkIntValue(controllerNumber); Utils.checkIntValue(pinNumber); checkDirection(direction); checkMode(mode); checkTrigger(trigger); checkConsistency(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy