public interface AnalogInput extends Closeable {
    /**
     * Gets the analog input reading, as an absolute voltage in Volt units.
     * <p/>
     * It typically takes a few milliseconds between when the instance is created and until the
     * first value can be read. In this case, the method may block shortly. If this is a problem,
     * the calling thread can be interrupted.
     * <p/>
     * If a scaled value is desired, consider using {@link #read()}.
     *
     * @return The voltage, in Volt units.
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     * @see #read()
     */
    public float getVoltage() throws InterruptedException, ConnectionLostException;

    /**
     * This is very similar to {@link #getVoltage()}, but will wait for a new sample to arrive
     * before returning. This is useful in conjunction with {@link IOIO#sync()}, in cases when we
     * want to guarantee the we are looking at a sample that has been captured strictly after
     * certain other commands have been executed.
     *
     * @return
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     * @see #getVoltage()
     * @see #readSync()
     */
    public float getVoltageSync() throws InterruptedException, ConnectionLostException;

    /**
     * Gets the maximum value against which {@link #read()} values are scaled.
     *
     * @return The voltage, in Volts.
     */
    public float getReference();

    /**
     * Gets the analog input reading, as a scaled real value between 0 and 1.
     * <p/>
     * It typically takes a few milliseconds between when the instance is created and until the
     * first value can be read. In this case, the method may block shortly. If this is a problem,
     * the calling thread can be interrupted.
     * <p/>
     * If an absolute value is desired, consider using {@link #getVoltage()}.
     *
     * @return The voltage, in scaled units.
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     * @see #getVoltage()
     */
    public float read() throws InterruptedException, ConnectionLostException;

    /**
     * This is very similar to {@link #read()}, but will wait for a new sample to arrive before
     * returning. This is useful in conjunction with {@link IOIO#sync()}, in cases when we want to
     * guarantee the we are looking at a sample that has been captured strictly after certain other
     * commands have been executed.
     *
     * @return The voltage, in scaled units.
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     * @see #read()
     * @see #getVoltageSync()
     */
    public float readSync() throws InterruptedException, ConnectionLostException;

    /**
     * Initializes or destroys an internal buffer, used for queuing sampled data. When called with a
     * positive argument, an internal buffer will be created, and start storing sampled data. The
     * client can then call {@link #readBuffered()} or {@link #getVoltageBuffered()} for obtaining
     * buffered samples.
     * <p/>
     * When called with argument of 0, the internal buffer is destroyed.
     *
     * @param capacity The maximum number of unread samples that can be buffered before overflow occurs.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     */
    public void setBuffer(int capacity) throws ConnectionLostException;

    /**
     * Gets the number of samples that have been dropped as result of overflow, since
     * {@link #setBuffer(int)} has been called.
     *
     * @return The number of dropped samples.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     */
    public int getOverflowCount() throws ConnectionLostException;

    /**
     * Gets the number of samples currently in the buffer. Reading that many samples is guaranteed
     * not to block.
     *
     * @return The number of samples available in the buffer.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     */
    public int available() throws ConnectionLostException;

    /**
     * Read a sample from the internal buffer. This method will block until at least one sample is
     * available, the instance is closed (via {@link #close()}), the thread is interrupted (via
     * {@link Thread#interrupt()} or connection is lost. {@link #setBuffer(int)} must be called
     * prior to this method for setting up an internal buffer for storing samples.
     *
     * @return The earliest (oldest) sample available in the buffer, scaled to the range [0,1].
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     * @see #getVoltageBuffered()
     */
    public float readBuffered() throws InterruptedException, ConnectionLostException;

    /**
     * Read a sample from the internal buffer. This method will block until at least one sample is
     * available, the instance is closed (via {@link #close()}), the thread is interrupted (via
     * {@link Thread#interrupt()} or connection is lost. {@link #setBuffer(int)} must be called
     * prior to this method for setting up an internal buffer for storing samples.
     *
     * @return The earliest (oldest) sample available in the buffer, in Volt units.
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     * @see #readBuffered()
     */
    public float getVoltageBuffered() throws InterruptedException, ConnectionLostException;

