Started to update the library to API 3.22 RC
Change-Id: I8eaf3151b1d405799eb582564f0e1e8fbcb7744c Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
This commit is contained in:
@@ -52,10 +52,42 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
* Typical usage:
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* AnalogInput potentiometer = ioio.openAnalogInput(40);
|
||||
* float value = potentiometer.read();
|
||||
* ...
|
||||
* potentiometer.close(); // pin 40 can now be used for something else.
|
||||
* }
|
||||
* </pre>
|
||||
* <p>
|
||||
* An alternate usage allows reading periodically sampled data without missing
|
||||
* samples. The {@link #setBuffer(int)} method must first be called, for setting
|
||||
* up an internal buffer for queuing samples. Then, samples can be obtained by
|
||||
* calling {@link #readBuffered()} or {@link #getVoltageBuffered()}. These
|
||||
* methods will block until a sample is available. If this is undesirable, the
|
||||
* {@link #available()} method can be called first to check how many samples are
|
||||
* ready in the buffer. In case the buffer overflows, as result of the client
|
||||
* not reading fast enough, old samples will be dropped, and the client can
|
||||
* check {@link #getOverflowCount()} to determine how many samples have been
|
||||
* lost. The sample rate used for capturing samples can be obtained by calling
|
||||
* {@link #getSampleRate()}.
|
||||
* <p>
|
||||
* The non-buffered versions of the read methods will still behave normally when
|
||||
* buffering is enabled. The {@link #read()} and {@link #getVoltage()} methods
|
||||
* will always return the most recent value, regardless of the buffer state.
|
||||
* <p>
|
||||
* Typical usage:
|
||||
*
|
||||
* <pre>
|
||||
* AnalogInput potentiometer = ioio.openAnalogInput(40);
|
||||
* potentiometer.setBuffer(256);
|
||||
* for (int i = 0; i < 1024; ++i) {
|
||||
* // next line will block until at least one sample is available
|
||||
* float sample = potentiometer.readBuffered();
|
||||
* ...
|
||||
* }
|
||||
* ...
|
||||
* potentiometer.close(); // pin 40 can now be used for something else.
|
||||
* </pre>
|
||||
*
|
||||
* @see IOIO#openAnalogInput(int)
|
||||
@@ -69,11 +101,13 @@ public interface AnalogInput extends Closeable {
|
||||
* 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()}.
|
||||
* 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.
|
||||
* @throws InterruptedException
|
||||
* The calling thread has been interrupted.
|
||||
* @throws ConnectionLostException
|
||||
* The connection with the IOIO is lost.
|
||||
* @see #read()
|
||||
*/
|
||||
public float getVoltage() throws InterruptedException,
|
||||
@@ -81,6 +115,7 @@ public interface AnalogInput extends Closeable {
|
||||
|
||||
/**
|
||||
* Gets the maximum value against which {@link #read()} values are scaled.
|
||||
*
|
||||
* @return The voltage, in Volts.
|
||||
*/
|
||||
public float getReference();
|
||||
@@ -96,9 +131,95 @@ public interface AnalogInput extends Closeable {
|
||||
* 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.
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @see #getVoltageBuffered()
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @see #readBuffered()
|
||||
* @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.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1,140 +1,140 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.api;
|
||||
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
/**
|
||||
* A pin used for digital input.
|
||||
* <p>
|
||||
* A digital input pin can be used to read logic-level signals. DigitalInput
|
||||
* instances are obtained by calling {@link IOIO#openDigitalInput(Spec)}.
|
||||
* <p>
|
||||
* The value of the pin is obtained by calling {@link #read()}. It is also
|
||||
* possible for the client to block until a certain level is sensed, by using
|
||||
* {@link #waitForValue(boolean)}.
|
||||
* <p>
|
||||
* The instance is alive since its creation. The first {@link #read()} call
|
||||
* block for a few milliseconds until the initial value is updated. If the
|
||||
* connection with the IOIO drops at any point, the instance transitions to a
|
||||
* disconnected state, in which every attempt to use the pin (except
|
||||
* {@link #close()}) will throw a {@link ConnectionLostException}. Whenever
|
||||
* {@link #close()} is invoked the instance may no longer be used. Any resources
|
||||
* associated with it are freed and can be reused.
|
||||
* <p>
|
||||
* Typical usage:
|
||||
*
|
||||
* <pre>
|
||||
* DigitalInput button = ioio.openDigitalInput(10); // used an external pull-up
|
||||
* button.waitForValue(false); // wait for press
|
||||
* ...
|
||||
* button.close(); // pin 10 can now be used for something else.
|
||||
* </pre>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.api;
|
||||
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
/**
|
||||
* A pin used for digital input.
|
||||
* <p>
|
||||
* A digital input pin can be used to read logic-level signals. DigitalInput
|
||||
* instances are obtained by calling {@link IOIO#openDigitalInput(DigitalInput.Spec)}.
|
||||
* <p>
|
||||
* The value of the pin is obtained by calling {@link #read()}. It is also
|
||||
* possible for the client to block until a certain level is sensed, by using
|
||||
* {@link #waitForValue(boolean)}.
|
||||
* <p>
|
||||
* The instance is alive since its creation. The first {@link #read()} call
|
||||
* block for a few milliseconds until the initial value is updated. If the
|
||||
* connection with the IOIO drops at any point, the instance transitions to a
|
||||
* disconnected state, in which every attempt to use the pin (except
|
||||
* {@link #close()}) will throw a {@link ConnectionLostException}. Whenever
|
||||
* {@link #close()} is invoked the instance may no longer be used. Any resources
|
||||
* associated with it are freed and can be reused.
|
||||
* <p>
|
||||
* Typical usage:
|
||||
*
|
||||
* <pre>
|
||||
* DigitalInput button = ioio.openDigitalInput(10); // used an external pull-up
|
||||
* button.waitForValue(false); // wait for press
|
||||
* ...
|
||||
* button.close(); // pin 10 can now be used for something else.
|
||||
* </pre>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1,120 +1,120 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.api;
|
||||
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
/**
|
||||
* A pin used for digital output.
|
||||
* <p>
|
||||
* A digital input pin can be used to generate logic-level signals.
|
||||
* DigitalOutput instances are obtained by calling
|
||||
* {@link IOIO#openDigitalOutput(Spec, boolean)}.
|
||||
* <p>
|
||||
* The value of the pin is set by calling {@link #write(boolean)}.
|
||||
* <p>
|
||||
* The instance is alive since its creation. If the connection with the IOIO
|
||||
* drops at any point, the instance transitions to a disconnected state, in
|
||||
* which every attempt to use the pin (except {@link #close()}) will throw a
|
||||
* {@link ConnectionLostException}. Whenever {@link #close()} is invoked the
|
||||
* instance may no longer be used. Any resources associated with it are freed
|
||||
* and can be reused.
|
||||
* <p>
|
||||
* Typical usage:
|
||||
*
|
||||
* <pre>
|
||||
* DigitalOutput led = ioio.openDigitalInput(2); // LED anode on pin 2.
|
||||
* led.write(true); // turn LED on.
|
||||
* ...
|
||||
* led.close(); // pin 2 can now be used for something else.
|
||||
* </pre>
|
||||
*/
|
||||
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 #Spec(int, 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;
|
||||
}
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.api;
|
||||
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
/**
|
||||
* A pin used for digital output.
|
||||
* <p>
|
||||
* A digital input pin can be used to generate logic-level signals.
|
||||
* DigitalOutput instances are obtained by calling
|
||||
* {@link IOIO#openDigitalOutput(DigitalOutput.Spec, boolean)}.
|
||||
* <p>
|
||||
* The value of the pin is set by calling {@link #write(boolean)}.
|
||||
* <p>
|
||||
* The instance is alive since its creation. If the connection with the IOIO
|
||||
* drops at any point, the instance transitions to a disconnected state, in
|
||||
* which every attempt to use the pin (except {@link #close()}) will throw a
|
||||
* {@link ConnectionLostException}. Whenever {@link #close()} is invoked the
|
||||
* instance may no longer be used. Any resources associated with it are freed
|
||||
* and can be reused.
|
||||
* <p>
|
||||
* Typical usage:
|
||||
*
|
||||
* <pre>
|
||||
* DigitalOutput led = ioio.openDigitalInput(2); // LED anode on pin 2.
|
||||
* led.write(true); // turn LED on.
|
||||
* ...
|
||||
* led.close(); // pin 2 can now be used for something else.
|
||||
* </pre>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
0
IOIOLib/src/ioio/lib/api/IOIOConnection.java
Executable file → Normal file
0
IOIOLib/src/ioio/lib/api/IOIOConnection.java
Executable file → Normal file
@@ -28,10 +28,14 @@
|
||||
*/
|
||||
package ioio.lib.api;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import ioio.lib.impl.IOIOImpl;
|
||||
import ioio.lib.impl.SocketIOIOConnection;
|
||||
import ioio.lib.spi.IOIOConnectionFactory;
|
||||
import ioio.lib.util.IOIOConnectionRegistry;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Factory class for creating instances of the IOIO interface.
|
||||
@@ -55,22 +59,21 @@ import ioio.lib.impl.SocketIOIOConnection;
|
||||
* </pre>
|
||||
*/
|
||||
public class IOIOFactory {
|
||||
/** The TCP port used for communicating with the IOIO board. */
|
||||
public static final int IOIO_PORT = 4545;
|
||||
|
||||
/**
|
||||
* Create a IOIO instance. This specific implementation creates a IOIO
|
||||
* instance which works with the actual IOIO board connected via a TCP
|
||||
* connection (typically over a wired USB connection).
|
||||
*
|
||||
*
|
||||
* @return The IOIO instance.
|
||||
*/
|
||||
public static IOIO create() {
|
||||
Collection<IOIOConnectionFactory> factories = IOIOConnectionRegistry
|
||||
.getConnectionFactories();
|
||||
try {
|
||||
return create(SocketIOIOConnection.class.getName(), IOIO_PORT);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// we shouldn't get here - this class must always exist.
|
||||
throw new RuntimeException("Something is very wrong here");
|
||||
return create(factories.iterator().next().createConnection());
|
||||
} catch (NoSuchElementException e) {
|
||||
Log.e(TAG, "No connection is available. This shouldn't happen.");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,44 +81,15 @@ public class IOIOFactory {
|
||||
* Create a IOIO instance with a user-provided underlying connection class.
|
||||
* This method should be used for establishing a non-standard connection to
|
||||
* the IOIO board.
|
||||
*
|
||||
* @param connectionClassName
|
||||
* The name of the connection class. Must have a public default
|
||||
* constructor.
|
||||
*
|
||||
*
|
||||
* @param connection
|
||||
* An instance of a IOIO connection.
|
||||
*
|
||||
* @return The IOIO instance.
|
||||
* @throws ClassNotFoundException The given class name was not found.
|
||||
*/
|
||||
public static IOIO create(String connectionClassName, Object... args) throws ClassNotFoundException {
|
||||
IOIOConnection connection = createConnectionDynamically(connectionClassName, args);
|
||||
return create(connection);
|
||||
}
|
||||
|
||||
public static IOIO create(IOIOConnection connection) {
|
||||
return new IOIOImpl(connection);
|
||||
}
|
||||
|
||||
public static IOIOConnection createConnectionDynamically(
|
||||
String connectionClassName, Object... args)
|
||||
throws ClassNotFoundException {
|
||||
Class<?> cls;
|
||||
cls = Class.forName(connectionClassName);
|
||||
Object instance;
|
||||
try {
|
||||
Class<?>[] argTypes = new Class<?>[args.length];
|
||||
for (int i = 0; i < args.length; ++i) {
|
||||
argTypes[i] = args[i].getClass();
|
||||
}
|
||||
Constructor<?> constructor = cls.getConstructor(argTypes);
|
||||
instance = constructor.newInstance(args);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Provided class does not have a public ctor with the right signature", e);
|
||||
}
|
||||
if (!(instance instanceof IOIOConnection)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Provided class does not implement IOIOConnection");
|
||||
}
|
||||
return (IOIOConnection) instance;
|
||||
}
|
||||
private static final String TAG = "IOIOFactory";
|
||||
}
|
||||
|
||||
0
IOIOLib/src/ioio/lib/api/IcspMaster.java
Executable file → Normal file
0
IOIOLib/src/ioio/lib/api/IcspMaster.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/api/PulseInput.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/api/PulseInput.java
Executable file → Normal file
@@ -46,7 +46,7 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
* for measuring a turning shaft's speed.
|
||||
* <p>
|
||||
* {@link PulseInput} instances are obtained by calling
|
||||
* {@link IOIO#openPulseInput(ioio.lib.api.DigitalInput.Spec, ClockRate, PulseMode, boolean)}
|
||||
* {@link IOIO#openPulseInput(ioio.lib.api.DigitalInput.Spec, ioio.lib.api.PulseInput.ClockRate, ioio.lib.api.PulseInput.PulseMode, boolean)}
|
||||
* . When created, some important configuration decisions have to be made: the
|
||||
* precision (single or double), the clock rate and the mode of operation. Modes
|
||||
* are straightforward: {@link PulseMode#POSITIVE} is used for measuring a
|
||||
|
||||
13
IOIOLib/src/ioio/lib/api/SpiMaster.java
Executable file → Normal file
13
IOIOLib/src/ioio/lib/api/SpiMaster.java
Executable file → Normal file
@@ -28,7 +28,6 @@
|
||||
*/
|
||||
package ioio.lib.api;
|
||||
|
||||
import ioio.lib.api.DigitalInput.Spec;
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
/**
|
||||
@@ -41,7 +40,7 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
* 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. SpiMaster instances are obtained by calling
|
||||
* {@link IOIO#openSpiMaster(Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[], Config)}.
|
||||
* {@link IOIO#openSpiMaster(DigitalInput.Spec, DigitalOutput.Spec, DigitalOutput.Spec, DigitalOutput.Spec[], SpiMaster.Config)}.
|
||||
* <p>
|
||||
* The SPI protocol is comprised of simultaneous sending and receiving of data
|
||||
* between the bus master and a single slave. By the very nature of this
|
||||
@@ -90,9 +89,11 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
* spi.writeRead(request, 2, 4, response, 3);
|
||||
* ...
|
||||
* spi.close(); // free SPI module and pins
|
||||
* }</pre>
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see IOIO#openSpiMaster(Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[], Config)
|
||||
* @see IOIO#openSpiMaster(DigitalInput.Spec, DigitalOutput.Spec,
|
||||
* DigitalOutput.Spec, DigitalOutput.Spec[], SpiMaster.Config)
|
||||
*/
|
||||
public interface SpiMaster extends Closeable {
|
||||
/** Possible data rates for SPI, in Hz. */
|
||||
@@ -148,7 +149,7 @@ public interface SpiMaster extends Closeable {
|
||||
* Constructor with common defaults. Equivalent to Config(rate, false,
|
||||
* false)
|
||||
*
|
||||
* @see #Config(Rate, boolean, boolean)
|
||||
* @see SpiMaster.Config#Config(SpiMaster.Config.Rate, boolean, boolean)
|
||||
*/
|
||||
public Config(Rate rate) {
|
||||
this(rate, false, false);
|
||||
@@ -165,7 +166,7 @@ public interface SpiMaster extends Closeable {
|
||||
* @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(Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[], Config)}
|
||||
* {@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.
|
||||
|
||||
4
IOIOLib/src/ioio/lib/api/TwiMaster.java
Executable file → Normal file
4
IOIOLib/src/ioio/lib/api/TwiMaster.java
Executable file → Normal file
@@ -39,7 +39,7 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
* 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. TwiMaster
|
||||
* instances are obtained by calling
|
||||
* {@link IOIO#openTwiMaster(int, Rate, boolean)}.
|
||||
* {@link IOIO#openTwiMaster(int, ioio.lib.api.TwiMaster.Rate, boolean)}.
|
||||
* <p>
|
||||
* TWI is the generic name for the specific I2C and SMBus protocols, differing
|
||||
* mostly by the voltage levels they require. This module supports both.
|
||||
@@ -79,7 +79,7 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
* twi.close(); // free TWI module and pins
|
||||
* }</pre>
|
||||
*
|
||||
* @see IOIO#openTwiMaster(int, Rate, boolean)
|
||||
* @see IOIO#openTwiMaster(int, ioio.lib.api.TwiMaster.Rate, boolean)
|
||||
*/
|
||||
public interface TwiMaster extends Closeable {
|
||||
enum Rate {
|
||||
|
||||
@@ -1,108 +1,107 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.api;
|
||||
|
||||
import ioio.lib.api.DigitalInput.Spec;
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* An interface for controlling a UART module.
|
||||
* <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. Uart instances are obtained by calling
|
||||
* {@link IOIO#openUart(Spec, ioio.lib.api.DigitalOutput.Spec, int, Parity, StopBits)}.
|
||||
* <p>
|
||||
* The UART protocol is completely symmetric - there is no "master" and "slave"
|
||||
* at this layer. Each end may send any number of bytes at arbitrary times,
|
||||
* making it very useful for terminals and terminal-controllable devices.
|
||||
* <p>
|
||||
* Working with UART is very intuitive - it just provides a standard InputStream
|
||||
* and/or OutputStream. Optionally, one could create a read-only or write-only
|
||||
* UART instances, by passing null (or INVALID_PIN) for either TX or RX pins.
|
||||
* <p>
|
||||
* The instance is alive since its creation. If the connection with the IOIO
|
||||
* drops at any point, the instance transitions to a disconnected state, which
|
||||
* every attempt to use it (except {@link #close()}) will throw a
|
||||
* {@link ConnectionLostException}. Whenever {@link #close()} is invoked the
|
||||
* instance may no longer be used. Any resources associated with it are freed
|
||||
* and can be reused.
|
||||
* <p>
|
||||
* Typical usage:
|
||||
*
|
||||
* <pre>
|
||||
* Uart uart = ioio.openUart(3, 4, 19200, Parity.NONE, StopBits.ONE);
|
||||
* InputStream in = uart.getInputStream();
|
||||
* OutputStream out = uart.getOutputStream();
|
||||
* out.write(new String("Hello").getBytes());
|
||||
* int i = in.read(); // blocking
|
||||
* ...
|
||||
* uart.close(); // free UART module and pins
|
||||
* </pre>
|
||||
*
|
||||
* @see IOIO#openUart(Spec, ioio.lib.api.DigitalOutput.Spec, int, Parity,
|
||||
* StopBits)
|
||||
*/
|
||||
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();
|
||||
}
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.api;
|
||||
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* An interface for controlling a UART module.
|
||||
* <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. Uart instances are obtained by calling
|
||||
* {@link IOIO#openUart(DigitalInput.Spec, DigitalOutput.Spec, int, Uart.Parity, Uart.StopBits)}.
|
||||
* <p>
|
||||
* The UART protocol is completely symmetric - there is no "master" and "slave"
|
||||
* at this layer. Each end may send any number of bytes at arbitrary times,
|
||||
* making it very useful for terminals and terminal-controllable devices.
|
||||
* <p>
|
||||
* Working with UART is very intuitive - it just provides a standard InputStream
|
||||
* and/or OutputStream. Optionally, one could create a read-only or write-only
|
||||
* UART instances, by passing null (or INVALID_PIN) for either TX or RX pins.
|
||||
* <p>
|
||||
* The instance is alive since its creation. If the connection with the IOIO
|
||||
* drops at any point, the instance transitions to a disconnected state, which
|
||||
* every attempt to use it (except {@link #close()}) will throw a
|
||||
* {@link ConnectionLostException}. Whenever {@link #close()} is invoked the
|
||||
* instance may no longer be used. Any resources associated with it are freed
|
||||
* and can be reused.
|
||||
* <p>
|
||||
* Typical usage:
|
||||
*
|
||||
* <pre>
|
||||
* Uart uart = ioio.openUart(3, 4, 19200, Parity.NONE, StopBits.ONE);
|
||||
* InputStream in = uart.getInputStream();
|
||||
* OutputStream out = uart.getOutputStream();
|
||||
* out.write(new String("Hello").getBytes());
|
||||
* int i = in.read(); // blocking
|
||||
* ...
|
||||
* uart.close(); // free UART module and pins
|
||||
* </pre>
|
||||
*
|
||||
* @see IOIO#openUart(DigitalInput.Spec, DigitalOutput.Spec, int, Uart.Parity,
|
||||
* Uart.StopBits)
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
0
IOIOLib/src/ioio/lib/api/exception/IncompatibilityException.java
Executable file → Normal file
0
IOIOLib/src/ioio/lib/api/exception/IncompatibilityException.java
Executable file → Normal file
@@ -1,3 +1,32 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
package ioio.lib.bluetooth;
|
||||
|
||||
import ioio.lib.api.IOIOConnection;
|
||||
@@ -8,43 +37,41 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.UUID;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothSocket;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
public class BluetoothIOIOConnection implements IOIOConnection {
|
||||
private static final String TAG = "BluetoothIOIOConnection";
|
||||
private BluetoothSocket socket_ = null;
|
||||
private boolean disconnect_ = false;
|
||||
private final BluetoothDevice device_;
|
||||
private final String name_;
|
||||
private final String address_;
|
||||
|
||||
public BluetoothIOIOConnection(String name, String address) {
|
||||
name_ = name;
|
||||
address_ = address;
|
||||
public BluetoothIOIOConnection(BluetoothDevice device) {
|
||||
device_ = device;
|
||||
name_ = device.getName();
|
||||
address_ = device.getAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitForConnect() throws ConnectionLostException {
|
||||
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
final BluetoothDevice ioioDevice = adapter.getRemoteDevice(address_);
|
||||
synchronized (this) {
|
||||
if (disconnect_) {
|
||||
throw new ConnectionLostException();
|
||||
}
|
||||
Log.v(TAG, name_ + " Creating socket");
|
||||
try {
|
||||
socket_ = createSocket(ioioDevice);
|
||||
socket_ = createSocket(device_);
|
||||
} catch (IOException e) {
|
||||
throw new ConnectionLostException(e);
|
||||
}
|
||||
Log.v(TAG, name_ + " Created socket");
|
||||
}
|
||||
// keep trying to connect as long as we're not aborting
|
||||
while (true) {
|
||||
try {
|
||||
Log.v(TAG, name_ + "Connecting");
|
||||
Log.v(TAG, "Attempting to connect to Bluetooth device: " + name_);
|
||||
socket_.connect();
|
||||
Log.v(TAG, "Established connection to device " + name_
|
||||
+ " address: " + address_);
|
||||
@@ -61,17 +88,15 @@ public class BluetoothIOIOConnection implements IOIOConnection {
|
||||
}
|
||||
}
|
||||
|
||||
public BluetoothSocket createSocket(final BluetoothDevice device)
|
||||
public static BluetoothSocket createSocket(final BluetoothDevice device)
|
||||
throws IOException {
|
||||
try {
|
||||
// We're trying to create an insecure socket, which is
|
||||
// only supported
|
||||
// in API 10 and up. If we fail, we try a secure socket
|
||||
// with is in API
|
||||
// 7 and up.
|
||||
if (Build.VERSION.SDK_INT >= 10 ) {
|
||||
// We're trying to create an insecure socket, which is only
|
||||
// supported in API 10 and up. Otherwise, we try a secure socket
|
||||
// which is in API 7 and up.
|
||||
return device.createInsecureRfcommSocketToServiceRecord(UUID
|
||||
.fromString("00001101-0000-1000-8000-00805F9B34FB"));
|
||||
} catch (NoSuchMethodError e) {
|
||||
} else {
|
||||
return device.createRfcommSocketToServiceRecord(UUID
|
||||
.fromString("00001101-0000-1000-8000-00805F9B34FB"));
|
||||
}
|
||||
@@ -82,7 +107,7 @@ public class BluetoothIOIOConnection implements IOIOConnection {
|
||||
if (disconnect_) {
|
||||
return;
|
||||
}
|
||||
Log.d(TAG, "Client initiated disconnect");
|
||||
Log.v(TAG, "Client initiated disconnect");
|
||||
disconnect_ = true;
|
||||
if (socket_ != null) {
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
package ioio.lib.bluetooth;
|
||||
|
||||
import ioio.lib.api.IOIOConnection;
|
||||
import ioio.lib.spi.IOIOConnectionBootstrap;
|
||||
import ioio.lib.spi.IOIOConnectionFactory;
|
||||
import ioio.lib.spi.NoRuntimeSupportException;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.util.Log;
|
||||
|
||||
public class BluetoothIOIOConnectionBootstrap implements
|
||||
IOIOConnectionBootstrap {
|
||||
|
||||
private static final String TAG = "BluetoothIOIOConnectionDiscovery";
|
||||
private final BluetoothAdapter adapter_;
|
||||
|
||||
public BluetoothIOIOConnectionBootstrap() throws NoRuntimeSupportException {
|
||||
try {
|
||||
adapter_ = BluetoothAdapter.getDefaultAdapter();
|
||||
} catch (NoClassDefFoundError e) {
|
||||
throw new NoRuntimeSupportException(
|
||||
"Bluetooth is not supported on this device.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getFactories(Collection<IOIOConnectionFactory> result) {
|
||||
try {
|
||||
Set<BluetoothDevice> bondedDevices = adapter_.getBondedDevices();
|
||||
for (final BluetoothDevice device : bondedDevices) {
|
||||
if (device.getName().startsWith("IOIO")) {
|
||||
result.add(new IOIOConnectionFactory() {
|
||||
@Override
|
||||
public String getType() {
|
||||
return BluetoothIOIOConnection.class
|
||||
.getCanonicalName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getExtra() {
|
||||
return new Object[] { device.getName(),
|
||||
device.getAddress() };
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOIOConnection createConnection() {
|
||||
return new BluetoothIOIOConnection(device);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
Log.e(TAG,
|
||||
"Did you forget to declare uses-permission of android.permission.BLUETOOTH?");
|
||||
throw e;
|
||||
} catch (NoClassDefFoundError e) {
|
||||
Log.w(TAG, "Bluetooth is not supported on this device.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package ioio.lib.bluetooth;
|
||||
|
||||
import ioio.lib.util.IOIOConnectionDiscovery;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.util.Log;
|
||||
|
||||
public class BluetoothIOIOConnectionDiscovery implements
|
||||
IOIOConnectionDiscovery {
|
||||
|
||||
private static final String TAG = "BluetoothIOIOConnectionDiscovery";
|
||||
|
||||
@Override
|
||||
public void getSpecs(Collection<IOIOConnectionSpec> result) {
|
||||
try {
|
||||
final BluetoothAdapter adapter = BluetoothAdapter
|
||||
.getDefaultAdapter();
|
||||
Set<BluetoothDevice> bondedDevices = adapter.getBondedDevices();
|
||||
for (BluetoothDevice device : bondedDevices) {
|
||||
if (device.getName().startsWith("IOIO")) {
|
||||
result.add(new IOIOConnectionSpec(
|
||||
BluetoothIOIOConnection.class.getName(),
|
||||
new Object[] { device.getName(),
|
||||
device.getAddress() }));
|
||||
}
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
Log.e(TAG,
|
||||
"Did you forget to declare uses-permission of android.permission.BLUETOOTH?");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
IOIOLib/src/ioio/lib/impl/AbstractPin.java
Executable file → Normal file
3
IOIOLib/src/ioio/lib/impl/AbstractPin.java
Executable file → Normal file
@@ -30,7 +30,7 @@ package ioio.lib.impl;
|
||||
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
public abstract class AbstractPin extends AbstractResource {
|
||||
abstract class AbstractPin extends AbstractResource {
|
||||
protected final int pinNum_;
|
||||
|
||||
AbstractPin(IOIOImpl ioio, int pinNum) throws ConnectionLostException {
|
||||
@@ -38,6 +38,7 @@ public abstract class AbstractPin extends AbstractResource {
|
||||
pinNum_ = pinNum;
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public void close() {
|
||||
super.close();
|
||||
ioio_.closePin(pinNum_);
|
||||
|
||||
3
IOIOLib/src/ioio/lib/impl/AbstractResource.java
Executable file → Normal file
3
IOIOLib/src/ioio/lib/impl/AbstractResource.java
Executable file → Normal file
@@ -32,7 +32,7 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
import ioio.lib.impl.IncomingState.DisconnectListener;
|
||||
import ioio.lib.api.Closeable;
|
||||
|
||||
public class AbstractResource implements Closeable, DisconnectListener {
|
||||
class AbstractResource implements Closeable, DisconnectListener {
|
||||
enum State {
|
||||
OPEN,
|
||||
CLOSED,
|
||||
@@ -53,6 +53,7 @@ public class AbstractResource implements Closeable, DisconnectListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public void close() {
|
||||
if (state_ == State.CLOSED) {
|
||||
throw new IllegalStateException("Trying to use a closed resouce");
|
||||
|
||||
109
IOIOLib/src/ioio/lib/impl/AnalogInputImpl.java
Executable file → Normal file
109
IOIOLib/src/ioio/lib/impl/AnalogInputImpl.java
Executable file → Normal file
@@ -28,22 +28,31 @@
|
||||
*/
|
||||
package ioio.lib.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ioio.lib.api.AnalogInput;
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
import ioio.lib.impl.IncomingState.InputPinListener;
|
||||
|
||||
public class AnalogInputImpl extends AbstractPin implements AnalogInput, InputPinListener {
|
||||
import java.io.IOException;
|
||||
|
||||
class AnalogInputImpl extends AbstractPin implements AnalogInput,
|
||||
InputPinListener {
|
||||
private int value_;
|
||||
private boolean valid_ = false;
|
||||
|
||||
|
||||
short[] buffer_;
|
||||
int bufferSize_;
|
||||
int bufferCapacity_;
|
||||
int bufferReadCursor_;
|
||||
int bufferWriteCursor_;
|
||||
int bufferOverflowCount_ = 0;
|
||||
|
||||
AnalogInputImpl(IOIOImpl ioio, int pin) throws ConnectionLostException {
|
||||
super(ioio, pin);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public float getVoltage() throws InterruptedException, ConnectionLostException {
|
||||
public float getVoltage() throws InterruptedException,
|
||||
ConnectionLostException {
|
||||
return read() * getReference();
|
||||
}
|
||||
|
||||
@@ -55,18 +64,20 @@ public class AnalogInputImpl extends AbstractPin implements AnalogInput, InputPi
|
||||
@Override
|
||||
synchronized public void setValue(int value) {
|
||||
// Log.v("AnalogInputImpl", "Pin " + pinNum_ + " value is " + value);
|
||||
assert(value >= 0 || value < 1024);
|
||||
value_ = value;
|
||||
assert (value >= 0 && value < 1024);
|
||||
value_ = value;
|
||||
if (!valid_) {
|
||||
valid_ = true;
|
||||
notifyAll();
|
||||
}
|
||||
bufferPush((short) value);
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public float read() throws InterruptedException, ConnectionLostException {
|
||||
synchronized public float read() throws InterruptedException,
|
||||
ConnectionLostException {
|
||||
checkState();
|
||||
while (!valid_ && state_ != State.DISCONNECTED) {
|
||||
while (!valid_ && state_ == State.OPEN) {
|
||||
wait();
|
||||
}
|
||||
checkState();
|
||||
@@ -87,4 +98,82 @@ public class AnalogInputImpl extends AbstractPin implements AnalogInput, InputPi
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setBuffer(int capacity)
|
||||
throws ConnectionLostException {
|
||||
checkState();
|
||||
if (capacity <= 0) {
|
||||
buffer_ = null;
|
||||
} else {
|
||||
buffer_ = new short[capacity];
|
||||
}
|
||||
bufferCapacity_ = capacity;
|
||||
bufferSize_ = 0;
|
||||
bufferReadCursor_ = 0;
|
||||
bufferWriteCursor_ = 0;
|
||||
bufferOverflowCount_ = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float readBuffered() throws InterruptedException,
|
||||
ConnectionLostException {
|
||||
checkState();
|
||||
return (float) bufferPull() / 1023.0f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getVoltageBuffered() throws InterruptedException,
|
||||
ConnectionLostException {
|
||||
return readBuffered() * getReference();
|
||||
}
|
||||
|
||||
private void bufferPush(short value) {
|
||||
if (buffer_ == null) {
|
||||
return;
|
||||
}
|
||||
if (bufferSize_ == bufferCapacity_) {
|
||||
++bufferOverflowCount_;
|
||||
} else {
|
||||
++bufferSize_;
|
||||
}
|
||||
buffer_[bufferWriteCursor_++] = value;
|
||||
if (bufferWriteCursor_ == bufferCapacity_) {
|
||||
bufferWriteCursor_ = 0;
|
||||
}
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
private synchronized short bufferPull() throws InterruptedException,
|
||||
ConnectionLostException {
|
||||
if (buffer_ == null) {
|
||||
throw new IllegalStateException(
|
||||
"Need to call setBuffer() before reading buffered values.");
|
||||
}
|
||||
while (bufferSize_ == 0 && state_ == State.OPEN) {
|
||||
wait();
|
||||
}
|
||||
checkState();
|
||||
short result = buffer_[bufferReadCursor_++];
|
||||
if (bufferReadCursor_ == bufferCapacity_) {
|
||||
bufferReadCursor_ = 0;
|
||||
}
|
||||
--bufferSize_;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOverflowCount() throws ConnectionLostException {
|
||||
return bufferOverflowCount_;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getSampleRate() throws ConnectionLostException {
|
||||
return 1000.0f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws ConnectionLostException {
|
||||
return bufferSize_;
|
||||
}
|
||||
}
|
||||
|
||||
90
IOIOLib/src/ioio/lib/impl/Constants.java
Executable file → Normal file
90
IOIOLib/src/ioio/lib/impl/Constants.java
Executable file → Normal file
@@ -1,45 +1,45 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.impl;
|
||||
|
||||
class Constants {
|
||||
static final int NUM_PINS = 49;
|
||||
static final int NUM_ANALOG_PINS = 16;
|
||||
static final int NUM_PWM_MODULES = 9;
|
||||
static final int NUM_UART_MODULES = 4;
|
||||
static final int NUM_SPI_MODULES = 3;
|
||||
static final int NUM_TWI_MODULES = 3;
|
||||
static final int[] INCAP_MODULES_DOUBLE = new int[] { 0, 2, 4};
|
||||
static final int[] INCAP_MODULES_SINGLE = new int[] { 6, 7, 8};
|
||||
static final int BUFFER_SIZE = 1024;
|
||||
static final int PACKET_BUFFER_SIZE = 256;
|
||||
|
||||
static final int[][] TWI_PINS = new int[][] {{ 4, 5 }, { 47, 48 }, { 26, 25 }};
|
||||
static final int[] ICSP_PINS = new int[] { 36, 37, 38 };
|
||||
}
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.impl;
|
||||
|
||||
class Constants {
|
||||
static final int NUM_PINS = 49;
|
||||
static final int NUM_ANALOG_PINS = 16;
|
||||
static final int NUM_PWM_MODULES = 9;
|
||||
static final int NUM_UART_MODULES = 4;
|
||||
static final int NUM_SPI_MODULES = 3;
|
||||
static final int NUM_TWI_MODULES = 3;
|
||||
static final int[] INCAP_MODULES_DOUBLE = new int[] { 0, 2, 4};
|
||||
static final int[] INCAP_MODULES_SINGLE = new int[] { 6, 7, 8};
|
||||
static final int BUFFER_SIZE = 1024;
|
||||
static final int PACKET_BUFFER_SIZE = 256;
|
||||
|
||||
static final int[][] TWI_PINS = new int[][] {{ 4, 5 }, { 47, 48 }, { 26, 25 }};
|
||||
static final int[] ICSP_PINS = new int[] { 36, 37, 38 };
|
||||
}
|
||||
|
||||
3
IOIOLib/src/ioio/lib/impl/DigitalInputImpl.java
Executable file → Normal file
3
IOIOLib/src/ioio/lib/impl/DigitalInputImpl.java
Executable file → Normal file
@@ -34,7 +34,7 @@ import ioio.lib.impl.IncomingState.InputPinListener;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DigitalInputImpl extends AbstractPin implements DigitalInput,
|
||||
class DigitalInputImpl extends AbstractPin implements DigitalInput,
|
||||
InputPinListener {
|
||||
private boolean value_;
|
||||
private boolean valid_ = false;
|
||||
@@ -54,6 +54,7 @@ public class DigitalInputImpl extends AbstractPin implements DigitalInput,
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public void waitForValue(boolean value)
|
||||
throws InterruptedException, ConnectionLostException {
|
||||
checkState();
|
||||
|
||||
18
IOIOLib/src/ioio/lib/impl/DigitalOutputImpl.java
Executable file → Normal file
18
IOIOLib/src/ioio/lib/impl/DigitalOutputImpl.java
Executable file → Normal file
@@ -33,18 +33,24 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DigitalOutputImpl extends AbstractPin implements DigitalOutput {
|
||||
DigitalOutputImpl(IOIOImpl ioio, int pin) throws ConnectionLostException {
|
||||
class DigitalOutputImpl extends AbstractPin implements DigitalOutput {
|
||||
boolean value_;
|
||||
|
||||
DigitalOutputImpl(IOIOImpl ioio, int pin, boolean startValue) throws ConnectionLostException {
|
||||
super(ioio, pin);
|
||||
value_ = startValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public void write(boolean val) throws ConnectionLostException {
|
||||
checkState();
|
||||
try {
|
||||
ioio_.protocol_.setDigitalOutLevel(pinNum_, val);
|
||||
} catch (IOException e) {
|
||||
throw new ConnectionLostException(e);
|
||||
if (val != value_) {
|
||||
try {
|
||||
ioio_.protocol_.setDigitalOutLevel(pinNum_, val);
|
||||
value_ = val;
|
||||
} catch (IOException e) {
|
||||
throw new ConnectionLostException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
IOIOLib/src/ioio/lib/impl/FlowControlledOutputStream.java
Executable file → Normal file
9
IOIOLib/src/ioio/lib/impl/FlowControlledOutputStream.java
Executable file → Normal file
@@ -33,7 +33,7 @@ import java.io.OutputStream;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
public class FlowControlledOutputStream extends OutputStream {
|
||||
class FlowControlledOutputStream extends OutputStream {
|
||||
interface Sender {
|
||||
void send(byte[] data, int size);
|
||||
}
|
||||
@@ -91,15 +91,14 @@ public class FlowControlledOutputStream extends OutputStream {
|
||||
|
||||
@Override
|
||||
synchronized public void close() {
|
||||
if (closed_) {
|
||||
return;
|
||||
}
|
||||
closed_ = true;
|
||||
notifyAll();
|
||||
thread_.interrupt();
|
||||
}
|
||||
|
||||
synchronized public void kill() {
|
||||
thread_.interrupt();
|
||||
}
|
||||
|
||||
class FlushThread extends Thread {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
2
IOIOLib/src/ioio/lib/impl/FlowControlledPacketSender.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/FlowControlledPacketSender.java
Executable file → Normal file
@@ -32,7 +32,7 @@ import java.io.IOException;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
public class FlowControlledPacketSender {
|
||||
class FlowControlledPacketSender {
|
||||
interface Packet {
|
||||
int getSize();
|
||||
}
|
||||
|
||||
1354
IOIOLib/src/ioio/lib/impl/IOIOImpl.java
Executable file → Normal file
1354
IOIOLib/src/ioio/lib/impl/IOIOImpl.java
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
1655
IOIOLib/src/ioio/lib/impl/IOIOProtocol.java
Executable file → Normal file
1655
IOIOLib/src/ioio/lib/impl/IOIOProtocol.java
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
2
IOIOLib/src/ioio/lib/impl/IcspMasterImpl.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/IcspMasterImpl.java
Executable file → Normal file
@@ -36,7 +36,7 @@ import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
public class IcspMasterImpl extends AbstractResource implements IcspMaster,
|
||||
class IcspMasterImpl extends AbstractResource implements IcspMaster,
|
||||
DataModuleListener {
|
||||
private Queue<Integer> resultQueue_ = new LinkedList<Integer>();
|
||||
private int rxRemaining_ = 0;
|
||||
|
||||
2
IOIOLib/src/ioio/lib/impl/IncapImpl.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/IncapImpl.java
Executable file → Normal file
@@ -7,7 +7,7 @@ import ioio.lib.impl.IncomingState.DataModuleListener;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
public class IncapImpl extends AbstractPin implements DataModuleListener,
|
||||
class IncapImpl extends AbstractPin implements DataModuleListener,
|
||||
PulseInput {
|
||||
private static final int MAX_QUEUE_LEN = 32;
|
||||
private final PulseMode mode_;
|
||||
|
||||
2
IOIOLib/src/ioio/lib/impl/IncomingState.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/IncomingState.java
Executable file → Normal file
@@ -38,7 +38,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class IncomingState implements IncomingHandler {
|
||||
class IncomingState implements IncomingHandler {
|
||||
enum ConnectionState {
|
||||
INIT, ESTABLISHED, CONNECTED, DISCONNECTED, UNSUPPORTED_IID
|
||||
}
|
||||
|
||||
2
IOIOLib/src/ioio/lib/impl/ModuleAllocator.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/ModuleAllocator.java
Executable file → Normal file
@@ -44,7 +44,7 @@ import java.util.TreeSet;
|
||||
*
|
||||
* @author birmiwal
|
||||
*/
|
||||
public class ModuleAllocator {
|
||||
class ModuleAllocator {
|
||||
private final Set<Integer> availableModuleIds_;
|
||||
private final Set<Integer> allocatedModuleIds_;
|
||||
private final String name_;
|
||||
|
||||
2
IOIOLib/src/ioio/lib/impl/PinFunctionMap.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/PinFunctionMap.java
Executable file → Normal file
@@ -29,7 +29,7 @@
|
||||
package ioio.lib.impl;
|
||||
|
||||
|
||||
public class PinFunctionMap {
|
||||
class PinFunctionMap {
|
||||
private static final boolean[] PERIPHERAL_OUT = new boolean[] { true,
|
||||
false, false, true, true, true, true, true, false, false, true,
|
||||
true, true, true, true, false, false, false, false, false, false,
|
||||
|
||||
2
IOIOLib/src/ioio/lib/impl/PwmImpl.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/PwmImpl.java
Executable file → Normal file
@@ -33,7 +33,7 @@ import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class PwmImpl extends AbstractResource implements PwmOutput {
|
||||
class PwmImpl extends AbstractResource implements PwmOutput {
|
||||
private final int pwmNum_;
|
||||
private final int pinNum_;
|
||||
private final float baseUs_;
|
||||
|
||||
56
IOIOLib/src/ioio/lib/impl/QueueInputStream.java
Executable file → Normal file
56
IOIOLib/src/ioio/lib/impl/QueueInputStream.java
Executable file → Normal file
@@ -35,26 +35,60 @@ import java.util.concurrent.ArrayBlockingQueue;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class QueueInputStream extends InputStream {
|
||||
class QueueInputStream extends InputStream {
|
||||
private enum State {
|
||||
OPEN, CLOSED, KILLED
|
||||
};
|
||||
|
||||
private final Queue<Byte> queue_ = new ArrayBlockingQueue<Byte>(
|
||||
Constants.BUFFER_SIZE);
|
||||
private boolean closed_ = false;
|
||||
private State state_ = State.OPEN;
|
||||
|
||||
@Override
|
||||
synchronized public int read() throws IOException {
|
||||
try {
|
||||
while (!closed_ && queue_.isEmpty()) {
|
||||
while (state_ == State.OPEN && queue_.isEmpty()) {
|
||||
wait();
|
||||
}
|
||||
if (closed_) {
|
||||
if (state_ == State.KILLED) {
|
||||
throw new IOException("Stream has been closed");
|
||||
}
|
||||
if (state_ == State.CLOSED && queue_.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
return ((int) queue_.remove()) & 0xFF;
|
||||
} catch (InterruptedException e) {
|
||||
throw new IOException("Interrupted");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
while (state_ == State.OPEN && queue_.isEmpty()) {
|
||||
wait();
|
||||
}
|
||||
if (state_ == State.KILLED) {
|
||||
throw new IOException("Stream has been closed");
|
||||
}
|
||||
if (state_ == State.CLOSED && queue_.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
if (len > queue_.size()) {
|
||||
len = queue_.size();
|
||||
}
|
||||
for (int i = 0; i < len; ++i) {
|
||||
b[off++] = queue_.remove();
|
||||
}
|
||||
return len;
|
||||
} catch (InterruptedException e) {
|
||||
throw new IOException("Interrupted");
|
||||
}
|
||||
}
|
||||
|
||||
synchronized public void write(byte[] data, int size) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (queue_.size() == Constants.BUFFER_SIZE) {
|
||||
@@ -73,7 +107,19 @@ public class QueueInputStream extends InputStream {
|
||||
|
||||
@Override
|
||||
synchronized public void close() {
|
||||
closed_ = true;
|
||||
if (state_ != State.OPEN) {
|
||||
return;
|
||||
}
|
||||
state_ = State.CLOSED;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
synchronized public void kill() {
|
||||
if (state_ != State.OPEN) {
|
||||
return;
|
||||
}
|
||||
state_ = State.KILLED;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
19
IOIOLib/src/ioio/lib/impl/SocketIOIOConnection.java
Executable file → Normal file
19
IOIOLib/src/ioio/lib/impl/SocketIOIOConnection.java
Executable file → Normal file
@@ -41,6 +41,7 @@ import java.net.SocketException;
|
||||
import android.util.Log;
|
||||
|
||||
public class SocketIOIOConnection implements IOIOConnection {
|
||||
private static final String TAG = "SocketIOIOConnection";
|
||||
private final int port_;
|
||||
private ServerSocket server_ = null;
|
||||
private Socket socket_ = null;
|
||||
@@ -48,7 +49,7 @@ public class SocketIOIOConnection implements IOIOConnection {
|
||||
private boolean server_owned_by_connect_ = true;
|
||||
private boolean socket_owned_by_connect_ = true;
|
||||
|
||||
public SocketIOIOConnection(Integer port) {
|
||||
public SocketIOIOConnection(int port) {
|
||||
port_ = port;
|
||||
}
|
||||
|
||||
@@ -59,13 +60,13 @@ public class SocketIOIOConnection implements IOIOConnection {
|
||||
if (disconnect_) {
|
||||
throw new ConnectionLostException();
|
||||
}
|
||||
Log.d("SocketIOIOConnection", "Creating server socket");
|
||||
Log.v(TAG, "Creating server socket");
|
||||
server_ = new ServerSocket(port_);
|
||||
server_owned_by_connect_ = false;
|
||||
}
|
||||
Log.d("SocketIOIOConnection", "Waiting for TCP connection");
|
||||
Log.v(TAG, "Waiting for TCP connection");
|
||||
socket_ = server_.accept();
|
||||
Log.d("SocketIOIOConnection", "TCP connected");
|
||||
Log.v(TAG, "TCP connected");
|
||||
synchronized (this) {
|
||||
if (disconnect_) {
|
||||
socket_.close();
|
||||
@@ -80,18 +81,18 @@ public class SocketIOIOConnection implements IOIOConnection {
|
||||
try {
|
||||
server_.close();
|
||||
} catch (IOException e1) {
|
||||
Log.e("SocketIOIOConnection", "Unexpected exception", e1);
|
||||
Log.e(TAG, "Unexpected exception", e1);
|
||||
}
|
||||
}
|
||||
if (socket_owned_by_connect_ && socket_ != null) {
|
||||
try {
|
||||
socket_.close();
|
||||
} catch (IOException e1) {
|
||||
Log.e("SocketIOIOConnection", "Unexpected exception", e1);
|
||||
Log.e(TAG, "Unexpected exception", e1);
|
||||
}
|
||||
}
|
||||
if (e instanceof SocketException && e.getMessage().equals("Permission denied")) {
|
||||
Log.e("SocketIOIOConnection", "Did you forget to declare uses-permission of android.permission.INTERNET?");
|
||||
Log.e(TAG, "Did you forget to declare uses-permission of android.permission.INTERNET?");
|
||||
}
|
||||
throw new ConnectionLostException(e);
|
||||
}
|
||||
@@ -103,13 +104,13 @@ public class SocketIOIOConnection implements IOIOConnection {
|
||||
if (disconnect_) {
|
||||
return;
|
||||
}
|
||||
Log.d("SocketIOIOConnection", "Client initiated disconnect");
|
||||
Log.v(TAG, "Client initiated disconnect");
|
||||
disconnect_ = true;
|
||||
if (!server_owned_by_connect_) {
|
||||
try {
|
||||
server_.close();
|
||||
} catch (IOException e1) {
|
||||
Log.e("SocketIOIOConnection", "Unexpected exception", e1);
|
||||
Log.e(TAG, "Unexpected exception", e1);
|
||||
}
|
||||
}
|
||||
if (!socket_owned_by_connect_) {
|
||||
|
||||
63
IOIOLib/src/ioio/lib/impl/SocketIOIOConnectionBootstrap.java
Normal file
63
IOIOLib/src/ioio/lib/impl/SocketIOIOConnectionBootstrap.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
package ioio.lib.impl;
|
||||
|
||||
import ioio.lib.api.IOIOConnection;
|
||||
import ioio.lib.spi.IOIOConnectionBootstrap;
|
||||
import ioio.lib.spi.IOIOConnectionFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class SocketIOIOConnectionBootstrap implements IOIOConnectionBootstrap {
|
||||
/** The TCP port used for communicating with the IOIO board. */
|
||||
public static final int IOIO_PORT = 4545;
|
||||
|
||||
@Override
|
||||
public void getFactories(Collection<IOIOConnectionFactory> result) {
|
||||
result.add(new IOIOConnectionFactory() {
|
||||
private Integer port_ = new Integer(IOIO_PORT);
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return SocketIOIOConnection.class.getCanonicalName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getExtra() {
|
||||
return port_;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOIOConnection createConnection() {
|
||||
return new SocketIOIOConnection(IOIO_PORT);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
2
IOIOLib/src/ioio/lib/impl/SpiMasterImpl.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/SpiMasterImpl.java
Executable file → Normal file
@@ -42,7 +42,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class SpiMasterImpl extends AbstractResource implements SpiMaster,
|
||||
class SpiMasterImpl extends AbstractResource implements SpiMaster,
|
||||
DataModuleListener, Sender {
|
||||
public class SpiResult implements Result {
|
||||
boolean ready_;
|
||||
|
||||
2
IOIOLib/src/ioio/lib/impl/TwiMasterImpl.java
Executable file → Normal file
2
IOIOLib/src/ioio/lib/impl/TwiMasterImpl.java
Executable file → Normal file
@@ -40,7 +40,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class TwiMasterImpl extends AbstractResource implements TwiMaster,
|
||||
class TwiMasterImpl extends AbstractResource implements TwiMaster,
|
||||
DataModuleListener, Sender {
|
||||
class TwiResult implements Result {
|
||||
boolean ready_ = false;
|
||||
|
||||
5
IOIOLib/src/ioio/lib/impl/UartImpl.java
Executable file → Normal file
5
IOIOLib/src/ioio/lib/impl/UartImpl.java
Executable file → Normal file
@@ -40,7 +40,7 @@ import java.io.OutputStream;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class UartImpl extends AbstractResource implements DataModuleListener, Sender, Uart {
|
||||
class UartImpl extends AbstractResource implements DataModuleListener, Sender, Uart {
|
||||
private static final int MAX_PACKET = 64;
|
||||
|
||||
private final int uartNum_;
|
||||
@@ -87,7 +87,8 @@ public class UartImpl extends AbstractResource implements DataModuleListener, Se
|
||||
@Override
|
||||
synchronized public void disconnected() {
|
||||
super.disconnected();
|
||||
outgoing_.kill();
|
||||
incoming_.kill();
|
||||
outgoing_.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
41
IOIOLib/src/ioio/lib/spi/IOIOConnectionBootstrap.java
Normal file
41
IOIOLib/src/ioio/lib/spi/IOIOConnectionBootstrap.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
package ioio.lib.spi;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Implementing class must have a default constructor. The default constructor
|
||||
* must throw a NoRuntimeSupportException in case the required libraries for
|
||||
* implementing the connections are not available in run-time.
|
||||
*/
|
||||
public interface IOIOConnectionBootstrap {
|
||||
public void getFactories(Collection<IOIOConnectionFactory> result);
|
||||
}
|
||||
21
IOIOLib/src/ioio/lib/spi/IOIOConnectionFactory.java
Normal file
21
IOIOLib/src/ioio/lib/spi/IOIOConnectionFactory.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package ioio.lib.spi;
|
||||
|
||||
import ioio.lib.api.IOIOConnection;
|
||||
|
||||
public interface IOIOConnectionFactory {
|
||||
/**
|
||||
* A unique name of the connection type. Typically a fully-qualified
|
||||
* name of the connection class.
|
||||
*/
|
||||
public String getType();
|
||||
|
||||
/**
|
||||
* Extra information on the connection. This is specific to the
|
||||
* connection type. For example, for a Bluetooth connection, this is an
|
||||
* array containing the name and the Bluetooth address of the remote
|
||||
* IOIO.
|
||||
*/
|
||||
public Object getExtra();
|
||||
|
||||
public IOIOConnection createConnection();
|
||||
}
|
||||
9
IOIOLib/src/ioio/lib/spi/NoRuntimeSupportException.java
Normal file
9
IOIOLib/src/ioio/lib/spi/NoRuntimeSupportException.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package ioio.lib.spi;
|
||||
|
||||
public class NoRuntimeSupportException extends Exception {
|
||||
private static final long serialVersionUID = -6559208663699429514L;
|
||||
|
||||
public NoRuntimeSupportException(String desc) {
|
||||
super(desc);
|
||||
}
|
||||
}
|
||||
664
IOIOLib/src/ioio/lib/util/AbstractIOIOActivity.java
Executable file → Normal file
664
IOIOLib/src/ioio/lib/util/AbstractIOIOActivity.java
Executable file → Normal file
@@ -1,295 +1,369 @@
|
||||
package ioio.lib.util;
|
||||
|
||||
import ioio.lib.api.IOIO;
|
||||
import ioio.lib.api.IOIOFactory;
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
import ioio.lib.api.exception.IncompatibilityException;
|
||||
import ioio.lib.util.IOIOConnectionDiscovery.IOIOConnectionSpec;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* A convenience class for easy creation of IOIO-based applications.
|
||||
*
|
||||
* It is used by creating a concrete Activity in your application, which extends
|
||||
* this class. This class then takes care of proper creation and abortion of the
|
||||
* IOIO connection and of a dedicated thread for IOIO communication.
|
||||
*
|
||||
* In the basic usage the client should extend this class and implement
|
||||
* {@link #createIOIOThread()}, which should return an implementation of the
|
||||
* {@link IOIOThread} abstract class. In this implementation, the client
|
||||
* implements the {@link IOIOThread#setup()} method, which gets called as soon
|
||||
* as communication with the IOIO is established, and the {@link IOIOThread
|
||||
* #loop()} method, which gets called repetitively as long as the IOIO is
|
||||
* connected. Both methods should access the {@link IOIOThread#ioio_} field for
|
||||
* controlling the IOIO.
|
||||
*
|
||||
* In addition, the {@link IOIOThread#disconnected()} method may be overridden
|
||||
* in order to execute logic as soon as a disconnection occurs for whichever
|
||||
* reason. The {@link IOIOThread#incompatible()} method may be overridden in
|
||||
* order to take action in case where a IOIO whose firmware is incompatible with
|
||||
* the IOIOLib version that application is built with.
|
||||
*
|
||||
* In a more advanced use case, more than one IOIO is available. In this case, a
|
||||
* thread will be created for each IOIO, whose semantics are as defined above.
|
||||
* If the client needs to be able to distinguish between them, it is possible to
|
||||
* override {@link #createIOIOThread(String, Object[])} instead of
|
||||
* {@link #createIOIOThread()}. The first argument provided will contain the
|
||||
* connection class name, such as ioio.lib.impl.SocketIOIOConnection for a
|
||||
* connection established over a TCP socket (which is used over ADB). The second
|
||||
* argument will contain information specific to the connection type. For
|
||||
* example, in the case of SocketIOIOConnection, the array will contain an
|
||||
* {@link Integer} representing the local port number.
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractIOIOActivity extends Activity {
|
||||
private static final String TAG = "AbstractIOIOActivity";
|
||||
private IOIOConnectionSpec currentSpec_;
|
||||
private Collection<IOIOThread> threads_ = new LinkedList<IOIOThread>();
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onResume() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
createAllThreads();
|
||||
startAllThreads();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onPause() if
|
||||
* overloaded. It takes care of disconnecting from the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
abortAllThreads();
|
||||
try {
|
||||
joinAllThreads();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should implement this method by returning a concrete subclass
|
||||
* of {@link IOIOThread}. <code>null</code> may be returned if the client
|
||||
* is not interested to connect a thread for this IOIO. In multi-IOIO
|
||||
* scenarios, where you want to identify which IOIO the thread is for,
|
||||
* consider using {@link #createIOIOThread()} instead.
|
||||
*
|
||||
* @return An implementation of {@link IOIOThread}, or <code>null</code> to
|
||||
* skip.
|
||||
*/
|
||||
protected IOIOThread createIOIOThread() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should implement this method by returning a concrete subclass
|
||||
* of {@link IOIOThread}. This overload is useful in multi-IOIO scenarios,
|
||||
* where you want to identify which IOIO the thread is for. The provided
|
||||
* arguments should provide enough information to be unique per connection.
|
||||
* <code>null</code> may be returned if the client is not interested to
|
||||
* connect a thread for this IOIO. This can be used in order to filter out
|
||||
* unwanted connections, for example if the application is only intended for
|
||||
* wireless connection, any wired connection attempts may be rejected, thus
|
||||
* saving resources used for listening for incoming wired connections.
|
||||
*
|
||||
* @param connectionClass
|
||||
* The fully-qualified name of the connection class used to
|
||||
* connect to the IOIO.
|
||||
* @param connectionArgs
|
||||
* A list of arguments passed to the constructor of the
|
||||
* connection class. Should provide information that enables
|
||||
* distinguishing between different IOIO instances using the same
|
||||
* connection class.
|
||||
*
|
||||
* @return An implementation of {@link IOIOThread}, or <code>null</code> to
|
||||
* skip.
|
||||
*/
|
||||
protected IOIOThread createIOIOThread(String connectionClass,
|
||||
Object[] connectionArgs) {
|
||||
return createIOIOThread();
|
||||
}
|
||||
|
||||
/**
|
||||
* An abstract class, which facilitates a thread dedicated for communication
|
||||
* with a single physical IOIO device.
|
||||
*/
|
||||
protected abstract class IOIOThread extends Thread {
|
||||
/** Subclasses should use this field for controlling the IOIO. */
|
||||
protected IOIO ioio_;
|
||||
private boolean abort_ = false;
|
||||
private boolean connected_ = true;
|
||||
private final IOIOConnectionSpec spec_ = currentSpec_;
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to
|
||||
* be done once as soon as IOIO communication is established. Typically,
|
||||
* this will include opening pins and modules using the openXXX()
|
||||
* methods of the {@link #ioio_} field.
|
||||
*/
|
||||
protected void setup() throws ConnectionLostException,
|
||||
InterruptedException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to
|
||||
* be done repetitively as long as IOIO communication persists.
|
||||
* Typically, this will be the main logic of the application, processing
|
||||
* inputs and producing outputs.
|
||||
*/
|
||||
protected void loop() throws ConnectionLostException,
|
||||
InterruptedException {
|
||||
sleep(100000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to
|
||||
* be done once as soon as IOIO communication is lost or closed.
|
||||
* Typically, this will include GUI changes corresponding to the change.
|
||||
* This method will only be called if setup() has been called. The
|
||||
* {@link #ioio_} member must not be used from within this method.
|
||||
*/
|
||||
protected void disconnected() throws InterruptedException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to
|
||||
* be done if an incompatible IOIO firmware is detected. The
|
||||
* {@link #ioio_} member must not be used from within this method. This
|
||||
* method will only be called once, until a compatible IOIO is connected
|
||||
* (i.e. {@link #setup()} gets called).
|
||||
*/
|
||||
protected void incompatible() {
|
||||
}
|
||||
|
||||
/** Not relevant to subclasses. */
|
||||
@Override
|
||||
public final void run() {
|
||||
super.run();
|
||||
Looper.prepare();
|
||||
while (true) {
|
||||
try {
|
||||
synchronized (this) {
|
||||
if (abort_) {
|
||||
break;
|
||||
}
|
||||
ioio_ = IOIOFactory.create(spec_.className, spec_.args);
|
||||
}
|
||||
ioio_.waitForConnect();
|
||||
connected_ = true;
|
||||
setup();
|
||||
while (!abort_) {
|
||||
loop();
|
||||
}
|
||||
ioio_.disconnect();
|
||||
} catch (ConnectionLostException e) {
|
||||
if (abort_) {
|
||||
break;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
ioio_.disconnect();
|
||||
break;
|
||||
} catch (IncompatibilityException e) {
|
||||
Log.e(TAG, "Incompatible IOIO firmware", e);
|
||||
incompatible();
|
||||
// nothing to do - just wait until physical disconnection
|
||||
try {
|
||||
ioio_.waitForDisconnect();
|
||||
} catch (InterruptedException e1) {
|
||||
ioio_.disconnect();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Unexpected exception caught", e);
|
||||
ioio_.disconnect();
|
||||
break;
|
||||
} finally {
|
||||
try {
|
||||
if (ioio_ != null) {
|
||||
ioio_.waitForDisconnect();
|
||||
if (connected_) {
|
||||
disconnected();
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Not relevant to subclasses. */
|
||||
public synchronized final void abort() {
|
||||
abort_ = true;
|
||||
if (ioio_ != null) {
|
||||
ioio_.disconnect();
|
||||
}
|
||||
if (connected_) {
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void abortAllThreads() {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.abort();
|
||||
}
|
||||
}
|
||||
|
||||
private void joinAllThreads() throws InterruptedException {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
private void createAllThreads() {
|
||||
threads_.clear();
|
||||
Collection<IOIOConnectionSpec> specs = getConnectionSpecs();
|
||||
for (IOIOConnectionSpec spec : specs) {
|
||||
currentSpec_ = spec;
|
||||
IOIOThread thread = createIOIOThread(spec.className, spec.args);
|
||||
if (thread != null) {
|
||||
threads_.add(thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startAllThreads() {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<IOIOConnectionSpec> getConnectionSpecs() {
|
||||
Collection<IOIOConnectionSpec> result = new LinkedList<IOIOConnectionSpec>();
|
||||
addConnectionSpecs("ioio.lib.util.SocketIOIOConnectionDiscovery",
|
||||
result);
|
||||
addConnectionSpecs(
|
||||
"ioio.lib.bluetooth.BluetoothIOIOConnectionDiscovery", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void addConnectionSpecs(String discoveryClassName,
|
||||
Collection<IOIOConnectionSpec> result) {
|
||||
try {
|
||||
Class<?> cls = Class.forName(discoveryClassName);
|
||||
IOIOConnectionDiscovery discovery = (IOIOConnectionDiscovery) cls
|
||||
.newInstance();
|
||||
discovery.getSpecs(result);
|
||||
} catch (ClassNotFoundException e) {
|
||||
Log.d(TAG, "Discovery class not found: " + discoveryClassName
|
||||
+ ". Not adding.");
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG,
|
||||
"Exception caught while discovering connections - not adding connections of class "
|
||||
+ discoveryClassName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
package ioio.lib.util;
|
||||
|
||||
import ioio.lib.api.IOIO;
|
||||
import ioio.lib.api.IOIOFactory;
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
import ioio.lib.api.exception.IncompatibilityException;
|
||||
import ioio.lib.spi.IOIOConnectionBootstrap;
|
||||
import ioio.lib.spi.IOIOConnectionFactory;
|
||||
import ioio.lib.util.android.ContextWrapperDependent;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* A convenience class for easy creation of IOIO-based applications.
|
||||
*
|
||||
* It is used by creating a concrete Activity in your application, which extends
|
||||
* this class. This class then takes care of proper creation and abortion of the
|
||||
* IOIO connection and of a dedicated thread for IOIO communication.
|
||||
*
|
||||
* In the basic usage the client should extend this class and implement
|
||||
* {@link #createIOIOThread()}, which should return an implementation of the
|
||||
* {@link AbstractIOIOActivity.IOIOThread} abstract class. In this
|
||||
* implementation, the client implements the
|
||||
* {@link AbstractIOIOActivity.IOIOThread#setup()} method, which gets called as
|
||||
* soon as communication with the IOIO is established, and the
|
||||
* {@link AbstractIOIOActivity.IOIOThread#loop()} method, which gets called
|
||||
* repetitively as long as the IOIO is connected. Both methods should access the
|
||||
* {@link AbstractIOIOActivity.IOIOThread#ioio_} field for controlling the IOIO.
|
||||
*
|
||||
* In addition, the {@link AbstractIOIOActivity.IOIOThread#disconnected()}
|
||||
* method may be overridden in order to execute logic as soon as a disconnection
|
||||
* occurs for whichever reason. The
|
||||
* {@link AbstractIOIOActivity.IOIOThread#incompatible()} method may be
|
||||
* overridden in order to take action in case where a IOIO whose firmware is
|
||||
* incompatible with the IOIOLib version that application is built with.
|
||||
*
|
||||
* In a more advanced use case, more than one IOIO is available. In this case, a
|
||||
* thread will be created for each IOIO, whose semantics are as defined above.
|
||||
* If the client needs to be able to distinguish between them, it is possible to
|
||||
* override {@link #createIOIOThread(String, Object)} instead of
|
||||
* {@link #createIOIOThread()}. The first argument provided will contain the
|
||||
* connection class name, such as ioio.lib.impl.SocketIOIOConnection for a
|
||||
* connection established over a TCP socket (which is used over ADB). The second
|
||||
* argument will contain information specific to the connection type. For
|
||||
* example, in the case of SocketIOIOConnection, the second argument will
|
||||
* contain an {@link Integer} representing the local port number.
|
||||
*
|
||||
* @deprecated Please use {@link ioio.lib.util.android.IOIOActivity} instead.
|
||||
*/
|
||||
public abstract class AbstractIOIOActivity extends Activity {
|
||||
private static final String TAG = "AbstractIOIOActivity";
|
||||
|
||||
static {
|
||||
IOIOConnectionRegistry
|
||||
.addBootstraps(new String[] {
|
||||
"ioio.lib.android.accessory.AccessoryConnectionBootstrap",
|
||||
"ioio.lib.android.bluetooth.BluetoothIOIOConnectionBootstrap" });
|
||||
}
|
||||
|
||||
private Collection<IOIOThread> threads_ = new LinkedList<IOIOThread>();
|
||||
private Collection<IOIOConnectionBootstrap> bootstraps_ = IOIOConnectionRegistry
|
||||
.getBootstraps();
|
||||
private IOIOConnectionFactory currentConnectionFactory_;
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onCreate() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).onCreate(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onDestroy() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).onDestroy();
|
||||
}
|
||||
}
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onStart() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).open();
|
||||
}
|
||||
}
|
||||
createAllThreads();
|
||||
startAllThreads();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onStop() if overloaded.
|
||||
* It takes care of disconnecting from the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onStop() {
|
||||
abortAllThreads();
|
||||
try {
|
||||
joinAllThreads();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).close();
|
||||
}
|
||||
}
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).open();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must either implement this method or its other overload by
|
||||
* returning a concrete subclass of {@link IOIOThread}. <code>null</code>
|
||||
* may be returned if the client is not interested to create a thread for
|
||||
* this IOIO. In multi-IOIO scenarios, where you want to identify which IOIO
|
||||
* the thread is for, consider using {@link #createIOIOThread()} instead.
|
||||
*
|
||||
* @return An implementation of {@link IOIOThread}, or <code>null</code> to
|
||||
* skip.
|
||||
*/
|
||||
protected IOIOThread createIOIOThread() {
|
||||
throw new RuntimeException(
|
||||
"Client must override on of the createIOIOThread overloads!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should implement this method by returning a concrete subclass
|
||||
* of {@link IOIOThread}. This overload is useful in multi-IOIO scenarios,
|
||||
* where you want to identify which IOIO the thread is for. The provided
|
||||
* arguments should provide enough information to be unique per connection.
|
||||
* <code>null</code> may be returned if the client is not interested to
|
||||
* connect a thread for this IOIO. This can be used in order to filter out
|
||||
* unwanted connections, for example if the application is only intended for
|
||||
* wireless connection, any wired connection attempts may be rejected, thus
|
||||
* saving resources used for listening for incoming wired connections.
|
||||
*
|
||||
* @param connectionType
|
||||
* A unique name of the connection type. Typically, the
|
||||
* fully-qualified name of the connection class used to connect
|
||||
* to the IOIO.
|
||||
* @param extra
|
||||
* A connection-type-specific object with extra information on
|
||||
* the specific connection. Should provide information that
|
||||
* enables distinguishing between different IOIO instances using
|
||||
* the same connection class. For example, a Bluetooth connection
|
||||
* type, might have the remote IOIO's Bluetooth name as extra.
|
||||
*
|
||||
* @return An implementation of {@link IOIOThread}, or <code>null</code> to
|
||||
* skip.
|
||||
*/
|
||||
protected IOIOThread createIOIOThread(String connectionType, Object extra) {
|
||||
return createIOIOThread();
|
||||
}
|
||||
|
||||
/**
|
||||
* An abstract class, which facilitates a thread dedicated for communication
|
||||
* with a single physical IOIO device.
|
||||
*/
|
||||
protected abstract class IOIOThread extends Thread {
|
||||
/** Subclasses should use this field for controlling the IOIO. */
|
||||
protected IOIO ioio_;
|
||||
private boolean abort_ = false;
|
||||
private boolean connected_ = true;
|
||||
private final IOIOConnectionFactory connectionFactory_ = currentConnectionFactory_;
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to
|
||||
* be done once as soon as IOIO communication is established. Typically,
|
||||
* this will include opening pins and modules using the openXXX()
|
||||
* methods of the {@link #ioio_} field.
|
||||
*/
|
||||
protected void setup() throws ConnectionLostException,
|
||||
InterruptedException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to
|
||||
* be done repetitively as long as IOIO communication persists.
|
||||
* Typically, this will be the main logic of the application, processing
|
||||
* inputs and producing outputs.
|
||||
*/
|
||||
protected void loop() throws ConnectionLostException,
|
||||
InterruptedException {
|
||||
sleep(100000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to
|
||||
* be done once as soon as IOIO communication is lost or closed.
|
||||
* Typically, this will include GUI changes corresponding to the change.
|
||||
* This method will only be called if setup() has been called. The
|
||||
* {@link #ioio_} member must not be used from within this method. This
|
||||
* method should not block for long, since it may cause an ANR.
|
||||
*/
|
||||
protected void disconnected() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to
|
||||
* be done if an incompatible IOIO firmware is detected. The
|
||||
* {@link #ioio_} member must not be used from within this method. This
|
||||
* method will only be called once, until a compatible IOIO is connected
|
||||
* (i.e. {@link #setup()} gets called).
|
||||
*/
|
||||
protected void incompatible() {
|
||||
}
|
||||
|
||||
/** Not relevant to subclasses. */
|
||||
@Override
|
||||
public final void run() {
|
||||
super.run();
|
||||
while (!abort_) {
|
||||
try {
|
||||
synchronized (this) {
|
||||
if (abort_) {
|
||||
break;
|
||||
}
|
||||
ioio_ = IOIOFactory.create(connectionFactory_
|
||||
.createConnection());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Failed to create IOIO, aborting IOIOThread!");
|
||||
return;
|
||||
}
|
||||
// if we got here, we have a ioio_!
|
||||
try {
|
||||
ioio_.waitForConnect();
|
||||
connected_ = true;
|
||||
setup();
|
||||
while (!abort_) {
|
||||
loop();
|
||||
}
|
||||
} catch (ConnectionLostException e) {
|
||||
} catch (InterruptedException e) {
|
||||
ioio_.disconnect();
|
||||
} catch (IncompatibilityException e) {
|
||||
Log.e(TAG, "Incompatible IOIO firmware", e);
|
||||
incompatible();
|
||||
// nothing to do - just wait until physical disconnection
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Unexpected exception caught", e);
|
||||
ioio_.disconnect();
|
||||
break;
|
||||
} finally {
|
||||
try {
|
||||
ioio_.waitForDisconnect();
|
||||
} catch (InterruptedException e1) {
|
||||
}
|
||||
synchronized (this) {
|
||||
ioio_ = null;
|
||||
}
|
||||
if (connected_) {
|
||||
disconnected();
|
||||
connected_ = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "IOIOThread is exiting");
|
||||
}
|
||||
|
||||
/** Not relevant to subclasses. */
|
||||
public synchronized final void abort() {
|
||||
abort_ = true;
|
||||
if (ioio_ != null) {
|
||||
ioio_.disconnect();
|
||||
}
|
||||
if (connected_) {
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void abortAllThreads() {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.abort();
|
||||
}
|
||||
}
|
||||
|
||||
private void joinAllThreads() throws InterruptedException {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
private void createAllThreads() {
|
||||
threads_.clear();
|
||||
Collection<IOIOConnectionFactory> factories = IOIOConnectionRegistry
|
||||
.getConnectionFactories();
|
||||
for (IOIOConnectionFactory factory : factories) {
|
||||
currentConnectionFactory_ = factory;
|
||||
IOIOThread thread = createIOIOThread(factory.getType(),
|
||||
factory.getExtra());
|
||||
if (thread != null) {
|
||||
threads_.add(thread);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startAllThreads() {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
48
IOIOLib/src/ioio/lib/util/BaseIOIOLooper.java
Normal file
48
IOIOLib/src/ioio/lib/util/BaseIOIOLooper.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package ioio.lib.util;
|
||||
|
||||
import ioio.lib.api.IOIO;
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
/**
|
||||
* A convenience implementation of {@link IOIOLooper}.
|
||||
*
|
||||
* This base class provides no-op implementations for all methods and provides
|
||||
* the {@link #ioio_} field for subclasses.
|
||||
*
|
||||
*/
|
||||
public class BaseIOIOLooper implements IOIOLooper {
|
||||
protected IOIO ioio_;
|
||||
|
||||
@Override
|
||||
public final void setup(IOIO ioio) throws ConnectionLostException,
|
||||
InterruptedException {
|
||||
ioio_ = ioio;
|
||||
setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will be called as soon as connection to the IOIO has been
|
||||
* established. Typically, this will include opening pins and modules using
|
||||
* the openXXX() methods of the {@link #ioio_} field.
|
||||
*
|
||||
* @throws ConnectionLostException
|
||||
* The connection to the IOIO has been lost.
|
||||
* @throws InterruptedException
|
||||
* The thread has been interrupted.
|
||||
*/
|
||||
protected void setup() throws ConnectionLostException, InterruptedException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loop() throws ConnectionLostException, InterruptedException {
|
||||
Thread.sleep(20);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incompatible() {
|
||||
}
|
||||
}
|
||||
166
IOIOLib/src/ioio/lib/util/IOIOApplicationHelper.java
Normal file
166
IOIOLib/src/ioio/lib/util/IOIOApplicationHelper.java
Normal file
@@ -0,0 +1,166 @@
|
||||
package ioio.lib.util;
|
||||
|
||||
import ioio.lib.api.IOIO;
|
||||
import ioio.lib.api.IOIOFactory;
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
import ioio.lib.api.exception.IncompatibilityException;
|
||||
import ioio.lib.spi.IOIOConnectionBootstrap;
|
||||
import ioio.lib.spi.IOIOConnectionFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* A helper class for creating different kinds of IOIO based applications.
|
||||
*
|
||||
* This class implements a common life-cycle for applications interacting with
|
||||
* IOIO devices.
|
||||
* <p>
|
||||
* When the application starts, call {@link #start()}, which will in turn
|
||||
* attempt to create a thread for each possible IOIO connection channel. Each
|
||||
* thread will have a respective {@link IOIOLooper}, which the client provides,
|
||||
* through which the client gets context for working with the IOIO.
|
||||
* <p>
|
||||
* When the application exits, call {@link #stop()}, which will disconnect all
|
||||
* open connections and will abort and join all the threads.
|
||||
*
|
||||
*/
|
||||
public class IOIOApplicationHelper {
|
||||
/**
|
||||
* An abstract class, which facilitates a thread dedicated for communication
|
||||
* with a single physical IOIO device.
|
||||
*/
|
||||
static private class IOIOThread extends Thread {
|
||||
protected IOIO ioio_;
|
||||
private boolean abort_ = false;
|
||||
private boolean connected_ = true;
|
||||
private final IOIOLooper looper_;
|
||||
private final IOIOConnectionFactory connectionFactory_;
|
||||
|
||||
IOIOThread(IOIOLooper looper, IOIOConnectionFactory factory) {
|
||||
looper_ = looper;
|
||||
connectionFactory_ = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void run() {
|
||||
super.run();
|
||||
while (!abort_) {
|
||||
try {
|
||||
synchronized (this) {
|
||||
if (abort_) {
|
||||
break;
|
||||
}
|
||||
ioio_ = IOIOFactory.create(connectionFactory_
|
||||
.createConnection());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Failed to create IOIO, aborting IOIOThread!");
|
||||
return;
|
||||
}
|
||||
// if we got here, we have a ioio_!
|
||||
try {
|
||||
ioio_.waitForConnect();
|
||||
connected_ = true;
|
||||
looper_.setup(ioio_);
|
||||
while (!abort_ && ioio_.getState() == IOIO.State.CONNECTED) {
|
||||
looper_.loop();
|
||||
}
|
||||
} catch (ConnectionLostException e) {
|
||||
} catch (InterruptedException e) {
|
||||
ioio_.disconnect();
|
||||
} catch (IncompatibilityException e) {
|
||||
Log.e(TAG, "Incompatible IOIO firmware", e);
|
||||
looper_.incompatible();
|
||||
// nothing to do - just wait until physical
|
||||
// disconnection
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Unexpected exception caught", e);
|
||||
ioio_.disconnect();
|
||||
break;
|
||||
} finally {
|
||||
try {
|
||||
ioio_.waitForDisconnect();
|
||||
} catch (InterruptedException e1) {
|
||||
}
|
||||
synchronized (this) {
|
||||
ioio_ = null;
|
||||
}
|
||||
if (connected_) {
|
||||
looper_.disconnected();
|
||||
connected_ = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "IOIOThread is exiting");
|
||||
}
|
||||
|
||||
/** Not relevant to subclasses. */
|
||||
public synchronized final void abort() {
|
||||
abort_ = true;
|
||||
if (ioio_ != null) {
|
||||
ioio_.disconnect();
|
||||
}
|
||||
if (connected_) {
|
||||
interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static final String TAG = "IOIOAndroidApplicationHelper";
|
||||
protected final IOIOLooperProvider looperProvider_;
|
||||
private Collection<IOIOThread> threads_ = new LinkedList<IOIOThread>();
|
||||
protected Collection<IOIOConnectionBootstrap> bootstraps_ = IOIOConnectionRegistry
|
||||
.getBootstraps();
|
||||
|
||||
public IOIOApplicationHelper(IOIOLooperProvider provider) {
|
||||
looperProvider_ = provider;
|
||||
}
|
||||
|
||||
protected void abortAllThreads() {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.abort();
|
||||
}
|
||||
}
|
||||
|
||||
protected void joinAllThreads() throws InterruptedException {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
protected void createAllThreads() {
|
||||
threads_.clear();
|
||||
Collection<IOIOConnectionFactory> factories = IOIOConnectionRegistry
|
||||
.getConnectionFactories();
|
||||
for (IOIOConnectionFactory factory : factories) {
|
||||
IOIOLooper looper = looperProvider_.createIOIOLooper(
|
||||
factory.getType(), factory.getExtra());
|
||||
if (looper != null) {
|
||||
threads_.add(new IOIOThread(looper, factory));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void startAllThreads() {
|
||||
for (IOIOThread thread : threads_) {
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
|
||||
public void start() {
|
||||
createAllThreads();
|
||||
startAllThreads();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
abortAllThreads();
|
||||
try {
|
||||
joinAllThreads();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package ioio.lib.util;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface IOIOConnectionDiscovery {
|
||||
public static class IOIOConnectionSpec {
|
||||
public final String className;
|
||||
public final Object[] args;
|
||||
|
||||
public IOIOConnectionSpec(String c, Object[] a) {
|
||||
className = c;
|
||||
args = a;
|
||||
}
|
||||
}
|
||||
|
||||
public void getSpecs(Collection<IOIOConnectionSpec> result);
|
||||
}
|
||||
133
IOIOLib/src/ioio/lib/util/IOIOConnectionRegistry.java
Normal file
133
IOIOLib/src/ioio/lib/util/IOIOConnectionRegistry.java
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
package ioio.lib.util;
|
||||
|
||||
import ioio.lib.api.IOIOConnection;
|
||||
import ioio.lib.api.IOIOFactory;
|
||||
import ioio.lib.spi.IOIOConnectionBootstrap;
|
||||
import ioio.lib.spi.IOIOConnectionFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* A utility class for managing available connection types to IOIO.
|
||||
* <p>
|
||||
* <b>For advanced usage only!</b>
|
||||
* <p>
|
||||
* This class facilitates dynamic linkage and instantiation of different IOIO
|
||||
* connection types. {@link IOIOConnectionBootstrap} classes enable creation of
|
||||
* {@link IOIOConnectionFactory} instances, from which concrete
|
||||
* {@link IOIOConnection}s are created. The binding to
|
||||
* {@link IOIOConnectionBootstrap} is dynamic, thus enabling linkage to succeed
|
||||
* with or without those bootstraps. Likewise, during runtime, the absence of
|
||||
* bootstraps is handled gracefully.
|
||||
*
|
||||
* A typical usage will call {@link #addBootstraps(String[])} with a list of
|
||||
* class names to be sought from a static initializer block. It may then call
|
||||
* {@link #getBootstraps()} to obtain any bootstrap classes that are available
|
||||
* in runtime, in case the bootstrap classes themselves need some runtime
|
||||
* handling. Last, the {@link #getConnectionFactories()} will return a
|
||||
* collection of {@link IOIOConnectionFactory}, each representing one possible
|
||||
* communication channel to a IOIO.
|
||||
*
|
||||
*/
|
||||
public class IOIOConnectionRegistry {
|
||||
/**
|
||||
* Get all available connection specifications. This is a list of all
|
||||
* currently available communication channels in which a IOIO may be
|
||||
* available. The client typically passes elements of this collection to
|
||||
* {@link IOIOFactory#create(IOIOConnection)}, possibly after filtering based on the
|
||||
* specification's properties.
|
||||
*
|
||||
* @return A collection of specifications.
|
||||
*/
|
||||
public static Collection<IOIOConnectionFactory> getConnectionFactories() {
|
||||
Collection<IOIOConnectionFactory> result = new LinkedList<IOIOConnectionFactory>();
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
bootstrap.getFactories(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* For advanced usage only! Used for special runtime handling of bootstrap
|
||||
* classes.
|
||||
*
|
||||
* @return The bootstraps.
|
||||
*/
|
||||
public static Collection<IOIOConnectionBootstrap> getBootstraps() {
|
||||
return bootstraps_;
|
||||
}
|
||||
|
||||
/**
|
||||
* For advanced usage only! Add platform-specific connection bootstrap
|
||||
* classes. Call before calling {@link #getConnectionFactories()}.
|
||||
*/
|
||||
public static void addBootstraps(String[] classNames) {
|
||||
for (String className : classNames) {
|
||||
addBootstrap(className);
|
||||
}
|
||||
}
|
||||
|
||||
private static final String TAG = "IOIOConnectionRegistry";
|
||||
|
||||
private static Collection<IOIOConnectionBootstrap> bootstraps_;
|
||||
|
||||
static {
|
||||
bootstraps_ = new LinkedList<IOIOConnectionBootstrap>();
|
||||
String[] classNames = new String[] { "ioio.lib.impl.SocketIOIOConnectionBootstrap" };
|
||||
addBootstraps(classNames);
|
||||
}
|
||||
|
||||
private static void addBootstrap(String className) {
|
||||
try {
|
||||
Class<? extends IOIOConnectionBootstrap> bootstrapClass = Class
|
||||
.forName(className).asSubclass(
|
||||
IOIOConnectionBootstrap.class);
|
||||
bootstraps_.add(bootstrapClass.newInstance());
|
||||
Log.d(TAG, "Successfully added bootstrap class: " + className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
Log.d(TAG, "Bootstrap class not found: " + className
|
||||
+ ". Not adding.");
|
||||
} catch (RuntimeException e) {
|
||||
Log.e(TAG,
|
||||
"Runtime exception caught while attempting to initialize accessory connection factory",
|
||||
e);
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG,
|
||||
"Exception caught while attempting to initialize accessory connection factory",
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
56
IOIOLib/src/ioio/lib/util/IOIOLooper.java
Normal file
56
IOIOLib/src/ioio/lib/util/IOIOLooper.java
Normal file
@@ -0,0 +1,56 @@
|
||||
package ioio.lib.util;
|
||||
|
||||
import ioio.lib.api.IOIO;
|
||||
import ioio.lib.api.exception.ConnectionLostException;
|
||||
|
||||
/**
|
||||
* A handler implementing interaction with a single IOIO over a single
|
||||
* connection period. The interface utilizes a basic workflow for working with a
|
||||
* IOIO instance: as soon as a connection is established, {@link #setup(IOIO)}
|
||||
* will be called. Then, the {@link #loop()} method will be called repeatedly as
|
||||
* long as the connection is alive. Last, the {@link #disconnected()} method
|
||||
* will be called upon losing the connection (as result of physical
|
||||
* disconnection, closing the application, etc). In case a IOIO with an
|
||||
* incompatible firmware is encountered, {@link #incompatible()} will be called
|
||||
* instead of {@link #setup(IOIO)}, and the IOIO instance is entirely useless,
|
||||
* until eventually {@link #disconnected()} gets called.
|
||||
*
|
||||
*/
|
||||
public interface IOIOLooper {
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to be
|
||||
* done once as soon as IOIO communication is established.
|
||||
*/
|
||||
public abstract void setup(IOIO ioio) throws ConnectionLostException,
|
||||
InterruptedException;
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to be
|
||||
* done repetitively as long as IOIO communication persists. Typically, this
|
||||
* will be the main logic of the application, processing inputs and
|
||||
* producing outputs.
|
||||
*/
|
||||
public abstract void loop() throws ConnectionLostException,
|
||||
InterruptedException;
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to be
|
||||
* done once as soon as IOIO communication is lost or closed. Typically,
|
||||
* this will include GUI changes corresponding to the change. This method
|
||||
* will only be called if setup() has been called. The ioio argument passed
|
||||
* to {@link #setup(IOIO)} must not be used from within this method - it is
|
||||
* invalid. This method should not block for long, since it may cause an
|
||||
* ANR.
|
||||
*/
|
||||
public abstract void disconnected();
|
||||
|
||||
/**
|
||||
* Subclasses should override this method for performing operations to be
|
||||
* done if an incompatible IOIO firmware is detected. The ioio argument
|
||||
* passed to {@link #setup(IOIO)} must not be used from within this method -
|
||||
* it is invalid. This method will only be called once, until a compatible
|
||||
* IOIO is connected (i.e. {@link #setup(IOIO)} gets called).
|
||||
*/
|
||||
public abstract void incompatible();
|
||||
|
||||
}
|
||||
36
IOIOLib/src/ioio/lib/util/IOIOLooperProvider.java
Normal file
36
IOIOLib/src/ioio/lib/util/IOIOLooperProvider.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package ioio.lib.util;
|
||||
|
||||
/**
|
||||
* An entity that provides {@link IOIOLooper} instances on demand, per
|
||||
* connection specifications.
|
||||
*/
|
||||
public interface IOIOLooperProvider {
|
||||
|
||||
/**
|
||||
* Subclasses should implement this method by returning an implementation of
|
||||
* {@link IOIOLooper}. The caller provide enough information to uniquely
|
||||
* identify the connection, through the parameters. <code>null</code> may be
|
||||
* returned if the client is not interested to create a thread for this
|
||||
* IOIO. This can be used in order to filter out unwanted connections, for
|
||||
* example if the application is only intended for wireless connection, any
|
||||
* wired connection attempts may be rejected, thus saving resources used for
|
||||
* listening for incoming wired connections.
|
||||
*
|
||||
* @param connectionType
|
||||
* A unique name of the connection type. Typically, the
|
||||
* fully-qualified name of the connection class used to connect
|
||||
* to the IOIO.
|
||||
* @param extra
|
||||
* A connection-type-specific object with extra information on
|
||||
* the specific connection. Should provide information that
|
||||
* enables distinguishing between different IOIO instances using
|
||||
* the same connection class. For example, a Bluetooth connection
|
||||
* type, might have the remote IOIO's Bluetooth name as extra.
|
||||
*
|
||||
* @return An implementation of {@link IOIOLooper}, or <code>null</code> to
|
||||
* skip.
|
||||
*/
|
||||
public abstract IOIOLooper createIOIOLooper(String connectionType,
|
||||
Object extra);
|
||||
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package ioio.lib.util;
|
||||
|
||||
import ioio.lib.api.IOIOFactory;
|
||||
import ioio.lib.impl.SocketIOIOConnection;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class SocketIOIOConnectionDiscovery implements IOIOConnectionDiscovery {
|
||||
|
||||
@Override
|
||||
public void getSpecs(Collection<IOIOConnectionSpec> result) {
|
||||
result.add(new IOIOConnectionSpec(SocketIOIOConnection.class.getName(),
|
||||
new Object[] { new Integer(IOIOFactory.IOIO_PORT) }));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
package ioio.lib.util.android;
|
||||
|
||||
import android.content.ContextWrapper;
|
||||
|
||||
|
||||
public interface ContextWrapperDependent {
|
||||
public void onCreate(ContextWrapper wrapper);
|
||||
public void onDestroy();
|
||||
public void open();
|
||||
public void reopen();
|
||||
public void close();
|
||||
}
|
||||
148
IOIOLib/src/ioio/lib/util/android/IOIOActivity.java
Normal file
148
IOIOLib/src/ioio/lib/util/android/IOIOActivity.java
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
package ioio.lib.util.android;
|
||||
|
||||
import ioio.lib.impl.SocketIOIOConnection;
|
||||
import ioio.lib.util.IOIOLooper;
|
||||
import ioio.lib.util.IOIOLooperProvider;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* A convenience class for easy creation of IOIO-based activities.
|
||||
*
|
||||
* It is used by creating a concrete {@link Activity} in your application, which
|
||||
* extends this class. This class then takes care of proper creation and
|
||||
* abortion of the IOIO connection and of a dedicated thread for IOIO
|
||||
* communication.
|
||||
* <p>
|
||||
* In the basic usage the client should extend this class and implement
|
||||
* {@link #createIOIOLooper()}, which should return an implementation of the
|
||||
* {@link IOIOLooper} interface. In this implementation, the client implements
|
||||
* the {@link IOIOLooper#setup(ioio.lib.api.IOIO)} method, which gets called as
|
||||
* soon as communication with the IOIO is established, and the
|
||||
* {@link IOIOLooper#loop()} method, which gets called repetitively as long as
|
||||
* the IOIO is connected.
|
||||
* <p>
|
||||
* In addition, the {@link IOIOLooper#disconnected()} method may be overridden
|
||||
* in order to execute logic as soon as a disconnection occurs for whichever
|
||||
* reason. The {@link IOIOLooper#incompatible()} method may be overridden in
|
||||
* order to take action in case where a IOIO whose firmware is incompatible with
|
||||
* the IOIOLib version that application is built with.
|
||||
* <p>
|
||||
* In a more advanced use case, more than one IOIO is available. In this case, a
|
||||
* thread will be created for each IOIO, whose semantics are as defined above.
|
||||
* If the client needs to be able to distinguish between them, it is possible to
|
||||
* override {@link #createIOIOLooper(String, Object)} instead of
|
||||
* {@link #createIOIOLooper()}. The first argument provided will contain the
|
||||
* connection class name, such as ioio.lib.impl.SocketIOIOConnection for a
|
||||
* connection established over a TCP socket (which is used over ADB). The second
|
||||
* argument will contain information specific to the connection type. For
|
||||
* example, in the case of {@link SocketIOIOConnection}, the second argument
|
||||
* will contain an {@link Integer} representing the local port number.
|
||||
*/
|
||||
public abstract class IOIOActivity extends Activity implements
|
||||
IOIOLooperProvider {
|
||||
private final IOIOAndroidApplicationHelper helper_ = new IOIOAndroidApplicationHelper(
|
||||
this, this);
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onCreate() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
helper_.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onDestroy() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
helper_.destroy();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onStart() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
helper_.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onStop() if overloaded.
|
||||
* It takes care of disconnecting from the IOIO.
|
||||
*/
|
||||
@Override
|
||||
protected void onStop() {
|
||||
helper_.stop();
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
|
||||
helper_.restart();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must either implement this method or its other overload by
|
||||
* returning an implementation of {@link IOIOLooper}. A dedicated thread
|
||||
* will be created for each available IOIO, from which the
|
||||
* {@link IOIOLooper}'s methods will be invoked. <code>null</code> may be
|
||||
* returned if the client is not interested to create a thread for this
|
||||
* IOIO. In multi-IOIO scenarios, where you want to identify which IOIO the
|
||||
* thread is for, consider overriding
|
||||
* {@link #createIOIOLooper(String, Object)} instead.
|
||||
*
|
||||
* @return An implementation of {@link IOIOLooper}, or <code>null</code> to
|
||||
* skip.
|
||||
*/
|
||||
protected IOIOLooper createIOIOLooper() {
|
||||
throw new RuntimeException(
|
||||
"Client must override one of the createIOIOLooper overloads!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOIOLooper createIOIOLooper(String connectionType, Object extra) {
|
||||
return createIOIOLooper();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package ioio.lib.util.android;
|
||||
|
||||
import ioio.lib.spi.IOIOConnectionBootstrap;
|
||||
import ioio.lib.util.IOIOApplicationHelper;
|
||||
import ioio.lib.util.IOIOConnectionRegistry;
|
||||
import ioio.lib.util.IOIOLooperProvider;
|
||||
|
||||
import android.content.ContextWrapper;
|
||||
|
||||
public class IOIOAndroidApplicationHelper extends IOIOApplicationHelper {
|
||||
private final ContextWrapper contextWrapper_;
|
||||
|
||||
public IOIOAndroidApplicationHelper(ContextWrapper wrapper,
|
||||
IOIOLooperProvider provider) {
|
||||
super(provider);
|
||||
contextWrapper_ = wrapper;
|
||||
}
|
||||
|
||||
static {
|
||||
IOIOConnectionRegistry
|
||||
.addBootstraps(new String[] {
|
||||
"ioio.lib.android.accessory.AccessoryConnectionBootstrap",
|
||||
"ioio.lib.android.bluetooth.BluetoothIOIOConnectionBootstrap" });
|
||||
}
|
||||
|
||||
public void create() {
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).onCreate(contextWrapper_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).onDestroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).open();
|
||||
}
|
||||
}
|
||||
super.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
super.stop();
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void restart() {
|
||||
for (IOIOConnectionBootstrap bootstrap : bootstraps_) {
|
||||
if (bootstrap instanceof ContextWrapperDependent) {
|
||||
((ContextWrapperDependent) bootstrap).reopen();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
149
IOIOLib/src/ioio/lib/util/android/IOIOService.java
Normal file
149
IOIOLib/src/ioio/lib/util/android/IOIOService.java
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright 2011 Ytai Ben-Tsvi. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARSHAN POURSOHI OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied.
|
||||
*/
|
||||
|
||||
package ioio.lib.util.android;
|
||||
|
||||
import ioio.lib.impl.SocketIOIOConnection;
|
||||
import ioio.lib.util.IOIOLooper;
|
||||
import ioio.lib.util.IOIOLooperProvider;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* A convenience class for easy creation of IOIO-based services.
|
||||
*
|
||||
* It is used by creating a concrete {@link Service} in your application, which
|
||||
* extends this class. This class then takes care of proper creation and
|
||||
* abortion of the IOIO connection and of a dedicated thread for IOIO
|
||||
* communication.
|
||||
* <p>
|
||||
* In the basic usage the client should extend this class and implement
|
||||
* {@link #createIOIOLooper()}, which should return an implementation of the
|
||||
* {@link IOIOLooper} interface. In this implementation, the client implements
|
||||
* the {@link IOIOLooper#setup(ioio.lib.api.IOIO)} method, which gets called as
|
||||
* soon as communication with the IOIO is established, and the
|
||||
* {@link IOIOLooper#loop()} method, which gets called repetitively as long as
|
||||
* the IOIO is connected.
|
||||
* <p>
|
||||
* In addition, the {@link IOIOLooper#disconnected()} method may be overridden
|
||||
* in order to execute logic as soon as a disconnection occurs for whichever
|
||||
* reason. The {@link IOIOLooper#incompatible()} method may be overridden in
|
||||
* order to take action in case where a IOIO whose firmware is incompatible with
|
||||
* the IOIOLib version that application is built with.
|
||||
* <p>
|
||||
* In a more advanced use case, more than one IOIO is available. In this case, a
|
||||
* thread will be created for each IOIO, whose semantics are as defined above.
|
||||
* If the client needs to be able to distinguish between them, it is possible to
|
||||
* override {@link #createIOIOLooper(String, Object)} instead of
|
||||
* {@link #createIOIOLooper()}. The first argument provided will contain the
|
||||
* connection class name, such as ioio.lib.impl.SocketIOIOConnection for a
|
||||
* connection established over a TCP socket (which is used over ADB). The second
|
||||
* argument will contain information specific to the connection type. For
|
||||
* example, in the case of {@link SocketIOIOConnection}, the second argument
|
||||
* will contain an {@link Integer} representing the local port number.
|
||||
*/
|
||||
public abstract class IOIOService extends Service implements
|
||||
IOIOLooperProvider {
|
||||
private final IOIOAndroidApplicationHelper helper_ = new IOIOAndroidApplicationHelper(
|
||||
this, this);
|
||||
private boolean started_ = false;
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onCreate() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
helper_.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onDestroy() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
stop();
|
||||
helper_.destroy();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method from their own onStart() if
|
||||
* overloaded. It takes care of connecting with the IOIO.
|
||||
*/
|
||||
@Override
|
||||
public void onStart(Intent intent, int startId) {
|
||||
super.onStart(intent, startId);
|
||||
if (!started_) {
|
||||
helper_.start();
|
||||
started_ = true;
|
||||
} else {
|
||||
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
|
||||
helper_.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses should call this method if they wish to disconnect from the
|
||||
* IOIO(s) until the next onStart().
|
||||
*/
|
||||
protected void stop() {
|
||||
if (started_) {
|
||||
helper_.stop();
|
||||
started_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must either implement this method or its other overload by
|
||||
* returning an implementation of {@link IOIOLooper}. A dedicated thread
|
||||
* will be created for each available IOIO, from which the
|
||||
* {@link IOIOLooper}'s methods will be invoked. <code>null</code> may be
|
||||
* returned if the client is not interested to create a thread for this
|
||||
* IOIO. In multi-IOIO scenarios, where you want to identify which IOIO the
|
||||
* thread is for, consider overriding
|
||||
* {@link #createIOIOLooper(String, Object)} instead.
|
||||
*
|
||||
* @return An implementation of {@link IOIOLooper}, or <code>null</code> to
|
||||
* skip.
|
||||
*/
|
||||
protected IOIOLooper createIOIOLooper() {
|
||||
throw new RuntimeException(
|
||||
"Client must override one of the createIOIOLooper overloads!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOIOLooper createIOIOLooper(String connectionType, Object extra) {
|
||||
return createIOIOLooper();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user