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

jdk.dio.counter.PulseCounterConfig 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.counter;

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.DeviceDescriptor;
import jdk.dio.DeviceManager;
import jdk.dio.InvalidDeviceConfigException;
import jdk.dio.gpio.GPIOPin;
import jdk.dio.gpio.GPIOPinConfig;

import romizer.*;

import serializator.*;

/**
 * The {@code PulseCounterConfig} class encapsulates the hardware addressing information, and static
 * and dynamic configuration parameters of a pulse counter.
 * 

* 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 PulseCounterConfig} 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 counter * 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_counter") public final class PulseCounterConfig implements DeviceConfig, DeviceConfig.HardwareAddressing { /** * Falling pulse edge (counting only falling pulse edges). When the pulse source is a GPIO pin * then this pulse edge type can only be used if the pin is configured with the * {@link GPIOPinConfig#TRIGGER_FALLING_EDGE} trigger mode. */ public static final int TYPE_FALLING_EDGE_ONLY = 0; /** * Negative edge pulse: measured from falling edge to rising edge (counting well-formed negative * edge pulses). When the pulse source is a GPIO pin then this pulse edge type can only be used * if the pin is configured with the {@link GPIOPinConfig#TRIGGER_BOTH_EDGES} trigger mode. */ public static final int TYPE_NEGATIVE_PULSE = 3; /** * Positive edge pulse: measured from rising edge to falling edge (counting well-formed positive * edge pulses). When the pulse source is a GPIO pin then this pulse edge type can only be used * if the pin is configured with the {@link GPIOPinConfig#TRIGGER_BOTH_EDGES} trigger mode. */ public static final int TYPE_POSITIVE_PULSE = 2; /** * Rising pulse edge (counting only rising pulse edges). When the pulse source is a GPIO pin * then this pulse edge type can only be used if the pin is configured with the * {@link GPIOPinConfig#TRIGGER_RISING_EDGE} trigger mode. */ public static final int TYPE_RISING_EDGE_ONLY = 1; private String controllerName; private int controllerNumber = UNASSIGNED; private int channelNumber = UNASSIGNED; private GPIOPinConfig sourceConfig; private int type = UNASSIGNED; /** * The {@code Builder} class allows for creating and initializing * {@code PulseCounterConfig} objects. Calls can be chained in the following * manner: *
*
     *   PulseCounterConfig config = new PulseCounterConfig.Builder()
     *           .setControllerNumber(1)
     *           .setChannelNumber(1)
     *           .setType(TYPE_NEGATIVE_PULSE)
     *           .build();
     * 
*
* * @since 1.1 */ @apimarker.API("device-io_1.1_counter") public static final class Builder { private final PulseCounterConfig instance = new PulseCounterConfig(); /** * Creates a new {@code Builder} instance. */ public Builder() { } /** * Creates a new {@code PulseCounterConfig} 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 PulseCounterConfig} instance. * @throws IllegalArgumentException if any of the following is true: *
    *
  • if the provided source (GPIO pin - if any provided) configuration's trigger mode is * not compatible with the specified pulse or pulse edge type (see the description of each * {@link PulseCounterConfig#TYPE_FALLING_EDGE_ONLY TYPE_*} constant).
  • *
* @throws IllegalStateException if any of the following is true: *
    *
  • the pulse or pulse edge type is not set.
  • *
*/ public PulseCounterConfig build() { if (instance.type == UNASSIGNED) { throw new IllegalStateException(); } instance.checkValues(); return (PulseCounterConfig) Platform.clone(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 channel/counter number (default value is {@code UNASSIGNED} if not * set). * * @param channelNumber the channel/counter number (a positive or zero integer) * or {@link #UNASSIGNED UNASSIGNED}. * @return this {@code Builder} instance. * @throws IllegalArgumentException if {@code channelNumber} is not in * the defined range. */ public Builder setChannelNumber(int channelNumber) { Utils.checkIntValue(channelNumber); instance.channelNumber = channelNumber; 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 configuration of the source (a GPIO input pin) on which the pulses are to be * counted (default value is {@code null} if not set). * * @param sourceConfig the configuration of the source (a GPIO input pin); or {@code null} if the source is * implicit. * @return this {@code Builder} instance. * @throws IllegalArgumentException if {@code sourceConfig} is not * {@code null} and {@code sourceConfig}'s direction is not set to * {@link GPIOPinConfig#DIR_INPUT_ONLY} or {@link GPIOPinConfig#DIR_BOTH_INIT_INPUT}. */ public Builder setSourceConfig(GPIOPinConfig source) { if (null != source) { checkSourceConfig(source); } instance.sourceConfig = source; return this; } /** * Sets the pulse or pulse edge type. * * @param type the pulse or pulse edge type: {@link #TYPE_FALLING_EDGE_ONLY}, * {@link #TYPE_RISING_EDGE_ONLY}, {@link #TYPE_NEGATIVE_PULSE} or * {@link #TYPE_POSITIVE_PULSE}. * @return this {@code Builder} instance. * @throws IllegalArgumentException if {@code type} is not in the * defined range. */ public Builder setType(int type) { checkType(type); instance.type = type; return this; } } // hidden constructor for serializer @DontRenameMethod PulseCounterConfig(){} /** * Creates a new {@code PulseCounterConfig} with the specified hardware addressing information * and type. The source of the pulse counter is implicit (such as a dedicated input pin). *

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

* * @param controllerNumber * the hardware controller's number (a positive or zero integer) or {@link #UNASSIGNED UNASSIGNED}. * @param channelNumber * the hardware counter's number (a positive or zero integer) or {@link #UNASSIGNED UNASSIGNED}. * @param type * the pulse or pulse edge type: {@link #TYPE_FALLING_EDGE_ONLY}, * {@link #TYPE_RISING_EDGE_ONLY}, {@link #TYPE_NEGATIVE_PULSE} or * {@link #TYPE_POSITIVE_PULSE}. * @throws IllegalArgumentException * if any of the following is true: *
    *
  • {@code controllerNumber} is not in the defined range;
  • *
  • {@code channelNumber} is not in the defined range;
  • *
  • {@code type} is not one of the defined values.
  • *
* * @deprecated As of 1.1, use {@link Builder} instead. */ @Deprecated public PulseCounterConfig(int controllerNumber, int channelNumber, int type) { this.controllerNumber = controllerNumber; this.channelNumber = channelNumber; this.type = type; checkValues(); } /** * Creates a new {@code PulseCounterConfig} the specified hardware addressing information, type * and GPIO pin source. *

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

* * @param controllerNumber * the hardware controller's number (a positive or zero integer) or {@link #UNASSIGNED UNASSIGNED}. * @param channelNumber * the hardware counter's number (a positive or zero integer) or {@link #UNASSIGNED UNASSIGNED}. * @param type * the pulse or pulse edge type: {@link #TYPE_FALLING_EDGE_ONLY}, * {@link #TYPE_RISING_EDGE_ONLY}, {@link #TYPE_NEGATIVE_PULSE} or * {@link #TYPE_POSITIVE_PULSE}. * @param source * the configuration of the source (a GPIO input pin) on which the pulses are to be * counted. * @throws IllegalArgumentException * if any of the following is true: *
    *
  • {@code controllerNumber} is not in the defined range;
  • *
  • {@code channelNumber} is not in the defined range;
  • *
  • {@code type} is not one of the defined values;
  • *
  • if the provided source (GPIO pin) configuration's direction is not set to * {@link GPIOPinConfig#DIR_INPUT_ONLY} or {@link GPIOPinConfig#DIR_BOTH_INIT_INPUT};
  • *
  • if the provided source (GPIO pin) configuration's trigger mode is not compatible * with the specified pulse type (see the description of each * {@link PulseCounterConfig#TYPE_FALLING_EDGE_ONLY TYPE_*} constant).
  • *
* @throws NullPointerException * if {@code source} is {@code null}. * * @deprecated As of 1.1, use {@link Builder} instead. */ @Deprecated public PulseCounterConfig(int controllerNumber, int channelNumber, int type, GPIOPinConfig source) { this(controllerNumber, channelNumber, type); checkSourceConfig(source); this.sourceConfig = source; } /** * Creates a new {@code PulseCounterConfig} with the specified hardware addressing information * and type. The source of the pulse counter is implicit (such as a dedicated input pin). *

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

* * @param controllerName * the controller name (such as its device file name on UNIX systems). * @param channelNumber * the hardware counter's number (a positive or zero integer) or {@link #UNASSIGNED UNASSIGNED}. * @param type * the pulse or pulse edge type: {@link #TYPE_FALLING_EDGE_ONLY}, * {@link #TYPE_RISING_EDGE_ONLY}, {@link #TYPE_NEGATIVE_PULSE} or * {@link #TYPE_POSITIVE_PULSE}. * @throws NullPointerException * if {@code controllerName} is {@code null}. * @throws IllegalArgumentException * if any of the following is true: *
    *
  • {@code channelNumber} is not in the defined range;
  • *
  • {@code type} is not one of the defined values.
  • *
* * @deprecated As of 1.1, use {@link Builder} instead. */ @Deprecated public PulseCounterConfig(String controllerName, int channelNumber, int type) { this(UNASSIGNED, channelNumber, type); // checks for null controllerName.length(); this.controllerName = controllerName; } /** * Creates a new {@code PulseCounterConfig} the specified hardware addressing information, type * and GPIO pin source. *

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

* * @param controllerName * the controller name (such as its device file name on UNIX systems). * @param channelNumber * the hardware counter's number (a positive or zero integer) or {@link #UNASSIGNED UNASSIGNED}. * @param type * the pulse or pulse edge type: {@link #TYPE_FALLING_EDGE_ONLY}, * {@link #TYPE_RISING_EDGE_ONLY}, {@link #TYPE_NEGATIVE_PULSE} or * {@link #TYPE_POSITIVE_PULSE}. * @param source * the configuration of the source (a GPIO input pin) on which the pulses are to be * counted. * @throws IllegalArgumentException * if any of the following is true: *
    *
  • {@code channelNumber} is not in the defined range;
  • *
  • {@code type} is not one of the defined values;
  • *
  • if the provided source (GPIO pin) configuration's direction is not set to * {@link GPIOPinConfig#DIR_INPUT_ONLY} or {@link GPIOPinConfig#DIR_BOTH_INIT_INPUT};
  • *
  • if the provided source (GPIO pin) configuration's trigger mode is not compatible * with the specified pulse type (see the description of each * {@link PulseCounterConfig#TYPE_FALLING_EDGE_ONLY TYPE_*} constant).
  • *
* @throws NullPointerException * if {@code controllerName} or {@code source} is {@code null}. * * @deprecated As of 1.1, use {@link Builder} instead. */ @Deprecated public PulseCounterConfig(String controllerName, int channelNumber, int type, GPIOPinConfig source) { this(controllerName, channelNumber, type); checkSourceConfig(source); this.sourceConfig = source; } /** * Creates a new {@code PulseCounterConfig} whose state is deserialized from the specified {@code InputStream}. * This method may be invoked to restore the state of a {@code PulseCounterConfig} * object from a persistent store. * * @param in the stream to read from. * @return a new {@code PulseCounterConfig} instance. * @throws IOException if an I/O error occurs or if the provided stream does not * contain a representation of a {@code PulseCounterConfig} object. * * @since 1.1 */ public static PulseCounterConfig deserialize(InputStream in) throws IOException { return (PulseCounterConfig) Platform.deserialize(in); } /** * Serializes the state of this {@code PulseCounterConfig} 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 PulseCounterConfig} 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 controller number. * * @return the controller number (a positive or zero integer); or {@link #UNASSIGNED UNASSIGNED}. */ @Override public int getControllerNumber() { return controllerNumber; } /** * Gets the configured counter number. * * @return the counter number (a positive or zero integer); or {@link #UNASSIGNED UNASSIGNED}. */ public int getChannelNumber() { return channelNumber; } /** * 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 source (GPIO input pin) on which the pulses are to be counted/measured. *

* A concurrent runtime change of the * dynamic configuration parameters of the source (such as of its direction) may result in * {@code IOException} being thrown by counting operations. *

* * @return the source on which the pulses are to be counted/measured; or {@code null} if the source is implicit * or if this {@code PusleCounterConfig} instance is not associated to an actual {@code PulseCounter} instance. * * @deprecated As of 1.1, replaced by {@link PulseCounter#getSource PulseCounter.getSource}. */ @Deprecated public GPIOPin getSource() { return null; } /** * Gets the configured source (GPIO input pin) configuration on which the pulses are to be * counted/measured. * * @return the configuration of the source on which the pulses are to be counted/measured; or * {@code null} if the source is implicit. */ public GPIOPinConfig getSourceConfig() { return sourceConfig; } /** * Gets the configured pulse or pulse edge type. * * @return the pulse or pulse edge type: {@link #TYPE_FALLING_EDGE_ONLY}, * {@link #TYPE_RISING_EDGE_ONLY}, {@link #TYPE_NEGATIVE_PULSE} or * {@link #TYPE_POSITIVE_PULSE}. */ public int getType() { return type; } /** * 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, 83); } /** * Checks two {@code PulseCounterConfig} objects for equality. * * @param obj * the object to test for equality with this object. * @return {@code true} if {@code obj} is a {@code PulseCounterConfig} and has the same hardware * addressing information and configuration parameter values as this * {@code PulseCounterConfig} object; {@code false} otherwise. */ @Override public boolean equals(Object obj) { return Platform.equals(this, obj); } private static void checkType(int type) { if (TYPE_NEGATIVE_PULSE < type || TYPE_FALLING_EDGE_ONLY > type ) { throw new IllegalArgumentException( ExceptionMessage.format(ExceptionMessage.COUNTER_INVALID_TYPE) ); } } private static void checkSourceConfig(GPIOPinConfig sourceConfig) { if (sourceConfig.getDirection() != GPIOPinConfig.DIR_INPUT_ONLY && sourceConfig.getDirection() != GPIOPinConfig.DIR_BOTH_INIT_INPUT) { throw new IllegalArgumentException(ExceptionMessage.format(ExceptionMessage.COUNTER_CONFIG_CANNOT_BE_USED)); } } private void checkValues() throws IllegalArgumentException { Utils.checkIntValue(controllerNumber); Utils.checkIntValue(channelNumber); checkType(type); // rising and falling edges if (null != sourceConfig) { int trigger = sourceConfig.getTrigger(); if (((trigger >>> 1) != type && // When the pulse source is a GPIO pin then this pulse edge type can only be used if the pin is configured with the // GPIOPinConfig#TRIGGER_BOTH_EDGES trigger mode (type > TYPE_RISING_EDGE_ONLY && trigger != GPIOPinConfig.TRIGGER_BOTH_EDGES))) { throw new IllegalArgumentException(ExceptionMessage.format(ExceptionMessage.COUNTER_CONFIG_CANNOT_BE_USED)); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy