Updated ioio library to the lastest code

Orignal code pulled from git://github.com/ytai/ioio.git

Please note that built in Android Open Accessory support is included in
Android 3.1 (API Level 12). If you want to use Android 2.3.4 (API Level
10) amd higher, you will need to use the Add-On Support Library.
This commit is contained in:
2012-12-11 11:06:07 -05:00
parent b8a55682d4
commit efb63070a2
41 changed files with 3235 additions and 3230 deletions

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@@ -9,4 +9,4 @@
android.library=true
# Project target.
target=android-15
target=android-17

View File

@@ -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(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;
}
/*
* 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;
}

View File

@@ -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(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;
}
/*
* 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

View File

@@ -1,107 +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.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();
}
/*
* 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();
}

View 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 };
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -32,6 +32,7 @@ import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.impl.IOIOProtocol.IncomingHandler;
import java.util.HashSet;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -395,10 +396,11 @@ class IncomingState implements IncomingHandler {
}
@Override
public void handleReportAnalogInStatus(int pins[], int values[]) {
public void handleReportAnalogInStatus(List<Integer> pins,
List<Integer> values) {
// logMethod("handleReportAnalogInStatus", pins, values);
for (int i = 0; i < pins.length; ++i) {
intputPinStates_[pins[i]].setValue(values[i]);
for (int i = 0; i < pins.size(); ++i) {
intputPinStates_[pins.get(i)].setValue(values.get(i));
}
}

View File

@@ -137,7 +137,7 @@ class TwiMasterImpl extends AbstractResource implements TwiMaster,
synchronized (result) {
result.ready_ = true;
result.success_ = (size != 0xFF);
if (result.success_) {
if (result.success_ && size > 0) {
System.arraycopy(data, 0, result.data_, 0, size);
}
result.notify();

View File

@@ -1,6 +1,6 @@
package ioio.lib.spi;
public class NoRuntimeSupportException extends Exception {
public class NoRuntimeSupportException extends RuntimeException {
private static final long serialVersionUID = -6559208663699429514L;
public NoRuntimeSupportException(String desc) {

View File

@@ -1,369 +1,369 @@
/*
* 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();
}
}
}
/*
* 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();
}
}
}

View File

@@ -1,133 +1,131 @@
/*
* 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);
}
}
}
/*
* 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 ioio.lib.spi.NoRuntimeSupportException;
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 (NoRuntimeSupportException e) {
Log.d(TAG, "No runtime support for: " + className + ". Not adding.");
} catch (Throwable e) {
Log.e(TAG,
"Exception caught while attempting to initialize accessory connection factory",
e);
}
}
}

View File

@@ -1,56 +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();
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();
}