diff --git a/IOIOLib/.classpath b/IOIOLib/.classpath
index a4763d1..3f9691c 100755
--- a/IOIOLib/.classpath
+++ b/IOIOLib/.classpath
@@ -1,8 +1,8 @@
- * A digital input pin can be used to read logic-level signals. DigitalInput - * instances are obtained by calling {@link IOIO#openDigitalInput(DigitalInput.Spec)}. - *
- * 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)}. - *
- * 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. - *
- * Typical usage: - * - *
- * 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. - *- */ -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. + *
+ * A digital input pin can be used to read logic-level signals. DigitalInput + * instances are obtained by calling {@link IOIO#openDigitalInput(DigitalInput.Spec)}. + *
+ * 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)}. + *
+ * 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. + *
+ * Typical usage: + * + *
+ * 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. + *+ */ +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; +} diff --git a/IOIOLib/src/ioio/lib/api/DigitalOutput.java b/IOIOLib/src/ioio/lib/api/DigitalOutput.java index 6d6a2a5..ccb8824 100644 --- a/IOIOLib/src/ioio/lib/api/DigitalOutput.java +++ b/IOIOLib/src/ioio/lib/api/DigitalOutput.java @@ -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. - *
- * A digital input pin can be used to generate logic-level signals. - * DigitalOutput instances are obtained by calling - * {@link IOIO#openDigitalOutput(DigitalOutput.Spec, boolean)}. - *
- * The value of the pin is set by calling {@link #write(boolean)}. - *
- * 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. - *
- * Typical usage: - * - *
- * 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. - *- */ -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. + *
+ * A digital input pin can be used to generate logic-level signals. + * DigitalOutput instances are obtained by calling + * {@link IOIO#openDigitalOutput(DigitalOutput.Spec, boolean)}. + *
+ * The value of the pin is set by calling {@link #write(boolean)}. + *
+ * 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. + *
+ * Typical usage: + * + *
+ * 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. + *+ */ +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; +} diff --git a/IOIOLib/src/ioio/lib/api/IOIO.java b/IOIOLib/src/ioio/lib/api/IOIO.java index 627e2e7..2f2de6c 100644 --- a/IOIOLib/src/ioio/lib/api/IOIO.java +++ b/IOIOLib/src/ioio/lib/api/IOIO.java @@ -1,696 +1,696 @@ -/* - * 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.PulseInput.PulseMode; -import ioio.lib.api.TwiMaster.Rate; -import ioio.lib.api.Uart.Parity; -import ioio.lib.api.Uart.StopBits; -import ioio.lib.api.exception.ConnectionLostException; -import ioio.lib.api.exception.IncompatibilityException; -import ioio.lib.api.exception.OutOfResourceException; - -import java.io.Closeable; - -/** - * This interface provides control over all the IOIO board functions. - *
- * An instance of this interface is typically obtained by using the - * {@link IOIOFactory} class. Initially, a connection should be established, by - * calling {@link #waitForConnect()}. This method will block until the board is - * connected an a connection has been established. - *
- * During the connection process, this library verifies that the IOIO firmware - * is compatible with the required version. If not, {@link #waitForConnect()} - * will throw a {@link IncompatibilityException}, putting the {@link IOIO} - * instance in a "zombie" state: nothing could be done with it except calling - * {@link #disconnect()}, or waiting for the physical connection to drop via - * {@link #waitForDisconnect()}. - *
- * As soon as a connection is established, the IOIO can be used, typically, by - * calling the openXXX() functions to obtain additional interfaces for - * controlling specific function of the board. - *
- * Whenever a connection is lost as a result of physically disconnecting the - * board or as a result of calling {@link #disconnect()}, this instance and all - * the interfaces obtained from it become invalid, and will throw a - * {@link ConnectionLostException} on every operation. Once the connection is - * lost, those instances cannot be recycled, but rather it is required to create - * new ones and wait for a connection again. - *
- * Initially all pins are tri-stated (floating), and all functions are disabled. - * Whenever a connection is lost or dropped, the board will immediately return - * to the this initial state. - *
- * Typical usage: - * - *
- * IOIO ioio = IOIOFactory.create();
- * try {
- * ioio.waitForConnect();
- * DigitalOutput out = ioio.openDigitalOutput(10);
- * out.write(true);
- * ...
- * } catch (ConnectionLostException e) {
- * } catch (Exception e) {
- * ioio.disconnect();
- * } finally {
- * ioio.waitForDisconnect();
- * }
- *
- *
- * @see IOIOFactory#create()
- */
-public interface IOIO {
- /** An invalid pin number. */
- public static final int INVALID_PIN = -1;
- /** The pin number used to designate the on-board 'stat' LED. */
- public static final int LED_PIN = 0;
-
- /**
- * A versioned component in the system.
- *
- * @see IOIO#getImplVersion(VersionType)
- */
- public enum VersionType {
- /** Hardware version. */
- HARDWARE_VER,
- /** Bootloader version. */
- BOOTLOADER_VER,
- /** Application layer firmware version. */
- APP_FIRMWARE_VER,
- /** IOIOLib version. */
- IOIOLIB_VER
- }
-
- /**
- * A state of a IOIO instance.
- */
- public enum State {
- /** Connection not yet established. */
- INIT,
- /** Connected. */
- CONNECTED,
- /** Connection established, incompatible firmware detected. */
- INCOMPATIBLE,
- /** Disconnected. Instance is useless. */
- DEAD
- }
-
- /**
- * Establishes connection with the IOIO board.
- * - * This method is blocking until connection is established. This method can - * be aborted by calling {@link #disconnect()}. In this case, it will throw - * a {@link ConnectionLostException}. - * - * @throws ConnectionLostException - * An error occurred during connection or disconnect() has been - * called during connection. The instance state is disconnected. - * @throws IncompatibilityException - * An incompatible board firmware of hardware has been detected. - * The instance state is disconnected. - * @see #disconnect() - * @see #waitForDisconnect() - */ - public void waitForConnect() throws ConnectionLostException, - IncompatibilityException; - - /** - * Closes the connection to the board, or aborts a connection process - * started with waitForConnect(). - *
- * Once this method is called, this IOIO instance and all the instances - * obtain from it become invalid and will throw an exception on every - * operation. - *
- * This method is asynchronous, i.e. it returns immediately, but it is not - * guaranteed that all connection-related resources has already been freed - * and can be reused upon return. In cases when this is important, client - * can call {@link #waitForDisconnect()}, which will block until all - * resources have been freed. - */ - public void disconnect(); - - /** - * Blocks until IOIO has been disconnected and all connection-related - * resources have been freed, so that a new connection can be attempted. - * - * @throws InterruptedException - * When interrupt() has been called on this thread. This might - * mean that an immediate attempt to create and connect a new - * IOIO object might fail for resource contention. - * @see #disconnect() - * @see #waitForConnect() - */ - public void waitForDisconnect() throws InterruptedException; - - /** - * Gets the connections state. - * - * @return The connection state. - */ - public State getState(); - - /** - * Resets the entire state (returning to initial state), without dropping - * the connection. - *
- * It is equivalent to calling {@link Closeable#close()} on every interface - * obtained from this instance. A connection must have been established - * prior to calling this method, by invoking {@link #waitForConnect()}. - * - * @throws ConnectionLostException - * Connection was lost before or during the execution of this - * method. - * @see #hardReset() - */ - public void softReset() throws ConnectionLostException; - - /** - * Equivalent to disconnecting and reconnecting the board power supply. - *
- * The connection will be dropped and not reestablished. Full boot sequence - * will take place, so firmware upgrades can be performed. A connection must - * have been established prior to calling this method, by invoking - * {@link #waitForConnect()}. - * - * @throws ConnectionLostException - * Connection was lost before or during the execution of this - * method. - * @see #softReset() - */ - public void hardReset() throws ConnectionLostException; - - /** - * Query the implementation version of the system's components. The - * implementation version uniquely identifies a hardware revision or a - * software build. Returned version IDs are always 8-character long, - * according to the IOIO versioning system: first 4 characters are the - * version authority and last 4 characters are the revision. - * - * @param v - * The component whose version we query. - * @return An 8-character implementation version ID. - * @throws ConnectionLostException - * Connection was lost before or during the execution of this - * method. - */ - public String getImplVersion(VersionType v) throws ConnectionLostException; - - /** - * Open a pin for digital input. - *
- * A digital input pin can be used to read logic-level signals. The pin will - * operate in this mode until close() is invoked on the returned interface. - * It is illegal to open a pin that has already been opened and has not been - * closed. A connection must have been established prior to calling this - * method, by invoking {@link #waitForConnect()}. - * - * @param spec - * Pin specification, consisting of the pin number, as labeled on - * the board, and the mode, which determines whether the pin will - * be floating, pull-up or pull-down. See - * {@link DigitalInput.Spec.Mode} for more information. - * @return Interface of the assigned pin. - * @throws ConnectionLostException - * Connection was lost before or during the execution of this - * method. - * @see DigitalInput - */ - public DigitalInput openDigitalInput(DigitalInput.Spec spec) - throws ConnectionLostException; - - /** - * Shorthand for openDigitalInput(new DigitalInput.Spec(pin)). - * - * @see #openDigitalInput(ioio.lib.api.DigitalInput.Spec) - */ - public DigitalInput openDigitalInput(int pin) - throws ConnectionLostException; - - /** - * Shorthand for openDigitalInput(new DigitalInput.Spec(pin, mode)). - * - * @see #openDigitalInput(ioio.lib.api.DigitalInput.Spec) - */ - public DigitalInput openDigitalInput(int pin, DigitalInput.Spec.Mode mode) - throws ConnectionLostException; - - /** - * Open a pin for digital output. - *
- * A digital output pin can be used to generate logic-level signals. The pin - * will operate in this mode until close() is invoked on the returned - * interface. It is illegal to open a pin that has already been opened and - * has not been closed. A connection must have been established prior to - * calling this method, by invoking {@link #waitForConnect()}. - * - * @param spec - * Pin specification, consisting of the pin number, as labeled on - * the board, and the mode, which determines whether the pin will - * be normal or open-drain. See {@link DigitalOutput.Spec.Mode} - * for more information. - * @param startValue - * The initial logic level this pin will generate as soon at it - * is open. - * @return Interface of the assigned pin. - * @throws ConnectionLostException - * Connection was lost before or during the execution of this - * method. - * @see DigitalOutput - */ - public DigitalOutput openDigitalOutput(DigitalOutput.Spec spec, - boolean startValue) throws ConnectionLostException; - - /** - * Shorthand for openDigitalOutput(new DigitalOutput.Spec(pin, mode), - * startValue). - * - * @see #openDigitalOutput(ioio.lib.api.DigitalOutput.Spec, boolean) - */ - public DigitalOutput openDigitalOutput(int pin, - DigitalOutput.Spec.Mode mode, boolean startValue) - throws ConnectionLostException; - - /** - * Shorthand for openDigitalOutput(new DigitalOutput.Spec(pin), startValue). - * Pin mode will be "normal" (as opposed to "open-drain". - * - * @see #openDigitalOutput(ioio.lib.api.DigitalOutput.Spec, boolean) - */ - public DigitalOutput openDigitalOutput(int pin, boolean startValue) - throws ConnectionLostException; - - /** - * Shorthand for openDigitalOutput(new DigitalOutput.Spec(pin), false). Pin - * mode will be "normal" (as opposed to "open-drain". - * - * @see #openDigitalOutput(ioio.lib.api.DigitalOutput.Spec, boolean) - */ - public DigitalOutput openDigitalOutput(int pin) - throws ConnectionLostException; - - /** - * Open a pin for analog input. - *
- * An analog input pin can be used to measure voltage. Note that not every - * pin can be used as an analog input. See board documentation for the legal - * pins and permitted voltage range. - *
- * The pin will operate in this mode until close() is invoked on the - * returned interface. It is illegal to open a pin that has already been - * opened and has not been closed. A connection must have been established - * prior to calling this method, by invoking {@link #waitForConnect()}. - * - * @param pin - * Pin number, as labeled on the board. - * @return Interface of the assigned pin. - * @throws ConnectionLostException - * Connection was lost before or during the execution of this - * method. - * @see AnalogInput - */ - public AnalogInput openAnalogInput(int pin) throws ConnectionLostException; - - /** - * Open a pin for PWM (Pulse-Width Modulation) output. - *
- * A PWM pin produces a logic-level PWM signal. These signals are typically - * used for simulating analog outputs for controlling the intensity of LEDs, - * the rotation speed of motors, etc. They are also frequently used for - * controlling hobby servo motors. - *
- * Note that not every pin can be used as PWM output. In addition, the total - * number of concurrent PWM modules in use is limited. See board - * documentation for the legal pins and limit on concurrent usage. - *
- * The pin will operate in this mode until close() is invoked on the - * returned interface. It is illegal to open a pin that has already been - * opened and has not been closed. A connection must have been established - * prior to calling this method, by invoking {@link #waitForConnect()}. - * - * @param spec - * Pin specification, consisting of the pin number, as labeled on - * the board, and the mode, which determines whether the pin will - * be normal or open-drain. See {@link DigitalOutput.Spec.Mode} - * for more information. - * @param freqHz - * PWM frequency, in Hertz. - * @return Interface of the assigned pin. - * @throws ConnectionLostException - * Connection was lost before or during the execution of this - * method. - * @throws OutOfResourceException - * This is a runtime exception, so it is not necessary to catch - * it if the client guarantees that the total number of - * concurrent PWM resources is not exceeded. - * @see PwmOutput - */ - public PwmOutput openPwmOutput(DigitalOutput.Spec spec, int freqHz) - throws ConnectionLostException; - - /** - * Shorthand for openPwmOutput(new DigitalOutput.Spec(pin), freqHz). - * - * @see #openPwmOutput(ioio.lib.api.DigitalOutput.Spec, int) - */ - public PwmOutput openPwmOutput(int pin, int freqHz) - throws ConnectionLostException; - - /** - * Open a pin for pulse input. - *
- * The pulse input module is quite flexible. It enables several kinds of - * timing measurements on a digital signal: pulse width measurement - * (positive or negative pulse), and frequency of a periodic signal. - *
- * Note that not every pin can be used as pulse input. In addition, the - * total number of concurrent pulse input modules in use is limited. See - * board documentation for the legal pins and limit on concurrent usage. - *
- * The pin will operate in this mode until close() is invoked on the - * returned interface. It is illegal to open a pin that has already been - * opened and has not been closed. A connection must have been established - * prior to calling this method, by invoking {@link #waitForConnect()}. - * - * @param spec - * Pin specification, consisting of the pin number, as labeled on - * the board, and the mode, which determines whether the pin will - * be floating, pull-up or pull-down. See - * {@link DigitalInput.Spec.Mode} for more information. - * @param rate - * The clock rate to use for timing the signal. A faster clock - * rate will result in better precision but will only be able to - * measure narrow pulses / high frequencies. - * @param mode - * The mode in which to operate. Determines whether the module - * will measure pulse durations or frequency. - * @param doublePrecision - * Whether to open a double-precision pulse input module. Double- - * precision modules enable reading of much longer pulses and - * lower frequencies with high accuracy than single precision - * modules. However, their number is limited, so when possible, - * and if the resources are all needed, use single-precision. For - * more details on the exact spec of single- vs. double- - * precision, see {@link PulseInput}. - * @return An instance of the {@link PulseInput}, which can be used to - * obtain the data. - * @throws ConnectionLostException - * Connection was lost before or during the execution of this - * method. - * @throws OutOfResourceException - * This is a runtime exception, so it is not necessary to catch - * it if the client guarantees that the total number of - * concurrent PWM resources is not exceeded. - * @see PulseInput - */ - public PulseInput openPulseInput(DigitalInput.Spec spec, - PulseInput.ClockRate rate, PulseInput.PulseMode mode, - boolean doublePrecision) throws ConnectionLostException; - - /** - * Shorthand for openPulseInput(new DigitalInput.Spec(pin), rate, mode, - * true), i.e. opens a double-precision, 16MHz pulse input on the given pin - * with the given mode. - * - * @see #openPulseInput(ioio.lib.api.DigitalInput.Spec, - * ioio.lib.api.PulseInput.ClockRate, - * ioio.lib.api.PulseInput.PulseMode, boolean) - */ - public PulseInput openPulseInput(int pin, PulseMode mode) - throws ConnectionLostException; - - /** - * Open a UART module, enabling a bulk transfer of byte buffers. - *
- * 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. - *
- * Note that not every pin can be used for UART RX or TX. In addition, the - * total number of concurrent UART modules in use is limited. See board - * documentation for the legal pins and limit on concurrent usage. - *
- * The UART module will operate, and the pins will work in their respective - * modes until close() is invoked on the returned interface. It is illegal - * to use pins that have already been opened and has not been closed. A - * connection must have been established prior to calling this method, by - * invoking {@link #waitForConnect()}. - * - * @param rx - * Pin specification for the RX pin, consisting of the pin - * number, as labeled on the board, and the mode, which - * determines whether the pin will be floating, pull-up or - * pull-down. See {@link DigitalInput.Spec.Mode} for more - * information. null can be passed to designate that we do not - * want RX input to this module. - * @param tx - * Pin specification for the TX pin, consisting of the pin - * number, as labeled on the board, and the mode, which - * determines whether the pin will be normal or open-drain. See - * {@link DigitalOutput.Spec.Mode} for more information. null can - * be passed to designate that we do not want TX output to this - * module. - * @param baud - * The clock frequency of the UART module in Hz. - * @param parity - * The parity mode, as in {@link Parity}. - * @param stopbits - * Number of stop bits, as in {@link StopBits}. - * @return Interface of the assigned module. - * @throws ConnectionLostException - * Connection was lost before or during the execution of this - * method. - * @throws OutOfResourceException - * This is a runtime exception, so it is not necessary to catch - * it if the client guarantees that the total number of - * concurrent UART resources is not exceeded. - * @see Uart - */ - public Uart openUart(DigitalInput.Spec rx, DigitalOutput.Spec tx, int baud, - Parity parity, StopBits stopbits) throws ConnectionLostException; - - /** - * Shorthand for - * {@link #openUart(DigitalInput.Spec, DigitalOutput.Spec, int, Uart.Parity, Uart.StopBits)} - * , where the input pins use their default specs. {@link #INVALID_PIN} can - * be used on either pin if a TX- or RX-only UART is needed. - * - * @see #openUart(DigitalInput.Spec, DigitalOutput.Spec, int, Uart.Parity, - * Uart.StopBits) - */ - public Uart openUart(int rx, int tx, int baud, Parity parity, - StopBits stopbits) throws ConnectionLostException; - - /** - * Open a SPI master module, enabling communication with multiple - * SPI-enabled slave modules. - *
- * SPI is a common hardware communication protocol, enabling full-duplex, - * synchronous point-to-multi-point data transfer. It requires MOSI, MISO - * and CLK lines shared by all nodes, as well as a SS line per slave, - * connected between this slave and a respective pin on the master. The MISO - * line should operate in pull-up mode, using either the internal pull-up or - * an external resistor. - *
- * Note that not every pin can be used for SPI MISO, MOSI or CLK. In - * addition, the total number of concurrent SPI modules in use is limited. - * See board documentation for the legal pins and limit on concurrent usage. - *
- * The SPI module will operate, and the pins will work in their respective - * modes until close() is invoked on the returned interface. It is illegal - * to use pins that have already been opened and has not been closed. A - * connection must have been established prior to calling this method, by - * invoking {@link #waitForConnect()}. - * - * @param miso - * Pin specification for the MISO (Master In Slave Out) pin, - * consisting of the pin number, as labeled on the board, and the - * mode, which determines whether the pin will be floating, - * pull-up or pull-down. See {@link DigitalInput.Spec.Mode} for - * more information. - * @param mosi - * Pin specification for the MOSI (Master Out Slave In) pin, - * consisting of the pin number, as labeled on the board, and the - * mode, which determines whether the pin will be normal or - * open-drain. See {@link DigitalOutput.Spec.Mode} for more - * information. - * @param clk - * Pin specification for the CLK pin, consisting of the pin - * number, as labeled on the board, and the mode, which - * determines whether the pin will be normal or open-drain. See - * {@link DigitalOutput.Spec.Mode} for more information. - * @param slaveSelect - * An array of pin specifications for each of the slaves' SS - * (Slave Select) pin. The index of this array designates the - * slave index, used later to refer to this slave. The spec is - * consisting of the pin number, as labeled on the board, and the - * mode, which determines whether the pin will be normal or - * open-drain. See {@link DigitalOutput.Spec.Mode} for more - * information. - * @param config - * The configuration of the SPI module. See - * {@link SpiMaster.Config} for details. - * @return Interface of the assigned module. - * @throws ConnectionLostException - * Connection was lost before or during the execution of this - * method. - * @throws OutOfResourceException - * This is a runtime exception, so it is not necessary to catch - * it if the client guarantees that the total number of - * concurrent SPI resources is not exceeded. - * @see SpiMaster - */ - public SpiMaster openSpiMaster(DigitalInput.Spec miso, - DigitalOutput.Spec mosi, DigitalOutput.Spec clk, - DigitalOutput.Spec[] slaveSelect, SpiMaster.Config config) - throws ConnectionLostException; - - /** - * Shorthand for - * {@link #openSpiMaster(ioio.lib.api.DigitalInput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[], ioio.lib.api.SpiMaster.Config)} - * , where the pins are all open with the default modes and default - * configuration values are used. - * - * @see #openSpiMaster(ioio.lib.api.DigitalInput.Spec, - * ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, - * ioio.lib.api.DigitalOutput.Spec[], ioio.lib.api.SpiMaster.Config) - */ - public SpiMaster openSpiMaster(int miso, int mosi, int clk, - int[] slaveSelect, SpiMaster.Rate rate) - throws ConnectionLostException; - - /** - * Shorthand for - * {@link #openSpiMaster(ioio.lib.api.DigitalInput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[], ioio.lib.api.SpiMaster.Config)} - * , where the MISO pins is opened with pull up, and the other pins are open - * with the default modes and default configuration values are used. In this - * version, a single slave is used. - * - * @see #openSpiMaster(ioio.lib.api.DigitalInput.Spec, - * ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, - * ioio.lib.api.DigitalOutput.Spec[], ioio.lib.api.SpiMaster.Config) - */ - public SpiMaster openSpiMaster(int miso, int mosi, int clk, - int slaveSelect, SpiMaster.Rate rate) - throws ConnectionLostException; - - /** - * Open a TWI (Two-Wire Interface, such as I2C/SMBus) master module, - * enabling communication with multiple TWI-enabled slave modules. - *
- * TWI is a common hardware communication protocol, enabling half-duplex, - * synchronous point-to-multi-point data transfer. It requires a physical - * connection of two lines (SDA, SCL) shared by all the bus nodes, where the - * SDA is open-drain and externally pulled-up. - *
- * Note that there is a fixed number of TWI modules, and the pins they use - * are static. Client has to make sure these pins are not already opened - * before calling this method. See board documentation for the number of - * modules and the respective pins they use. - *
- * The TWI module will operate, and the pins will work in their respective - * modes until close() is invoked on the returned interface. It is illegal - * to use pins that have already been opened and has not been closed. A - * connection must have been established prior to calling this method, by - * invoking {@link #waitForConnect()}. - * - * @param twiNum - * The TWI module index to use. Will also determine the pins - * used. - * @param rate - * The clock rate. Can be 100KHz / 400KHz / 1MHz. - * @param smbus - * When true, will use SMBus voltage levels. When false, I2C - * voltage levels. - * @return Interface of the assigned module. - * @throws ConnectionLostException - * Connection was lost before or during the execution of this - * method. - * @see TwiMaster - */ - public TwiMaster openTwiMaster(int twiNum, Rate rate, boolean smbus) - throws ConnectionLostException; - - /** - * Open an ICSP channel, enabling Flash programming of an external PIC MCU, - * and in particular, another IOIO board. - *
- * ICSP (In-Circuit Serial Programming) is a protocol intended for - * programming of PIC MCUs. It is a serial protocol over three wires: PGC - * (clock), PGD (data) and MCLR (reset), where PGC and MCLR are controlled - * by the master and PGD is shared by the master and slave, depending on the - * transaction state. - *
- * Note that there is only one ICSP modules, and the pins it uses are - * static. Client has to make sure that the ICSP module is not already in - * use, as well as those dedicated pins. See board documentation for the - * actual pins used for ICSP. - * - * @return Interface of the ICSP module. - * @see IcspMaster - * @throws ConnectionLostException - * Connection was lost before or during the execution of this - * method. - */ - public IcspMaster openIcspMaster() throws ConnectionLostException; - - /** - * Start a batch of operations. This is strictly an optimization and will - * not change functionality: if the client knows that a sequence of several - * IOIO operations are going to be performed immediately following each - * other, a call to {@link #beginBatch()} before the sequence and - * {@link #endBatch()} after the sequence will cause the operations to be - * grouped into one transfer to the IOIO, thus reducing latency. A matching - * {@link #endBatch()} operation must always follow, or otherwise no - * operation will ever be actually executed. {@link #beginBatch()} / - * {@link #endBatch()} blocks may be nested - the transfer will occur when - * the outermost {@link #endBatch()} is invoked. Note that it is not - * guaranteed that no transfers will happen while inside a batch - it should - * be treated as a hint. Code running inside the block must be quick as it - * blocks all transfers to the IOIO, including those performed from - * other threads. - * - * @throws ConnectionLostException - * Connection was lost before or during the execution of this - * method. - */ - public void beginBatch() throws ConnectionLostException; - - /** - * End a batch of operations. For explanation, see {@link #beginBatch()}. - * - * @throws ConnectionLostException - * Connection was lost before or during the execution of this - * method. - */ - public void endBatch() throws ConnectionLostException; -} +/* + * 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.PulseInput.PulseMode; +import ioio.lib.api.TwiMaster.Rate; +import ioio.lib.api.Uart.Parity; +import ioio.lib.api.Uart.StopBits; +import ioio.lib.api.exception.ConnectionLostException; +import ioio.lib.api.exception.IncompatibilityException; +import ioio.lib.api.exception.OutOfResourceException; + +import java.io.Closeable; + +/** + * This interface provides control over all the IOIO board functions. + *
+ * An instance of this interface is typically obtained by using the + * {@link IOIOFactory} class. Initially, a connection should be established, by + * calling {@link #waitForConnect()}. This method will block until the board is + * connected an a connection has been established. + *
+ * During the connection process, this library verifies that the IOIO firmware + * is compatible with the required version. If not, {@link #waitForConnect()} + * will throw a {@link IncompatibilityException}, putting the {@link IOIO} + * instance in a "zombie" state: nothing could be done with it except calling + * {@link #disconnect()}, or waiting for the physical connection to drop via + * {@link #waitForDisconnect()}. + *
+ * As soon as a connection is established, the IOIO can be used, typically, by + * calling the openXXX() functions to obtain additional interfaces for + * controlling specific function of the board. + *
+ * Whenever a connection is lost as a result of physically disconnecting the + * board or as a result of calling {@link #disconnect()}, this instance and all + * the interfaces obtained from it become invalid, and will throw a + * {@link ConnectionLostException} on every operation. Once the connection is + * lost, those instances cannot be recycled, but rather it is required to create + * new ones and wait for a connection again. + *
+ * Initially all pins are tri-stated (floating), and all functions are disabled. + * Whenever a connection is lost or dropped, the board will immediately return + * to the this initial state. + *
+ * Typical usage: + * + *
+ * IOIO ioio = IOIOFactory.create();
+ * try {
+ * ioio.waitForConnect();
+ * DigitalOutput out = ioio.openDigitalOutput(10);
+ * out.write(true);
+ * ...
+ * } catch (ConnectionLostException e) {
+ * } catch (Exception e) {
+ * ioio.disconnect();
+ * } finally {
+ * ioio.waitForDisconnect();
+ * }
+ *
+ *
+ * @see IOIOFactory#create()
+ */
+public interface IOIO {
+ /** An invalid pin number. */
+ public static final int INVALID_PIN = -1;
+ /** The pin number used to designate the on-board 'stat' LED. */
+ public static final int LED_PIN = 0;
+
+ /**
+ * A versioned component in the system.
+ *
+ * @see IOIO#getImplVersion(VersionType)
+ */
+ public enum VersionType {
+ /** Hardware version. */
+ HARDWARE_VER,
+ /** Bootloader version. */
+ BOOTLOADER_VER,
+ /** Application layer firmware version. */
+ APP_FIRMWARE_VER,
+ /** IOIOLib version. */
+ IOIOLIB_VER
+ }
+
+ /**
+ * A state of a IOIO instance.
+ */
+ public enum State {
+ /** Connection not yet established. */
+ INIT,
+ /** Connected. */
+ CONNECTED,
+ /** Connection established, incompatible firmware detected. */
+ INCOMPATIBLE,
+ /** Disconnected. Instance is useless. */
+ DEAD
+ }
+
+ /**
+ * Establishes connection with the IOIO board.
+ * + * This method is blocking until connection is established. This method can + * be aborted by calling {@link #disconnect()}. In this case, it will throw + * a {@link ConnectionLostException}. + * + * @throws ConnectionLostException + * An error occurred during connection or disconnect() has been + * called during connection. The instance state is disconnected. + * @throws IncompatibilityException + * An incompatible board firmware of hardware has been detected. + * The instance state is disconnected. + * @see #disconnect() + * @see #waitForDisconnect() + */ + public void waitForConnect() throws ConnectionLostException, + IncompatibilityException; + + /** + * Closes the connection to the board, or aborts a connection process + * started with waitForConnect(). + *
+ * Once this method is called, this IOIO instance and all the instances + * obtain from it become invalid and will throw an exception on every + * operation. + *
+ * This method is asynchronous, i.e. it returns immediately, but it is not + * guaranteed that all connection-related resources has already been freed + * and can be reused upon return. In cases when this is important, client + * can call {@link #waitForDisconnect()}, which will block until all + * resources have been freed. + */ + public void disconnect(); + + /** + * Blocks until IOIO has been disconnected and all connection-related + * resources have been freed, so that a new connection can be attempted. + * + * @throws InterruptedException + * When interrupt() has been called on this thread. This might + * mean that an immediate attempt to create and connect a new + * IOIO object might fail for resource contention. + * @see #disconnect() + * @see #waitForConnect() + */ + public void waitForDisconnect() throws InterruptedException; + + /** + * Gets the connections state. + * + * @return The connection state. + */ + public State getState(); + + /** + * Resets the entire state (returning to initial state), without dropping + * the connection. + *
+ * It is equivalent to calling {@link Closeable#close()} on every interface + * obtained from this instance. A connection must have been established + * prior to calling this method, by invoking {@link #waitForConnect()}. + * + * @throws ConnectionLostException + * Connection was lost before or during the execution of this + * method. + * @see #hardReset() + */ + public void softReset() throws ConnectionLostException; + + /** + * Equivalent to disconnecting and reconnecting the board power supply. + *
+ * The connection will be dropped and not reestablished. Full boot sequence + * will take place, so firmware upgrades can be performed. A connection must + * have been established prior to calling this method, by invoking + * {@link #waitForConnect()}. + * + * @throws ConnectionLostException + * Connection was lost before or during the execution of this + * method. + * @see #softReset() + */ + public void hardReset() throws ConnectionLostException; + + /** + * Query the implementation version of the system's components. The + * implementation version uniquely identifies a hardware revision or a + * software build. Returned version IDs are always 8-character long, + * according to the IOIO versioning system: first 4 characters are the + * version authority and last 4 characters are the revision. + * + * @param v + * The component whose version we query. + * @return An 8-character implementation version ID. + * @throws ConnectionLostException + * Connection was lost before or during the execution of this + * method. + */ + public String getImplVersion(VersionType v) throws ConnectionLostException; + + /** + * Open a pin for digital input. + *
+ * A digital input pin can be used to read logic-level signals. The pin will + * operate in this mode until close() is invoked on the returned interface. + * It is illegal to open a pin that has already been opened and has not been + * closed. A connection must have been established prior to calling this + * method, by invoking {@link #waitForConnect()}. + * + * @param spec + * Pin specification, consisting of the pin number, as labeled on + * the board, and the mode, which determines whether the pin will + * be floating, pull-up or pull-down. See + * {@link DigitalInput.Spec.Mode} for more information. + * @return Interface of the assigned pin. + * @throws ConnectionLostException + * Connection was lost before or during the execution of this + * method. + * @see DigitalInput + */ + public DigitalInput openDigitalInput(DigitalInput.Spec spec) + throws ConnectionLostException; + + /** + * Shorthand for openDigitalInput(new DigitalInput.Spec(pin)). + * + * @see #openDigitalInput(ioio.lib.api.DigitalInput.Spec) + */ + public DigitalInput openDigitalInput(int pin) + throws ConnectionLostException; + + /** + * Shorthand for openDigitalInput(new DigitalInput.Spec(pin, mode)). + * + * @see #openDigitalInput(ioio.lib.api.DigitalInput.Spec) + */ + public DigitalInput openDigitalInput(int pin, DigitalInput.Spec.Mode mode) + throws ConnectionLostException; + + /** + * Open a pin for digital output. + *
+ * A digital output pin can be used to generate logic-level signals. The pin + * will operate in this mode until close() is invoked on the returned + * interface. It is illegal to open a pin that has already been opened and + * has not been closed. A connection must have been established prior to + * calling this method, by invoking {@link #waitForConnect()}. + * + * @param spec + * Pin specification, consisting of the pin number, as labeled on + * the board, and the mode, which determines whether the pin will + * be normal or open-drain. See {@link DigitalOutput.Spec.Mode} + * for more information. + * @param startValue + * The initial logic level this pin will generate as soon at it + * is open. + * @return Interface of the assigned pin. + * @throws ConnectionLostException + * Connection was lost before or during the execution of this + * method. + * @see DigitalOutput + */ + public DigitalOutput openDigitalOutput(DigitalOutput.Spec spec, + boolean startValue) throws ConnectionLostException; + + /** + * Shorthand for openDigitalOutput(new DigitalOutput.Spec(pin, mode), + * startValue). + * + * @see #openDigitalOutput(ioio.lib.api.DigitalOutput.Spec, boolean) + */ + public DigitalOutput openDigitalOutput(int pin, + DigitalOutput.Spec.Mode mode, boolean startValue) + throws ConnectionLostException; + + /** + * Shorthand for openDigitalOutput(new DigitalOutput.Spec(pin), startValue). + * Pin mode will be "normal" (as opposed to "open-drain". + * + * @see #openDigitalOutput(ioio.lib.api.DigitalOutput.Spec, boolean) + */ + public DigitalOutput openDigitalOutput(int pin, boolean startValue) + throws ConnectionLostException; + + /** + * Shorthand for openDigitalOutput(new DigitalOutput.Spec(pin), false). Pin + * mode will be "normal" (as opposed to "open-drain". + * + * @see #openDigitalOutput(ioio.lib.api.DigitalOutput.Spec, boolean) + */ + public DigitalOutput openDigitalOutput(int pin) + throws ConnectionLostException; + + /** + * Open a pin for analog input. + *
+ * An analog input pin can be used to measure voltage. Note that not every + * pin can be used as an analog input. See board documentation for the legal + * pins and permitted voltage range. + *
+ * The pin will operate in this mode until close() is invoked on the + * returned interface. It is illegal to open a pin that has already been + * opened and has not been closed. A connection must have been established + * prior to calling this method, by invoking {@link #waitForConnect()}. + * + * @param pin + * Pin number, as labeled on the board. + * @return Interface of the assigned pin. + * @throws ConnectionLostException + * Connection was lost before or during the execution of this + * method. + * @see AnalogInput + */ + public AnalogInput openAnalogInput(int pin) throws ConnectionLostException; + + /** + * Open a pin for PWM (Pulse-Width Modulation) output. + *
+ * A PWM pin produces a logic-level PWM signal. These signals are typically + * used for simulating analog outputs for controlling the intensity of LEDs, + * the rotation speed of motors, etc. They are also frequently used for + * controlling hobby servo motors. + *
+ * Note that not every pin can be used as PWM output. In addition, the total + * number of concurrent PWM modules in use is limited. See board + * documentation for the legal pins and limit on concurrent usage. + *
+ * The pin will operate in this mode until close() is invoked on the + * returned interface. It is illegal to open a pin that has already been + * opened and has not been closed. A connection must have been established + * prior to calling this method, by invoking {@link #waitForConnect()}. + * + * @param spec + * Pin specification, consisting of the pin number, as labeled on + * the board, and the mode, which determines whether the pin will + * be normal or open-drain. See {@link DigitalOutput.Spec.Mode} + * for more information. + * @param freqHz + * PWM frequency, in Hertz. + * @return Interface of the assigned pin. + * @throws ConnectionLostException + * Connection was lost before or during the execution of this + * method. + * @throws OutOfResourceException + * This is a runtime exception, so it is not necessary to catch + * it if the client guarantees that the total number of + * concurrent PWM resources is not exceeded. + * @see PwmOutput + */ + public PwmOutput openPwmOutput(DigitalOutput.Spec spec, int freqHz) + throws ConnectionLostException; + + /** + * Shorthand for openPwmOutput(new DigitalOutput.Spec(pin), freqHz). + * + * @see #openPwmOutput(ioio.lib.api.DigitalOutput.Spec, int) + */ + public PwmOutput openPwmOutput(int pin, int freqHz) + throws ConnectionLostException; + + /** + * Open a pin for pulse input. + *
+ * The pulse input module is quite flexible. It enables several kinds of + * timing measurements on a digital signal: pulse width measurement + * (positive or negative pulse), and frequency of a periodic signal. + *
+ * Note that not every pin can be used as pulse input. In addition, the + * total number of concurrent pulse input modules in use is limited. See + * board documentation for the legal pins and limit on concurrent usage. + *
+ * The pin will operate in this mode until close() is invoked on the + * returned interface. It is illegal to open a pin that has already been + * opened and has not been closed. A connection must have been established + * prior to calling this method, by invoking {@link #waitForConnect()}. + * + * @param spec + * Pin specification, consisting of the pin number, as labeled on + * the board, and the mode, which determines whether the pin will + * be floating, pull-up or pull-down. See + * {@link DigitalInput.Spec.Mode} for more information. + * @param rate + * The clock rate to use for timing the signal. A faster clock + * rate will result in better precision but will only be able to + * measure narrow pulses / high frequencies. + * @param mode + * The mode in which to operate. Determines whether the module + * will measure pulse durations or frequency. + * @param doublePrecision + * Whether to open a double-precision pulse input module. Double- + * precision modules enable reading of much longer pulses and + * lower frequencies with high accuracy than single precision + * modules. However, their number is limited, so when possible, + * and if the resources are all needed, use single-precision. For + * more details on the exact spec of single- vs. double- + * precision, see {@link PulseInput}. + * @return An instance of the {@link PulseInput}, which can be used to + * obtain the data. + * @throws ConnectionLostException + * Connection was lost before or during the execution of this + * method. + * @throws OutOfResourceException + * This is a runtime exception, so it is not necessary to catch + * it if the client guarantees that the total number of + * concurrent PWM resources is not exceeded. + * @see PulseInput + */ + public PulseInput openPulseInput(DigitalInput.Spec spec, + PulseInput.ClockRate rate, PulseInput.PulseMode mode, + boolean doublePrecision) throws ConnectionLostException; + + /** + * Shorthand for openPulseInput(new DigitalInput.Spec(pin), rate, mode, + * true), i.e. opens a double-precision, 16MHz pulse input on the given pin + * with the given mode. + * + * @see #openPulseInput(ioio.lib.api.DigitalInput.Spec, + * ioio.lib.api.PulseInput.ClockRate, + * ioio.lib.api.PulseInput.PulseMode, boolean) + */ + public PulseInput openPulseInput(int pin, PulseMode mode) + throws ConnectionLostException; + + /** + * Open a UART module, enabling a bulk transfer of byte buffers. + *
+ * 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. + *
+ * Note that not every pin can be used for UART RX or TX. In addition, the + * total number of concurrent UART modules in use is limited. See board + * documentation for the legal pins and limit on concurrent usage. + *
+ * The UART module will operate, and the pins will work in their respective + * modes until close() is invoked on the returned interface. It is illegal + * to use pins that have already been opened and has not been closed. A + * connection must have been established prior to calling this method, by + * invoking {@link #waitForConnect()}. + * + * @param rx + * Pin specification for the RX pin, consisting of the pin + * number, as labeled on the board, and the mode, which + * determines whether the pin will be floating, pull-up or + * pull-down. See {@link DigitalInput.Spec.Mode} for more + * information. null can be passed to designate that we do not + * want RX input to this module. + * @param tx + * Pin specification for the TX pin, consisting of the pin + * number, as labeled on the board, and the mode, which + * determines whether the pin will be normal or open-drain. See + * {@link DigitalOutput.Spec.Mode} for more information. null can + * be passed to designate that we do not want TX output to this + * module. + * @param baud + * The clock frequency of the UART module in Hz. + * @param parity + * The parity mode, as in {@link Parity}. + * @param stopbits + * Number of stop bits, as in {@link StopBits}. + * @return Interface of the assigned module. + * @throws ConnectionLostException + * Connection was lost before or during the execution of this + * method. + * @throws OutOfResourceException + * This is a runtime exception, so it is not necessary to catch + * it if the client guarantees that the total number of + * concurrent UART resources is not exceeded. + * @see Uart + */ + public Uart openUart(DigitalInput.Spec rx, DigitalOutput.Spec tx, int baud, + Parity parity, StopBits stopbits) throws ConnectionLostException; + + /** + * Shorthand for + * {@link #openUart(DigitalInput.Spec, DigitalOutput.Spec, int, Uart.Parity, Uart.StopBits)} + * , where the input pins use their default specs. {@link #INVALID_PIN} can + * be used on either pin if a TX- or RX-only UART is needed. + * + * @see #openUart(DigitalInput.Spec, DigitalOutput.Spec, int, Uart.Parity, + * Uart.StopBits) + */ + public Uart openUart(int rx, int tx, int baud, Parity parity, + StopBits stopbits) throws ConnectionLostException; + + /** + * Open a SPI master module, enabling communication with multiple + * SPI-enabled slave modules. + *
+ * SPI is a common hardware communication protocol, enabling full-duplex, + * synchronous point-to-multi-point data transfer. It requires MOSI, MISO + * and CLK lines shared by all nodes, as well as a SS line per slave, + * connected between this slave and a respective pin on the master. The MISO + * line should operate in pull-up mode, using either the internal pull-up or + * an external resistor. + *
+ * Note that not every pin can be used for SPI MISO, MOSI or CLK. In + * addition, the total number of concurrent SPI modules in use is limited. + * See board documentation for the legal pins and limit on concurrent usage. + *
+ * The SPI module will operate, and the pins will work in their respective + * modes until close() is invoked on the returned interface. It is illegal + * to use pins that have already been opened and has not been closed. A + * connection must have been established prior to calling this method, by + * invoking {@link #waitForConnect()}. + * + * @param miso + * Pin specification for the MISO (Master In Slave Out) pin, + * consisting of the pin number, as labeled on the board, and the + * mode, which determines whether the pin will be floating, + * pull-up or pull-down. See {@link DigitalInput.Spec.Mode} for + * more information. + * @param mosi + * Pin specification for the MOSI (Master Out Slave In) pin, + * consisting of the pin number, as labeled on the board, and the + * mode, which determines whether the pin will be normal or + * open-drain. See {@link DigitalOutput.Spec.Mode} for more + * information. + * @param clk + * Pin specification for the CLK pin, consisting of the pin + * number, as labeled on the board, and the mode, which + * determines whether the pin will be normal or open-drain. See + * {@link DigitalOutput.Spec.Mode} for more information. + * @param slaveSelect + * An array of pin specifications for each of the slaves' SS + * (Slave Select) pin. The index of this array designates the + * slave index, used later to refer to this slave. The spec is + * consisting of the pin number, as labeled on the board, and the + * mode, which determines whether the pin will be normal or + * open-drain. See {@link DigitalOutput.Spec.Mode} for more + * information. + * @param config + * The configuration of the SPI module. See + * {@link SpiMaster.Config} for details. + * @return Interface of the assigned module. + * @throws ConnectionLostException + * Connection was lost before or during the execution of this + * method. + * @throws OutOfResourceException + * This is a runtime exception, so it is not necessary to catch + * it if the client guarantees that the total number of + * concurrent SPI resources is not exceeded. + * @see SpiMaster + */ + public SpiMaster openSpiMaster(DigitalInput.Spec miso, + DigitalOutput.Spec mosi, DigitalOutput.Spec clk, + DigitalOutput.Spec[] slaveSelect, SpiMaster.Config config) + throws ConnectionLostException; + + /** + * Shorthand for + * {@link #openSpiMaster(ioio.lib.api.DigitalInput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[], ioio.lib.api.SpiMaster.Config)} + * , where the pins are all open with the default modes and default + * configuration values are used. + * + * @see #openSpiMaster(ioio.lib.api.DigitalInput.Spec, + * ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, + * ioio.lib.api.DigitalOutput.Spec[], ioio.lib.api.SpiMaster.Config) + */ + public SpiMaster openSpiMaster(int miso, int mosi, int clk, + int[] slaveSelect, SpiMaster.Rate rate) + throws ConnectionLostException; + + /** + * Shorthand for + * {@link #openSpiMaster(ioio.lib.api.DigitalInput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec[], ioio.lib.api.SpiMaster.Config)} + * , where the MISO pins is opened with pull up, and the other pins are open + * with the default modes and default configuration values are used. In this + * version, a single slave is used. + * + * @see #openSpiMaster(ioio.lib.api.DigitalInput.Spec, + * ioio.lib.api.DigitalOutput.Spec, ioio.lib.api.DigitalOutput.Spec, + * ioio.lib.api.DigitalOutput.Spec[], ioio.lib.api.SpiMaster.Config) + */ + public SpiMaster openSpiMaster(int miso, int mosi, int clk, + int slaveSelect, SpiMaster.Rate rate) + throws ConnectionLostException; + + /** + * Open a TWI (Two-Wire Interface, such as I2C/SMBus) master module, + * enabling communication with multiple TWI-enabled slave modules. + *
+ * TWI is a common hardware communication protocol, enabling half-duplex, + * synchronous point-to-multi-point data transfer. It requires a physical + * connection of two lines (SDA, SCL) shared by all the bus nodes, where the + * SDA is open-drain and externally pulled-up. + *
+ * Note that there is a fixed number of TWI modules, and the pins they use + * are static. Client has to make sure these pins are not already opened + * before calling this method. See board documentation for the number of + * modules and the respective pins they use. + *
+ * The TWI module will operate, and the pins will work in their respective + * modes until close() is invoked on the returned interface. It is illegal + * to use pins that have already been opened and has not been closed. A + * connection must have been established prior to calling this method, by + * invoking {@link #waitForConnect()}. + * + * @param twiNum + * The TWI module index to use. Will also determine the pins + * used. + * @param rate + * The clock rate. Can be 100KHz / 400KHz / 1MHz. + * @param smbus + * When true, will use SMBus voltage levels. When false, I2C + * voltage levels. + * @return Interface of the assigned module. + * @throws ConnectionLostException + * Connection was lost before or during the execution of this + * method. + * @see TwiMaster + */ + public TwiMaster openTwiMaster(int twiNum, Rate rate, boolean smbus) + throws ConnectionLostException; + + /** + * Open an ICSP channel, enabling Flash programming of an external PIC MCU, + * and in particular, another IOIO board. + *
+ * ICSP (In-Circuit Serial Programming) is a protocol intended for + * programming of PIC MCUs. It is a serial protocol over three wires: PGC + * (clock), PGD (data) and MCLR (reset), where PGC and MCLR are controlled + * by the master and PGD is shared by the master and slave, depending on the + * transaction state. + *
+ * Note that there is only one ICSP modules, and the pins it uses are + * static. Client has to make sure that the ICSP module is not already in + * use, as well as those dedicated pins. See board documentation for the + * actual pins used for ICSP. + * + * @return Interface of the ICSP module. + * @see IcspMaster + * @throws ConnectionLostException + * Connection was lost before or during the execution of this + * method. + */ + public IcspMaster openIcspMaster() throws ConnectionLostException; + + /** + * Start a batch of operations. This is strictly an optimization and will + * not change functionality: if the client knows that a sequence of several + * IOIO operations are going to be performed immediately following each + * other, a call to {@link #beginBatch()} before the sequence and + * {@link #endBatch()} after the sequence will cause the operations to be + * grouped into one transfer to the IOIO, thus reducing latency. A matching + * {@link #endBatch()} operation must always follow, or otherwise no + * operation will ever be actually executed. {@link #beginBatch()} / + * {@link #endBatch()} blocks may be nested - the transfer will occur when + * the outermost {@link #endBatch()} is invoked. Note that it is not + * guaranteed that no transfers will happen while inside a batch - it should + * be treated as a hint. Code running inside the block must be quick as it + * blocks all transfers to the IOIO, including those performed from + * other threads. + * + * @throws ConnectionLostException + * Connection was lost before or during the execution of this + * method. + */ + public void beginBatch() throws ConnectionLostException; + + /** + * End a batch of operations. For explanation, see {@link #beginBatch()}. + * + * @throws ConnectionLostException + * Connection was lost before or during the execution of this + * method. + */ + public void endBatch() throws ConnectionLostException; +} diff --git a/IOIOLib/src/ioio/lib/api/Uart.java b/IOIOLib/src/ioio/lib/api/Uart.java index 30faa91..dd59f34 100644 --- a/IOIOLib/src/ioio/lib/api/Uart.java +++ b/IOIOLib/src/ioio/lib/api/Uart.java @@ -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. - *
- * 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)}. - *
- * 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. - *
- * 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. - *
- * 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. - *
- * Typical usage: - * - *
- * 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
- *
- *
- * @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.
+ * + * 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)}. + *
+ * 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. + *
+ * 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. + *
+ * 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. + *
+ * Typical usage: + * + *
+ * 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
+ *
+ *
+ * @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();
+}
diff --git a/IOIOLib/src/ioio/lib/impl/Constants.java b/IOIOLib/src/ioio/lib/impl/Constants.java
index abfefb4..aa82221 100644
--- a/IOIOLib/src/ioio/lib/impl/Constants.java
+++ b/IOIOLib/src/ioio/lib/impl/Constants.java
@@ -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 };
+}
diff --git a/IOIOLib/src/ioio/lib/impl/IOIOImpl.java b/IOIOLib/src/ioio/lib/impl/IOIOImpl.java
index 8731ea0..088110e 100644
--- a/IOIOLib/src/ioio/lib/impl/IOIOImpl.java
+++ b/IOIOLib/src/ioio/lib/impl/IOIOImpl.java
@@ -1,700 +1,700 @@
-/*
- * 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.AnalogInput;
-import ioio.lib.api.DigitalInput;
-import ioio.lib.api.DigitalInput.Spec;
-import ioio.lib.api.DigitalInput.Spec.Mode;
-import ioio.lib.api.DigitalOutput;
-import ioio.lib.api.IOIO;
-import ioio.lib.api.IOIOConnection;
-import ioio.lib.api.IcspMaster;
-import ioio.lib.api.PulseInput;
-import ioio.lib.api.PulseInput.ClockRate;
-import ioio.lib.api.PulseInput.PulseMode;
-import ioio.lib.api.PwmOutput;
-import ioio.lib.api.SpiMaster;
-import ioio.lib.api.TwiMaster;
-import ioio.lib.api.TwiMaster.Rate;
-import ioio.lib.api.Uart;
-import ioio.lib.api.exception.ConnectionLostException;
-import ioio.lib.api.exception.IncompatibilityException;
-import ioio.lib.impl.IOIOProtocol.PwmScale;
-import ioio.lib.impl.IncomingState.DisconnectListener;
-
-import java.io.IOException;
-
-import android.util.Log;
-
-public class IOIOImpl implements IOIO, DisconnectListener {
- private static final String TAG = "IOIOImpl";
- private boolean disconnect_ = false;
-
- private static final byte[] REQUIRED_INTERFACE_ID = new byte[] { 'I', 'O',
- 'I', 'O', '0', '0', '0', '3' };
-
- private final IOIOConnection connection_;
- private final IncomingState incomingState_ = new IncomingState();
- private final boolean openPins_[] = new boolean[Constants.NUM_PINS];
- private final boolean openTwi_[] = new boolean[Constants.NUM_TWI_MODULES];
- private boolean openIcsp_ = false;
- private final ModuleAllocator pwmAllocator_ = new ModuleAllocator(
- Constants.NUM_PWM_MODULES, "PWM");
- private final ModuleAllocator uartAllocator_ = new ModuleAllocator(
- Constants.NUM_UART_MODULES, "UART");
- private final ModuleAllocator spiAllocator_ = new ModuleAllocator(
- Constants.NUM_SPI_MODULES, "SPI");
- private final ModuleAllocator incapAllocatorDouble_ = new ModuleAllocator(
- Constants.INCAP_MODULES_DOUBLE, "INCAP_DOUBLE");
- private final ModuleAllocator incapAllocatorSingle_ = new ModuleAllocator(
- Constants.INCAP_MODULES_SINGLE, "INCAP_SINGLE");
- IOIOProtocol protocol_;
- private State state_ = State.INIT;
-
- public IOIOImpl(IOIOConnection con) {
- connection_ = con;
- }
-
- @Override
- public void waitForConnect() throws ConnectionLostException,
- IncompatibilityException {
- if (state_ == State.CONNECTED) {
- return;
- }
- if (state_ == State.DEAD) {
- throw new ConnectionLostException();
- }
- addDisconnectListener(this);
- Log.d(TAG, "Waiting for IOIO connection");
- try {
- try {
- Log.v(TAG, "Waiting for underlying connection");
- connection_.waitForConnect();
- synchronized (this) {
- if (disconnect_) {
- throw new ConnectionLostException();
- }
- protocol_ = new IOIOProtocol(connection_.getInputStream(),
- connection_.getOutputStream(), incomingState_);
- // Once this block exits, a disconnect will also involve
- // softClose().
- }
- } catch (ConnectionLostException e) {
- incomingState_.handleConnectionLost();
- throw e;
- }
- Log.v(TAG, "Waiting for handshake");
- incomingState_.waitConnectionEstablished();
- Log.v(TAG, "Querying for required interface ID");
- checkInterfaceVersion();
- Log.v(TAG, "Required interface ID is supported");
- state_ = State.CONNECTED;
- Log.i(TAG, "IOIO connection established");
- } catch (ConnectionLostException e) {
- Log.d(TAG, "Connection lost / aborted");
- state_ = State.DEAD;
- throw e;
- } catch (InterruptedException e) {
- Log.e(TAG, "Unexpected exception", e);
- }
- }
-
- @Override
- public synchronized void disconnect() {
- Log.d(TAG, "Client requested disconnect.");
- if (disconnect_) {
- return;
- }
- disconnect_ = true;
- try {
- if (protocol_ != null) {
- protocol_.softClose();
- }
- } catch (IOException e) {
- Log.e(TAG, "Soft close failed", e);
- }
- connection_.disconnect();
- }
-
- @Override
- public synchronized void disconnected() {
- state_ = State.DEAD;
- if (disconnect_) {
- return;
- }
- Log.d(TAG, "Physical disconnect.");
- disconnect_ = true;
- // The IOIOConnection doesn't necessarily know about the disconnect
- connection_.disconnect();
- }
-
- @Override
- public void waitForDisconnect() throws InterruptedException {
- incomingState_.waitDisconnect();
- }
-
- @Override
- public State getState() {
- return state_;
- }
-
- private void checkInterfaceVersion() throws IncompatibilityException,
- ConnectionLostException, InterruptedException {
- try {
- protocol_.checkInterface(REQUIRED_INTERFACE_ID);
- } catch (IOException e) {
- throw new ConnectionLostException(e);
- }
- if (!incomingState_.waitForInterfaceSupport()) {
- state_ = State.INCOMPATIBLE;
- Log.e(TAG, "Required interface ID is not supported");
- throw new IncompatibilityException(
- "IOIO firmware does not support required firmware: "
- + new String(REQUIRED_INTERFACE_ID));
- }
- }
-
- synchronized void removeDisconnectListener(DisconnectListener listener) {
- incomingState_.removeDisconnectListener(listener);
- }
-
- synchronized void addDisconnectListener(DisconnectListener listener)
- throws ConnectionLostException {
- incomingState_.addDisconnectListener(listener);
- }
-
- synchronized void closePin(int pin) {
- try {
- checkState();
- if (!openPins_[pin]) {
- throw new IllegalStateException("Pin not open: " + pin);
- }
- protocol_.setPinDigitalIn(pin, DigitalInput.Spec.Mode.FLOATING);
- openPins_[pin] = false;
- } catch (IOException e) {
- } catch (ConnectionLostException e) {
- }
- }
-
- synchronized void closePwm(int pwmNum) {
- try {
- checkState();
- pwmAllocator_.releaseModule(pwmNum);
- protocol_.setPwmPeriod(pwmNum, 0, IOIOProtocol.PwmScale.SCALE_1X);
- } catch (IOException e) {
- } catch (ConnectionLostException e) {
- }
- }
-
- synchronized void closeUart(int uartNum) {
- try {
- checkState();
- uartAllocator_.releaseModule(uartNum);
- protocol_.uartClose(uartNum);
- } catch (IOException e) {
- } catch (ConnectionLostException e) {
- }
- }
-
- synchronized void closeTwi(int twiNum) {
- try {
- checkState();
- if (!openTwi_[twiNum]) {
- throw new IllegalStateException("TWI not open: " + twiNum);
- }
- openTwi_[twiNum] = false;
- openPins_[Constants.TWI_PINS[twiNum][0]] = false;
- openPins_[Constants.TWI_PINS[twiNum][1]] = false;
- protocol_.i2cClose(twiNum);
- } catch (IOException e) {
- } catch (ConnectionLostException e) {
- }
- }
-
- synchronized void closeIcsp() {
- try {
- checkState();
- if (!openIcsp_) {
- throw new IllegalStateException("ICSP not open");
- }
- openIcsp_ = false;
- openPins_[Constants.ICSP_PINS[0]] = false;
- openPins_[Constants.ICSP_PINS[1]] = false;
- protocol_.icspClose();
- } catch (ConnectionLostException e) {
- } catch (IOException e) {
- }
- }
-
- synchronized void closeSpi(int spiNum) {
- try {
- checkState();
- spiAllocator_.releaseModule(spiNum);
- protocol_.spiClose(spiNum);
- } catch (IOException e) {
- } catch (ConnectionLostException e) {
- }
- }
-
- synchronized void closeIncap(int incapNum, boolean doublePrecision) {
- try {
- checkState();
- if (doublePrecision) {
- incapAllocatorDouble_.releaseModule(incapNum);
- } else {
- incapAllocatorSingle_.releaseModule(incapNum);
- }
- protocol_.incapClose(incapNum);
- } catch (IOException e) {
- } catch (ConnectionLostException e) {
- }
- }
-
- @Override
- synchronized public void softReset() throws ConnectionLostException {
- checkState();
- try {
- protocol_.softReset();
- } catch (IOException e) {
- throw new ConnectionLostException(e);
- }
- }
-
- @Override
- synchronized public void hardReset() throws ConnectionLostException {
- checkState();
- try {
- protocol_.hardReset();
- } catch (IOException e) {
- throw new ConnectionLostException(e);
- }
- }
-
- @Override
- public String getImplVersion(VersionType v) throws ConnectionLostException {
- if (state_ == State.INIT) {
- throw new IllegalStateException(
- "Connection has not yet been established");
- }
- switch (v) {
- case HARDWARE_VER:
- return incomingState_.hardwareId_;
- case BOOTLOADER_VER:
- return incomingState_.bootloaderId_;
- case APP_FIRMWARE_VER:
- return incomingState_.firmwareId_;
- case IOIOLIB_VER:
- return "IOIO0322";
- }
- return null;
- }
-
- @Override
- public DigitalInput openDigitalInput(int pin)
- throws ConnectionLostException {
- return openDigitalInput(new DigitalInput.Spec(pin));
- }
-
- @Override
- public DigitalInput openDigitalInput(int pin, Mode mode)
- throws ConnectionLostException {
- return openDigitalInput(new DigitalInput.Spec(pin, mode));
- }
-
- @Override
- synchronized public DigitalInput openDigitalInput(DigitalInput.Spec spec)
- throws ConnectionLostException {
- checkState();
- PinFunctionMap.checkValidPin(spec.pin);
- checkPinFree(spec.pin);
- DigitalInputImpl result = new DigitalInputImpl(this, spec.pin);
- addDisconnectListener(result);
- openPins_[spec.pin] = true;
- incomingState_.addInputPinListener(spec.pin, result);
- try {
- protocol_.setPinDigitalIn(spec.pin, spec.mode);
- protocol_.setChangeNotify(spec.pin, true);
- } catch (IOException e) {
- result.close();
- throw new ConnectionLostException(e);
- }
- return result;
- }
-
- @Override
- public DigitalOutput openDigitalOutput(int pin,
- ioio.lib.api.DigitalOutput.Spec.Mode mode, boolean startValue)
- throws ConnectionLostException {
- return openDigitalOutput(new DigitalOutput.Spec(pin, mode), startValue);
- }
-
- @Override
- synchronized public DigitalOutput openDigitalOutput(
- DigitalOutput.Spec spec, boolean startValue)
- throws ConnectionLostException {
- checkState();
- PinFunctionMap.checkValidPin(spec.pin);
- checkPinFree(spec.pin);
- DigitalOutputImpl result = new DigitalOutputImpl(this, spec.pin, startValue);
- addDisconnectListener(result);
- openPins_[spec.pin] = true;
- try {
- protocol_.setPinDigitalOut(spec.pin, startValue, spec.mode);
- } catch (IOException e) {
- result.close();
- throw new ConnectionLostException(e);
- }
- return result;
- }
-
- @Override
- public DigitalOutput openDigitalOutput(int pin, boolean startValue)
- throws ConnectionLostException {
- return openDigitalOutput(new DigitalOutput.Spec(pin), startValue);
- }
-
- @Override
- public DigitalOutput openDigitalOutput(int pin)
- throws ConnectionLostException {
- return openDigitalOutput(new DigitalOutput.Spec(pin), false);
- }
-
- @Override
- synchronized public AnalogInput openAnalogInput(int pin)
- throws ConnectionLostException {
- checkState();
- PinFunctionMap.checkSupportsAnalogInput(pin);
- checkPinFree(pin);
- AnalogInputImpl result = new AnalogInputImpl(this, pin);
- addDisconnectListener(result);
- openPins_[pin] = true;
- incomingState_.addInputPinListener(pin, result);
- try {
- protocol_.setPinAnalogIn(pin);
- protocol_.setAnalogInSampling(pin, true);
- } catch (IOException e) {
- result.close();
- throw new ConnectionLostException(e);
- }
- return result;
- }
-
- @Override
- public PwmOutput openPwmOutput(int pin, int freqHz)
- throws ConnectionLostException {
- return openPwmOutput(new DigitalOutput.Spec(pin), freqHz);
- }
-
- @Override
- synchronized public PwmOutput openPwmOutput(DigitalOutput.Spec spec,
- int freqHz) throws ConnectionLostException {
- checkState();
- PinFunctionMap.checkSupportsPeripheralOutput(spec.pin);
- checkPinFree(spec.pin);
- int pwmNum = pwmAllocator_.allocateModule();
-
- int scale = 0;
- float baseUs;
- int period;
- while (true) {
- final int clk = 16000000 / IOIOProtocol.PwmScale.values()[scale].scale;
- period = clk / freqHz;
- if (period <= 65536) {
- baseUs = 1000000.0f / clk;
- break;
- }
- if (++scale >= PwmScale.values().length) {
- throw new IllegalArgumentException("Frequency too low: "
- + freqHz);
- }
- }
-
- PwmImpl pwm = new PwmImpl(this, spec.pin, pwmNum, period, baseUs);
- addDisconnectListener(pwm);
- openPins_[spec.pin] = true;
- try {
- protocol_.setPinDigitalOut(spec.pin, false, spec.mode);
- protocol_.setPinPwm(spec.pin, pwmNum, true);
- protocol_.setPwmPeriod(pwmNum, period - 1,
- IOIOProtocol.PwmScale.values()[scale]);
- } catch (IOException e) {
- pwm.close();
- throw new ConnectionLostException(e);
- }
- return pwm;
- }
-
- @Override
- public Uart openUart(int rx, int tx, int baud, Uart.Parity parity,
- Uart.StopBits stopbits) throws ConnectionLostException {
- return openUart(rx == INVALID_PIN ? null : new DigitalInput.Spec(rx),
- tx == INVALID_PIN ? null : new DigitalOutput.Spec(tx), baud,
- parity, stopbits);
- }
-
- @Override
- synchronized public Uart openUart(DigitalInput.Spec rx,
- DigitalOutput.Spec tx, int baud, Uart.Parity parity,
- Uart.StopBits stopbits) throws ConnectionLostException {
- checkState();
- if (rx != null) {
- PinFunctionMap.checkSupportsPeripheralInput(rx.pin);
- checkPinFree(rx.pin);
- }
- if (tx != null) {
- PinFunctionMap.checkSupportsPeripheralOutput(tx.pin);
- checkPinFree(tx.pin);
- }
- int rxPin = rx != null ? rx.pin : INVALID_PIN;
- int txPin = tx != null ? tx.pin : INVALID_PIN;
- int uartNum = uartAllocator_.allocateModule();
- UartImpl uart = new UartImpl(this, txPin, rxPin, uartNum);
- addDisconnectListener(uart);
- incomingState_.addUartListener(uartNum, uart);
- try {
- if (rx != null) {
- openPins_[rx.pin] = true;
- protocol_.setPinDigitalIn(rx.pin, rx.mode);
- protocol_.setPinUart(rx.pin, uartNum, false, true);
- }
- if (tx != null) {
- openPins_[tx.pin] = true;
- protocol_.setPinDigitalOut(tx.pin, true, tx.mode);
- protocol_.setPinUart(tx.pin, uartNum, true, true);
- }
- boolean speed4x = true;
- int rate = Math.round(4000000.0f / baud) - 1;
- if (rate > 65535) {
- speed4x = false;
- rate = Math.round(1000000.0f / baud) - 1;
- }
- protocol_.uartConfigure(uartNum, rate, speed4x, stopbits, parity);
- } catch (IOException e) {
- uart.close();
- throw new ConnectionLostException(e);
- }
- return uart;
- }
-
- @Override
- synchronized public TwiMaster openTwiMaster(int twiNum, Rate rate,
- boolean smbus) throws ConnectionLostException {
- checkState();
- checkTwiFree(twiNum);
- checkPinFree(Constants.TWI_PINS[twiNum][0]);
- checkPinFree(Constants.TWI_PINS[twiNum][1]);
- openPins_[Constants.TWI_PINS[twiNum][0]] = true;
- openPins_[Constants.TWI_PINS[twiNum][1]] = true;
- openTwi_[twiNum] = true;
- TwiMasterImpl twi = new TwiMasterImpl(this, twiNum);
- addDisconnectListener(twi);
- incomingState_.addTwiListener(twiNum, twi);
- try {
- protocol_.i2cConfigureMaster(twiNum, rate, smbus);
- } catch (IOException e) {
- twi.close();
- throw new ConnectionLostException(e);
- }
- return twi;
- }
-
- @Override
- synchronized public IcspMaster openIcspMaster()
- throws ConnectionLostException {
- checkState();
- checkIcspFree();
- checkPinFree(Constants.ICSP_PINS[0]);
- checkPinFree(Constants.ICSP_PINS[1]);
- checkPinFree(Constants.ICSP_PINS[2]);
- openPins_[Constants.ICSP_PINS[0]] = true;
- openPins_[Constants.ICSP_PINS[1]] = true;
- openPins_[Constants.ICSP_PINS[2]] = true;
- openIcsp_ = true;
- IcspMasterImpl icsp = new IcspMasterImpl(this);
- addDisconnectListener(icsp);
- incomingState_.addIcspListener(icsp);
- try {
- protocol_.icspOpen();
- } catch (IOException e) {
- icsp.close();
- throw new ConnectionLostException(e);
- }
- return icsp;
- }
-
- @Override
- public SpiMaster openSpiMaster(int miso, int mosi, int clk,
- int slaveSelect, SpiMaster.Rate rate)
- throws ConnectionLostException {
- return openSpiMaster(miso, mosi, clk, new int[] { slaveSelect }, rate);
- }
-
- @Override
- public SpiMaster openSpiMaster(int miso, int mosi, int clk,
- int[] slaveSelect, SpiMaster.Rate rate)
- throws ConnectionLostException {
- DigitalOutput.Spec[] slaveSpecs = new DigitalOutput.Spec[slaveSelect.length];
- for (int i = 0; i < slaveSelect.length; ++i) {
- slaveSpecs[i] = new DigitalOutput.Spec(slaveSelect[i]);
- }
- return openSpiMaster(new DigitalInput.Spec(miso, Mode.PULL_UP),
- new DigitalOutput.Spec(mosi), new DigitalOutput.Spec(clk),
- slaveSpecs, new SpiMaster.Config(rate));
- }
-
- @Override
- synchronized public SpiMaster openSpiMaster(DigitalInput.Spec miso,
- DigitalOutput.Spec mosi, DigitalOutput.Spec clk,
- DigitalOutput.Spec[] slaveSelect, SpiMaster.Config config)
- throws ConnectionLostException {
- checkState();
- int ssPins[] = new int[slaveSelect.length];
- checkPinFree(miso.pin);
- PinFunctionMap.checkSupportsPeripheralInput(miso.pin);
- checkPinFree(mosi.pin);
- PinFunctionMap.checkSupportsPeripheralOutput(mosi.pin);
- checkPinFree(clk.pin);
- PinFunctionMap.checkSupportsPeripheralOutput(clk.pin);
- for (int i = 0; i < slaveSelect.length; ++i) {
- checkPinFree(slaveSelect[i].pin);
- ssPins[i] = slaveSelect[i].pin;
- }
-
- int spiNum = spiAllocator_.allocateModule();
- SpiMasterImpl spi = new SpiMasterImpl(this, spiNum, mosi.pin, miso.pin,
- clk.pin, ssPins);
- addDisconnectListener(spi);
-
- openPins_[miso.pin] = true;
- openPins_[mosi.pin] = true;
- openPins_[clk.pin] = true;
- for (int i = 0; i < slaveSelect.length; ++i) {
- openPins_[slaveSelect[i].pin] = true;
- }
-
- incomingState_.addSpiListener(spiNum, spi);
- try {
- protocol_.setPinDigitalIn(miso.pin, miso.mode);
- protocol_.setPinSpi(miso.pin, 1, true, spiNum);
- protocol_.setPinDigitalOut(mosi.pin, true, mosi.mode);
- protocol_.setPinSpi(mosi.pin, 0, true, spiNum);
- protocol_.setPinDigitalOut(clk.pin, config.invertClk, clk.mode);
- protocol_.setPinSpi(clk.pin, 2, true, spiNum);
- for (DigitalOutput.Spec spec : slaveSelect) {
- protocol_.setPinDigitalOut(spec.pin, true, spec.mode);
- }
- protocol_.spiConfigureMaster(spiNum, config);
- } catch (IOException e) {
- spi.close();
- throw new ConnectionLostException(e);
- }
- return spi;
- }
-
- @Override
- public PulseInput openPulseInput(Spec spec, ClockRate rate, PulseMode mode,
- boolean doublePrecision) throws ConnectionLostException {
- checkState();
- checkPinFree(spec.pin);
- PinFunctionMap.checkSupportsPeripheralInput(spec.pin);
- int incapNum = doublePrecision ? incapAllocatorDouble_.allocateModule()
- : incapAllocatorSingle_.allocateModule();
- IncapImpl incap = new IncapImpl(this, mode, incapNum, spec.pin,
- rate.hertz, mode.scaling, doublePrecision);
- addDisconnectListener(incap);
- incomingState_.addIncapListener(incapNum, incap);
- openPins_[spec.pin] = true;
- try {
- protocol_.setPinDigitalIn(spec.pin, spec.mode);
- protocol_.setPinIncap(spec.pin, incapNum, true);
- protocol_.incapConfigure(incapNum, doublePrecision,
- mode.ordinal() + 1, rate.ordinal());
- } catch (IOException e) {
- incap.close();
- throw new ConnectionLostException(e);
- }
- return incap;
- }
-
- @Override
- public PulseInput openPulseInput(int pin, PulseMode mode)
- throws ConnectionLostException {
- return openPulseInput(new DigitalInput.Spec(pin), ClockRate.RATE_16MHz,
- mode, true);
- }
-
- private void checkPinFree(int pin) {
- if (openPins_[pin]) {
- throw new IllegalArgumentException("Pin already open: " + pin);
- }
- }
-
- private void checkTwiFree(int twi) {
- if (openTwi_[twi]) {
- throw new IllegalArgumentException("TWI already open: " + twi);
- }
- }
-
- private void checkIcspFree() {
- if (openIcsp_) {
- throw new IllegalArgumentException("ICSP already open");
- }
- }
-
- private void checkState() throws ConnectionLostException {
- if (state_ == State.DEAD) {
- throw new ConnectionLostException();
- }
- if (state_ == State.INCOMPATIBLE) {
- throw new IllegalStateException(
- "Incompatibility has been reported - IOIO cannot be used");
- }
- if (state_ != State.CONNECTED) {
- throw new IllegalStateException(
- "Connection has not yet been established");
- }
- }
-
- @Override
- public synchronized void beginBatch() throws ConnectionLostException {
- checkState();
- protocol_.beginBatch();
- }
-
- @Override
- public synchronized void endBatch() throws ConnectionLostException {
- checkState();
- try {
- protocol_.endBatch();
- } catch (IOException e) {
- throw new ConnectionLostException(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.impl;
+
+import ioio.lib.api.AnalogInput;
+import ioio.lib.api.DigitalInput;
+import ioio.lib.api.DigitalInput.Spec;
+import ioio.lib.api.DigitalInput.Spec.Mode;
+import ioio.lib.api.DigitalOutput;
+import ioio.lib.api.IOIO;
+import ioio.lib.api.IOIOConnection;
+import ioio.lib.api.IcspMaster;
+import ioio.lib.api.PulseInput;
+import ioio.lib.api.PulseInput.ClockRate;
+import ioio.lib.api.PulseInput.PulseMode;
+import ioio.lib.api.PwmOutput;
+import ioio.lib.api.SpiMaster;
+import ioio.lib.api.TwiMaster;
+import ioio.lib.api.TwiMaster.Rate;
+import ioio.lib.api.Uart;
+import ioio.lib.api.exception.ConnectionLostException;
+import ioio.lib.api.exception.IncompatibilityException;
+import ioio.lib.impl.IOIOProtocol.PwmScale;
+import ioio.lib.impl.IncomingState.DisconnectListener;
+
+import java.io.IOException;
+
+import android.util.Log;
+
+public class IOIOImpl implements IOIO, DisconnectListener {
+ private static final String TAG = "IOIOImpl";
+ private boolean disconnect_ = false;
+
+ private static final byte[] REQUIRED_INTERFACE_ID = new byte[] { 'I', 'O',
+ 'I', 'O', '0', '0', '0', '3' };
+
+ private final IOIOConnection connection_;
+ private final IncomingState incomingState_ = new IncomingState();
+ private final boolean openPins_[] = new boolean[Constants.NUM_PINS];
+ private final boolean openTwi_[] = new boolean[Constants.NUM_TWI_MODULES];
+ private boolean openIcsp_ = false;
+ private final ModuleAllocator pwmAllocator_ = new ModuleAllocator(
+ Constants.NUM_PWM_MODULES, "PWM");
+ private final ModuleAllocator uartAllocator_ = new ModuleAllocator(
+ Constants.NUM_UART_MODULES, "UART");
+ private final ModuleAllocator spiAllocator_ = new ModuleAllocator(
+ Constants.NUM_SPI_MODULES, "SPI");
+ private final ModuleAllocator incapAllocatorDouble_ = new ModuleAllocator(
+ Constants.INCAP_MODULES_DOUBLE, "INCAP_DOUBLE");
+ private final ModuleAllocator incapAllocatorSingle_ = new ModuleAllocator(
+ Constants.INCAP_MODULES_SINGLE, "INCAP_SINGLE");
+ IOIOProtocol protocol_;
+ private State state_ = State.INIT;
+
+ public IOIOImpl(IOIOConnection con) {
+ connection_ = con;
+ }
+
+ @Override
+ public void waitForConnect() throws ConnectionLostException,
+ IncompatibilityException {
+ if (state_ == State.CONNECTED) {
+ return;
+ }
+ if (state_ == State.DEAD) {
+ throw new ConnectionLostException();
+ }
+ addDisconnectListener(this);
+ Log.d(TAG, "Waiting for IOIO connection");
+ try {
+ try {
+ Log.v(TAG, "Waiting for underlying connection");
+ connection_.waitForConnect();
+ synchronized (this) {
+ if (disconnect_) {
+ throw new ConnectionLostException();
+ }
+ protocol_ = new IOIOProtocol(connection_.getInputStream(),
+ connection_.getOutputStream(), incomingState_);
+ // Once this block exits, a disconnect will also involve
+ // softClose().
+ }
+ } catch (ConnectionLostException e) {
+ incomingState_.handleConnectionLost();
+ throw e;
+ }
+ Log.v(TAG, "Waiting for handshake");
+ incomingState_.waitConnectionEstablished();
+ Log.v(TAG, "Querying for required interface ID");
+ checkInterfaceVersion();
+ Log.v(TAG, "Required interface ID is supported");
+ state_ = State.CONNECTED;
+ Log.i(TAG, "IOIO connection established");
+ } catch (ConnectionLostException e) {
+ Log.d(TAG, "Connection lost / aborted");
+ state_ = State.DEAD;
+ throw e;
+ } catch (InterruptedException e) {
+ Log.e(TAG, "Unexpected exception", e);
+ }
+ }
+
+ @Override
+ public synchronized void disconnect() {
+ Log.d(TAG, "Client requested disconnect.");
+ if (disconnect_) {
+ return;
+ }
+ disconnect_ = true;
+ try {
+ if (protocol_ != null) {
+ protocol_.softClose();
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Soft close failed", e);
+ }
+ connection_.disconnect();
+ }
+
+ @Override
+ public synchronized void disconnected() {
+ state_ = State.DEAD;
+ if (disconnect_) {
+ return;
+ }
+ Log.d(TAG, "Physical disconnect.");
+ disconnect_ = true;
+ // The IOIOConnection doesn't necessarily know about the disconnect
+ connection_.disconnect();
+ }
+
+ @Override
+ public void waitForDisconnect() throws InterruptedException {
+ incomingState_.waitDisconnect();
+ }
+
+ @Override
+ public State getState() {
+ return state_;
+ }
+
+ private void checkInterfaceVersion() throws IncompatibilityException,
+ ConnectionLostException, InterruptedException {
+ try {
+ protocol_.checkInterface(REQUIRED_INTERFACE_ID);
+ } catch (IOException e) {
+ throw new ConnectionLostException(e);
+ }
+ if (!incomingState_.waitForInterfaceSupport()) {
+ state_ = State.INCOMPATIBLE;
+ Log.e(TAG, "Required interface ID is not supported");
+ throw new IncompatibilityException(
+ "IOIO firmware does not support required firmware: "
+ + new String(REQUIRED_INTERFACE_ID));
+ }
+ }
+
+ synchronized void removeDisconnectListener(DisconnectListener listener) {
+ incomingState_.removeDisconnectListener(listener);
+ }
+
+ synchronized void addDisconnectListener(DisconnectListener listener)
+ throws ConnectionLostException {
+ incomingState_.addDisconnectListener(listener);
+ }
+
+ synchronized void closePin(int pin) {
+ try {
+ checkState();
+ if (!openPins_[pin]) {
+ throw new IllegalStateException("Pin not open: " + pin);
+ }
+ protocol_.setPinDigitalIn(pin, DigitalInput.Spec.Mode.FLOATING);
+ openPins_[pin] = false;
+ } catch (IOException e) {
+ } catch (ConnectionLostException e) {
+ }
+ }
+
+ synchronized void closePwm(int pwmNum) {
+ try {
+ checkState();
+ pwmAllocator_.releaseModule(pwmNum);
+ protocol_.setPwmPeriod(pwmNum, 0, IOIOProtocol.PwmScale.SCALE_1X);
+ } catch (IOException e) {
+ } catch (ConnectionLostException e) {
+ }
+ }
+
+ synchronized void closeUart(int uartNum) {
+ try {
+ checkState();
+ uartAllocator_.releaseModule(uartNum);
+ protocol_.uartClose(uartNum);
+ } catch (IOException e) {
+ } catch (ConnectionLostException e) {
+ }
+ }
+
+ synchronized void closeTwi(int twiNum) {
+ try {
+ checkState();
+ if (!openTwi_[twiNum]) {
+ throw new IllegalStateException("TWI not open: " + twiNum);
+ }
+ openTwi_[twiNum] = false;
+ openPins_[Constants.TWI_PINS[twiNum][0]] = false;
+ openPins_[Constants.TWI_PINS[twiNum][1]] = false;
+ protocol_.i2cClose(twiNum);
+ } catch (IOException e) {
+ } catch (ConnectionLostException e) {
+ }
+ }
+
+ synchronized void closeIcsp() {
+ try {
+ checkState();
+ if (!openIcsp_) {
+ throw new IllegalStateException("ICSP not open");
+ }
+ openIcsp_ = false;
+ openPins_[Constants.ICSP_PINS[0]] = false;
+ openPins_[Constants.ICSP_PINS[1]] = false;
+ protocol_.icspClose();
+ } catch (ConnectionLostException e) {
+ } catch (IOException e) {
+ }
+ }
+
+ synchronized void closeSpi(int spiNum) {
+ try {
+ checkState();
+ spiAllocator_.releaseModule(spiNum);
+ protocol_.spiClose(spiNum);
+ } catch (IOException e) {
+ } catch (ConnectionLostException e) {
+ }
+ }
+
+ synchronized void closeIncap(int incapNum, boolean doublePrecision) {
+ try {
+ checkState();
+ if (doublePrecision) {
+ incapAllocatorDouble_.releaseModule(incapNum);
+ } else {
+ incapAllocatorSingle_.releaseModule(incapNum);
+ }
+ protocol_.incapClose(incapNum, doublePrecision);
+ } catch (IOException e) {
+ } catch (ConnectionLostException e) {
+ }
+ }
+
+ @Override
+ synchronized public void softReset() throws ConnectionLostException {
+ checkState();
+ try {
+ protocol_.softReset();
+ } catch (IOException e) {
+ throw new ConnectionLostException(e);
+ }
+ }
+
+ @Override
+ synchronized public void hardReset() throws ConnectionLostException {
+ checkState();
+ try {
+ protocol_.hardReset();
+ } catch (IOException e) {
+ throw new ConnectionLostException(e);
+ }
+ }
+
+ @Override
+ public String getImplVersion(VersionType v) throws ConnectionLostException {
+ if (state_ == State.INIT) {
+ throw new IllegalStateException(
+ "Connection has not yet been established");
+ }
+ switch (v) {
+ case HARDWARE_VER:
+ return incomingState_.hardwareId_;
+ case BOOTLOADER_VER:
+ return incomingState_.bootloaderId_;
+ case APP_FIRMWARE_VER:
+ return incomingState_.firmwareId_;
+ case IOIOLIB_VER:
+ return "IOIO0326";
+ }
+ return null;
+ }
+
+ @Override
+ public DigitalInput openDigitalInput(int pin)
+ throws ConnectionLostException {
+ return openDigitalInput(new DigitalInput.Spec(pin));
+ }
+
+ @Override
+ public DigitalInput openDigitalInput(int pin, Mode mode)
+ throws ConnectionLostException {
+ return openDigitalInput(new DigitalInput.Spec(pin, mode));
+ }
+
+ @Override
+ synchronized public DigitalInput openDigitalInput(DigitalInput.Spec spec)
+ throws ConnectionLostException {
+ checkState();
+ PinFunctionMap.checkValidPin(spec.pin);
+ checkPinFree(spec.pin);
+ DigitalInputImpl result = new DigitalInputImpl(this, spec.pin);
+ addDisconnectListener(result);
+ openPins_[spec.pin] = true;
+ incomingState_.addInputPinListener(spec.pin, result);
+ try {
+ protocol_.setPinDigitalIn(spec.pin, spec.mode);
+ protocol_.setChangeNotify(spec.pin, true);
+ } catch (IOException e) {
+ result.close();
+ throw new ConnectionLostException(e);
+ }
+ return result;
+ }
+
+ @Override
+ public DigitalOutput openDigitalOutput(int pin,
+ ioio.lib.api.DigitalOutput.Spec.Mode mode, boolean startValue)
+ throws ConnectionLostException {
+ return openDigitalOutput(new DigitalOutput.Spec(pin, mode), startValue);
+ }
+
+ @Override
+ synchronized public DigitalOutput openDigitalOutput(
+ DigitalOutput.Spec spec, boolean startValue)
+ throws ConnectionLostException {
+ checkState();
+ PinFunctionMap.checkValidPin(spec.pin);
+ checkPinFree(spec.pin);
+ DigitalOutputImpl result = new DigitalOutputImpl(this, spec.pin, startValue);
+ addDisconnectListener(result);
+ openPins_[spec.pin] = true;
+ try {
+ protocol_.setPinDigitalOut(spec.pin, startValue, spec.mode);
+ } catch (IOException e) {
+ result.close();
+ throw new ConnectionLostException(e);
+ }
+ return result;
+ }
+
+ @Override
+ public DigitalOutput openDigitalOutput(int pin, boolean startValue)
+ throws ConnectionLostException {
+ return openDigitalOutput(new DigitalOutput.Spec(pin), startValue);
+ }
+
+ @Override
+ public DigitalOutput openDigitalOutput(int pin)
+ throws ConnectionLostException {
+ return openDigitalOutput(new DigitalOutput.Spec(pin), false);
+ }
+
+ @Override
+ synchronized public AnalogInput openAnalogInput(int pin)
+ throws ConnectionLostException {
+ checkState();
+ PinFunctionMap.checkSupportsAnalogInput(pin);
+ checkPinFree(pin);
+ AnalogInputImpl result = new AnalogInputImpl(this, pin);
+ addDisconnectListener(result);
+ openPins_[pin] = true;
+ incomingState_.addInputPinListener(pin, result);
+ try {
+ protocol_.setPinAnalogIn(pin);
+ protocol_.setAnalogInSampling(pin, true);
+ } catch (IOException e) {
+ result.close();
+ throw new ConnectionLostException(e);
+ }
+ return result;
+ }
+
+ @Override
+ public PwmOutput openPwmOutput(int pin, int freqHz)
+ throws ConnectionLostException {
+ return openPwmOutput(new DigitalOutput.Spec(pin), freqHz);
+ }
+
+ @Override
+ synchronized public PwmOutput openPwmOutput(DigitalOutput.Spec spec,
+ int freqHz) throws ConnectionLostException {
+ checkState();
+ PinFunctionMap.checkSupportsPeripheralOutput(spec.pin);
+ checkPinFree(spec.pin);
+ int pwmNum = pwmAllocator_.allocateModule();
+
+ int scale = 0;
+ float baseUs;
+ int period;
+ while (true) {
+ final int clk = 16000000 / IOIOProtocol.PwmScale.values()[scale].scale;
+ period = clk / freqHz;
+ if (period <= 65536) {
+ baseUs = 1000000.0f / clk;
+ break;
+ }
+ if (++scale >= PwmScale.values().length) {
+ throw new IllegalArgumentException("Frequency too low: "
+ + freqHz);
+ }
+ }
+
+ PwmImpl pwm = new PwmImpl(this, spec.pin, pwmNum, period, baseUs);
+ addDisconnectListener(pwm);
+ openPins_[spec.pin] = true;
+ try {
+ protocol_.setPinDigitalOut(spec.pin, false, spec.mode);
+ protocol_.setPinPwm(spec.pin, pwmNum, true);
+ protocol_.setPwmPeriod(pwmNum, period - 1,
+ IOIOProtocol.PwmScale.values()[scale]);
+ } catch (IOException e) {
+ pwm.close();
+ throw new ConnectionLostException(e);
+ }
+ return pwm;
+ }
+
+ @Override
+ public Uart openUart(int rx, int tx, int baud, Uart.Parity parity,
+ Uart.StopBits stopbits) throws ConnectionLostException {
+ return openUart(rx == INVALID_PIN ? null : new DigitalInput.Spec(rx),
+ tx == INVALID_PIN ? null : new DigitalOutput.Spec(tx), baud,
+ parity, stopbits);
+ }
+
+ @Override
+ synchronized public Uart openUart(DigitalInput.Spec rx,
+ DigitalOutput.Spec tx, int baud, Uart.Parity parity,
+ Uart.StopBits stopbits) throws ConnectionLostException {
+ checkState();
+ if (rx != null) {
+ PinFunctionMap.checkSupportsPeripheralInput(rx.pin);
+ checkPinFree(rx.pin);
+ }
+ if (tx != null) {
+ PinFunctionMap.checkSupportsPeripheralOutput(tx.pin);
+ checkPinFree(tx.pin);
+ }
+ int rxPin = rx != null ? rx.pin : INVALID_PIN;
+ int txPin = tx != null ? tx.pin : INVALID_PIN;
+ int uartNum = uartAllocator_.allocateModule();
+ UartImpl uart = new UartImpl(this, txPin, rxPin, uartNum);
+ addDisconnectListener(uart);
+ incomingState_.addUartListener(uartNum, uart);
+ try {
+ if (rx != null) {
+ openPins_[rx.pin] = true;
+ protocol_.setPinDigitalIn(rx.pin, rx.mode);
+ protocol_.setPinUart(rx.pin, uartNum, false, true);
+ }
+ if (tx != null) {
+ openPins_[tx.pin] = true;
+ protocol_.setPinDigitalOut(tx.pin, true, tx.mode);
+ protocol_.setPinUart(tx.pin, uartNum, true, true);
+ }
+ boolean speed4x = true;
+ int rate = Math.round(4000000.0f / baud) - 1;
+ if (rate > 65535) {
+ speed4x = false;
+ rate = Math.round(1000000.0f / baud) - 1;
+ }
+ protocol_.uartConfigure(uartNum, rate, speed4x, stopbits, parity);
+ } catch (IOException e) {
+ uart.close();
+ throw new ConnectionLostException(e);
+ }
+ return uart;
+ }
+
+ @Override
+ synchronized public TwiMaster openTwiMaster(int twiNum, Rate rate,
+ boolean smbus) throws ConnectionLostException {
+ checkState();
+ checkTwiFree(twiNum);
+ checkPinFree(Constants.TWI_PINS[twiNum][0]);
+ checkPinFree(Constants.TWI_PINS[twiNum][1]);
+ openPins_[Constants.TWI_PINS[twiNum][0]] = true;
+ openPins_[Constants.TWI_PINS[twiNum][1]] = true;
+ openTwi_[twiNum] = true;
+ TwiMasterImpl twi = new TwiMasterImpl(this, twiNum);
+ addDisconnectListener(twi);
+ incomingState_.addTwiListener(twiNum, twi);
+ try {
+ protocol_.i2cConfigureMaster(twiNum, rate, smbus);
+ } catch (IOException e) {
+ twi.close();
+ throw new ConnectionLostException(e);
+ }
+ return twi;
+ }
+
+ @Override
+ synchronized public IcspMaster openIcspMaster()
+ throws ConnectionLostException {
+ checkState();
+ checkIcspFree();
+ checkPinFree(Constants.ICSP_PINS[0]);
+ checkPinFree(Constants.ICSP_PINS[1]);
+ checkPinFree(Constants.ICSP_PINS[2]);
+ openPins_[Constants.ICSP_PINS[0]] = true;
+ openPins_[Constants.ICSP_PINS[1]] = true;
+ openPins_[Constants.ICSP_PINS[2]] = true;
+ openIcsp_ = true;
+ IcspMasterImpl icsp = new IcspMasterImpl(this);
+ addDisconnectListener(icsp);
+ incomingState_.addIcspListener(icsp);
+ try {
+ protocol_.icspOpen();
+ } catch (IOException e) {
+ icsp.close();
+ throw new ConnectionLostException(e);
+ }
+ return icsp;
+ }
+
+ @Override
+ public SpiMaster openSpiMaster(int miso, int mosi, int clk,
+ int slaveSelect, SpiMaster.Rate rate)
+ throws ConnectionLostException {
+ return openSpiMaster(miso, mosi, clk, new int[] { slaveSelect }, rate);
+ }
+
+ @Override
+ public SpiMaster openSpiMaster(int miso, int mosi, int clk,
+ int[] slaveSelect, SpiMaster.Rate rate)
+ throws ConnectionLostException {
+ DigitalOutput.Spec[] slaveSpecs = new DigitalOutput.Spec[slaveSelect.length];
+ for (int i = 0; i < slaveSelect.length; ++i) {
+ slaveSpecs[i] = new DigitalOutput.Spec(slaveSelect[i]);
+ }
+ return openSpiMaster(new DigitalInput.Spec(miso, Mode.PULL_UP),
+ new DigitalOutput.Spec(mosi), new DigitalOutput.Spec(clk),
+ slaveSpecs, new SpiMaster.Config(rate));
+ }
+
+ @Override
+ synchronized public SpiMaster openSpiMaster(DigitalInput.Spec miso,
+ DigitalOutput.Spec mosi, DigitalOutput.Spec clk,
+ DigitalOutput.Spec[] slaveSelect, SpiMaster.Config config)
+ throws ConnectionLostException {
+ checkState();
+ int ssPins[] = new int[slaveSelect.length];
+ checkPinFree(miso.pin);
+ PinFunctionMap.checkSupportsPeripheralInput(miso.pin);
+ checkPinFree(mosi.pin);
+ PinFunctionMap.checkSupportsPeripheralOutput(mosi.pin);
+ checkPinFree(clk.pin);
+ PinFunctionMap.checkSupportsPeripheralOutput(clk.pin);
+ for (int i = 0; i < slaveSelect.length; ++i) {
+ checkPinFree(slaveSelect[i].pin);
+ ssPins[i] = slaveSelect[i].pin;
+ }
+
+ int spiNum = spiAllocator_.allocateModule();
+ SpiMasterImpl spi = new SpiMasterImpl(this, spiNum, mosi.pin, miso.pin,
+ clk.pin, ssPins);
+ addDisconnectListener(spi);
+
+ openPins_[miso.pin] = true;
+ openPins_[mosi.pin] = true;
+ openPins_[clk.pin] = true;
+ for (int i = 0; i < slaveSelect.length; ++i) {
+ openPins_[slaveSelect[i].pin] = true;
+ }
+
+ incomingState_.addSpiListener(spiNum, spi);
+ try {
+ protocol_.setPinDigitalIn(miso.pin, miso.mode);
+ protocol_.setPinSpi(miso.pin, 1, true, spiNum);
+ protocol_.setPinDigitalOut(mosi.pin, true, mosi.mode);
+ protocol_.setPinSpi(mosi.pin, 0, true, spiNum);
+ protocol_.setPinDigitalOut(clk.pin, config.invertClk, clk.mode);
+ protocol_.setPinSpi(clk.pin, 2, true, spiNum);
+ for (DigitalOutput.Spec spec : slaveSelect) {
+ protocol_.setPinDigitalOut(spec.pin, true, spec.mode);
+ }
+ protocol_.spiConfigureMaster(spiNum, config);
+ } catch (IOException e) {
+ spi.close();
+ throw new ConnectionLostException(e);
+ }
+ return spi;
+ }
+
+ @Override
+ public PulseInput openPulseInput(Spec spec, ClockRate rate, PulseMode mode,
+ boolean doublePrecision) throws ConnectionLostException {
+ checkState();
+ checkPinFree(spec.pin);
+ PinFunctionMap.checkSupportsPeripheralInput(spec.pin);
+ int incapNum = doublePrecision ? incapAllocatorDouble_.allocateModule()
+ : incapAllocatorSingle_.allocateModule();
+ IncapImpl incap = new IncapImpl(this, mode, incapNum, spec.pin,
+ rate.hertz, mode.scaling, doublePrecision);
+ addDisconnectListener(incap);
+ incomingState_.addIncapListener(incapNum, incap);
+ openPins_[spec.pin] = true;
+ try {
+ protocol_.setPinDigitalIn(spec.pin, spec.mode);
+ protocol_.setPinIncap(spec.pin, incapNum, true);
+ protocol_.incapConfigure(incapNum, doublePrecision,
+ mode.ordinal() + 1, rate.ordinal());
+ } catch (IOException e) {
+ incap.close();
+ throw new ConnectionLostException(e);
+ }
+ return incap;
+ }
+
+ @Override
+ public PulseInput openPulseInput(int pin, PulseMode mode)
+ throws ConnectionLostException {
+ return openPulseInput(new DigitalInput.Spec(pin), ClockRate.RATE_16MHz,
+ mode, true);
+ }
+
+ private void checkPinFree(int pin) {
+ if (openPins_[pin]) {
+ throw new IllegalArgumentException("Pin already open: " + pin);
+ }
+ }
+
+ private void checkTwiFree(int twi) {
+ if (openTwi_[twi]) {
+ throw new IllegalArgumentException("TWI already open: " + twi);
+ }
+ }
+
+ private void checkIcspFree() {
+ if (openIcsp_) {
+ throw new IllegalArgumentException("ICSP already open");
+ }
+ }
+
+ private void checkState() throws ConnectionLostException {
+ if (state_ == State.DEAD) {
+ throw new ConnectionLostException();
+ }
+ if (state_ == State.INCOMPATIBLE) {
+ throw new IllegalStateException(
+ "Incompatibility has been reported - IOIO cannot be used");
+ }
+ if (state_ != State.CONNECTED) {
+ throw new IllegalStateException(
+ "Connection has not yet been established");
+ }
+ }
+
+ @Override
+ public synchronized void beginBatch() throws ConnectionLostException {
+ checkState();
+ protocol_.beginBatch();
+ }
+
+ @Override
+ public synchronized void endBatch() throws ConnectionLostException {
+ checkState();
+ try {
+ protocol_.endBatch();
+ } catch (IOException e) {
+ throw new ConnectionLostException(e);
+ }
+ }
+}
diff --git a/IOIOLib/src/ioio/lib/impl/IOIOProtocol.java b/IOIOLib/src/ioio/lib/impl/IOIOProtocol.java
index 95ac03a..6afb210 100644
--- a/IOIOLib/src/ioio/lib/impl/IOIOProtocol.java
+++ b/IOIOLib/src/ioio/lib/impl/IOIOProtocol.java
@@ -1,857 +1,862 @@
-/*
- * 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.DigitalInput;
-import ioio.lib.api.DigitalOutput;
-import ioio.lib.api.SpiMaster;
-import ioio.lib.api.TwiMaster.Rate;
-import ioio.lib.api.Uart;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import android.util.Log;
-
-class IOIOProtocol {
- static final int HARD_RESET = 0x00;
- static final int ESTABLISH_CONNECTION = 0x00;
- static final int SOFT_RESET = 0x01;
- static final int CHECK_INTERFACE = 0x02;
- static final int CHECK_INTERFACE_RESPONSE = 0x02;
- static final int SET_PIN_DIGITAL_OUT = 0x03;
- static final int SET_DIGITAL_OUT_LEVEL = 0x04;
- static final int REPORT_DIGITAL_IN_STATUS = 0x04;
- static final int SET_PIN_DIGITAL_IN = 0x05;
- static final int REPORT_PERIODIC_DIGITAL_IN_STATUS = 0x05;
- static final int SET_CHANGE_NOTIFY = 0x06;
- static final int REGISTER_PERIODIC_DIGITAL_SAMPLING = 0x07;
- static final int SET_PIN_PWM = 0x08;
- static final int SET_PWM_DUTY_CYCLE = 0x09;
- static final int SET_PWM_PERIOD = 0x0A;
- static final int SET_PIN_ANALOG_IN = 0x0B;
- static final int REPORT_ANALOG_IN_STATUS = 0x0B;
- static final int SET_ANALOG_IN_SAMPLING = 0x0C;
- static final int REPORT_ANALOG_IN_FORMAT = 0x0C;
- static final int UART_CONFIG = 0x0D;
- static final int UART_STATUS = 0x0D;
- static final int UART_DATA = 0x0E;
- static final int SET_PIN_UART = 0x0F;
- static final int UART_REPORT_TX_STATUS = 0x0F;
- static final int SPI_CONFIGURE_MASTER = 0x10;
- static final int SPI_STATUS = 0x10;
- static final int SPI_MASTER_REQUEST = 0x11;
- static final int SPI_DATA = 0x11;
- static final int SET_PIN_SPI = 0x12;
- static final int SPI_REPORT_TX_STATUS = 0x12;
- static final int I2C_CONFIGURE_MASTER = 0x13;
- static final int I2C_STATUS = 0x13;
- static final int I2C_WRITE_READ = 0x14;
- static final int I2C_RESULT = 0x14;
- static final int I2C_REPORT_TX_STATUS = 0x15;
- static final int ICSP_SIX = 0x16;
- static final int ICSP_REPORT_RX_STATUS = 0x16;
- static final int ICSP_REGOUT = 0x17;
- static final int ICSP_RESULT = 0x17;
- static final int ICSP_PROG_ENTER = 0x18;
- static final int ICSP_PROG_EXIT = 0x19;
- static final int ICSP_CONFIG = 0x1A;
- static final int INCAP_CONFIGURE = 0x1B;
- static final int INCAP_STATUS = 0x1B;
- static final int SET_PIN_INCAP = 0x1C;
- static final int INCAP_REPORT = 0x1C;
- static final int SOFT_CLOSE = 0x1D;
-
- static final int[] SCALE_DIV = new int[] {
- 0x1F, // 31.25
- 0x1E, // 35.714
- 0x1D, // 41.667
- 0x1C, // 50
- 0x1B, // 62.5
- 0x1A, // 83.333
- 0x17, // 125
- 0x16, // 142.857
- 0x15, // 166.667
- 0x14, // 200
- 0x13, // 250
- 0x12, // 333.333
- 0x0F, // 500
- 0x0E, // 571.429
- 0x0D, // 666.667
- 0x0C, // 800
- 0x0B, // 1000
- 0x0A, // 1333.333
- 0x07, // 2000
- 0x06, // 2285.714
- 0x05, // 2666.667
- 0x04, // 3200
- 0x03, // 4000
- 0x02, // 5333.333
- 0x01 // 8000
- };
-
- private static final String TAG = "IOIOProtocol";
-
- enum PwmScale {
- SCALE_1X(1, 0), SCALE_8X(8, 3), SCALE_64X(64, 2), SCALE_256X(256, 1);
-
- public final int scale;
- private final int encoding;
-
- PwmScale(int scale, int encoding) {
- this.scale = scale;
- this.encoding = encoding;
- }
- }
-
- private byte[] outbuf_ = new byte[256];
- private int pos_ = 0;
- private int batchCounter_ = 0;
-
- private void writeByte(int b) throws IOException {
- assert (b >= 0 && b < 256);
- if (pos_ == outbuf_.length) {
- // buffer is full
- flush();
- }
- //Log.v(TAG, "sending: 0x" + Integer.toHexString(b));
- outbuf_[pos_++] = (byte) b;
- }
-
- public synchronized void beginBatch() {
- ++batchCounter_;
- }
-
- public synchronized void endBatch() throws IOException {
- if (--batchCounter_ == 0) {
- flush();
- }
- }
-
- private void flush() throws IOException {
- try {
- out_.write(outbuf_, 0, pos_);
- } finally {
- pos_ = 0;
- }
- }
-
- private void writeTwoBytes(int i) throws IOException {
- writeByte(i & 0xFF);
- writeByte(i >> 8);
- }
-
- private void writeThreeBytes(int i) throws IOException {
- writeByte(i & 0xFF);
- writeByte((i >> 8) & 0xFF);
- writeByte((i >> 16) & 0xFF);
- }
-
- synchronized public void hardReset() throws IOException {
- beginBatch();
- writeByte(HARD_RESET);
- writeByte('I');
- writeByte('O');
- writeByte('I');
- writeByte('O');
- endBatch();
- }
-
- synchronized public void softReset() throws IOException {
- beginBatch();
- writeByte(SOFT_RESET);
- endBatch();
- }
-
- synchronized public void softClose() throws IOException {
- beginBatch();
- writeByte(SOFT_CLOSE);
- endBatch();
- }
-
- synchronized public void checkInterface(byte[] interfaceId)
- throws IOException {
- if (interfaceId.length != 8) {
- throw new IllegalArgumentException(
- "interface ID must be exactly 8 bytes long");
- }
- beginBatch();
- writeByte(CHECK_INTERFACE);
- for (int i = 0; i < 8; ++i) {
- writeByte(interfaceId[i]);
- }
- endBatch();
- }
-
- synchronized public void setDigitalOutLevel(int pin, boolean level)
- throws IOException {
- beginBatch();
- writeByte(SET_DIGITAL_OUT_LEVEL);
- writeByte(pin << 2 | (level ? 1 : 0));
- endBatch();
- }
-
- synchronized public void setPinPwm(int pin, int pwmNum, boolean enable)
- throws IOException {
- beginBatch();
- writeByte(SET_PIN_PWM);
- writeByte(pin & 0x3F);
- writeByte((enable ? 0x80 : 0x00) | (pwmNum & 0x0F));
- endBatch();
- }
-
- synchronized public void setPwmDutyCycle(int pwmNum, int dutyCycle,
- int fraction) throws IOException {
- beginBatch();
- writeByte(SET_PWM_DUTY_CYCLE);
- writeByte(pwmNum << 2 | fraction);
- writeTwoBytes(dutyCycle);
- endBatch();
- }
-
- synchronized public void setPwmPeriod(int pwmNum, int period, PwmScale scale)
- throws IOException {
- beginBatch();
- writeByte(SET_PWM_PERIOD);
- writeByte(((scale.encoding & 0x02) << 6) | (pwmNum << 1)
- | (scale.encoding & 0x01));
- writeTwoBytes(period);
- endBatch();
- }
-
- synchronized public void setPinIncap(int pin, int incapNum, boolean enable)
- throws IOException {
- beginBatch();
- writeByte(SET_PIN_INCAP);
- writeByte(pin);
- writeByte(incapNum | (enable ? 0x80 : 0x00));
- endBatch();
- }
-
- synchronized public void incapClose(int incapNum) throws IOException {
- beginBatch();
- writeByte(INCAP_CONFIGURE);
- writeByte(incapNum);
- writeByte(0x00);
- endBatch();
- }
-
- synchronized public void incapConfigure(int incapNum, boolean double_prec,
- int mode, int clock) throws IOException {
- beginBatch();
- writeByte(INCAP_CONFIGURE);
- writeByte(incapNum);
- writeByte((double_prec ? 0x80 : 0x00) | (mode << 3) | clock);
- endBatch();
- }
-
- synchronized public void i2cWriteRead(int i2cNum, boolean tenBitAddr,
- int address, int writeSize, int readSize, byte[] writeData)
- throws IOException {
- beginBatch();
- writeByte(I2C_WRITE_READ);
- writeByte(((address >> 8) << 6) | (tenBitAddr ? 0x20 : 0x00) | i2cNum);
- writeByte(address & 0xFF);
- writeByte(writeSize);
- writeByte(readSize);
- for (int i = 0; i < writeSize; ++i) {
- writeByte(((int) writeData[i]) & 0xFF);
- }
- endBatch();
- }
-
- synchronized public void setPinDigitalOut(int pin, boolean value,
- DigitalOutput.Spec.Mode mode) throws IOException {
- beginBatch();
- writeByte(SET_PIN_DIGITAL_OUT);
- writeByte((pin << 2)
- | (mode == DigitalOutput.Spec.Mode.OPEN_DRAIN ? 0x01 : 0x00)
- | (value ? 0x02 : 0x00));
- endBatch();
- }
-
- synchronized public void setPinDigitalIn(int pin,
- DigitalInput.Spec.Mode mode) throws IOException {
- int pull = 0;
- if (mode == DigitalInput.Spec.Mode.PULL_UP) {
- pull = 1;
- } else if (mode == DigitalInput.Spec.Mode.PULL_DOWN) {
- pull = 2;
- }
- beginBatch();
- writeByte(SET_PIN_DIGITAL_IN);
- writeByte((pin << 2) | pull);
- endBatch();
- }
-
- synchronized public void setChangeNotify(int pin, boolean changeNotify)
- throws IOException {
- beginBatch();
- writeByte(SET_CHANGE_NOTIFY);
- writeByte((pin << 2) | (changeNotify ? 0x01 : 0x00));
- endBatch();
- }
-
- synchronized public void registerPeriodicDigitalSampling(int pin,
- int freqScale) throws IOException {
- // TODO: implement
- }
-
- synchronized public void setPinAnalogIn(int pin) throws IOException {
- beginBatch();
- writeByte(SET_PIN_ANALOG_IN);
- writeByte(pin);
- endBatch();
- }
-
- synchronized public void setAnalogInSampling(int pin, boolean enable)
- throws IOException {
- beginBatch();
- writeByte(SET_ANALOG_IN_SAMPLING);
- writeByte((enable ? 0x80 : 0x00) | (pin & 0x3F));
- endBatch();
- }
-
- synchronized public void uartData(int uartNum, int numBytes, byte data[])
- throws IOException {
- if (numBytes > 64) {
- throw new IllegalArgumentException(
- "A maximum of 64 bytes can be sent in one uartData message. Got: "
- + numBytes);
- }
- beginBatch();
- writeByte(UART_DATA);
- writeByte((numBytes - 1) | uartNum << 6);
- for (int i = 0; i < numBytes; ++i) {
- writeByte(((int) data[i]) & 0xFF);
- }
- endBatch();
- }
-
- synchronized public void uartConfigure(int uartNum, int rate,
- boolean speed4x, Uart.StopBits stopbits, Uart.Parity parity)
- throws IOException {
- int parbits = parity == Uart.Parity.EVEN ? 1
- : (parity == Uart.Parity.ODD ? 2 : 0);
- beginBatch();
- writeByte(UART_CONFIG);
- writeByte((uartNum << 6) | (speed4x ? 0x08 : 0x00)
- | (stopbits == Uart.StopBits.TWO ? 0x04 : 0x00) | parbits);
- writeTwoBytes(rate);
- endBatch();
- }
-
- synchronized public void uartClose(int uartNum) throws IOException {
- beginBatch();
- writeByte(UART_CONFIG);
- writeByte(uartNum << 6);
- writeTwoBytes(0);
- endBatch();
- }
-
- synchronized public void setPinUart(int pin, int uartNum, boolean tx,
- boolean enable) throws IOException {
- beginBatch();
- writeByte(SET_PIN_UART);
- writeByte(pin);
- writeByte((enable ? 0x80 : 0x00) | (tx ? 0x40 : 0x00) | uartNum);
- endBatch();
- }
-
- synchronized public void spiConfigureMaster(int spiNum,
- SpiMaster.Config config) throws IOException {
- beginBatch();
- writeByte(SPI_CONFIGURE_MASTER);
- writeByte((spiNum << 5) | SCALE_DIV[config.rate.ordinal()]);
- writeByte((config.sampleOnTrailing ? 0x00 : 0x02)
- | (config.invertClk ? 0x01 : 0x00));
- endBatch();
- }
-
- synchronized public void spiClose(int spiNum) throws IOException {
- beginBatch();
- writeByte(SPI_CONFIGURE_MASTER);
- writeByte(spiNum << 5);
- writeByte(0x00);
- endBatch();
- }
-
- synchronized public void setPinSpi(int pin, int mode, boolean enable,
- int spiNum) throws IOException {
- beginBatch();
- writeByte(SET_PIN_SPI);
- writeByte(pin);
- writeByte((1 << 4) | (mode << 2) | spiNum);
- endBatch();
- }
-
- synchronized public void spiMasterRequest(int spiNum, int ssPin,
- byte data[], int dataBytes, int totalBytes, int responseBytes)
- throws IOException {
- final boolean dataNeqTotal = (dataBytes != totalBytes);
- final boolean resNeqTotal = (responseBytes != totalBytes);
- beginBatch();
- writeByte(SPI_MASTER_REQUEST);
- writeByte((spiNum << 6) | ssPin);
- writeByte((dataNeqTotal ? 0x80 : 0x00) | (resNeqTotal ? 0x40 : 0x00)
- | totalBytes - 1);
- if (dataNeqTotal) {
- writeByte(dataBytes);
- }
- if (resNeqTotal) {
- writeByte(responseBytes);
- }
- for (int i = 0; i < dataBytes; ++i) {
- writeByte(((int) data[i]) & 0xFF);
- }
- endBatch();
- }
-
- synchronized public void i2cConfigureMaster(int i2cNum, Rate rate,
- boolean smbusLevels) throws IOException {
- int rateBits = (rate == Rate.RATE_1MHz ? 3
- : (rate == Rate.RATE_400KHz ? 2 : 1));
- beginBatch();
- writeByte(I2C_CONFIGURE_MASTER);
- writeByte((smbusLevels ? 0x80 : 0) | (rateBits << 5) | i2cNum);
- endBatch();
- }
-
- synchronized public void i2cClose(int i2cNum) throws IOException {
- beginBatch();
- writeByte(I2C_CONFIGURE_MASTER);
- writeByte(i2cNum);
- endBatch();
- }
-
- public void icspOpen() throws IOException {
- beginBatch();
- writeByte(ICSP_CONFIG);
- writeByte(0x01);
- endBatch();
- }
-
- public void icspClose() throws IOException {
- beginBatch();
- writeByte(ICSP_CONFIG);
- writeByte(0x00);
- endBatch();
- }
-
- public void icspEnter() throws IOException {
- beginBatch();
- writeByte(ICSP_PROG_ENTER);
- endBatch();
- }
-
- public void icspExit() throws IOException {
- beginBatch();
- writeByte(ICSP_PROG_EXIT);
- endBatch();
- }
-
- public void icspSix(int instruction) throws IOException {
- beginBatch();
- writeByte(ICSP_SIX);
- writeThreeBytes(instruction);
- endBatch();
- }
-
- public void icspRegout() throws IOException {
- beginBatch();
- writeByte(ICSP_REGOUT);
- endBatch();
- }
-
- public interface IncomingHandler {
- public void handleEstablishConnection(byte[] hardwareId,
- byte[] bootloaderId, byte[] firmwareId);
-
- public void handleConnectionLost();
-
- public void handleSoftReset();
-
- public void handleCheckInterfaceResponse(boolean supported);
-
- public void handleSetChangeNotify(int pin, boolean changeNotify);
-
- public void handleReportDigitalInStatus(int pin, boolean level);
-
- public void handleRegisterPeriodicDigitalSampling(int pin, int freqScale);
-
- public void handleReportPeriodicDigitalInStatus(int frameNum,
- boolean values[]);
-
- public void handleAnalogPinStatus(int pin, boolean open);
-
- public void handleReportAnalogInStatus(int pins[], int values[]);
-
- public void handleUartOpen(int uartNum);
-
- public void handleUartClose(int uartNum);
-
- public void handleUartData(int uartNum, int numBytes, byte data[]);
-
- public void handleUartReportTxStatus(int uartNum, int bytesRemaining);
-
- public void handleSpiOpen(int spiNum);
-
- public void handleSpiClose(int spiNum);
-
- public void handleSpiData(int spiNum, int ssPin, byte data[],
- int dataBytes);
-
- public void handleSpiReportTxStatus(int spiNum, int bytesRemaining);
-
- public void handleI2cOpen(int i2cNum);
-
- public void handleI2cClose(int i2cNum);
-
- public void handleI2cResult(int i2cNum, int size, byte[] data);
-
- public void handleI2cReportTxStatus(int spiNum, int bytesRemaining);
-
- void handleIcspOpen();
-
- void handleIcspClose();
-
- void handleIcspReportRxStatus(int bytesRemaining);
-
- void handleIcspResult(int size, byte[] data);
-
- public void handleIncapReport(int incapNum, int size, byte[] data);
-
- public void handleIncapClose(int incapNum);
-
- public void handleIncapOpen(int incapNum);
- }
-
- class IncomingThread extends Thread {
- private int readOffset_ = 0;
- private int validBytes_ = 0;
- private byte[] inbuf_ = new byte[64];
-
- private int[] analogFramePins_ = new int[0];
- private Setnull
- * 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 null 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.
- * null 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 null 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();
- Collectionnull
+ * 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 null 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.
+ * null 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 null 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- * For advanced usage only! - *
- * 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
+ * For advanced usage only!
+ *
+ * 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