    /**
     * Gets the sample rate used for obtaining buffered samples.
     *
     * @return The sample rate, in Hz units.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     */
    public float getSampleRate() throws ConnectionLostException;
} public interface CapSense extends Closeable {
    public static final float DEFAULT_COEF = 25.f;

    /**
     * Gets the capacitance reading.
     * <p/>
     * It typically takes a few milliseconds between when the instance is created and until the
     * first value can be read. In this case, the method may block shortly. If this is a problem,
     * the calling thread can be interrupted.
     * <p/>
     * This value is computed using a filtered signal, which is configured via
     * {@link #setFilterCoef(float)}
     *
     * @return The capacitance, in pico-Farade units.
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     */
    public float read() throws InterruptedException, ConnectionLostException;

    /**
     * This is very similar to {@link #read()}, but will wait for a new sample to arrive before
     * returning. This is useful in conjunction with {@link IOIO#sync()}, in cases when we want to
     * guarantee the we are looking at a sample that has been captured strictly after certain other
     * commands have been executed.
     *
     * @return The capacitance, in pico-Farade units.
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     * @see #read()
     */
    public float readSync() throws InterruptedException, ConnectionLostException;

    /**
     * Sets the low-pass filter coefficient.
     * <p/>
     * This coefficient is the typical time constant of the system, which gives us an order of
     * magnitude of its response time. Slower response time typically provides better noise immunity
     * at the expense of higher latency.
     *
     * @param t The time constant, in milliseconds.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     */
    public void setFilterCoef(float t) throws ConnectionLostException;

    /**
     * Block until sensed capacitance becomes greater than a given threshold.
     * <p/>
     * For using a touch surface as a digital button, a threshold of 50pF is normally useful, with
     * some hysteresis recommended.
     *
     * @param threshold The threshold value, in pF units.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     * @throws InterruptedException    The calling thread has been interrupted.
     */
    public void waitOver(float threshold) throws ConnectionLostException, InterruptedException;

    /**
     * This is very similar to {@link #waitOver()}, but will wait for a new sample to arrive before
     * returning. This is useful in conjunction with {@link IOIO#sync()}, in cases when we want to
     * guarantee the we are looking at a sample that has been captured strictly after certain other
     * commands have been executed.
     *
     * @return The capacitance, in pico-Farade units.
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     * @see #waitOver()
     */
    public void waitOverSync(float threshold) throws ConnectionLostException, InterruptedException;

    /**
     * Block until sensed capacitance becomes less than a given threshold.
     * <p/>
     * For using a touch surface as a digital button, a threshold of 50pF is normally useful, with
     * some hysteresis recommended.
     *
     * @param threshold The threshold value, in pF units.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     * @throws InterruptedException    The calling thread has been interrupted.
     */
    public void waitUnder(float threshold) throws ConnectionLostException, InterruptedException;

    /**
     * This is very similar to {@link #waitUnder()}, but will wait for a new sample to arrive before
     * returning. This is useful in conjunction with {@link IOIO#sync()}, in cases when we want to
     * guarantee the we are looking at a sample that has been captured strictly after certain other
     * commands have been executed.
     *
     * @return The capacitance, in pico-Farade units.
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     * @see #waitUnder()
     */
    public void waitUnderSync(float threshold) throws ConnectionLostException, InterruptedException;
} public interface DigitalInput extends Closeable {
    /**
     * A digital input pin specification, used when opening digital inputs.
     */
    static public class Spec {
        /**
         * Input pin mode.
         */
        public enum Mode {
            /**
             * Pin is floating. When the pin is left disconnected the value
             * sensed is undefined. Use this mode when an external pull-up or
             * pull-down resistor is used or when interfacing push-pull type
             * logic circuits.
             */
            FLOATING,
            /**
             * Internal pull-up resistor is used. When the pin is left
             * disconnected, a logical "HIGH" (true) will be sensed. This is
             * useful for interfacing with open drain circuits or for
             * interacting with a switch connected between the pin and ground.
             */
            PULL_UP,
            /**
             * Internal pull-down resistor is used. When the pin is left
             * disconnected, a logical "LOW" (false) will be sensed. This is
             * useful for interacting with a switch connected between the pin
             * and Vdd.
             */
            PULL_DOWN
        }

        /**
         * The pin number, as labeled on the board.
         */
        public int pin;
        /**
         * The pin mode.
         */
        public Mode mode;

        /**
         * Constructor.
         *
         * @param pin  Pin number, as labeled on the board.
         * @param mode Pin mode.
         */
        public Spec(int pin, Mode mode) {
            this.pin = pin;
            this.mode = mode;
        }

        /**
         * Shorthand for Spec(pin, Mode.FLOATING).
         */
        public Spec(int pin) {
            this(pin, Mode.FLOATING);
        }
    }

    /**
     * Read the value sensed on the pin. May block for a few milliseconds if
     * called right after creation of the instance. If this is a problem, the
     * calling thread may be interrupted.
     *
     * @return True for logical "HIGH", false for logical "LOW".
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO has been lost.
     */
    public boolean read() throws InterruptedException, ConnectionLostException;

    /**
     * Block until a desired logical level is sensed. The calling thread can be
     * interrupted for aborting this operation.
     *
     * @param value The desired logical level. true for "HIGH", false for "LOW".
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO has been lost.
     */
    public void waitForValue(boolean value) throws InterruptedException,
            ConnectionLostException;
} static public class Spec {
    /**
     * Input pin mode.
     */
    public enum Mode {
        /**
         * Pin is floating. When the pin is left disconnected the value
         * sensed is undefined. Use this mode when an external pull-up or
         * pull-down resistor is used or when interfacing push-pull type
         * logic circuits.
         */
        FLOATING,
        /**
         * Internal pull-up resistor is used. When the pin is left
         * disconnected, a logical "HIGH" (true) will be sensed. This is
         * useful for interfacing with open drain circuits or for
         * interacting with a switch connected between the pin and ground.
         */
        PULL_UP,
        /**
         * Internal pull-down resistor is used. When the pin is left
         * disconnected, a logical "LOW" (false) will be sensed. This is
         * useful for interacting with a switch connected between the pin
         * and Vdd.
         */
        PULL_DOWN
    }

    /**
     * The pin number, as labeled on the board.
     */
    public int pin;
    /**
     * The pin mode.
     */
    public Mode mode;

    /**
     * Constructor.
     *
     * @param pin  Pin number, as labeled on the board.
     * @param mode Pin mode.
     */
    public Spec(int pin, Mode mode) {
        this.pin = pin;
        this.mode = mode;
    }

    /**
     * Shorthand for Spec(pin, Mode.FLOATING).
     */
    public Spec(int pin) {
        this(pin, Mode.FLOATING);
    }
} public enum Mode {
    /**
     * Pin is floating. When the pin is left disconnected the value
     * sensed is undefined. Use this mode when an external pull-up or
     * pull-down resistor is used or when interfacing push-pull type
     * logic circuits.
     */
    FLOATING,
    /**
     * Internal pull-up resistor is used. When the pin is left
     * disconnected, a logical "HIGH" (true) will be sensed. This is
     * useful for interfacing with open drain circuits or for
     * interacting with a switch connected between the pin and ground.
     */
    PULL_UP,
    /**
     * Internal pull-down resistor is used. When the pin is left
     * disconnected, a logical "LOW" (false) will be sensed. This is
     * useful for interacting with a switch connected between the pin
     * and Vdd.
     */
    PULL_DOWN
} public interface DigitalOutput extends Closeable {
    /**
     * A digital output pin specification, used when opening digital outputs.
     */
    public static class Spec {
        /**
         * Output pin mode.
         */
        public enum Mode {
            /**
             * Pin operates in push-pull mode, i.e. a logical "HIGH" is
             * represented by a voltage of Vdd on the pin and a logical "LOW" by
             * a voltage of 0 (ground).
             */
            NORMAL,
            /**
             * Pin operates in open-drain mode, i.e. a logical "HIGH" is
             * represented by a high impedance on the pin (as if it is
             * disconnected) and a logical "LOW" by a voltage of 0 (ground).
             * This mode is most commonly used for generating 5V logical signal
             * on a 3.3V pin: 5V tolerant pins must be used; a pull-up resistor
             * is connected between the pin and 5V, and the pin is used in open-
             * drain mode.
             */
            OPEN_DRAIN,
        }

        /**
         * The pin number, as labeled on the board.
         */
        public int pin;
        /**
         * The pin mode.
         */
        public Mode mode;

        /**
         * Constructor.
         *
         * @param pin  Pin number, as labeled on the board.
         * @param mode Pin mode.
         */
        public Spec(int pin, Mode mode) {
            this.pin = pin;
            this.mode = mode;
        }

        /**
         * Shorthand for Spec(pin, Mode.NORMAL).
         *
         * @see DigitalOutput.Spec#Spec(int, DigitalOutput.Spec.Mode)
         */
        public Spec(int pin) {
            this(pin, Mode.NORMAL);
        }
    }

    /**
     * Set the output of the pin.
     *
     * @param val The output. true is logical "HIGH", false is logical "LOW".
     * @throws ConnectionLostException The connection with the IOIO has been lost.
     */
    public void write(boolean val) throws ConnectionLostException;
} public interface IOIO {
    /**
     * An invalid pin number.
     */
    public static final int INVALID_PIN = -1;
    /**
     * The pin number used to designate the on-board 'stat' LED.
     */
    public static final int LED_PIN = 0;

    /**
     * A versioned component in the system.
     *
     * @see IOIO#getImplVersion(VersionType)
     */
    public enum VersionType {
        /**
         * Hardware version.
         */
        HARDWARE_VER,
        /**
         * Bootloader version.
         */
        BOOTLOADER_VER,
        /**
         * Application layer firmware version.
         */
        APP_FIRMWARE_VER,
        /**
         * IOIOLib version.
         */
        IOIOLIB_VER
    }

    /**
     * A state of a IOIO instance.
     */
    public enum State {
        /**
         * Connection not yet established.
         */
        INIT,
        /**
         * Connected.
         */
        CONNECTED,
        /**
         * Connection established, incompatible firmware detected.
         */
        INCOMPATIBLE,
        /**
         * Disconnected. Instance is useless.
         */
        DEAD
    }

    /**
     * Establishes connection with the IOIO board.
     * <p/>
     * This method is blocking until connection is established. This method can be aborted by
     * calling {@link #disconnect()}. In this case, it will throw a {@link ConnectionLostException}.
     *
     * @throws ConnectionLostException  An error occurred during connection or disconnect() has been called during
     *                                  connection. The instance state is disconnected.
     * @throws IncompatibilityException An incompatible board firmware of hardware has been detected. The instance state
     *                                  is disconnected.
     * @see #disconnect()
     * @see #waitForDisconnect()
     */
    public void waitForConnect() throws ConnectionLostException, IncompatibilityException;

    /**
     * Closes the connection to the board, or aborts a connection process started with
     * waitForConnect().
     * <p/>
     * Once this method is called, this IOIO instance and all the instances obtain from it become
     * invalid and will throw an exception on every operation.
     * <p/>
     * This method is asynchronous, i.e. it returns immediately, but it is not guaranteed that all
     * connection-related resources has already been freed and can be reused upon return. In cases
     * when this is important, client can call {@link #waitForDisconnect()}, which will block until
     * all resources have been freed.
     */
    public void disconnect();

    /**
     * Blocks until IOIO has been disconnected and all connection-related resources have been freed,
     * so that a new connection can be attempted.
     *
     * @throws InterruptedException When interrupt() has been called on this thread. This might mean that an
     *                              immediate attempt to create and connect a new IOIO object might fail for resource
     *                              contention.
     * @see #disconnect()
     * @see #waitForConnect()
     */
    public void waitForDisconnect() throws InterruptedException;

    /**
     * Gets the connections state.
     *
     * @return The connection state.
     */
    public State getState();

    /**
     * Resets the entire state (returning to initial state), without dropping the connection.
     * <p/>
     * It is equivalent to calling {@link Closeable#close()} on every interface obtained from this
     * instance. A connection must have been established prior to calling this method, by invoking
     * {@link #waitForConnect()}.
     *
     * @throws ConnectionLostException Connection was lost before or during the execution of this method.
     * @see #hardReset()
     */
    public void softReset() throws ConnectionLostException;

    /**
     * Equivalent to disconnecting and reconnecting the board power supply.
     * <p/>
     * The connection will be dropped and not reestablished. Full boot sequence will take place, so
     * firmware upgrades can be performed. A connection must have been established prior to calling
     * this method, by invoking {@link #waitForConnect()}.
     *
     * @throws ConnectionLostException Connection was lost before or during the execution of this method.
     * @see #softReset()
     */
    public void hardReset() throws ConnectionLostException;

    /**
     * Query the implementation version of the system's components. The implementation version
     * uniquely identifies a hardware revision or a software build. Returned version IDs are always
     * 8-character long, according to the IOIO versioning system: first 4 characters are the version
     * authority and last 4 characters are the revision.
     *
     * @param v The component whose version we query.
     * @return An 8-character implementation version ID.
     */
    public String getImplVersion(VersionType v);

    /**
     * Open a pin for digital input.
     * <p/>
     * A digital input pin can be used to read logic-level signals. The pin will operate in this
     * mode until close() is invoked on the returned interface. It is illegal to open a pin that has
     * already been opened and has not been closed. A connection must have been established prior to
     * calling this method, by invoking {@link #waitForConnect()}.
     *
     * @param spec Pin specification, consisting of the pin number, as labeled on the board, and the
     *             mode, which determines whether the pin will be floating, pull-up or pull-down. See
     *             {@link DigitalInput.Spec.Mode} for more information.
     * @return Interface of the assigned pin.
     * @throws ConnectionLostException Connection was lost before or during the execution of this method.
     * @see DigitalInput
     */
    public DigitalInput openDigitalInput(DigitalInput.Spec spec) throws ConnectionLostException;

    /**
     * Shorthand for openDigitalInput(new DigitalInput.Spec(pin)).
     *
     * @see #openDigitalInput(ioio.lib.api.DigitalInput.Spec)
     */
    public DigitalInput openDigitalInput(int pin) throws ConnectionLostException;

    /**
     * Shorthand for openDigitalInput(new DigitalInput.Spec(pin, mode)).
     *
     * @see #openDigitalInput(ioio.lib.api.DigitalInput.Spec)
     */
    public DigitalInput openDigitalInput(int pin, DigitalInput.Spec.Mode mode)
            throws ConnectionLostException;

    /**
     * Open a pin for digital output.
     * <p/>
     * A digital output pin can be used to generate logic-level signals. The pin will operate in
     * this mode until close() is invoked on the returned interface. It is illegal to open a pin
     * that has already been opened and has not been closed. A connection must have been established
     * prior to calling this method, by invoking {@link #waitForConnect()}.
     *
     * @param spec       Pin specification, consisting of the pin number, as labeled on the board, and the
     *                   mode, which determines whether the pin will be normal or open-drain. See
     *                   {@link DigitalOutput.Spec.Mode} for more information.
     * @param startValue The initial logic level this pin will generate as soon at it is open.
     * @return Interface of the assigned pin.
     * @throws ConnectionLostException Connection was lost before or during the execution of this method.
     * @see DigitalOutput
     */
    public DigitalOutput openDigitalOutput(DigitalOutput.Spec spec, boolean startValue)
            throws ConnectionLostException;

    /**
     * Shorthand for openDigitalOutput(new DigitalOutput.Spec(pin, mode), startValue).
     *
     * @see #openDigitalOutput(ioio.lib.api.DigitalOutput.Spec, boolean)
     */
    public DigitalOutput openDigitalOutput(int pin, DigitalOutput.Spec.Mode mode, boolean startValue)
            throws ConnectionLostException;

    /**
     * Shorthand for openDigitalOutput(new DigitalOutput.Spec(pin), startValue). Pin mode will be
     * "normal" (as opposed to "open-drain".
     *
     * @see #openDigitalOutput(ioio.lib.api.DigitalOutput.Spec, boolean)
     */
    public DigitalOutput openDigitalOutput(int pin, boolean startValue)
            throws ConnectionLostException;

    /**
     * Shorthand for openDigitalOutput(new DigitalOutput.Spec(pin), false). Pin mode will be
     * "normal" (as opposed to "open-drain".
     *
     * @see #openDigitalOutput(ioio.lib.api.DigitalOutput.Spec, boolean)
     */
    public DigitalOutput openDigitalOutput(int pin) throws ConnectionLostException;

    /**
     * Open a pin for analog input.
     * <p/>
     * An analog input pin can be used to measure voltage. Note that not every pin can be used as an
     * analog input. See board documentation for the legal pins and permitted voltage range.
     * <p/>
     * The pin will operate in this mode until close() is invoked on the returned interface. It is
     * illegal to open a pin that has already been opened and has not been closed. A connection must
     * have been established prior to calling this method, by invoking {@link #waitForConnect()}.
     *
     * @param pin Pin number, as labeled on the board.
     * @return Interface of the assigned pin.
     * @throws ConnectionLostException Connection was lost before or during the execution of this method.
     * @see AnalogInput
     */
    public AnalogInput openAnalogInput(int pin) throws ConnectionLostException;

    /**
     * Open a pin for PWM (Pulse-Width Modulation) output.
     * <p/>
     * A PWM pin produces a logic-level PWM signal. These signals are typically used for simulating
     * analog outputs for controlling the intensity of LEDs, the rotation speed of motors, etc. They
     * are also frequently used for controlling hobby servo motors.
     * <p/>
     * Note that not every pin can be used as PWM output. In addition, the total number of
     * concurrent PWM modules in use is limited. See board documentation for the legal pins and
     * limit on concurrent usage.
     * <p/>
     * The pin will operate in this mode until close() is invoked on the returned interface. It is
     * illegal to open a pin that has already been opened and has not been closed. A connection must
     * have been established prior to calling this method, by invoking {@link #waitForConnect()}.
     *
     * @param spec   Pin specification, consisting of the pin number, as labeled on the board, and the
     *               mode, which determines whether the pin will be normal or open-drain. See
     *               {@link DigitalOutput.Spec.Mode} for more information.
     * @param freqHz PWM frequency, in Hertz.
     * @return Interface of the assigned pin.
     * @throws ConnectionLostException Connection was lost before or during the execution of this method.
     * @throws OutOfResourceException  This is a runtime exception, so it is not necessary to catch it if the client
     *                                 guarantees that the total number of concurrent PWM resources is not exceeded.
     * @see PwmOutput
     */
    public PwmOutput openPwmOutput(DigitalOutput.Spec spec, int freqHz)
            throws ConnectionLostException;

    /**
     * Shorthand for openPwmOutput(new DigitalOutput.Spec(pin), freqHz).
     *
     * @see #openPwmOutput(ioio.lib.api.DigitalOutput.Spec, int)
     */
    public PwmOutput openPwmOutput(int pin, int freqHz) throws ConnectionLostException;

    /**
     * Open a pin for pulse input.
     * <p/>
     * The pulse input module is quite flexible. It enables several kinds of timing measurements on
     * a digital signal: pulse width measurement (positive or negative pulse), and frequency of a
     * periodic signal.
     * <p/>
     * Note that not every pin can be used as pulse input. In addition, the total number of
     * concurrent pulse input modules in use is limited. See board documentation for the legal pins
     * and limit on concurrent usage.
     * <p/>
     * The pin will operate in this mode until close() is invoked on the returned interface. It is
     * illegal to open a pin that has already been opened and has not been closed. A connection must
     * have been established prior to calling this method, by invoking {@link #waitForConnect()}.
     *
     * @param spec            Pin specification, consisting of the pin number, as labeled on the board, and the
     *                        mode, which determines whether the pin will be floating, pull-up or pull-down. See
     *                        {@link DigitalInput.Spec.Mode} for more information.
     * @param rate            The clock rate to use for timing the signal. A faster clock rate will result in
     *                        better precision but will only be able to measure narrow pulses / high
     *                        frequencies.
     * @param mode            The mode in which to operate. Determines whether the module will measure pulse
     *                        durations or frequency.
     * @param doublePrecision Whether to open a double-precision pulse input module. Double- precision modules
     *                        enable reading of much longer pulses and lower frequencies with high accuracy than
     *                        single precision modules. However, their number is limited, so when possible, and
     *                        if the resources are all needed, use single-precision. For more details on the
     *                        exact spec of single- vs. double- precision, see {@link PulseInput}.
     * @return An instance of the {@link PulseInput}, which can be used to obtain the data.
     * @throws ConnectionLostException Connection was lost before or during the execution of this method.
     * @throws OutOfResourceException  This is a runtime exception, so it is not necessary to catch it if the client
     *                                 guarantees that the total number of concurrent PWM resources is not exceeded.
     * @see PulseInput
     */
    public PulseInput openPulseInput(DigitalInput.Spec spec, PulseInput.ClockRate rate,
                                     PulseInput.PulseMode mode, boolean doublePrecision) throws ConnectionLostException;

    /**
     * Shorthand for openPulseInput(new DigitalInput.Spec(pin), rate, mode, true), i.e. opens a
     * double-precision, 16MHz pulse input on the given pin with the given mode.
     *
     * @see #openPulseInput(ioio.lib.api.DigitalInput.Spec, ioio.lib.api.PulseInput.ClockRate,
     * ioio.lib.api.PulseInput.PulseMode, boolean)
     */
    public PulseInput openPulseInput(int pin, PulseMode mode) throws ConnectionLostException;

    /**
     * Open a UART module, enabling a bulk transfer of byte buffers.
     * <p/>
     * UART is a very common hardware communication protocol, enabling full- duplex, asynchronous
     * point-to-point data transfer. It typically serves for opening consoles or as a basis for
     * higher-level protocols, such as MIDI RS-232, and RS-485.
     * <p/>
     * Note that not every pin can be used for UART RX or TX. In addition, the total number of
     * concurrent UART modules in use is limited. See board documentation for the legal pins and
     * limit on concurrent usage.
     * <p/>
     * The UART module will operate, and the pins will work in their respective modes until close()
     * is invoked on the returned interface. It is illegal to use pins that have already been opened
     * and has not been closed. A connection must have been established prior to calling this
     * method, by invoking {@link #waitForConnect()}.
     *
     * @param rx       Pin specification for the RX pin, consisting of the pin number, as labeled on the
     *                 board, and the mode, which determines whether the pin will be floating, pull-up or
     *                 pull-down. See {@link DigitalInput.Spec.Mode} for more information. null can be
     *                 passed to designate that we do not want RX input to this module.
     * @param tx       Pin specification for the TX pin, consisting of the pin number, as labeled on the
     *                 board, and the mode, which determines whether the pin will be normal or
     *                 open-drain. See {@link DigitalOutput.Spec.Mode} for more information. null can be
     *                 passed to designate that we do not want TX output to this module.
     * @param baud     The clock frequency of the UART module in Hz.
     * @param parity   The parity mode, as in {@link Parity}.
     * @param stopbits Number of stop bits, as in {@link StopBits}.
     * @return Interface of the assigned module.
     * @throws ConnectionLostException Connection was lost before or during the execution of this method.
     * @throws OutOfResourceException  This is a runtime exception, so it is not necessary to catch it if the client
     *                                 guarantees that the total number of concurrent UART resources is not exceeded.
     * @see Uart
     */
    public Uart openUart(DigitalInput.Spec rx, DigitalOutput.Spec tx, int baud, Parity parity,
                         StopBits stopbits) throws ConnectionLostException;

    /**
     * Shorthand for
     * {@link #openUart(DigitalInput.Spec, DigitalOutput.Spec, int, Uart.Parity, Uart.StopBits)} ,
     * where the input pins use their default specs. {@link #INVALID_PIN} can be used on either pin
     * if a TX- or RX-only UART is needed.
     *
     * @see #openUart(DigitalInput.Spec, DigitalOutput.Spec, int, Uart.Parity, Uart.StopBits)
     */
    public Uart openUart(int rx, int tx, int baud, Parity parity, StopBits stopbits)
            throws ConnectionLostException;

    /**
     * Open a SPI master module, enabling communication with multiple SPI-enabled slave modules.
     * <p/>
     * SPI is a common hardware communication protocol, enabling full-duplex, synchronous
     * point-to-multi-point data transfer. It requires MOSI, MISO and CLK lines shared by all nodes,
     * as well as a SS line per slave, connected between this slave and a respective pin on the
     * master. The MISO line should operate in pull-up mode, using either the internal pull-up or an
     * external resistor.
     * <p/>
     * Note that not every pin can be used for SPI MISO, MOSI or CLK. In addition, the total number
     * of concurrent SPI modules in use is limited. See board documentation for the legal pins and
     * limit on concurrent usage.
     * <p/>
     * The SPI module will operate, and the pins will work in their respective modes until close()
     * is invoked on the returned interface. It is illegal to use pins that have already been opened
     * and has not been closed. A connection must have been established prior to calling this
     * method, by invoking {@link #waitForConnect()}.
     *
     * @param miso        Pin specification for the MISO (Master In Slave Out) pin, consisting of the pin
     *                    number, as labeled on the board, and the mode, which determines whether the pin
     *                    will be floating, pull-up or pull-down. See {@link DigitalInput.Spec.Mode} for
     *                    more information.
     * @param mosi        Pin specification for the MOSI (Master Out Slave In) pin, consisting of the pin
     *                    number, as labeled on the board, and the mode, which determines whether the pin
     *                    will be normal or open-drain. See {@link DigitalOutput.Spec.Mode} for more
     *                    information.
     * @param clk         Pin specification for the CLK pin, consisting of the pin number, as labeled on the
     *                    board, and the mode, which determines whether the pin will be normal or
     *                    open-drain. See {@link DigitalOutput.Spec.Mode} for more information.
     * @param slaveSelect An array of pin specifications for each of the slaves' SS (Slave Select) pin. The
     *                    index of this array designates the slave index, used later to refer to this slave.
     *                    The spec is consisting of the pin number, as labeled on the board, and the mode,
     *                    which determines whether the pin will be normal or open-drain. See
     *                    {@link DigitalOutput.Spec.Mode} for more information.
     * @param config      The configuration of the SPI module. See {@link SpiMaster.Config} for details.
     * @return Interface of the assigned module.
     * @throws ConnectionLostException Connection was lost before or during the execution of this method.
     * @throws OutOfResourceException  This is a runtime exception, so it is not necessary to catch it if the client
     *                                 guarantees that the total number of concurrent SPI resources is not exceeded.
     * @see SpiMaster
     */
    public SpiMaster openSpiMaster(DigitalInput.Spec miso, DigitalOutput.Spec mosi,
                                   DigitalOutput.Spec clk, DigitalOutput.Spec[] slaveSelect, SpiMaster.Config config)
            throws ConnectionLostException;

    /**
     * Shorthand for
     * {@link #openSpiMaster(ioio.lib.api.DigitalInput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[], ioio.lib.api.SpiMaster.Config)}
     * , where the pins are all open with the default modes and default configuration values are
     * used.
     *
     * @see #openSpiMaster(ioio.lib.api.DigitalInput.Spec, ioio.lib.api.DigitalOutput.Spec,
     * ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[],
     * ioio.lib.api.SpiMaster.Config)
     */
    public SpiMaster openSpiMaster(int miso, int mosi, int clk, int[] slaveSelect,
                                   SpiMaster.Rate rate) throws ConnectionLostException;

    /**
     * Shorthand for
     * {@link #openSpiMaster(ioio.lib.api.DigitalInput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[], ioio.lib.api.SpiMaster.Config)}
     * , where the MISO pins is opened with pull up, and the other pins are open with the default
     * modes and default configuration values are used. In this version, a single slave is used.
     *
     * @see #openSpiMaster(ioio.lib.api.DigitalInput.Spec, ioio.lib.api.DigitalOutput.Spec,
     * ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[],
     * ioio.lib.api.SpiMaster.Config)
     */
    public SpiMaster openSpiMaster(int miso, int mosi, int clk, int slaveSelect, SpiMaster.Rate rate)
            throws ConnectionLostException;

    /**
     * Open a TWI (Two-Wire Interface, such as I2C/SMBus) master module, enabling communication with
     * multiple TWI-enabled slave modules.
     * <p/>
     * TWI is a common hardware communication protocol, enabling half-duplex, synchronous
     * point-to-multi-point data transfer. It requires a physical connection of two lines (SDA, SCL)
     * shared by all the bus nodes, where the SDA is open-drain and externally pulled-up.
     * <p/>
     * Note that there is a fixed number of TWI modules, and the pins they use are static. Client
     * has to make sure these pins are not already opened before calling this method. See board
     * documentation for the number of modules and the respective pins they use.
     * <p/>
     * The TWI module will operate, and the pins will work in their respective modes until close()
     * is invoked on the returned interface. It is illegal to use pins that have already been opened
     * and has not been closed. A connection must have been established prior to calling this
     * method, by invoking {@link #waitForConnect()}.
     *
     * @param twiNum The TWI module index to use. Will also determine the pins used.
     * @param rate   The clock rate. Can be 100KHz / 400KHz / 1MHz.
     * @param smbus  When true, will use SMBus voltage levels. When false, I2C voltage levels.
     * @return Interface of the assigned module.
     * @throws ConnectionLostException Connection was lost before or during the execution of this method.
     * @see TwiMaster
     */
    public TwiMaster openTwiMaster(int twiNum, Rate rate, boolean smbus)
            throws ConnectionLostException;

    /**
     * Open an ICSP channel, enabling Flash programming of an external PIC MCU, and in particular,
     * another IOIO board.
     * <p/>
     * ICSP (In-Circuit Serial Programming) is a protocol intended for programming of PIC MCUs. It
     * is a serial protocol over three wires: PGC (clock), PGD (data) and MCLR (reset), where PGC
     * and MCLR are controlled by the master and PGD is shared by the master and slave, depending on
     * the transaction state.
     * <p/>
     * Note that there is only one ICSP modules, and the pins it uses are static. Client has to make
     * sure that the ICSP module is not already in use, as well as those dedicated pins. See board
     * documentation for the actual pins used for ICSP.
     *
     * @return Interface of the ICSP module.
     * @throws ConnectionLostException Connection was lost before or during the execution of this method.
     * @see IcspMaster
     */
    public IcspMaster openIcspMaster() throws ConnectionLostException;

    /**
     * Shorthand for openCapSense(pin, CapSense.DEFAULT_COEF).
     *
     * @see #openCapSense(int, float)
     */
    public CapSense openCapSense(int pin) throws ConnectionLostException;

    /**
     * Open a pin for cap-sense.
     * <p/>
     * A cap-sense input pin can be used to measure capacitance, typically in touch sensing
     * applications. Note that not every pin can be used as cap- sense. See board documentation for
     * the legal pins.
     * <p/>
     * The pin will operate in this mode until close() is invoked on the returned interface. It is
     * illegal to open a pin that has already been opened and has not been closed. A connection must
     * have been established prior to calling this method, by invoking {@link #waitForConnect()}.
     *
     * @param pin Pin number, as labeled on the board.
     * @return Interface of the assigned pin.
     * @throws ConnectionLostException Connection was lost before or during the execution of this method.
     * @see CapSense
     */
    public CapSense openCapSense(int pin, float filterCoef) throws ConnectionLostException;

    /**
     * Open a motion-control sequencer.
     * <p/>
     * This module allows fast and precise sequencing of waveforms, primarily intended for
     * synchronized driving of various kinds of motors and other actuators. There is currently
     * support for only a single instance of this module. For more details, see {@link Sequencer}.
     *
     * @param config The sequencer configuration.
     * @return The sequencer instance.
     * @throws ConnectionLostException Connection was lost before or during the execution of this method.
     */
    public Sequencer openSequencer(Sequencer.ChannelConfig config[]) throws ConnectionLostException;

    /**
     * Start a batch of operations. This is strictly an optimization and will not change
     * functionality: if the client knows that a sequence of several IOIO operations are going to be
     * performed immediately following each other, a call to {@link #beginBatch()} before the
     * sequence and {@link #endBatch()} after the sequence will cause the operations to be grouped
     * into one transfer to the IOIO, thus reducing latency. A matching {@link #endBatch()}
     * operation must always follow, or otherwise no operation will ever be actually executed.
     * {@link #beginBatch()} / {@link #endBatch()} blocks may be nested - the transfer will occur
     * when the outermost {@link #endBatch()} is invoked. Note that it is not guaranteed that no
     * transfers will happen while inside a batch - it should be treated as a hint. Code running
     * inside the block must be quick as it blocks <b>all</b> transfers to the IOIO, including those
     * performed from other threads.
     *
     * @throws ConnectionLostException Connection was lost before or during the execution of this method.
     */
    public void beginBatch() throws ConnectionLostException;

    /**
     * End a batch of operations. For explanation, see {@link #beginBatch()}.
     *
     * @throws ConnectionLostException Connection was lost before or during the execution of this method.
     */
    public void endBatch() throws ConnectionLostException;

    /**
     * Sends a message to the IOIO and waits for an echo.
     * <p/>
     * This is useful for synchronizing asynchronous calls across the entire API, for example: When
     * writing to a {@link DigitalOutput} and then reading from a {@link DigitalInput}, if you want
     * to guarantee that the reading was obtained after the write has taken place, call this method
     * in between.
     *
     * @throws ConnectionLostException Connection was lost before or during the execution of this method.
     * @throws InterruptedException    When interrupt() has been called on this thread.
     */
    public void sync() throws ConnectionLostException, InterruptedException;
} public interface IOIOConnection {
    void waitForConnect() throws ConnectionLostException;

    void disconnect();

    InputStream getInputStream() throws ConnectionLostException;

    OutputStream getOutputStream() throws ConnectionLostException;

    /**
     * Can this connection be closed. Normally the answer would be "true", but
     * some weird connections cannot be closed and need the higher layer to do
     * a "soft close" instead.
     *
     * @return true This connection can be closed.
     */
    boolean canClose();
} public interface IcspMaster extends Closeable {
    /**
     * Initiate a sequence that will put the slave device in programming mode.
     * This sequence is necessary for executing instructions and reading
     * register values.
     *
     * @throws ConnectionLostException Connection to the IOIO has been lost.
     */
    public void enterProgramming() throws ConnectionLostException;

    /**
     * Initiate a sequence that will put the slave device out of programming
     * mode. It will be held in reset.
     *
     * @throws ConnectionLostException Connection to the IOIO has been lost.
     */
    public void exitProgramming() throws ConnectionLostException;

    /**
     * Execute a single instruction on the slave MCU.
     *
     * @param instruction a 24-bit PIC instruction.
     * @throws ConnectionLostException Connection to the IOIO has been lost.
     */
    public void executeInstruction(int instruction)
            throws ConnectionLostException;

    /**
     * Request a read of the VISI register on the slave MCU. This is an
     * asynchronous call, in which the 16-bit result is obtained by
     * {@link #waitVisiResult()}.
     * This method may block if the read queue on the IOIO is full, but this
     * should be for short periods only.
     *
     * @throws ConnectionLostException Connection to the IOIO has been lost.
     * @throws InterruptedException    Interrupted while blocking.
     */
    public void readVisi() throws ConnectionLostException, InterruptedException;

    /**
     * Wait and return a result of a call to {@link #readVisi()}.
     * Results will be returned in the same order as requested.
     * <p/>
     * The call will block until there is data, until interrupted, or until
     * connection to the IOIO has been lost.
     *
     * @return The result - an unsigned 16-bit number.
     * @throws ConnectionLostException Connection to the IOIO has been lost.
     * @throws InterruptedException    Interrupted while blocking.
     */
    public int waitVisiResult() throws ConnectionLostException,
            InterruptedException;
} public interface PulseInput extends Closeable {
    /**
     * An enumeration for describing the module's operating mode.
     */
    public enum PulseMode {
        /**
         * Positive pulse measurement (rising-edge-to-falling-edge).
         */
        POSITIVE(1),
        /**
         * Negative pulse measurement (falling-edge-to-rising-edge).
         */
        NEGATIVE(1),
        /**
         * Frequency measurement (rising-edge-to-rising-edge).
         */
        FREQ(1),
        /**
         * Frequency measurement (rising-edge-to-rising-edge) with 4x scaling.
         */
        FREQ_SCALE_4(4),
        /**
         * Frequency measurement (rising-edge-to-rising-edge) with 16x scaling.
         */
        FREQ_SCALE_16(16);

        /**
         * The scaling factor as an integer.
         */
        public final int scaling;

        private PulseMode(int s) {
            scaling = s;
        }
    }

    /**
     * Supported clock rate enum.
     */
    public enum ClockRate {
        /**
         * 16MHz
         */
        RATE_16MHz(16000000),
        /**
         * 2MHz
         */
        RATE_2MHz(2000000),
        /**
         * 250KHz
         */
        RATE_250KHz(250000),
        /**
         * 62.5KHz
         */
        RATE_62KHz(62500);

        /**
         * The value in Hertz units.
         */
        public final int hertz;

        private ClockRate(int h) {
            hertz = h;
        }
    }

    /**
     * Gets the pulse duration in case of pulse measurement mode, or the period in case of frequency
     * mode. When scaling is used, this is compensated for here, so the duration of a single cycle
     * will be returned.
     * <p/>
     * The first call to this method may block shortly until the first data update arrives. The
     * client may interrupt the calling thread.
     *
     * @return The duration, in seconds.
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO has been lost.
     */
    public float getDuration() throws InterruptedException, ConnectionLostException;

    /**
     * This is very similar to {@link #getDuration()}, but will wait for a new sample to arrive
     * before returning. This is useful in conjunction with {@link IOIO#sync()}, in cases when we
     * want to guarantee the we are looking at a sample that has been captured strictly after
     * certain other commands have been executed.
     *
     * @return The duration, in seconds.
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     * @see #getDuration()
     */
    public float getDurationSync() throws InterruptedException, ConnectionLostException;

    /**
     * Reads a single measurement from the queue. If the queue is empty, will block until more data
     * arrives. The calling thread may be interrupted in order to abort the call. See interface
     * documentation for further explanation regarding the read queue.
     * <p/>
     * This method may not be used if the interface has was opened in frequency mode.
     *
     * @return The duration, in seconds.
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO has been lost.
     */
    public float getDurationBuffered() throws InterruptedException, ConnectionLostException;

    /**
     * @deprecated Please use {@link #getDurationBuffered()} instead.
     */
    public float waitPulseGetDuration() throws InterruptedException, ConnectionLostException;

    /**
     * Gets the momentary frequency of the measured signal. When scaling is used, this is
     * compensated for here, so the true frequency of the signal will be returned.
     * <p/>
     * The first call to this method may block shortly until the first data update arrives. The
     * client may interrupt the calling thread. - *
     * <p/>
     * This method may only be used if the interface has been opened in frequency mode.
     *
     * @return The frequency, in Hz.
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO has been lost.
     */
    public float getFrequency() throws InterruptedException, ConnectionLostException;

    /**
     * This is very similar to {@link #getFrequency()}, but will wait for a new sample to arrive
     * before returning. This is useful in conjunction with {@link IOIO#sync()}, in cases when we
     * want to guarantee the we are looking at a sample that has been captured strictly after
     * certain other commands have been executed.
     *
     * @return The frequency, in Hz.
     * @throws InterruptedException    The calling thread has been interrupted.
     * @throws ConnectionLostException The connection with the IOIO is lost.
     * @see #getFrequency()
     */
    public float getFrequencySync() throws InterruptedException, ConnectionLostException;
} public enum ClockRate {
    /**
     * 16MHz
     */
    RATE_16MHz(16000000),
    /**
     * 2MHz
     */
    RATE_2MHz(2000000),
    /**
     * 250KHz
     */
    RATE_250KHz(250000),
    /**
     * 62.5KHz
     */
    RATE_62KHz(62500);

    /**
     * The value in Hertz units.
     */
    public final int hertz;

    private ClockRate(int h) {
        hertz = h;
    }
} public enum PulseMode {
    /**
     * Positive pulse measurement (rising-edge-to-falling-edge).
     */
    POSITIVE(1),
    /**
     * Negative pulse measurement (falling-edge-to-rising-edge).
     */
    NEGATIVE(1),
    /**
     * Frequency measurement (rising-edge-to-rising-edge).
     */
    FREQ(1),
    /**
     * Frequency measurement (rising-edge-to-rising-edge) with 4x scaling.
     */
    FREQ_SCALE_4(4),
    /**
     * Frequency measurement (rising-edge-to-rising-edge) with 16x scaling.
     */
    FREQ_SCALE_16(16);

    /**
     * The scaling factor as an integer.
     */
    public final int scaling;

    private PulseMode(int s) {
        scaling = s;
    }
} public interface PwmOutput extends Closeable {
    /**
     * Sets the duty cycle of the PWM output. The duty cycle is defined to be
     * the pulse width divided by the total cycle period. For absolute control
     * of the pulse with, consider using {@link #setPulseWidth(int)}.
     *
     * @param dutyCycle The duty cycle, as a real value from 0.0 to 1.0.
     * @throws ConnectionLostException The connection to the IOIO has been lost.
     * @see #setPulseWidth(int)
     */
    public void setDutyCycle(float dutyCycle) throws ConnectionLostException;

    /**
     * Sets the pulse width of the PWM output. The pulse width is duration of
     * the high-time within a single period of the signal. For relative control
     * of the pulse with, consider using {@link #setDutyCycle(float)}.
     *
     * @param pulseWidthUs The pulse width, in microsecond units.
     * @throws ConnectionLostException The connection to the IOIO has been lost.
     * @see #setDutyCycle(float)
     */
    public void setPulseWidth(int pulseWidthUs) throws ConnectionLostException;

    /**
     * The same as {@link #setPulseWidth(int)}, but with sub-microsecond
     * precision.
     */
    public void setPulseWidth(float pulseWidthUs)
            throws ConnectionLostException;
} public interface Sequencer extends Closeable {
    /**
     * A clock rate selection, which implies a time-base.
     */
    public enum Clock {
        /**
         * 16 MHz (62.5ns time-base).
         */
        CLK_16M,
        /**
         * 2 MHz (0.5us time-base).
         */
        CLK_2M,
        /**
         * 250 KHz (4us time-base).
         */
        CLK_250K,
        /**
         * 62.5 KHz (16us time-base).
         */
        CLK_62K5
    }

    /**
     * A sequencer event. Used for tracking execution progress.
     */
    public class Event {
        /**
         * Event type.
         */
        public enum Type {
            /**
             * The sequencer has been stopped or never started. This will always be accompanied by a
             * numCuesStarted of 0. This event will also be the first event appearing on the event
             * queue to designate the the sequencer has been opened and the cue FIFO is at its full
             * capacity for pushing messages. This is useful if the client wants to pre-fill the
             * FIFO in order to avoid stalls.
             */
            STOPPED,
            /**
             * A new cue has started executing.
             */
            CUE_STARTED,
            /**
             * A cue has ended execution and the sequencer is idle as result of a pause request.
             */
            PAUSED,
            /**
             * A cue has ended execution and the sequencer is idle as result of the queue becoming
             * empty.
             */
            STALLED,
            /**
             * This event type is only sent once, when the sequencer has been closed. It is mostly
             * intended to release a client blocking on {@link Sequencer#waitEvent()}. It is also
             * used if {@link Sequencer#getLastEvent()} is called before any event has been sent.
             */
            CLOSED
        }

        /**
         * The event type.
         */
        public final Type type;

        /**
         * This gives a counter of the number cues started execution until now, which is
         * synchronized with the events. When the first cue begins execution, the event will be
         * CUE_STARTED and numCuesStarted will be 1.
         */
        public final int numCuesStarted;

        /**
         * Constructor.
         */
        public Event(Type t, int n) {
            type = t;
            numCuesStarted = n;
        }
    }

    /**
     * A marker interface for channel configurations. A concrete instance of this describes the
     * configuration of a single channel.
     */
    public static interface ChannelConfig {
    }

    /**
     * Configuration for a channel of type PWM Position.
     * <p/>
     * PWM position channels are channels in which a PWM signal is generated, and the pulse width
     * controls the position of the actuator. A good example is a hobby servo motor. The main
     * difference from a PWM speed channel is that the position channel will retain its pulse width
     * during a stall event.
     */
    public static class ChannelConfigPwmPosition implements ChannelConfig {
        /**
         * Specification of the output pin(s) for this channel.
         */
        public final DigitalOutput.Spec[] pinSpec;

        /**
         * The clock rate for this channel (cannot be changed on a per-cue basis).
         */
        public final Clock clk;

        /**
         * The PWM period, in time-base units, determined by {@link #clk}. Valid values are
         * [2..65536].
         */
        public final int period;

        /**
         * The initial pulse width (before any cue is executed), in time-base units, determined by
         * {@link #clk}. Valid values are 0 or [2..65536].
         */
        public final int initialPulseWidth;

        /**
         * Constructor.
         * <p/>
         *
         * @param clk               See {@link #clk}.
         * @param period            See {@link #period}.
         * @param initialPulseWidth See {@link #initialPulseWidth}.
         * @param pinSpec           See {@link #pinSpec}.
         */
        public ChannelConfigPwmPosition(Clock clk, int period, int initialPulseWidth,
                                        DigitalOutput.Spec... pinSpec) {
            if (period < 2 || period > (1 << 16)) {
                throw new IllegalArgumentException("Period width must be between [2..65536]");
            }
            if (initialPulseWidth != 0 && (initialPulseWidth < 2 || initialPulseWidth > (1 << 16))) {
                throw new IllegalArgumentException(
                        "Initial pulse width must be 0 or between [2..65536]");
            }
            this.pinSpec = pinSpec;
            this.clk = clk;
            this.period = period;
            this.initialPulseWidth = initialPulseWidth;
        }
    }

    /**
     * Configuration for a channel of type PWM speed.
     * <p/>
     * PWM speed channels are channels in which a PWM signal is generated, and the pulse width
     * controls the speed of the actuator. A good example is a DC motor. The main difference from a
     * PWM position channel is that the position channel will go back to its initial pulse width
     * during a stall event.
     */
    public static class ChannelConfigPwmSpeed implements ChannelConfig {
        /**
         * Specification of the output pin(s) for this channel.
         */
        public final DigitalOutput.Spec[] pinSpec;

        /**
         * The clock rate for this channel (cannot be changed on a per-cue basis).
         */
        public final Clock clk;

        /**
         * The PWM period, in time-base units, determined by {@link #clk}. Valid values are
         * [2..65536].
         */
        public final int period;

        /**
         * The initial pulse width (before any cue is executed), in time-base units, determined by
         * {@link #clk}. Valid values are 0 or [2..65536]. Also used in the event of a stall.
         */
        public final int initialPulseWidth;

        /**
         * Constructor.
         * <p/>
         *
         * @param clk               See {@link #clk}.
         * @param period            See {@link #period}.
         * @param initialPulseWidth See {@link #initialPulseWidth}.
         * @param pinSpec           See {@link #pinSpec}.
         */
        public ChannelConfigPwmSpeed(Clock clk, int period, int initialPulseWidth,
                                     DigitalOutput.Spec... pinSpec) {
            if (period < 2 || period > (1 << 16)) {
                throw new IllegalArgumentException("Period width must be between [2..65536]");
            }
            if (initialPulseWidth != 0 && (initialPulseWidth < 2 || initialPulseWidth > (1 << 16))) {
                throw new IllegalArgumentException(
                        "Initial pulse width must be 0 or between [2..65536]");
            }
            this.pinSpec = pinSpec;
            this.clk = clk;
            this.period = period;
            this.initialPulseWidth = initialPulseWidth;
        }
    }

    /**
     * Configuration for a channel of type FM speed.
     * <p/>
     * FM speed channels are channels in which fixed-width pulses are generated with varying
     * frequency, which corresponds to the actuator speed. A good example is a stepper motor in an
     * application which requires speed control and not position control (for the latter see
     * {@link ChannelConfigSteps}). An FM speed channel will idle (not produce any pulses) during a
     * stall event.
     */
    public static class ChannelConfigFmSpeed implements ChannelConfig {
        /**
         * Specification of the output pin(s) for this channel.
         */
        public final DigitalOutput.Spec[] pinSpec;

        /**
         * The clock rate for this channel (cannot be changed on a per-cue basis).
         */
        public final Clock clk;

        /**
         * The width (duration) of each pulse, in time-base units, determined by {@link #clk}. Valid
         * values are [2..65536].
         */
        public final int pulseWidth;

        /**
         * Constructor.
         * <p/>
         *
         * @param clk        See {@link #clk}.
         * @param pulseWidth See {@link #pulseWidth}.
         * @param pinSpec    See {@link #pinSpec}.
         */
        public ChannelConfigFmSpeed(Clock clk, int pulseWidth, DigitalOutput.Spec... pinSpec) {
            if (pulseWidth < 2 || pulseWidth > (1 << 16)) {
                throw new IllegalArgumentException("Pulse width must be between [2..65536]");
            }
            this.pinSpec = pinSpec;
            this.clk = clk;
            this.pulseWidth = pulseWidth;
        }
    }

    /**
     * Configuration for a channel of type steps.
     * <p/>
     * Steps channels are channels in which fixed-width pulses are generated with varying frequency,
     * which corresponds to the actuator speed. A good example is a stepper motor in an application
     * which requires position control. Unlike the FM speed channel, steps channels will generate a
     * deterministic number of steps in a given duration, as well as allow changing the time-base on
     * every cue. See {@link ChannelCueSteps} for a discussion on number of steps calculation. A
     * steps channel will idle (not produce any pulses) during a stall event.
     */
    public static class ChannelConfigSteps implements ChannelConfig {
        /**
         * Specification of the output pin(s) for this channel.
         */
        public final DigitalOutput.Spec[] pinSpec;

        /**
         * Constructor.
         * <p/>
         *
         * @param pinSpec See {@link #pinSpec}.
         */
        public ChannelConfigSteps(DigitalOutput.Spec... pinSpec) {
            this.pinSpec = pinSpec;
        }
    }

    /**
     * Configuration for a binary channel.
     * <p/>
     * A binary channel is a simple digital output, which is driven in synchronization with the
     * sequence. Solenoids, DC motors running at full speed (no PWM) or LED are all examples for
     * actuators that can be controlled by a binary channel. During a stall event, the channel can
     * be configured to either retain its last state, or go to its initial state.
     */
    public static class ChannelConfigBinary implements ChannelConfig {
        /**
         * Specification of the output pin(s) for this channel.
         */
        public final DigitalOutput.Spec pinSpec;

        /**
         * Initial value for this channel (true = HIGH, false = LOW).
         */
        public final boolean initialValue;

        /**
         * When true, channel will go to initial state when stalled or stopped. Otherwise, channel
         * will retain its last state.
         */
        public final boolean initWhenIdle;

        /**
         * Constructor.
         * <p/>
         *
         * @param initialValue See {@link #initialValue}.
         * @param initWhenIdle See {@link #initWhenIdle}.
         * @param pinSpec      See {@link #pinSpec}.
         */
        public ChannelConfigBinary(boolean initialValue, boolean initWhenIdle,
                                   DigitalOutput.Spec pinSpec) {
            this.pinSpec = pinSpec;
            this.initialValue = initialValue;
            this.initWhenIdle = initWhenIdle;
        }
    }

    /**
     * A marker interface for channel cues. A concrete instance of this describes a single cue of a
     * single channel.
     */
    public static interface ChannelCue {
    }

    /**
     * A cue for a PWM position channel.
     * <p/>
     * Determines what is going to be the pulse width will while cue is executing.
     */
    public static class ChannelCuePwmPosition implements ChannelCue {
        /**
         * The pulse-width, in time-base units, as determined for this channel in its configuration.
         * Valid values are 0 or [2..65536].
         */
        public int pulseWidth;
    }

    /**
     * A cue for a PWM speed channel.
     * <p/>
     * Determines what is going to be the pulse width while this cue is executing.
     */
    public static class ChannelCuePwmSpeed implements ChannelCue {
        /**
         * The pulse-width, in time-base units, as determined for this channel in its configuration.
         * Valid values are 0 or [2..65536].
         */
        public int pulseWidth;
    }

    /**
     * A cue for a FM speed channel.
     * <p/>
     * Determines what is going to be the period duration (frequency) while this cue is executing.
     */
    public static class ChannelCueFmSpeed implements ChannelCue {
        /**
         * The pulse period, in time-base units, as determined for this channel in its
         * configuration. Valid values are [0..65536]. Note that:
         * <ul>
         * <li>A period of 0 will result in no pulses generated for this cue.</li>
         * <li>A non-0 period smaller than the pulse duration will result in the output constantly
         * high.</li>
         * </ul>
         */
        public int period;
    }

    /**
     * A cue for a steps channel.
     * <p/>
     * Determines the clock rate, pulse width and period durations while this cue is executing. This
     * kind of channel produces deterministic waveforms, which are typically used to generate a
     * precise number of steps during a given cue period. However, this comes at a cost of being a
     * little more involved from the user's perspective, since delicate timing considerations need
     * to be taken into account.
     * <p/>
     * The number of steps within a given cue period is given by floor(Tc / Ts), where Tc is the cue
     * duration and Ts is the step period duration. Each pulse is center-aligned within its period.
     * In order to maintain a deterministic result, the user must guarantee that no pulse falls
     * within the last 6 microseconds of the cue period (this effectively limits the maximum pulse
     * rate to 80[kHz], considering the the pulse itself must be at least 1/8[us] wide, and that the
     * rising edge of the pulse is center-aligned). Thus, it is possible that due to precision
     * limitations, in an arbitrarily long period it will be impossible to generate the exact number
     * of desired pulses. Likewise, a very low pulse rate (high pulse duration) may be outside of
     * the permitted range or will result in having to use a slower time-base. The solution to both
     * problems is splitting a single cue into two or more cues of shorted durations, until
     * eventually the precision is sufficient (this always converges, since eventually we can always
     * go to arbitrarily short cue durations, so that each one contains either zero or one steps.
     * <p/>
     * A steps channel allows determining the clock rate on a per-cue basis. This often allows
     * avoiding having to split cues, thus resulting in a less total cues and more efficient
     * execution. The rule for choosing the correct clock is to always use the highest rate that
     * will cause the resulting period to be <= 2^16. In other words, choose the highest available
     * clock which is less than or equal to (2^16 / Tp) or (2^16 * Fp), where Tp is the desired
     * period in seconds, or Fp is the desired frequency in Hz. For example, if we want to generate
     * pulses at 51Hz, 65536 * Fp = 3.34MHz, so we should use the 2MHz clock, and the period value
     * will be round(2MHz / 51Hz) = 39216. This result in an actual rate of 2MHz / 39216 ~=
     * 50.9996[Hz].
     */
    public static class ChannelCueSteps implements ChannelCue {
        /**
         * The clock rate for this cue. See discussion in the class documentation on how to choose
         * it.
         */
        public Clock clk;

        /**
         * The pulse-width, in time-base units, as determined for this channel in its configuration.
         * Valid values are [0..floor(period / 2)].
         */
        public int pulseWidth;

        /**
         * The pulse period, in time-base units, as determined for this channel in its
         * configuration. Valid values are [3..65536].
         */
        public int period;
    }

    /**
     * A cue for a binary channel.
     * <p/>
     * This cue determines whether the output should be high or low while the cue is executing.
     */
    public static class ChannelCueBinary implements ChannelCue {
        /**
         * The desired output state (true = high, false = low).
         */
        public boolean value;
    }

    /**
     * Push a timed cue to the sequencer.
     * <p/>
     * This method will block until there is at least one free space in the FIFO (which may be
     * forever if the sequencer is not running -- use {@link Sequencer.available()} first in this
     * case). Then, it will queue the cue for execution.
     *
     * @param cues     An array of channel cues. Has to be the exact same length as the
     *                 {@link ChannelConfig} array that was used to configure the sequencer. Each
     *                 element's type should be the counterpart of the corresponding configuration type.
     *                 For example, it element number 5 in the configuration array was of type
     *                 {@link Sequencer.ChannleConfigBinary}, then cues[5] needs to be of type
     *                 {@link Sequencer.ChannelCueBinary}
     * @param duration The time duration for which this cue is to be executed, before moving to the next
     *                 cue (or stalling). The units are 16 microseconds. For example, passing 10 here
     *                 would mean a duration of 160 microseconds. Valid values are [2..65536] (approx.
     *                 1.05 seconds).
     * @throws ConnectionLostException Connection to the IOIO was lost before or during this operation.
     * @throws InterruptedException    The operation was interrupted before completion.
     */
    public void push(ChannelCue[] cues, int duration) throws ConnectionLostException,
            InterruptedException;

    /**
     * Execute a cue until further notice.
     * <p/>
     * This method may only be called when the sequencer is not in the Running state. It will not
     * affect the queue of pending timed-cues previously filled via {@link #push(ChannelCue[], int)}
     * calls. The cue will be executed until explicitly stopped via {@link #manualStop()}. A
     * subsequent call to {@link #manualStart(ChannelCue[])} can be used to immediately have a new
     * cue take into effect.
     *
     * @param cues An array of channel cues to execute. See the description of the same argument in
     *             {@link #push(ChannelCue[], int)} for details.
     * @throws ConnectionLostException Connection to the IOIO was lost before or during this operation.
     */
    public void manualStart(ChannelCue[] cues) throws ConnectionLostException;

    /**
     * Stop a manual cue currently running.
     * <p/>
     * This may be called only when a the sequencer is not in the Running state, typically in the
     * Manual state, as result of a previous {@link #manualStart(ChannelCue[])}. This causes the
     * execution to stop immediately and the sequencer is now back in paused mode, ready for another
     * manual cue or for resuming execution of its previously queued sequence. Calling while in the
     * Idle state is legal, but does nothing.
     *
     * @throws ConnectionLostException Connection to the IOIO was lost before or during this operation.
     */
    public void manualStop() throws ConnectionLostException;

    /**
     * Start execution of the sequence.
     * <p/>
     * This method will cause any previously queued cues (via {@link #push(ChannelCue[], int)}) to
     * start execution in order of pushing, according to their specified timings. The sequencer must
     * be paused before calling this method.
     *
     * @throws ConnectionLostException Connection to the IOIO was lost before or during this operation.
     */
    public void start() throws ConnectionLostException;

    /**
     * Pause execution of the sequence.
     * <p/>
     * This method can be called when the sequencer is running, as result of previous invocation of
     * {@link #start()}. It will cause execution to suspend as soon as the currently executing cue
     * is done. The queue of pending cues will not be affected, and operation can be resumed
     * seamlessly by calling {@link #start()} again.
     *
     * @throws ConnectionLostException Connection to the IOIO was lost before or during this operation.
     */
    public void pause() throws ConnectionLostException;

    /**
     * Stop execution of the sequence.
     * <p/>
     * This will cause the sequence execution to stop immediately (without waiting for the current
     * cue to complete). All previously queued cues will be discarded. The sequence will then go to
     * paused state.
     *
     * @throws ConnectionLostException Connection to the IOIO was lost before or during this operation.
     */
    public void stop() throws ConnectionLostException;

    /**
     * Get the number of cues which can be pushed without blocking.
     * <p/>
     * This is useful for pre-filling the queue before starting the sequencer, or if the client
     * wants to do other operations on the same thread that pushes cues. The value returned will
     * indicate how many calls to {@link #push(ChannelCue[], int)} can be completed without
     * blocking.
     *
     * @return The number of available slots in the cue FIFO.
     */
    public int available() throws ConnectionLostException;

    ;

    /**
     * Get the most recent execution event.
     * <p/>
     * This includes the event type and the number of cues that started executing, since opening the
     * sequencer or the last call to {@link #stop()}. Immediately after opening the sequencer, the
     * event type may be {@link Event.Type.CLOSED}, and as soon as the sequencer finished opening an
     * {@link Event.Type.STOPPED} will be sent.
     *
     * @return The last event.
     * @throws ConnectionLostException Connection to the IOIO was lost before or during this operation.
     */
    public Event getLastEvent() throws ConnectionLostException;

    /**
     * Waits until an execution event occurs and returns it.
     * <p/>
     * In case the client is not reading fast enough, older events will be discarded as new once
     * arrive, so that the queue always stores the most recent events.
     *
     * @throws ConnectionLostException Connection to the IOIO was lost before or during this operation.
     * @throws InterruptedException    The operation was interrupted before completion.
     */
    public Event waitEvent() throws ConnectionLostException, InterruptedException;

    /**
     * A convenience method for blocking until an event of a certain type appears on the event
     * queue. All events proceeding this event type, including the event of the requested type will
     * be removed from the queue and discarded.
     *
     * @throws ConnectionLostException Connection to the IOIO was lost before or during this operation.
     * @throws InterruptedException    The operation was interrupted before completion.
     */
    public void waitEventType(Event.Type type) throws ConnectionLostException, InterruptedException;

    /**
     * Sets a new size for the incoming event queue.
     * <p/>
     * Initially the size of the queue is 32, which should suffice for most purposes. If, however, a
     * client is not able to read frequently enough to not miss events, increasing the size is an
     * option.
     * <p/>
     * Any pending events will be discarded. It is recommended to call this method only once,
     * immediately after opening the sequencer.
     *
     * @param size The new queue size.
     * @throws ConnectionLostException Connection to the IOIO was lost before or during this operation.
     */
    public void setEventQueueSize(int size) throws ConnectionLostException;
} public interface SpiMaster extends Closeable {
    /**
     * Possible data rates for SPI, in Hz.
     */
    enum Rate {
        RATE_31K, RATE_35K, RATE_41K, RATE_50K, RATE_62K, RATE_83K, RATE_125K, RATE_142K, RATE_166K, RATE_200K, RATE_250K, RATE_333K, RATE_500K, RATE_571K, RATE_666K, RATE_800K, RATE_1M, RATE_1_3M, RATE_2M, RATE_2_2M, RATE_2_6M, RATE_3_2M, RATE_4M, RATE_5_3M, RATE_8M
    }

    /**
     * An object that can be waited on for asynchronous calls.
     */
    public interface Result {
        /**
         * Wait until the asynchronous call which returned this instance is
         * complete.
         *
         * @throws ConnectionLostException Connection with the IOIO has been lost.
         * @throws InterruptedException    This operation has been interrupted.
         */
        public void waitReady() throws ConnectionLostException,
                InterruptedException;
    }

    /**
     * SPI configuration structure.
     */
    static class Config {
        /**
         * Data rate.
         */
        public Rate rate;
        /**
         * Whether to invert clock polarity.
         */
        public boolean invertClk;
        /**
         * Whether to do the input and output sampling on the trailing clock
         * edge.
         */
        public boolean sampleOnTrailing;

        /**
         * Constructor.
         *
         * @param rate             Data rate.
         * @param invertClk        Whether to invert clock polarity.
         * @param sampleOnTrailing Whether to do the input and output sampling on the
         *                         trailing clock edge.
         */
        public Config(Rate rate, boolean invertClk, boolean sampleOnTrailing) {
            this.rate = rate;
            this.invertClk = invertClk;
            this.sampleOnTrailing = sampleOnTrailing;
        }

        /**
         * Constructor with common defaults. Equivalent to Config(rate, false,
         * false)
         *
         * @see SpiMaster.Config#Config(SpiMaster.Config.Rate, boolean, boolean)
         */
        public Config(Rate rate) {
            this(rate, false, false);
        }
    }

    /**
     * Perform a single SPI transaction which includes optional transmission and
     * optional reception of data to a single slave. This is a blocking
     * operation that can take a few milliseconds to a few tens of milliseconds.
     * To abort this operation, client can interrupt the blocked thread. If
     * readSize is 0, the call returns immediately.
     *
     * @param slave     The slave index. It is determined by the index of its
     *                  slave-select pin, as per the array passed to
     *                  {@link IOIO#openSpiMaster(DigitalInput.Spec, DigitalOutput.Spec, DigitalOutput.Spec, DigitalOutput.Spec[], SpiMaster.Config)}
     *                  .
     * @param writeData A byte array of data to write. May be null if writeSize is 0.
     * @param writeSize Number of bytes to write. Valid values are 0 to totalSize.
     * @param totalSize Total transaction length, in bytes. Valid values are 1 to 64.
     * @param readData  An array where the response is to be stored. May be null if
     *                  readSize is 0.
     * @param readSize  The number of expected response bytes. Valid values are 0 to
     *                  totalSize.
     * @throws ConnectionLostException Connection to the IOIO has been lost.
     * @throws InterruptedException    Calling thread has been interrupted.
     */
    public void writeRead(int slave, byte[] writeData, int writeSize,
                          int totalSize, byte[] readData, int readSize)
            throws ConnectionLostException, InterruptedException;

    /**
     * Shorthand for {@link #writeRead(int, byte[], int, int, byte[], int)} for
     * the single-slave case.
     *
     * @see #writeRead(int, byte[], int, int, byte[], int)
     */
    public void writeRead(byte[] writeData, int writeSize, int totalSize,
                          byte[] readData, int readSize) throws ConnectionLostException,
            InterruptedException;

    /**
     * The same as {@link #writeRead(int, byte[], int, int, byte[], int)}, but
     * returns immediately and returns a {@link Result} object that can be
     * waited on. If readSize is 0, the result object is ready immediately.
     *
     * @see #writeRead(int, byte[], int, int, byte[], int)
     */
    public Result writeReadAsync(int slave, byte[] writeData, int writeSize,
                                 int totalSize, byte[] readData, int readSize)
            throws ConnectionLostException;
} public interface TwiMaster extends Closeable {
    enum Rate {
        RATE_100KHz, RATE_400KHz, RATE_1MHz
    }

    /**
     * An object that can be waited on for asynchronous calls.
     */
    public interface Result {
        /**
         * Wait until the asynchronous call which returned this instance is
         * complete.
         *
         * @return true if TWI transaction succeeded.
         * @throws ConnectionLostException Connection with the IOIO has been lost.
         * @throws InterruptedException    This operation has been interrupted.
         */
        public boolean waitReady() throws ConnectionLostException,
                InterruptedException;
    }

    /**
     * Perform a single TWI transaction which includes optional transmission and
     * optional reception of data to a single slave. This is a blocking
     * operation that can take a few milliseconds to a few tens of milliseconds.
     * To abort this operation, client can interrupt the blocked thread.
     *
     * @param address    The slave address, either 7-bit or 10-bit. Note that in some
     *                   TWI device documentation the documented addresses are actually
     *                   2x the address values used here, as they regard the trailing
     *                   0-bit as part of the address.
     * @param tenBitAddr Whether this is a 10-bit addressing mode.
     * @param writeData  The request data.
     * @param writeSize  The number of bytes to write. Valid value are 0-255.
     * @param readData   The array where the response should be stored.
     * @param readSize   The expected number of response bytes. Valid value are 0-255.
     * @return Whether operation succeeded.
     * @throws ConnectionLostException Connection to the IOIO has been lost.
     * @throws InterruptedException    Calling thread has been interrupted.
     */
    public boolean writeRead(int address, boolean tenBitAddr, byte[] writeData,
                             int writeSize, byte[] readData, int readSize)
            throws ConnectionLostException, InterruptedException;

    /**
     * Asynchronous version of
     * {@link #writeRead(int, boolean, byte[], int, byte[], int)}. Returns
     * immediately and provides a {@link Result} object on which the client can
     * wait for the result.
     *
     * @see #writeRead(int, boolean, byte[], int, byte[], int)
     */
    public Result writeReadAsync(int address, boolean tenBitAddr,
                                 byte[] writeData, int writeSize, byte[] readData, int readSize)
            throws ConnectionLostException;
} enum Rate {
    RATE_100KHz, RATE_400KHz, RATE_1MHz
} public interface Uart extends Closeable {
    /**
     * Parity-bit mode.
     */
    enum Parity {
        /**
         * No parity.
         */
        NONE,
        /**
         * Even parity.
         */
        EVEN,
        /**
         * Odd parity.
         */
        ODD
    }

    /**
     * Number of stop-bits.
     */
    enum StopBits {
        /**
         * One stop bit.
         */
        ONE,
        /**
         * Two stop bits.
         */
        TWO
    }

    /**
     * Gets the input stream.
     *
     * @return An input stream.
     */
    public InputStream getInputStream();

    /**
     * Gets the output stream.
     *
     * @return An output stream.
     */
    public OutputStream getOutputStream();
} enum PwmScale {
    SCALE_1X(1, 0), SCALE_8X(8, 3), SCALE_64X(64, 2), SCALE_256X(256, 1);

    public final int scale;
    private final int encoding;

    PwmScale(int scale, int encoding) {
        this.scale = scale;
        this.encoding = encoding;
    }
} interface DisconnectListener {
    void disconnected();
} public class Log {
    public static int println(int priority, String tag, String msg) {
        return android.util.Log.println(priority, tag, msg);
    }

    public static void e(String tag, String message) {
        android.util.Log.e(tag, message);
    }

    public static void e(String tag, String message, Throwable tr) {
        android.util.Log.e(tag, message, tr);
    }

    public static void w(String tag, String message) {
        android.util.Log.w(tag, message);
    }

    public static void w(String tag, String message, Throwable tr) {
        android.util.Log.w(tag, message);
    }

    public static void i(String tag, String message) {
        android.util.Log.i(tag, message);
    }

    public static void d(String tag, String message) {
        android.util.Log.d(tag, message);
    }

    public static void v(String tag, String message) {
        android.util.Log.v(tag, message);
    }
}
import java.io.IOException;
import ioio.lib.api.AnalogInput;
import ioio.lib.api.CapSense;
import ioio.lib.api.DigitalInput;
import ioio.lib.api.DigitalInput.Spec;
import ioio.lib.api.DigitalInput.Spec.Mode;
import ioio.lib.api.DigitalOutput;
import ioio.lib.api.IOIO;
import ioio.lib.api.IOIOConnection;
import ioio.lib.api.IcspMaster;
import ioio.lib.api.PulseInput;
import ioio.lib.api.PulseInput.ClockRate;
import ioio.lib.api.PulseInput.PulseMode;
import ioio.lib.api.PwmOutput;
import ioio.lib.api.Sequencer;
import ioio.lib.api.SpiMaster;
import ioio.lib.api.TwiMaster;
import ioio.lib.api.TwiMaster.Rate;
import ioio.lib.api.Uart;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.api.exception.IncompatibilityException;
import ioio.lib.impl.IOIOProtocol.PwmScale;
import ioio.lib.impl.IncomingState.DisconnectListener;
import ioio.lib.impl.ResourceManager.Resource;
import ioio.lib.impl.ResourceManager.ResourceType;
import ioio.lib.spi.Log;
            IncompatibilityException {
        if (state_ == State.CONNECTED) {
            return;
        }
        if (state_ == State.DEAD) {
            throw new ConnectionLostException();
        }
        addDisconnectListener(this);
        Log.d(TAG, "Waiting for IOIO connection");
        try {
            try {
                Log.v(TAG, "Waiting for underlying connection");
                connection_.waitForConnect();
                synchronized (this) {
                    if (disconnect_) {
                        throw new ConnectionLostException();
                    }
                    protocol_ = new IOIOProtocol(connection_.getInputStream(),
                            connection_.getOutputStream(), incomingState_);
                    // Once this block exits, a disconnect will also involve
                    // softClose().
                }
            } catch (ConnectionLostException e) {
                incomingState_.handleConnectionLost();
                throw e;
            }
            Log.v(TAG, "Waiting for handshake");
            incomingState_.waitConnectionEstablished();
            initBoard();
            Log.v(TAG, "Querying for required interface ID");
            checkInterfaceVersion();
            Log.v(TAG, "Required interface ID is supported");
            state_ = State.CONNECTED;
            Log.i(TAG, "IOIO connection established");
        } catch (ConnectionLostException e) {
            Log.d(TAG, "Connection lost / aborted");
            state_ = State.DEAD;
            throw e;
        } catch (IncompatibilityException e) {
            throw e;
        } catch (InterruptedException e) {
            Log.e(TAG, "Unexpected exception", e);
        }
    }

    @Override
    public synchronized void disconnect() {
        Log.d(TAG, "Client requested disconnect.");
        if (disconnect_) {
            return;
        }
        disconnect_ = true;
        try {
            if (protocol_ != null && !connection_.canClose()) {
                protocol_.softClose();
            }
        } catch (IOException e) {
            Log.e(TAG, "Soft close failed", e);
        }
        connection_.disconnect();
    }

    @Override
    public synchronized void disconnected() {
        state_ = State.DEAD;
        if (disconnect_) {
            return;
        }
        Log.d(TAG, "Physical disconnect.");
        disconnect_ = true;
        // The IOIOConnection doesn't necessarily know about the disconnect
        connection_.disconnect();
    }

    @Override
    public void waitForDisconnect() throws InterruptedException {
        incomingState_.waitDisconnect();
    }

    @Override
    public State getState() {
        return state_;
    }

    private void initBoard() throws IncompatibilityException {
        if (incomingState_.board_ == null) {
            throw new IncompatibilityException("Unknown board: "
                    + incomingState_.hardwareId_);
        }
        hardware_ = incomingState_.board_.hardware;
        resourceManager_ = new ResourceManager(hardware_);
    }

    private void checkInterfaceVersion() throws IncompatibilityException,
            ConnectionLostException, InterruptedException {
        try {
            protocol_.checkInterface(REQUIRED_INTERFACE_ID);
        } catch (IOException e) {
            throw new ConnectionLostException(e);
        }
        if (!incomingState_.waitForInterfaceSupport()) {
            state_ = State.INCOMPATIBLE;
            Log.e(TAG, "Required interface ID is not supported");
            throw new IncompatibilityException(
                    "IOIO firmware does not support required firmware: "
                            + new String(REQUIRED_INTERFACE_ID));
        }
    }

    synchronized void removeDisconnectListener(DisconnectListener listener) {
        incomingState_.removeDisconnectListener(listener);
    }

    synchronized void addDisconnectListener(DisconnectListener listener)
            throws ConnectionLostException {
        incomingState_.addDisconnectListener(listener);
    }

    synchronized void closePin(ResourceManager.Resource pin) {
        try {
            protocol_.setPinDigitalIn(pin.id, DigitalInput.Spec.Mode.FLOATING);