diff --git a/.gitignore b/.gitignore
index 1f2093e..80ef0dc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,13 @@
+# General temp. files
+*~
+*.tmp
+
# Eclipse project files
#.classpath
#.project
# built application files
-#*.apk
+*.apk
*.ap_
# files for the dex VM
@@ -12,14 +16,18 @@
# Java class files
*.class
-# generated files
+# Generated files
bin/
gen/
+out/
lint.xml
# Local configuration file (sdk path, etc)
local.properties
+# Proguard folder generated by Eclipse
+proguard/
+
# Eclipse project files
#.classpath
#.project
@@ -31,20 +39,34 @@ release.properties
pom.xml.*
# Ant
-build.xml
+#build.xml
ant.properties
local.properties
proguard.cfg
proguard-project.txt
+# Gradle files
+.gradle/
+build/
+
+# Log Files
+*.log
+
+# Netbeans files
+.netbeans.xml
+
# Intellij project files
*.iml
*.ipr
*.iws
.idea/
-out/
gen-external-apklibs/
-# Gradle
-.gradle
-build
+# Android Studio Navigation editor temp files
+.navigation/
+
+# Android Studio captures folder
+captures/
+
+# Keystore files
+*.jks
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..5497bdc
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,32 @@
+language: android
+#install: ant deps
+
+android:
+
+ components:
+
+ # The BuildTools version used by the Physicaloid project
+ - build-tools-18.0.1
+
+ # The SDK version used to compile the Physicaloid project
+ - android-18
+
+ # List of the specified system images,
+ # to run emulator(s) during the tests
+ #- sys-img-armeabi-v7a-android-18
+ #- sys-img-armeabi-v7a-android-26
+
+before_install:
+ - wget --no-check-certificate https://www.apache.org/dist/ant/binaries/apache-ant-1.9.13-bin.tar.gz
+ - tar -xzvf apache-ant-1.9.13-bin.tar.gz
+ - export PATH=`pwd`/apache-ant-1.9.13/bin:$PATH
+ - echo $(ant -version)
+
+script:
+ - cd ./SampleProjects/PhysicaloidTest
+ - ant -v debug
+
+after_success:
+ - cp bin/PhysicaloidTest-debug.apk ./result.apk
+ - link=$(curl -F "file=@result.apk" https://file.io?expires=1m | jq --raw-output '.link')
+ - echo "Uploaded the result to $link"
\ No newline at end of file
diff --git a/PhysicaloidLibrary/AndroidManifest.xml b/PhysicaloidLibrary/AndroidManifest.xml
index d5024fd..01b2cff 100644
--- a/PhysicaloidLibrary/AndroidManifest.xml
+++ b/PhysicaloidLibrary/AndroidManifest.xml
@@ -1,10 +1,10 @@
+ android:versionCode="20000"
+ android:versionName="02.00.00" >
+ android:minSdkVersion="19"
+ android:targetSdkVersion="19" />
\ No newline at end of file
diff --git a/PhysicaloidLibrary/bin/physicaloidlibrary.jar b/PhysicaloidLibrary/bin/physicaloidlibrary.jar
deleted file mode 100644
index acc510d..0000000
Binary files a/PhysicaloidLibrary/bin/physicaloidlibrary.jar and /dev/null differ
diff --git a/PhysicaloidLibrary/build.xml b/PhysicaloidLibrary/build.xml
new file mode 100644
index 0000000..adcc7ad
--- /dev/null
+++ b/PhysicaloidLibrary/build.xml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PhysicaloidLibrary/libs/d2xx.jar b/PhysicaloidLibrary/libs/d2xx.jar
deleted file mode 100755
index be24cf9..0000000
Binary files a/PhysicaloidLibrary/libs/d2xx.jar and /dev/null differ
diff --git a/PhysicaloidLibrary/project.properties b/PhysicaloidLibrary/project.properties
index 5f6ad43..1b8c5a3 100644
--- a/PhysicaloidLibrary/project.properties
+++ b/PhysicaloidLibrary/project.properties
@@ -11,5 +11,5 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
-target=android-12
+target=android-18
android.library=true
diff --git a/PhysicaloidLibrary/src/com/physicaloid/lib/Physicaloid.java b/PhysicaloidLibrary/src/com/physicaloid/lib/Physicaloid.java
index 0ea469f..bade21c 100644
--- a/PhysicaloidLibrary/src/com/physicaloid/lib/Physicaloid.java
+++ b/PhysicaloidLibrary/src/com/physicaloid/lib/Physicaloid.java
@@ -13,418 +13,649 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.physicaloid.lib;
import android.content.Context;
import android.util.Log;
-
import com.physicaloid.BuildConfig;
import com.physicaloid.lib.framework.AutoCommunicator;
import com.physicaloid.lib.framework.SerialCommunicator;
import com.physicaloid.lib.framework.Uploader;
import com.physicaloid.lib.programmer.avr.UploadErrors;
import com.physicaloid.lib.usb.driver.uart.ReadLisener;
+import com.physicaloid.lib.usb.driver.uart.ReadListener;
import com.physicaloid.lib.usb.driver.uart.UartConfig;
-
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class Physicaloid {
- private static final boolean DEBUG_SHOW = true && BuildConfig.DEBUG;
- private static final String TAG = Physicaloid.class.getSimpleName();
-
- private Context mContext;
- private Boards mBoard;
-
- protected SerialCommunicator mSerial;
- private Uploader mUploader;
- private Thread mUploadThread;
-
- private UploadCallBack mCallBack;
- private InputStream mFileStream;
-
- private static final Object LOCK = new Object();
- protected static final Object LOCK_WRITE = new Object();
- protected static final Object LOCK_READ = new Object();
-
- public Physicaloid(Context context) {
- this.mContext = context;
- }
-
- /**
- * Opens a device and communicate USB UART by default settings
- * @return true : successful , false : fail
- * @throws RuntimeException
- */
- public boolean open() throws RuntimeException {
- return open(new UartConfig());
- }
-
- /**
- * Opens a device and communicate USB UART
- * @param uart UART configuration
- * @return true : successful , false : fail
- * @throws RuntimeException
- */
- public boolean open(UartConfig uart) throws RuntimeException {
- synchronized (LOCK) {
- if(mSerial == null) {
- mSerial = new AutoCommunicator().getSerialCommunicator(mContext);
- if(mSerial == null) return false;
- }
- if(mSerial.open()) {
- mSerial.setUartConfig(uart);
- return true;
- } else {
- return false;
- }
+
+ /**
+ * USB physical connection as a number
+ */
+ public static final int USB = 1;
+ /**
+ * WIFI physical connection as a number
+ */
+ public static final int WIFI = 2;
+ /**
+ * Bluetooth physical connection as a number
+ */
+ public static final int BLUETOOTH = 3;
+ /**
+ * USB physical connection as a string
+ */
+ public static final String USB_STRING = "USB";
+ /**
+ * WIFI physical connection as a string
+ */
+ public static final String WIFI_STRING = "WiFi";
+ /**
+ * Bluetooth physical connection as a string
+ */
+ public static final String BLUETOOTH_STRING = "BlueTooth";
+ private static final boolean DEBUG_SHOW = true && BuildConfig.DEBUG;
+ private static final String TAG = Physicaloid.class.getSimpleName();
+ private Context mContext;
+ private Boards mBoard;
+ protected SerialCommunicator mSerial;
+ private Uploader mUploader;
+ private Thread mUploadThread;
+ private UploadCallBack mCallBack;
+ private InputStream mFileStream;
+ private static final Object LOCK = new Object();
+ protected static final Object LOCK_WRITE = new Object();
+ protected static final Object LOCK_READ = new Object();
+ private String mNetdest = null;
+ private String mBlueName = null;
+ private int mDport = 9001;
+ private int mCport = 9002;
+ private boolean USE_USB = true;
+ private boolean USE_WIFI = false;
+ private boolean USE_BLUETOOTH = false;
+
+ /**
+ * Default, USB only
+ *
+ * @param context
+ */
+ public Physicaloid(Context context) {
+ USE_USB = true;
+ USE_WIFI = false;
+ USE_BLUETOOTH = false;
+ this.mContext = context;
+ }
+
+ /**
+ * Bluetooth, optional USB
+ *
+ * @param context
+ * @param u true = use USB
+ * @param BlueName Name of bluetooth, null for automatic default
+ */
+ public Physicaloid(Context context, boolean u, String BlueName) {
+ USE_USB = u;
+ USE_WIFI = false;
+ USE_BLUETOOTH = true;
+ mBlueName = BlueName;
+ this.mContext = context;
+ }
+
+ // WiFi, optional USB
+ /**
+ *
+ * @param context
+ * @param u true = use USB
+ * @param Netdest e.g. "192.168.4.1" or a host name
+ * @param Dport port number for data
+ * @param Cport port number for controls
+ */
+ public Physicaloid(Context context, boolean u, String Netdest, int Dport, int Cport) {
+ USE_USB = u;
+ USE_WIFI = true;
+ USE_BLUETOOTH = false;
+ if(Dport > 0) {
+ mDport = Dport;
+ } else {
+ mDport = 9001;
+ }
+ if(Cport > 0) {
+ mCport = Cport;
+ } else {
+ mCport = mDport + 1;
+ }
+ if(mNetdest != null) {
+ mNetdest = Netdest;
+ } else {
+ mNetdest = "192.168.4.1";
+ }
+ this.mContext = context;
+ }
+
+ // WiFi, Bluetooth, optional USB
+ /**
+ *
+ * @param context
+ * @param u true = use USB
+ * @param BlueName Name of bluetooth, null for automatic default
+ * @param Netdest e.g. "192.168.4.1" or a host name, null defaults to
+ * "192.168.4.1"
+ * @param Dport port number for data, Zero = 9001
+ * @param Cport port number for controls, Zero = Dport + 1
+ */
+ public Physicaloid(Context context, boolean u, String BlueName, String Netdest, int Dport, int Cport) {
+ this.mContext = context;
+ USE_USB = u;
+ USE_WIFI = true;
+ USE_BLUETOOTH = true;
+ if(Dport > 0) {
+ mDport = Dport;
+ } else {
+ mDport = 9001;
+ }
+ if(Cport > 0) {
+ mCport = Cport;
+ } else {
+ mCport = mDport + 1;
+ }
+ if(mNetdest != null) {
+ mNetdest = Netdest;
+ } else {
+ mNetdest = "192.168.4.1";
+ }
+ mBlueName = BlueName;
+ }
+
+ /**
+ * Opens a device and communicate USB UART by default settings
+ *
+ * @return true : successful , false : fail
+ * @throws RuntimeException
+ */
+ public boolean open() throws RuntimeException {
+ return open(new UartConfig());
+ }
+
+ /**
+ * Opens a device and communicate USB UART
+ *
+ * @param uart UART configuration
+ * @return true : successful , false : fail
+ * @throws RuntimeException
+ */
+ public boolean open(UartConfig uart) throws RuntimeException {
+ synchronized(LOCK) {
+ if(mSerial == null) {
+ mSerial = new AutoCommunicator(USE_USB, USE_WIFI, USE_BLUETOOTH, mDport, mCport, mNetdest, mBlueName).getSerialCommunicator(mContext);
+ if(mSerial == null) {
+ return false;
+ }
+ }
+ if(mSerial.open()) {
+ mSerial.setUartConfig(uart);
+ return true;
+ } else {
+ return false;
+ }
+ }
}
- }
-
- /**
- * Closes a device.
- * @return true : successful , false : fail
- * @throws RuntimeException
- */
- public boolean close() throws RuntimeException {
- synchronized (LOCK) {
- if(mSerial == null) return true;
- if(mSerial.close()) {
- mSerial = null;
- return true;
- } else {
- return false;
- }
+
+ /**
+ * Closes a device.
+ *
+ * @return true : successful , false : fail
+ * @throws RuntimeException
+ */
+ public boolean close() throws RuntimeException {
+ synchronized(LOCK) {
+ if(mSerial == null) {
+ return true;
+ }
+ if(mSerial.close()) {
+ mSerial = null;
+ return true;
+ } else {
+ return false;
+ }
+ }
}
- }
-
- /**
- * Reads from a device
- * @param buf
- * @return read byte size
- * @throws RuntimeException
- */
- public int read(byte[] buf) throws RuntimeException {
- if(mSerial == null) return 0;
- return read(buf, buf.length);
- }
-
- /**
- * Reads from a device
- * @param buf
- * @param size
- * @return read byte size
- * @throws RuntimeException
- */
- public int read(byte[] buf, int size) throws RuntimeException {
- synchronized (LOCK_READ) {
- if(mSerial == null) return 0;
- return mSerial.read(buf, size);
+
+ /**
+ * Reads from a device
+ *
+ * @param buf
+ * @return read byte size
+ * @throws RuntimeException
+ */
+ public int read(byte[] buf) throws RuntimeException {
+ if(mSerial == null) {
+ return 0;
+ }
+ return read(buf, buf.length);
}
- }
-
- /**
- * Adds read listener
- * @param listener ReadListener
- * @return true : successful , false : fail
- * @throws RuntimeException
- */
- public boolean addReadListener(ReadLisener listener) throws RuntimeException {
- synchronized (LOCK_READ) {
- if(mSerial == null) return false;
- if(listener == null) return false;
- mSerial.addReadListener(listener);
- return true;
+
+ /**
+ * Reads from a device
+ *
+ * @param buf
+ * @param size
+ * @return read byte size
+ * @throws RuntimeException
+ */
+ public int read(byte[] buf, int size) throws RuntimeException {
+ synchronized(LOCK_READ) {
+ if(mSerial == null) {
+ return 0;
+ }
+ return mSerial.read(buf, size);
+ }
}
- }
-
- /**
- * Clears read listener
- * @throws RuntimeException
- */
- public void clearReadListener() throws RuntimeException {
- synchronized (LOCK_READ) {
- if(mSerial == null) return;
- mSerial.clearReadListener();
+
+ /**
+ * Adds read listener
+ *
+ * @param listener ReadListener
+ * @return true : successful , false : fail
+ * @throws RuntimeException
+ */
+ public boolean addReadListener(ReadListener listener) throws RuntimeException {
+ synchronized(LOCK_READ) {
+ if(mSerial == null) {
+ return false;
+ }
+ if(listener == null) {
+ return false;
+ }
+ mSerial.addReadListener(listener);
+ return true;
+ }
}
- }
-
- /**
- * Writes to a device.
- * @param buf
- * @return written byte size
- * @throws RuntimeException
- */
- public int write(byte[] buf) throws RuntimeException {
- if(mSerial == null) return 0;
- return write(buf, buf.length);
- }
-
- /**
- * Writes to a device.
- * @param buf
- * @param size
- * @return written byte size
- * @throws RuntimeException
- */
- public int write(byte[] buf, int size) throws RuntimeException {
- synchronized (LOCK_WRITE){
- if(mSerial == null) return 0;
- return mSerial.write(buf, size);
+
+ /**
+ * Adds read listener
+ *
+ * @param listener ReadListener
+ * @return true : successful , false : fail
+ * @throws RuntimeException
+ */
+ public boolean addReadListener(ReadLisener listener) throws RuntimeException {
+ return addReadListener((ReadListener) listener);
}
- }
-
- /**
- * Uploads a binary file to a device on background process. No need to open().
- * @param board board profile e.g. Boards.ARDUINO_UNO
- * @param filePath a binary file path e.g. /sdcard/arduino/Blink.hex
- * @throws RuntimeException
- */
- public void upload(Boards board, String filePath) throws RuntimeException {
- upload(board, filePath, null);
- }
-
- /**
- * Uploads a binary file to a device on background process. No need to open().
- * @param board board profile e.g. Boards.ARDUINO_UNO
- * @param filePath a binary file path e.g. /sdcard/arduino/Blink.uno.hex
- * @param callback
- * @throws RuntimeException
- */
- public void upload(Boards board, String filePath, UploadCallBack callback) throws RuntimeException {
- if(filePath == null) {
- if(callback != null){ callback.onError(UploadErrors.FILE_OPEN); }
- return;
+ /**
+ * Clears read listener
+ *
+ * @throws RuntimeException
+ */
+ public void clearReadListener() throws RuntimeException {
+ synchronized(LOCK_READ) {
+ if(mSerial == null) {
+ return;
+ }
+ mSerial.clearReadListener();
+ }
}
- File file = new File(filePath);
- if(!file.exists() || !file.isFile() || !file.canRead()) {
- if(callback != null){ callback.onError(UploadErrors.FILE_OPEN); }
- return;
+ /**
+ * Writes to a device.
+ *
+ * @param buf
+ * @return written byte size
+ * @throws RuntimeException
+ */
+ public int write(byte[] buf) throws RuntimeException {
+ if(mSerial == null) {
+ return 0;
+ }
+ return write(buf, buf.length);
}
- InputStream is;
- try {
- is = new FileInputStream(filePath);
- } catch(Exception e) {
- if(callback != null){ callback.onError(UploadErrors.FILE_OPEN); }
- return;
+ /**
+ * Writes to a device.
+ *
+ * @param buf
+ * @param size
+ * @return written byte size
+ * @throws RuntimeException
+ */
+ public int write(byte[] buf, int size) throws RuntimeException {
+ synchronized(LOCK_WRITE) {
+ if(mSerial == null) {
+ return 0;
+ }
+ return mSerial.write(buf, size);
+ }
}
- upload(board, is, callback);
- }
-
- /**
- * Uploads a binary file to a device on background process. No need to open().
- * @param board board profile e.g. Boards.ARDUINO_UNO
- * @param fileStream a binary stream e.g. getResources().getAssets().open("Blink.uno.hex")
- * @throws RuntimeException
- */
- public void upload(Boards board, InputStream fileStream) throws RuntimeException {
- upload(board, fileStream, null);
- }
-
- boolean serialIsNull = false;
- /**
- * Uploads a binary file to a device on background process. No need to open().
- * @param board board profile e.g. Boards.ARDUINO_UNO
- * @param fileStream a binary stream e.g. getResources().getAssets().open("Blink.uno.hex")
- * @param callback
- * @throws RuntimeException
- */
- public void upload(Boards board, InputStream fileStream, UploadCallBack callback) throws RuntimeException {
- mUploader = new Uploader();
- mCallBack = callback;
- mFileStream = fileStream;
- mBoard = board;
-
- if (mSerial == null) { // if not open
- if(DEBUG_SHOW) { Log.d(TAG, "upload : mSerial is null"); }
- mSerial = new AutoCommunicator()
- .getSerialCommunicator(mContext); // need to run on non-thread
- serialIsNull = true;
+
+ /**
+ * Uploads a binary file to a device on background process. No need to
+ * open().
+ *
+ * @param board board profile e.g. Boards.ARDUINO_UNO
+ * @param filePath a binary file path e.g. /sdcard/arduino/Blink.hex
+ * @throws RuntimeException
+ */
+ public void upload(Boards board, String filePath) throws RuntimeException {
+ upload(board, filePath, null);
}
- mUploadThread = new Thread(new Runnable() {
- @Override
- public void run() {
- synchronized (LOCK) {
- synchronized (LOCK_WRITE) {
- synchronized (LOCK_READ) {
- UartConfig tmpUartConfig = new UartConfig();
+ /**
+ * Uploads a binary file to a device on background process. No need to
+ * open().
+ *
+ * @param board board profile e.g. Boards.ARDUINO_UNO
+ * @param filePath a binary file path e.g. /sdcard/arduino/Blink.uno.hex
+ * @param callback
+ * @throws RuntimeException
+ */
+ public void upload(Boards board, String filePath, UploadCallBack callback) throws RuntimeException {
+ if(filePath == null) {
+ if(callback != null) {
+ callback.onError(UploadErrors.FILE_OPEN);
+ }
+ return;
+ }
+ File file = new File(filePath);
+ if(!file.exists() || !file.isFile() || !file.canRead()) {
+ if(callback != null) {
+ callback.onError(UploadErrors.FILE_OPEN);
+ }
+ return;
+ }
+
+ InputStream is;
+ try {
+ is = new FileInputStream(filePath);
+ } catch(Exception e) {
+ if(callback != null) {
+ callback.onError(UploadErrors.FILE_OPEN);
+ }
+ return;
+ }
+ upload(board, is, callback);
+ }
- if (mSerial == null) { // fail
- if(DEBUG_SHOW) { Log.d(TAG, "upload : mSerial is null"); }
- if (mCallBack != null) {
- mCallBack.onError(UploadErrors.OPEN_DEVICE);
+ /**
+ * Uploads a binary file to a device on background process. No need to
+ * open().
+ *
+ * @param board board profile e.g. Boards.ARDUINO_UNO
+ * @param fileStream a binary stream e.g.
+ * getResources().getAssets().open("Blink.uno.hex")
+ * @throws RuntimeException
+ */
+ public void upload(Boards board, InputStream fileStream) throws RuntimeException {
+ upload(board, fileStream, null);
+ }
+ boolean serialIsNull = false;
+
+ /**
+ * Uploads a binary file to a device on background process. No need to
+ * open().
+ *
+ * @param board board profile e.g. Boards.ARDUINO_UNO
+ * @param fileStream a binary stream e.g.
+ * getResources().getAssets().open("Blink.uno.hex")
+ * @param callback
+ * @throws RuntimeException
+ */
+ public void upload(Boards board, InputStream fileStream, UploadCallBack callback) throws RuntimeException {
+ mUploader = new Uploader();
+ mCallBack = callback;
+ mFileStream = fileStream;
+ mBoard = board;
+
+ if(mSerial == null) { // if not open
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "upload : mSerial is null");
+ }
+ mSerial = new AutoCommunicator(USE_USB, USE_WIFI, USE_BLUETOOTH, mDport, mCport, mNetdest, mBlueName).getSerialCommunicator(mContext); // need to run on non-thread
+ serialIsNull = true;
+ }
+
+ mUploadThread = new Thread(new Runnable() {
+
+ @Override
+ @SuppressWarnings("NestedSynchronizedStatement")
+ public void run() {
+ synchronized(LOCK) {
+ synchronized(LOCK_WRITE) {
+ synchronized(LOCK_READ) {
+ UartConfig tmpUartConfig = new UartConfig();
+
+
+ if(mSerial == null) { // fail
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "upload : mSerial is null");
+ }
+ if(mCallBack != null) {
+ mCallBack.onError(UploadErrors.OPEN_DEVICE);
+ }
+ mBoard = null;
+ mFileStream = null;
+ mCallBack = null;
+ mUploader = null;
+ mSerial = null;
+ return;
+ }
+
+ if(!mSerial.isOpened()) {
+ if(!mSerial.open()) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "upload : cannot mSerial.open");
+ }
+ if(mCallBack != null) {
+ mCallBack.onError(UploadErrors.OPEN_DEVICE);
+ }
+ mBoard = null;
+ mFileStream = null;
+ mCallBack = null;
+ mUploader = null;
+ mSerial = null;
+ return;
+ }
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "upload : open successful");
+ }
+ } else { // if already open
+ UartConfig origUartConfig = mSerial.getUartConfig();
+ tmpUartConfig.baudrate = origUartConfig.baudrate;
+ tmpUartConfig.dataBits = origUartConfig.dataBits;
+ tmpUartConfig.stopBits = origUartConfig.stopBits;
+ tmpUartConfig.parity = origUartConfig.parity;
+ tmpUartConfig.dtrOn = origUartConfig.dtrOn;
+ tmpUartConfig.rtsOn = origUartConfig.rtsOn;
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "upload : already open");
+ }
+ }
+
+ mSerial.stopReadListener();
+ mSerial.clearBuffer();
+
+ mUploader.upload(mFileStream, mBoard, mSerial, mCallBack);
+
+ mSerial.setUartConfig(tmpUartConfig); // recover if already
+ // open
+ mSerial.clearBuffer();
+ mSerial.startReadListener();
+ if(serialIsNull) {
+ mSerial.close();
+ }
+
+ mBoard = null;
+ mFileStream = null;
+ mCallBack = null;
+ mUploader = null;
+ }
+ }
+ }
}
- mBoard = null;
- mFileStream = null;
- mCallBack = null;
- mUploader = null;
- mSerial = null;
+ });
+
+ mUploadThread.start();
+ }
+
+ public void cancelUpload() {
+ if(mUploadThread == null) {
return;
- }
-
- if(!mSerial.isOpened()){
- if(!mSerial.open()) {
- if(DEBUG_SHOW) { Log.d(TAG, "upload : cannot mSerial.open"); }
- if (mCallBack != null) { mCallBack.onError(UploadErrors.OPEN_DEVICE); }
- mBoard = null;
- mFileStream = null;
- mCallBack = null;
- mUploader = null;
- mSerial = null;
- return;
+ }
+ mUploadThread.interrupt();
+ }
+
+ /**
+ * Callbacks of program process
normal process:
onPreUpload() ->
+ * onUploading -> onPostUpload
cancel:
onPreUpload() ->
+ * onUploading -> onCancel -> onPostUpload
error:
onPreUpload
+ * |
onUploading | -> onError
onPostUpload |
+ *
+ * @author keisuke
+ *
+ */
+ public interface UploadCallBack {
+ /*
+ * Callback methods
+ */
+
+ void onPreUpload();
+
+ void onUploading(int value);
+
+ void onPostUpload(boolean success);
+
+ void onCancel();
+
+ void onError(UploadErrors err);
+ }
+
+ /**
+ * Gets opened or closed status
+ *
+ * @return true : opened, false : closed
+ * @throws RuntimeException
+ */
+ public boolean isOpened() throws RuntimeException {
+ synchronized(LOCK) {
+ if(mSerial == null) {
+ return false;
}
- if(DEBUG_SHOW) { Log.d(TAG, "upload : open successful"); }
- } else { // if already open
- UartConfig origUartConfig = mSerial.getUartConfig();
- tmpUartConfig.baudrate = origUartConfig.baudrate;
- tmpUartConfig.dataBits = origUartConfig.dataBits;
- tmpUartConfig.stopBits = origUartConfig.stopBits;
- tmpUartConfig.parity = origUartConfig.parity;
- tmpUartConfig.dtrOn = origUartConfig.dtrOn;
- tmpUartConfig.rtsOn = origUartConfig.rtsOn;
- if(DEBUG_SHOW) { Log.d(TAG, "upload : already open"); }
- }
-
- mSerial.stopReadListener();
- mSerial.clearBuffer();
-
- mUploader.upload(mFileStream, mBoard, mSerial, mCallBack);
-
- mSerial.setUartConfig(tmpUartConfig); // recover if already
- // open
- mSerial.clearBuffer();
- mSerial.startReadListener();
- if (serialIsNull) {
- mSerial.close();
- }
-
- mBoard = null;
- mFileStream = null;
- mCallBack = null;
- mUploader = null;
- }}}
- }
- });
-
- mUploadThread.start();
- }
-
- public void cancelUpload() {
- if(mUploadThread == null){ return; }
- mUploadThread.interrupt();
- }
-
- /**
- * Callbacks of program process
- * normal process:
- * onPreUpload() -> onUploading -> onPostUpload
- * cancel:
- * onPreUpload() -> onUploading -> onCancel -> onPostUpload
- * error:
- * onPreUpload |
- * onUploading | -> onError
- * onPostUpload |
- * @author keisuke
- *
- */
- public interface UploadCallBack{
- /*
- * Callback methods
- */
- void onPreUpload();
- void onUploading(int value);
- void onPostUpload(boolean success);
- void onCancel();
- void onError(UploadErrors err);
- }
-
- /**
- * Gets opened or closed status
- * @return true : opened, false : closed
- * @throws RuntimeException
- */
- public boolean isOpened() throws RuntimeException {
- synchronized (LOCK) {
- if(mSerial == null) return false;
- return mSerial.isOpened();
+ return mSerial.isOpened();
+ }
}
- }
-
- /**
- * Sets Serial Configuration
- * @param settings
- */
- public void setConfig(UartConfig settings) throws RuntimeException{
- synchronized (LOCK) {
- if(mSerial == null) return;
- mSerial.setUartConfig(settings);
+
+ /**
+ * Sets Serial Configuration
+ *
+ * @param settings
+ */
+ public void setConfig(UartConfig settings) throws RuntimeException {
+ synchronized(LOCK) {
+ if(mSerial == null) {
+ return;
+ }
+ mSerial.setUartConfig(settings);
+ }
}
- }
-
- /**
- * Sets Baud Rate
- * @param baudrate any baud-rate e.g. 9600
- * @return true : successful, false : fail
- */
- public boolean setBaudrate(int baudrate) throws RuntimeException{
- synchronized (LOCK) {
- if(mSerial == null) return false;
- return mSerial.setBaudrate(baudrate);
+
+ /**
+ * Sets Baud Rate
+ *
+ * @param baudrate any baud-rate e.g. 9600
+ * @return true : successful, false : fail
+ */
+ public boolean setBaudrate(int baudrate) throws RuntimeException {
+ synchronized(LOCK) {
+ if(mSerial == null) {
+ return false;
+ }
+ return mSerial.setBaudrate(baudrate);
+ }
}
- }
-
- /**
- * Sets Data Bits
- * @param dataBits data bits e.g. UartConfig.DATA_BITS8
- * @return true : successful, false : fail
- */
- public boolean setDataBits(int dataBits) throws RuntimeException{
- synchronized (LOCK) {
- if(mSerial == null) return false;
- return mSerial.setDataBits(dataBits);
+
+ /**
+ * Sets Data Bits
+ *
+ * @param dataBits data bits e.g. UartConfig.DATA_BITS8
+ * @return true : successful, false : fail
+ */
+ public boolean setDataBits(int dataBits) throws RuntimeException {
+ synchronized(LOCK) {
+ if(mSerial == null) {
+ return false;
+ }
+ return mSerial.setDataBits(dataBits);
+ }
}
- }
-
- /**
- * Sets Parity Bits
- * @param parity parity bits e.g. UartConfig.PARITY_NONE
- * @return true : successful, false : fail
- */
- public boolean setParity(int parity) throws RuntimeException{
- synchronized (LOCK) {
- if(mSerial == null) return false;
- return mSerial.setParity(parity);
+
+ /**
+ * Sets Parity Bits
+ *
+ * @param parity parity bits e.g. UartConfig.PARITY_NONE
+ * @return true : successful, false : fail
+ */
+ public boolean setParity(int parity) throws RuntimeException {
+ synchronized(LOCK) {
+ if(mSerial == null) {
+ return false;
+ }
+ return mSerial.setParity(parity);
+ }
}
- }
-
- /**
- * Sets Stop bits
- * @param stopBits stop bits e.g. UartConfig.STOP_BITS1
- * @return true : successful, false : fail
- */
- public boolean setStopBits(int stopBits) throws RuntimeException{
- synchronized (LOCK) {
- if(mSerial == null) return false;
- return mSerial.setStopBits(stopBits);
+
+ /**
+ * Sets Stop bits
+ *
+ * @param stopBits stop bits e.g. UartConfig.STOP_BITS1
+ * @return true : successful, false : fail
+ */
+ public boolean setStopBits(int stopBits) throws RuntimeException {
+ synchronized(LOCK) {
+ if(mSerial == null) {
+ return false;
+ }
+ return mSerial.setStopBits(stopBits);
+ }
+ }
+
+ /**
+ * Sets flow control DTR/RTS
+ *
+ * @param dtrOn true then DTR on
+ * @param rtsOn true then RTS on
+ * @return true : successful, false : fail
+ */
+ public boolean setDtrRts(boolean dtrOn, boolean rtsOn) throws RuntimeException {
+ synchronized(LOCK) {
+ if(mSerial == null) {
+ return false;
+ }
+ return mSerial.setDtrRts(dtrOn, rtsOn);
+ }
+ }
+
+ public String getDriverName() {
+ if(mSerial == null) {
+ return "None";
+ }
+ return mSerial.getClass().getName();
+ }
+ public String getPhysicalConnectionName() {
+ if(mSerial == null) {
+ return "No Physical Connection";
+ }
+ return mSerial.getPhysicalConnectionName();
+ }
+
+ public int getPhysicalConnectionType() {
+ if(mSerial == null) {
+ return 0;
+ }
+ return mSerial.getPhysicalConnectionType();
}
- }
-
- /**
- * Sets flow control DTR/RTS
- * @param dtrOn true then DTR on
- * @param rtsOn true then RTS on
- * @return true : successful, false : fail
- */
- public boolean setDtrRts(boolean dtrOn, boolean rtsOn) throws RuntimeException{
- synchronized (LOCK) {
- if(mSerial == null) return false;
- return mSerial.setDtrRts(dtrOn, rtsOn);
+ public void setDebug(boolean flag) {
+ if(mSerial != null) {
+ mSerial.setDebug(flag);
+ }
}
- }
}
diff --git a/PhysicaloidLibrary/src/com/physicaloid/lib/UsbVidList.java b/PhysicaloidLibrary/src/com/physicaloid/lib/UsbVidList.java
index 951c02d..bad2053 100644
--- a/PhysicaloidLibrary/src/com/physicaloid/lib/UsbVidList.java
+++ b/PhysicaloidLibrary/src/com/physicaloid/lib/UsbVidList.java
@@ -18,11 +18,13 @@
public enum UsbVidList {
ARDUINO (0x2341),
+ DCCDUINO (0x1A86),
FTDI (0x0403),
MBED_LPC1768 (0x0d28),
MBED_LPC11U24 (0x0d28),
MBED_FRDM_KL25Z_OPENSDA_PORT (0x1357),
MBED_FRDM_KL25Z_KL25Z_PORT (0x15a2),
+ WCH (0x4348),
CP210X (0x10C4);
int vid;
diff --git a/PhysicaloidLibrary/src/com/physicaloid/lib/bluetooth/driver/uart/UartBluetooth.java b/PhysicaloidLibrary/src/com/physicaloid/lib/bluetooth/driver/uart/UartBluetooth.java
new file mode 100644
index 0000000..9b44748
--- /dev/null
+++ b/PhysicaloidLibrary/src/com/physicaloid/lib/bluetooth/driver/uart/UartBluetooth.java
@@ -0,0 +1,431 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.physicaloid.lib.bluetooth.driver.uart;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothServerSocket;
+import android.bluetooth.BluetoothSocket;
+import android.content.Context;
+import android.util.Log;
+import com.physicaloid.BuildConfig;
+import com.physicaloid.lib.Physicaloid;
+import com.physicaloid.lib.framework.SerialCommunicator;
+import com.physicaloid.lib.usb.driver.uart.ReadLisener;
+import com.physicaloid.lib.usb.driver.uart.ReadListener;
+import com.physicaloid.lib.usb.driver.uart.UartConfig;
+import com.physicaloid.misc.RingBuffer;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ *
+ * @author root
+ */
+public class UartBluetooth extends SerialCommunicator {
+
+ private static final String TAG = UartBluetooth.class.getSimpleName();
+ private boolean DEBUG_SHOW = false;
+ private static final int DEFAULT_BAUDRATE = 9600;
+ private UartConfig mUartConfig;
+ private static final int RING_BUFFER_SIZE = 1024;
+ private static final int READ_BUFFER_SIZE = 256;
+ private static final int WRITE_BUFFER_SIZE = 256;
+ private RingBuffer mBuffer;
+ private boolean mReadThreadStop = true;
+ private boolean isOpened;
+ private String mBlueName;
+ private static final UUID uu = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
+ private BluetoothSocket DATA_socket;
+ volatile boolean DATA_keep_going = true;
+ volatile boolean DATA_still_going = true;
+ private DataOutputStream DATA_OUT;
+ private DataInputStream DATA_IN;
+ private BluetoothAdapter mBluetoothAdapter;
+ private BluetoothServerSocket serverSocket;
+
+ public UartBluetooth(Context context, String BlueName) {
+ super(context);
+ mUartConfig = new UartConfig();
+ mBuffer = new RingBuffer(RING_BUFFER_SIZE);
+ mBlueName = BlueName;
+ isOpened = false;
+ DATA_socket = null;
+ DATA_OUT = null;
+ DATA_IN = null;
+ }
+
+ @Override
+ public boolean open() {
+ if(!init()) {
+ return false;
+ }
+ if(!setBaudrate(DEFAULT_BAUDRATE)) {
+ return false;
+ }
+ mBuffer.clear();
+ startRead();
+ isOpened = true;
+ return true;
+ }
+ private Runnable connect_DATA = new Runnable() {
+
+ InetAddress serverAddr;
+
+ @Override
+ @SuppressWarnings("CallToThreadDumpStack")
+ public void run() {
+ while(DATA_keep_going) {
+ try {
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ if(mBluetoothAdapter != null) {
+ if(mBluetoothAdapter.isEnabled()) {
+ serverSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(mBlueName, uu);
+ DATA_socket = serverSocket.accept();
+ DATA_OUT = new DataOutputStream(DATA_socket.getOutputStream());
+ DATA_IN = new DataInputStream(DATA_socket.getInputStream());
+ DATA_still_going = false;
+ return;
+ }
+ }
+ } catch(Exception ex) {
+ Log.d(TAG, ex.toString());
+ ex.printStackTrace();
+ }
+ }
+ DATA_still_going = false;
+ }
+ };
+
+ @SuppressWarnings({"SleepWhileInLoop", "CallToThreadDumpStack"})
+ private boolean init() {
+ DATA_keep_going = true;
+ DATA_still_going = true;
+
+ Log.d(TAG, "********************* Bluetooth Connecting DATA **************");
+ new Thread(connect_DATA).start();
+ Log.d(TAG, "********************* Bluetooth WAITING **************");
+ // timeout after how many seconds? How about 30?
+ int timeout = (30 * 1000) / 50;
+ while(DATA_still_going && (timeout > 0)) {
+ try {
+ // STALL APP :-)
+ Thread.sleep(50);
+ timeout--;
+ } catch(InterruptedException ex) {
+ }
+ }
+ if(timeout == 0) {
+ // did not connect, kill threads.
+ DATA_keep_going = false;
+ while(DATA_still_going) {
+ try {
+ Thread.sleep(50);
+ } catch(InterruptedException ex) {
+ }
+ }
+ Log.d(TAG, "********************* Bluetooth Timed out! **************");
+ return false;
+ }
+ try {
+ DATA_OUT = new DataOutputStream(DATA_socket.getOutputStream());
+ DATA_IN = new DataInputStream(DATA_socket.getInputStream());
+ } catch(Exception ex) {
+ Log.d(TAG, ex.toString());
+ ex.printStackTrace();
+ }
+ Log.d(TAG, "********************* Bluetooth Connected! **************");
+ return true;
+ }
+
+ @Override
+ @SuppressWarnings({"SleepWhileInLoop", "CallToThreadDumpStack"})
+ public boolean close() {
+ stopRead();
+ isOpened = false;
+ if(DATA_OUT != null) {
+ try {
+ DATA_OUT.close();
+ } catch(Exception ex) {
+ Log.d(TAG, ex.toString());
+ ex.printStackTrace();
+ }
+ }
+ if(DATA_IN != null) {
+ try {
+ DATA_IN.close();
+ } catch(Exception ex) {
+ Log.d(TAG, ex.toString());
+ ex.printStackTrace();
+ }
+ }
+ if(DATA_socket != null) {
+ try {
+ DATA_socket.close();
+ } catch(Exception ex) {
+ Log.d(TAG, ex.toString());
+ ex.printStackTrace();
+ }
+ }
+ DATA_keep_going = false;
+ while(DATA_still_going) {
+ try {
+ Thread.sleep(50);
+ } catch(InterruptedException ex) {
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public int read(byte[] buf, int size) {
+ return mBuffer.get(buf, size);
+ }
+
+ @Override
+ @SuppressWarnings("CallToThreadDumpStack")
+ public int write(byte[] buf, int size) {
+ try {
+ DATA_OUT.write(buf, 0, size);
+ DATA_OUT.flush();
+ } catch(Exception ex) {
+ Log.d(TAG, ex.toString());
+ ex.printStackTrace();
+ }
+ return size;
+ }
+
+ @Override
+ public boolean setBaudrate(int baudrate) {
+ // We don't do this...
+ mUartConfig.baudrate = baudrate;
+ return true;
+ }
+
+ @Override
+ public boolean setDataBits(int dataBits) {
+ // We don't do this...
+ mUartConfig.dataBits = dataBits;
+ return true;
+ }
+
+ @Override
+ public boolean setParity(int parity) {
+ // We don't do this...
+ mUartConfig.parity = parity;
+ return true;
+ }
+
+ @Override
+ public boolean setStopBits(int stopBits) {
+ // We don't do this...
+ mUartConfig.stopBits = stopBits;
+ return true;
+ }
+
+ @Override
+ public boolean setDtrRts(boolean dtrOn, boolean rtsOn) {
+ // We don't do this...
+ mUartConfig.dtrOn = dtrOn;
+ mUartConfig.rtsOn = rtsOn;
+ return true;
+ }
+
+ //////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////
+ /**
+ * Sets Uart configurations
+ *
+ * @param config configurations
+ * @return true : successful, false : fail
+ */
+ public boolean setUartConfig(UartConfig config) {
+ boolean res;
+ boolean ret = true;
+ if(mUartConfig.baudrate != config.baudrate) {
+ res = setBaudrate(config.baudrate);
+ ret = ret && res;
+ }
+
+ if(mUartConfig.dataBits != config.dataBits) {
+ res = setDataBits(config.dataBits);
+ ret = ret && res;
+ }
+
+ if(mUartConfig.parity != config.parity) {
+ res = setParity(config.parity);
+ ret = ret && res;
+ }
+
+ if(mUartConfig.stopBits != config.stopBits) {
+ res = setStopBits(config.stopBits);
+ ret = ret && res;
+ }
+
+ if(mUartConfig.dtrOn != config.dtrOn
+ || mUartConfig.rtsOn != config.rtsOn) {
+ res = setDtrRts(config.dtrOn, config.rtsOn);
+ ret = ret && res;
+ }
+
+ return ret;
+ }
+
+ @Override
+ public boolean isOpened() {
+ return isOpened;
+ }
+
+ @Override
+ public UartConfig getUartConfig() {
+ return mUartConfig;
+ }
+
+ @Override
+ public int getBaudrate() {
+ return mUartConfig.baudrate;
+ }
+
+ @Override
+ public int getDataBits() {
+ return mUartConfig.dataBits;
+ }
+
+ @Override
+ public int getParity() {
+ return mUartConfig.parity;
+ }
+
+ @Override
+ public int getStopBits() {
+ return mUartConfig.stopBits;
+ }
+
+ @Override
+ public boolean getDtr() {
+ return mUartConfig.dtrOn;
+ }
+
+ @Override
+ public boolean getRts() {
+ return mUartConfig.rtsOn;
+ }
+
+ @Override
+ public void clearBuffer() {
+ mBuffer.clear();
+ }
+ //////////////////////////////////////////////////////////
+ // Listener for reading uart
+ //////////////////////////////////////////////////////////
+ private List uartReadListenerList = new ArrayList();
+ private boolean mStopReadListener = false;
+
+ @Override
+ public void addReadListener(ReadListener listener) {
+ uartReadListenerList.add(listener);
+ }
+
+ @Override
+ @Deprecated
+ public void addReadListener(ReadLisener listener) {
+ addReadListener((ReadListener) listener);
+ }
+
+ @Override
+ public void clearReadListener() {
+ uartReadListenerList.clear();
+ }
+
+ @Override
+ public void startReadListener() {
+ mStopReadListener = false;
+ }
+
+ @Override
+ public void stopReadListener() {
+ mStopReadListener = true;
+ }
+
+ private void onRead(int size) {
+ if(mStopReadListener) {
+ return;
+ }
+ for(ReadListener listener : uartReadListenerList) {
+ listener.onRead(size);
+ }
+ }
+ //////////////////////////////////////////////////////////
+
+ private void stopRead() {
+ mReadThreadStop = true;
+ }
+
+ private void startRead() {
+ if(mReadThreadStop) {
+ mReadThreadStop = false;
+ new Thread(mLoop).start();
+ }
+ }
+ private Runnable mLoop = new Runnable() {
+
+ @Override
+ public void run() {
+ int len;
+ byte[] rbuf = new byte[READ_BUFFER_SIZE];
+ android.os.Process.setThreadPriority(-20);
+ //ByteBuffer buf = ByteBuffer.wrap(rbuf);
+ for(;;) {
+ try {
+ // this is the main loop for transferring
+ len = 0;
+ //if (request.queue(buf, rbuf.length)) {
+ // response = mConnection.requestWait();
+ // if (response != null) {
+ // len = buf.position();
+ // }
+
+ while(DATA_IN.available() > 0 && len < READ_BUFFER_SIZE) {
+ DATA_IN.read(rbuf, len, 1);
+ len++;
+ }
+ if(len > 0) {
+ mBuffer.add(rbuf, len);
+ onRead(len);
+ }
+ if(mReadThreadStop) {
+ return;
+ }
+ } catch(IOException ex) {
+ // TO-DO: Needs to broadcast that it has been disconnected....
+ }
+ }
+ } // end of run()
+ }; // end of runnable
+
+ @Override
+ public String getPhysicalConnectionName() {
+ return Physicaloid.BLUETOOTH_STRING;
+ }
+
+ @Override
+ public int getPhysicalConnectionType() {
+ return Physicaloid.BLUETOOTH;
+ }
+
+ @Override
+ public void setDebug(boolean flag) {
+ DEBUG_SHOW = flag;
+ }
+}
diff --git a/PhysicaloidLibrary/src/com/physicaloid/lib/fpga/PhysicaloidFpga.java b/PhysicaloidLibrary/src/com/physicaloid/lib/fpga/PhysicaloidFpga.java
index 3b9a7cc..afac32c 100644
--- a/PhysicaloidLibrary/src/com/physicaloid/lib/fpga/PhysicaloidFpga.java
+++ b/PhysicaloidLibrary/src/com/physicaloid/lib/fpga/PhysicaloidFpga.java
@@ -1,9 +1,8 @@
package com.physicaloid.lib.fpga;
import android.content.Context;
-
-import com.physicaloid.lib.Physicaloid;
import com.physicaloid.BuildConfig;
+import com.physicaloid.lib.Physicaloid;
public class PhysicaloidFpga extends Physicaloid {
@SuppressWarnings("unused")
diff --git a/PhysicaloidLibrary/src/com/physicaloid/lib/fpga/PhysicaloidFpgaConfigurator.java b/PhysicaloidLibrary/src/com/physicaloid/lib/fpga/PhysicaloidFpgaConfigurator.java
index 3cce930..5aae4a2 100644
--- a/PhysicaloidLibrary/src/com/physicaloid/lib/fpga/PhysicaloidFpgaConfigurator.java
+++ b/PhysicaloidLibrary/src/com/physicaloid/lib/fpga/PhysicaloidFpgaConfigurator.java
@@ -1,12 +1,10 @@
package com.physicaloid.lib.fpga;
-import java.io.IOException;
-import java.io.InputStream;
-
import android.util.Log;
-
import com.physicaloid.BuildConfig;
import com.physicaloid.lib.framework.SerialCommunicator;
+import java.io.IOException;
+import java.io.InputStream;
public class PhysicaloidFpgaConfigurator {
@@ -28,15 +26,15 @@ public PhysicaloidFpgaConfigurator(SerialCommunicator comm) {
public boolean configuration(InputStream is) {
if(is == null) return false;
byte[] rbuf = new byte[1];
- int retlen=0;
- boolean readStatus=true;
+ int retlen;
+ boolean readStatus=false;
//////////////////////////////////////////////////////
// Switch user mode and check PS mode on
//////////////////////////////////////////////////////
if(DEBUG_SHOW){Log.d(TAG,"Configuration Step.1 : Switch user mode.");}
- for(int i=0; i 0) {
- startTime = System.currentTimeMillis();
- if(DEBUG_SHOW_DRAIN) {
- Log.d(TAG, "drain("+retval+") : " +toHexStr(buf[0]));
- }
- }
- endTime = System.currentTimeMillis();
- if((endTime - startTime) > 250) {break;}
+public class Stk500V2 extends UploadProtocol {
+
+ private static final String TAG = Stk500V2.class.getSimpleName();
+ private static final boolean DEBUG_NOT_SHOW = true || !BuildConfig.DEBUG;
+ private static final boolean DEBUG_SHOW_READ = true && !DEBUG_NOT_SHOW;
+ private static final boolean DEBUG_SHOW_WRITE = true && !DEBUG_NOT_SHOW;
+ private static final boolean DEBUG_SHOW_COMMAND = true && !DEBUG_NOT_SHOW;
+ private static final boolean DEBUG_SHOW_COMMAND_STATUS = true && !DEBUG_NOT_SHOW;
+ private static final boolean DEBUG_SHOW_RECV = true && !DEBUG_NOT_SHOW;
+ private static final boolean DEBUG_SHOW_GETSYNC = true && !DEBUG_NOT_SHOW;
+ private static final boolean DEBUG_SHOW_DRAIN = true && !DEBUG_NOT_SHOW;
+ private static final int RETRIES = 1; // was 5. Why is it 5?
+ // *** XPROG command constants ***
+ private static final int CMD_XPROG = 0x50;
+ private static final int CMD_XPROG_SETMODE = 0x51;
+ private static final int XPRG_ERR_OK = 0;
+ private static final int XPRG_ERR_FAILED = 1;
+ private static final int XPRG_ERR_COLLISION = 2;
+ private static final int XPRG_ERR_TIMEOUT = 3;
+ // *****************[ STK status constants ]***************************
+ // Success
+ private static final int STATUS_CMD_OK = 0x00;
+ // Warnings
+ private static final int STATUS_CMD_TOUT = 0x80;
+ private static final int STATUS_RDY_BSY_TOUT = 0x81;
+ private static final int STATUS_SET_PARAM_MISSING = 0x82;
+ // Errors
+ private static final int STATUS_CMD_FAILED = 0xC0;
+ @SuppressWarnings("unused")
+ private static final int STATUS_CKSUM_ERROR = 0xC1;
+ @SuppressWarnings("unused")
+ private static final int STATUS_CMD_UNKNOWN = 0xC9;
+ @SuppressWarnings("unused")
+ private static final int STATUS_CMD_ILLEGAL_PARAMETER = 0xCA;
+ // Status
+ @SuppressWarnings("unused")
+ private static final int STATUS_ISP_READY = 0x00;
+ @SuppressWarnings("unused")
+ private static final int STATUS_CONN_FAIL_MOSI = 0x01;
+ @SuppressWarnings("unused")
+ private static final int STATUS_CONN_FAIL_RST = 0x02;
+ @SuppressWarnings("unused")
+ private static final int STATUS_CONN_FAIL_SCK = 0x04;
+ @SuppressWarnings("unused")
+ private static final int STATUS_TGT_NOT_DETECTED = 0x10;
+ @SuppressWarnings("unused")
+ private static final int STATUS_TGT_REVERSE_INSERTED = 0x20;
+ // hw_status
+ // Bits in status variable
+ // Bit 0-3: Slave MCU
+ // Bit 4-7: Master MCU
+ @SuppressWarnings("unused")
+ private static final int STATUS_AREF_ERROR = 0;
+ // Set to '1' if AREF is short circuited
+ @SuppressWarnings("unused")
+ private static final int STATUS_VTG_ERROR = 4;
+ // Set to '1' if VTG is short circuited
+ @SuppressWarnings("unused")
+ private static final int STATUS_RC_CARD_ERROR = 5;
+ // Set to '1' if board id changes when board is powered
+ @SuppressWarnings("unused")
+ private static final int STATUS_PROGMODE = 6;
+ // Set to '1' if board is in programming mode
+ @SuppressWarnings("unused")
+ private static final int STATUS_POWER_SURGE = 7;
+ // Set to '1' if board draws excessive current
+ // *****************[ STK message constants ]***************************
+ private static final byte MESSAGE_START = 0x1B; //= ESC = 27 decimal
+ private static final byte TOKEN = 0x0E;
+ // *****************[ STK general command constants ]**************************
+ private static final byte CMD_SIGN_ON = 0x01;
+ @SuppressWarnings("unused")
+ private static final byte CMD_SET_PARAMETER = 0x02;
+ @SuppressWarnings("unused")
+ private static final byte CMD_GET_PARAMETER = 0x03;
+ @SuppressWarnings("unused")
+ private static final byte CMD_SET_DEVICE_PARAMETERS = 0x04;
+ @SuppressWarnings("unused")
+ private static final byte CMD_OSCCAL = 0x05;
+ private static final byte CMD_LOAD_ADDRESS = 0x06;
+ @SuppressWarnings("unused")
+ private static final byte CMD_FIRMWARE_UPGRADE = 0x07;
+ @SuppressWarnings("unused")
+ private static final byte CMD_CHECK_TARGET_CONNECTION = 0x0D;
+ @SuppressWarnings("unused")
+ private static final byte CMD_LOAD_RC_ID_TABLE = 0x0E;
+ @SuppressWarnings("unused")
+ private static final byte CMD_LOAD_EC_ID_TABLE = 0x0F;
+ // *****************[ STK ISP command constants ]******************************
+ private static final byte CMD_ENTER_PROGMODE_ISP = 0x10;
+ private static final byte CMD_LEAVE_PROGMODE_ISP = 0x11;
+ @SuppressWarnings("unused")
+ private static final byte CMD_CHIP_ERASE_ISP = 0x12;
+ private static final byte CMD_PROGRAM_FLASH_ISP = 0x13;
+ @SuppressWarnings("unused")
+ private static final byte CMD_READ_FLASH_ISP = 0x14;
+ private static final byte CMD_PROGRAM_EEPROM_ISP = 0x15;
+ @SuppressWarnings("unused")
+ private static final byte CMD_READ_EEPROM_ISP = 0x16;
+ @SuppressWarnings("unused")
+ private static final byte CMD_PROGRAM_FUSE_ISP = 0x17;
+ @SuppressWarnings("unused")
+ private static final byte CMD_READ_FUSE_ISP = 0x18;
+ @SuppressWarnings("unused")
+ private static final byte CMD_PROGRAM_LOCK_ISP = 0x19;
+ @SuppressWarnings("unused")
+ private static final byte CMD_READ_LOCK_ISP = 0x1A;
+ @SuppressWarnings("unused")
+ private static final byte CMD_READ_SIGNATURE_ISP = 0x1B;
+ @SuppressWarnings("unused")
+ private static final byte CMD_READ_OSCCAL_ISP = 0x1C;
+ @SuppressWarnings("unused")
+ private static final byte CMD_SPI_MULTI = 0x1D;
+ // *****************[ STK answer constants ]***************************
+ private static final int ANSWER_CKSUM_ERROR = 0xB0;
+ private static final int PGMTYPE_UNKNOWN = 0;
+ private static final int PGMTYPE_STK500 = 1;
+ private static final int PGMTYPE_AVRISP = 2;
+ private static final int PGMTYPE_AVRISP_MKII = 3;
+ @SuppressWarnings("unused")
+ private static final int PGMTYPE_JTAGICE_MKII = 4;
+ private static final int PGMTYPE_STK600 = 5;
+ private int mCommandSeqNum = 1;
+ private int mProgrammerType = PGMTYPE_UNKNOWN;
+ private SerialCommunicator mComm;
+ private AvrConf mAVRConf;
+ private AVRMem mAVRMem;
+
+ public Stk500V2() {
}
- return retval;
- }
- private int send(byte[] data, int len) {
- byte[] buf = new byte[275 + 6]; // max MESSAGE_BODY of 275 bytes, 6 bytes overhead
- int i;
-
- /*
- * if (PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII || PDATA(pgm)->pgmtype
- * == PGMTYPE_STK600) return stk500v2_send_mk2(pgm, data, len); else if
- * (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) return
- * stk500v2_jtagmkII_send(pgm, data, len);
- */
- buf[0] = MESSAGE_START;
- buf[1] = (byte) mCommandSeqNum;
- buf[2] = (byte) (len / 256);
- buf[3] = (byte) (len % 256);
- buf[4] = TOKEN;
- System.arraycopy(data, 0, buf, 5, len);
-
- // calculate the XOR checksum
- buf[5 + len] = 0;
- for (i = 0; i < 5 + len; i++)
- buf[5 + len] ^= buf[i];
-
- return write(buf, len + 6);
-
- }
-
- private int command(byte[] buf, int len, int maxlen) {
- int i;
- int tries = 0;
- int status;
- boolean bRetry=true;
-
- if(DEBUG_SHOW_COMMAND) { Log.d(TAG, "STK500V2.command("+toHexStr(buf, len)+", "+len+")"); }
-
- while (bRetry) {
- bRetry = false;
- tries++;
-
- // send the command to the programmer
- send(buf, len);
- // attempt to read the status back
- status = recv(buf, maxlen);
-
- if (DEBUG_SHOW_COMMAND_STATUS) {
- Log.d(TAG, "STK500V2.command(): status:"+status+",buf{"+toHexStr(buf, buf.length)+"}");
- }
-
- // if we got a successful readback, return
- if (status > 0) {
- if (DEBUG_SHOW_COMMAND_STATUS) {
- Log.d(TAG, "status = " + status);
- }
- if (status < 2) {
- Log.e(TAG, "STK500V2.command(): short reply\n");
- return -1;
- }
- if (buf[0] == CMD_XPROG_SETMODE || buf[0] == CMD_XPROG) {
- /*
- * Decode XPROG wrapper errors.
- */
- String msg;
-
- /*
- * For CMD_XPROG_SETMODE, the status is returned in buf[1].
- * For CMD_XPROG, buf[1] contains the XPRG_CMD_* command,
- * and buf[2] contains the status.
- */
- i = (buf[0] == CMD_XPROG_SETMODE) ? 1 : 2;
-
- if (buf[i] != XPRG_ERR_OK) {
- switch (buf[i]) {
- case XPRG_ERR_FAILED:
- msg = "Failed";
- break;
- case XPRG_ERR_COLLISION:
- msg = "Collision";
- break;
- case XPRG_ERR_TIMEOUT:
- msg = "Timeout";
- break;
- default:
- msg = "Unknown";
- break;
- }
- Log.e(TAG, "STK500V2.command(): error in " +
- (buf[0] == CMD_XPROG_SETMODE ? "CMD_XPROG_SETMODE" : "CMD_XPROG")
- + ": " + msg);
- return -1;
- }
- return 0;
- } else {
- /*
- * Decode STK500v2 errors.
- */
- if (buf[1] >= STATUS_CMD_TOUT && buf[1] < 0xa0) {
- String msg;
-// byte[] msgbuf = new byte[30];
- switch (buf[1]) {
- case (byte) STATUS_CMD_TOUT:
- msg = "Command timed out";
- break;
+ public void setSerial(SerialCommunicator comm) {
+ mComm = comm;
+ }
+ // Warning exporting non-public type through public API
- case (byte) STATUS_RDY_BSY_TOUT:
- msg = "Sampling of the RDY/nBSY pin timed out";
- break;
+ public void setConfig(AvrConf avrConf, AVRMem avrMem) {
+ mAVRConf = avrConf;
+ mAVRMem = avrMem;
+ }
- case (byte) STATUS_SET_PARAM_MISSING:
- msg = "The `Set Device Parameters' have not been "
- + "executed in advance of this command";
+ @SuppressWarnings("unused")
+ private void init() {
+ mCommandSeqNum = 1;
+ }
- default:
- msg = "unknown, code " + Integer.toHexString((int) buf[1]);
- break;
+ // リードバッファをカラにする Empty the read buffer
+ private int drain() {
+ byte[] buf = new byte[1];
+ int retval = 0;
+ long endTime;
+ long startTime = System.currentTimeMillis();
+ while(true) {
+ retval = mComm.read(buf, 1);
+ if(retval > 0) {
+ startTime = System.currentTimeMillis();
+ if(DEBUG_SHOW_DRAIN) {
+ Log.d(TAG, "drain(" + retval + ") : " + toHexStr(buf[0]));
+ }
}
- if (DEBUG_SHOW_COMMAND_STATUS) {
- Log.v(TAG, "STK500V2.command(): warning: " + msg);
+ endTime = System.currentTimeMillis();
+ if((endTime - startTime) > 250) {
+ break;
}
- } else if (buf[1] == (byte) STATUS_CMD_OK) {
- return status;
- } else if (buf[1] == (byte) STATUS_CMD_FAILED) {
- Log.e(TAG, "STK500V2.command(): command failed");
- } else {
- Log.e(TAG,
- "STK500V2.command(): unknown status "
- + Integer.toHexString((int) buf[1]));
- }
- return -1;
}
- } // end of if (status > 0)
-
- // otherwise try to sync up again
- status = getsync();
- if (status != 0) {
- if (tries > RETRIES) {
- Log.e(TAG,
- "STK500V2.command(): failed miserably to execute command "
- + Integer.toHexString((int) buf[0]));
- return -1;
- } else {
- bRetry = true;
+ return retval;
+ }
+
+ private int send(byte[] data, int len) {
+ byte[] buf = new byte[275 + 6]; // max MESSAGE_BODY of 275 bytes, 6 bytes overhead
+ int i;
+
+ /*
+ * if (PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII ||
+ * PDATA(pgm)->pgmtype == PGMTYPE_STK600) return
+ * stk500v2_send_mk2(pgm, data, len); else if
+ * (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) return
+ * stk500v2_jtagmkII_send(pgm, data, len);
+ */
+ buf[0] = MESSAGE_START;
+ buf[1] = (byte) mCommandSeqNum;
+ buf[2] = (byte) (len / 256);
+ buf[3] = (byte) (len % 256);
+ buf[4] = TOKEN;
+ System.arraycopy(data, 0, buf, 5, len);
+
+ // calculate the XOR checksum
+ buf[5 + len] = 0;
+ for(i = 0; i < 5 + len; i++) {
+ buf[5 + len] ^= buf[i];
}
- }
- } // end of while(bRetry)
- if (DEBUG_SHOW_COMMAND) {
- Log.d(TAG, " = 0");
+ return write(buf, len + 6);
+
}
- return 0;
- } // end of private int command()
+ private int command(byte[] buf, int len, int maxlen) {
+ int i;
+ int tries = 0;
+ int status;
+ boolean bRetry = true;
- private boolean compareByteArrayWithString(byte[] buf,int bufPos, String str) {
- byte[] tmpbuf = new byte[str.length()];
- System.arraycopy(buf, bufPos, tmpbuf, 0, str.length());
- if(Arrays.equals(tmpbuf, str.getBytes())) {
- return true;
- }
- return false;
- }
-
- private static final String[] PROGRAMMER_NAME =
- {
- "unknown",
- "STK500",
- "AVRISP",
- "AVRISP mkII",
- "JTAG ICE mkII",
- "STK600",
- };
-
- @SuppressWarnings("unused")
- private static final int sINIT = 0;
- private static final int sSTART = 1;
- private static final int sSEQNUM = 2;
- private static final int sSIZE1 = 3;
- private static final int sSIZE2 = 4;
- private static final int sTOKEN = 5;
- private static final int sDATA = 6;
- private static final int sCSUM = 7;
- private static final int sDONE = 8;
-
- private static final int SERIAL_TIMEOUT = 2;
-
- int recv(byte[] buf, int length) {
- int state = sSTART;
- int msglen = 0;
- int curlen = 0;
- byte[] c = new byte[1];
- c[0] = 0;
- byte checksum = 0;
-
- long timeoutval = SERIAL_TIMEOUT; // seconds
+ if(DEBUG_SHOW_COMMAND) {
+ Log.d(TAG, "STK500V2.command(" + toHexStr(buf, len) + ", " + len + ")");
+ }
- /*
- * if (mProgrammerType == PGMTYPE_AVRISP_MKII || mProgrammerType ==
- * PGMTYPE_STK600) return stk500v2_recv_mk2(pgm, msg, maxsize); else if
- * (mProgrammerType == PGMTYPE_JTAGICE_MKII) return
- * stk500v2_jtagmkII_recv(pgm, msg, maxsize);
- */
- if (DEBUG_SHOW_RECV) {
- Log.v(TAG, "STK500V2.recv(): ");
- }
+ while(bRetry) {
+ bRetry = false;
+ tries++;
+
+ // send the command to the programmer
+ send(buf, len);
+ // attempt to read the status back
+ // Need to zero buffer
+ Arrays.fill(buf, 0, maxlen, (byte) 0);
+ status = recv(buf, maxlen);
+
+ if(DEBUG_SHOW_COMMAND_STATUS) {
+ Log.d(TAG, "STK500V2.command(): status:" + status + ",buf{" + toHexStr(buf, buf.length) + "}");
+ }
- long tstart = java.lang.System.currentTimeMillis();
+ // if we got a successful readback, return
+ if(status > 0) {
+ if(DEBUG_SHOW_COMMAND_STATUS) {
+ Log.d(TAG, "status = " + status);
+ }
+ if(status < 2) {
+ Log.e(TAG, "STK500V2.command(): short reply\n");
+ return -1;
+ }
+ if(buf[0] == CMD_XPROG_SETMODE || buf[0] == CMD_XPROG) {
+ /*
+ * Decode XPROG wrapper errors.
+ */
+ String msg;
+
+ /*
+ * For CMD_XPROG_SETMODE, the status is
+ * returned in buf[1]. For CMD_XPROG,
+ * buf[1] contains the XPRG_CMD_*
+ * command, and buf[2] contains the
+ * status.
+ */
+ i = (buf[0] == CMD_XPROG_SETMODE) ? 1 : 2;
+
+ if(buf[i] != XPRG_ERR_OK) {
+ switch(buf[i]) {
+ case XPRG_ERR_FAILED:
+ msg = "Failed";
+ break;
+ case XPRG_ERR_COLLISION:
+ msg = "Collision";
+ break;
+ case XPRG_ERR_TIMEOUT:
+ msg = "Timeout";
+ break;
+ default:
+ msg = "Unknown";
+ break;
+ }
+ Log.e(TAG, "STK500V2.command(): error in "
+ + (buf[0] == CMD_XPROG_SETMODE ? "CMD_XPROG_SETMODE" : "CMD_XPROG")
+ + ": " + msg);
+ return -1;
+ }
+ return 0;
+ } else {
+ /*
+ * Decode STK500v2 errors.
+ */
+ if(buf[1] >= STATUS_CMD_TOUT && buf[1] < 0xa0) {
+ String msg;
+// byte[] msgbuf = new byte[30];
+ switch(buf[1]) {
+ case (byte) STATUS_CMD_TOUT:
+ msg = "Command timed out";
+ break;
+
+ case (byte) STATUS_RDY_BSY_TOUT:
+ msg = "Sampling of the RDY/nBSY pin timed out";
+ break;
+
+ case (byte) STATUS_SET_PARAM_MISSING:
+ msg = "The `Set Device Parameters' have not been "
+ + "executed in advance of this command";
+ break;
+ default:
+ msg = "unknown, code " + Integer.toHexString((int) buf[1]);
+ break;
+ }
+ if(DEBUG_SHOW_COMMAND_STATUS) {
+ Log.v(TAG, "STK500V2.command(): warning: " + msg);
+ }
+ } else if(buf[1] == (byte) STATUS_CMD_OK) {
+ return status;
+ } else if(buf[1] == (byte) STATUS_CMD_FAILED) {
+ Log.e(TAG, "STK500V2.command(): command failed");
+ } else {
+ Log.e(TAG,
+ "STK500V2.command(): unknown status "
+ + Integer.toHexString((int) buf[1]));
+ }
+ return -1;
+ }
+ } // end of if (status > 0)
+
+ // otherwise try to sync up again
+ status = getsync();
+ if(status != 0) {
+ if(tries > RETRIES) {
+ Log.e(TAG,
+ "STK500V2.command(): failed miserably to execute command "
+ + Integer.toHexString((int) buf[0]));
+ return -1;
+ } else {
+ bRetry = true;
+ }
+ }
+ } // end of while(bRetry)
+
+ if(DEBUG_SHOW_COMMAND) {
+ Log.d(TAG, " = 0");
+ }
+ return 0;
+ } // end of private int command()
- while ((state != sDONE)) {
- if (read(c, 1) <= 0) {
- long tnow = java.lang.System.currentTimeMillis();
- if ((tnow - tstart) / 1000 > timeoutval) { // wuff -
- // signed/unsigned/overflow
- Log.e(TAG, "STK500V2.recv(): timeout");
- return -1;
+ private boolean compareByteArrayWithString(byte[] buf, int bufPos, String str) {
+ byte[] tmpbuf = new byte[str.length()];
+ System.arraycopy(buf, bufPos, tmpbuf, 0, str.length());
+ if(Arrays.equals(tmpbuf, str.getBytes())) {
+ return true;
}
- continue;
- }
- if (DEBUG_SHOW_RECV) { Log.d(TAG, "recv : "+toHexStr(c[0])); }
- checksum ^= c[0];
-
- switch (state) {
- case sSTART:
- if (DEBUG_SHOW_RECV) { Log.d(TAG, "hoping for start token..."); }
-
- if (c[0] == MESSAGE_START) {
- if (DEBUG_SHOW_RECV) { Log.d(TAG, "got it\n"); }
- checksum = MESSAGE_START;
- state = sSEQNUM;
- } else {
- if (DEBUG_SHOW_RECV) { Log.d(TAG, "sorry\n"); }
- }
- break;
-
- case sSEQNUM:
- if (DEBUG_SHOW_RECV) { Log.d(TAG, "hoping for sequence...\n"); }
-
- if (c[0] == mCommandSeqNum) {
- if (DEBUG_SHOW_RECV) { Log.d(TAG, "got it, incrementing\n"); }
- state = sSIZE1;
- mCommandSeqNum++;
- } else {
- if (DEBUG_SHOW_RECV) { Log.d(TAG, "sorry\n"); }
- state = sSTART;
- }
- break;
-
- case sSIZE1:
- if (DEBUG_SHOW_RECV) { Log.d(TAG, "hoping for size LSB\n"); }
- msglen = ((int) c[0]) * 256;
- state = sSIZE2;
- break;
-
- case sSIZE2:
- if (DEBUG_SHOW_RECV) { Log.d(TAG, "hoping for size MSB..."); }
- msglen += (int) c[0];
- if (DEBUG_SHOW_RECV) { Log.d(TAG, " msg is " + msglen + " bytes"); }
- state = sTOKEN;
- break;
-
- case sTOKEN:
- if (c[0] == TOKEN) {
- if (DEBUG_SHOW_RECV) { Log.d(TAG, "recv : sTOKEN : sDATA"); }
- state = sDATA;
- } else {
- if (DEBUG_SHOW_RECV) { Log.d(TAG, "recv : sTOKEN : sSTART"); }
- state = sSTART;
- }
- break;
-
- case sDATA:
- if (DEBUG_SHOW_RECV) { Log.d(TAG, "recv | sDATA | msglen:"+msglen+", curlen:"+curlen+", length:"+length+", c[0]:"+toHexStr(c[0])); }
- if (curlen < length) {
- buf[curlen] = c[0];
- } else {
- Log.e(TAG, "STK500V2.recv(): buffer too small, received " + curlen
- + " byte into " + length + " byte buffer");
- return -2;
- }
- if ((curlen == 0) && (buf[0] == ANSWER_CKSUM_ERROR)) {
- Log.e(TAG, "STK500V2.recv(): previous packet sent with wrong checksum");
- return -3;
- }
- curlen++;
- if (curlen == msglen) {
- state = sCSUM;
- }
- break;
-
- case sCSUM:
- if (DEBUG_SHOW_RECV) { Log.d(TAG, "recv | sCSUM"); }
- if (checksum == 0) {
- state = sDONE;
- } else {
- state = sSTART;
- Log.e(TAG, "STK500V2.recv(): checksum error");
- return -4;
- }
- break;
- default:
- Log.e(TAG, "STK500V2.recv(): unknown state");
- return -5;
- } /* switch */
- } /* while */
-
- return (int) (msglen + 6);
- }
-
- int getsync() {
- int tries = 0;
- byte[] buf = new byte[1];
- byte[] resp = new byte[32];
- int status;
- boolean bRetry = true;
-
- if (DEBUG_SHOW_GETSYNC) {
- Log.d(TAG, "STK500V2.getsync()");
+ return false;
}
+ private static final String[] PROGRAMMER_NAME = {
+ "unknown",
+ "STK500",
+ "AVRISP",
+ "AVRISP mkII",
+ "JTAG ICE mkII",
+ "STK600",};
+ @SuppressWarnings("unused")
+ private static final int sINIT = 0;
+ private static final int sSTART = 1;
+ private static final int sSEQNUM = 2;
+ private static final int sSIZE1 = 3;
+ private static final int sSIZE2 = 4;
+ private static final int sTOKEN = 5;
+ private static final int sDATA = 6;
+ private static final int sCSUM = 7;
+ private static final int sDONE = 8;
+ private static final int SERIAL_TIMEOUT = 2;
+
+ int recv(byte[] buf, int length) {
+ int state = sSTART;
+ int msglen = 0;
+ int curlen = 0;
+ byte[] c = new byte[1];
+ c[0] = 0;
+ byte checksum = 0;
+
+ long timeoutval = SERIAL_TIMEOUT; // seconds
+
+ /*
+ * if (mProgrammerType == PGMTYPE_AVRISP_MKII || mProgrammerType
+ * == PGMTYPE_STK600) return stk500v2_recv_mk2(pgm, msg,
+ * maxsize); else if (mProgrammerType == PGMTYPE_JTAGICE_MKII)
+ * return stk500v2_jtagmkII_recv(pgm, msg, maxsize);
+ */
+ if(DEBUG_SHOW_RECV) {
+ Log.v(TAG, "STK500V2.recv(): ");
+ }
- while (bRetry) {
- bRetry = false;
- tries++;
-
- // send the sync command and see if we can get there
- buf[0] = CMD_SIGN_ON;
- send(buf, 1);
-
- // try to get the response back and see where we got
- status = recv(resp, resp.length);
-
- // if we got bytes returned, check to see what came back
- if (status > 0) {
- if ((resp[0] == CMD_SIGN_ON) && (resp[1] == STATUS_CMD_OK) &&
- (status > 3)) {
- // success!
- int siglen = resp[2];
- if (siglen >= "STK500_2".length() &&
- compareByteArrayWithString(resp, 3, "STK500_2")) {
- mProgrammerType = PGMTYPE_STK500;
- } else if (siglen >= "AVRISP_2".length() &&
- compareByteArrayWithString(resp, 3, "AVRISP_2")) {
- mProgrammerType = PGMTYPE_AVRISP;
- } else if (siglen >= "AVRISP_MK2".length() &&
- compareByteArrayWithString(resp, 3, "AVRISP_MK2")) {
- mProgrammerType = PGMTYPE_AVRISP_MKII;
- } else if (siglen >= "STK600".length() &&
- compareByteArrayWithString(resp, 3, "STK600")) {
- mProgrammerType = PGMTYPE_STK600;
- } else {
- resp[siglen + 3] = 0;
- byte[] tmpbuf = new byte[siglen];
- System.arraycopy(buf, 3, tmpbuf, 0, siglen);
- mProgrammerType = PGMTYPE_STK500;
- if (DEBUG_SHOW_GETSYNC) {
- Log.e(TAG,
- "STK500V2.getsync(): got response from unknown "
- + "programmer " + PROGRAMMER_NAME[mProgrammerType]
- + ", assuming STK500");
+ long tstart = java.lang.System.currentTimeMillis();
+
+ while((state != sDONE)) {
+ if(read(c, 1) <= 0) {
+ long tnow = java.lang.System.currentTimeMillis();
+ if((tnow - tstart) / 1000 > timeoutval) { // wuff -
+ // signed/unsigned/overflow
+ Log.e(TAG, "STK500V2.recv(): timeout");
+ return -1;
+ }
+ continue;
}
- }
-
- if (DEBUG_SHOW_GETSYNC) {
- Log.e(TAG,
- "STK500V2.getsync(): found " + PROGRAMMER_NAME[mProgrammerType]
- + " programmer");
- return 0;
- } else {
- if (tries > RETRIES) {
- Log.e(TAG,
- "STK500V2.getsync(): can't communicate with device: resp="
- + Integer.toHexString((int) resp[0]));
- return -6;
- } else {
- bRetry = true;
+ if(DEBUG_SHOW_RECV) {
+ Log.d(TAG, "recv : " + toHexStr(c[0]));
}
- }
+ checksum ^= c[0];
+
+ switch(state) {
+ case sSTART:
+ if(DEBUG_SHOW_RECV) {
+ Log.d(TAG, "hoping for start token...");
+ }
+
+ if(c[0] == MESSAGE_START) {
+ if(DEBUG_SHOW_RECV) {
+ Log.d(TAG, "got it\n");
+ }
+ checksum = MESSAGE_START;
+ state = sSEQNUM;
+ } else {
+ if(DEBUG_SHOW_RECV) {
+ Log.d(TAG, "sorry\n");
+ }
+ }
+ break;
+
+ case sSEQNUM:
+ if(DEBUG_SHOW_RECV) {
+ Log.d(TAG, "hoping for sequence...\n");
+ }
+
+ if((0x00ff & c[0]) == mCommandSeqNum) {
+ if(DEBUG_SHOW_RECV) {
+ Log.d(TAG, "got it, incrementing\n");
+ }
+ state = sSIZE1;
+ mCommandSeqNum = 0x00ff & (++mCommandSeqNum);
+ } else {
+ if(DEBUG_SHOW_RECV) {
+ Log.d(TAG, "sorry\n");
+ }
+ state = sSTART;
+ }
+ break;
+
+ case sSIZE1:
+ if(DEBUG_SHOW_RECV) {
+ Log.d(TAG, "hoping for size LSB\n");
+ }
+ msglen = ((int) c[0]) * 256;
+ state = sSIZE2;
+ break;
+
+ case sSIZE2:
+ if(DEBUG_SHOW_RECV) {
+ Log.d(TAG, "hoping for size MSB...");
+ }
+ msglen += (int) c[0];
+ if(DEBUG_SHOW_RECV) {
+ Log.d(TAG, " msg is " + msglen + " bytes");
+ }
+ state = sTOKEN;
+ break;
+
+ case sTOKEN:
+ if(c[0] == TOKEN) {
+ if(DEBUG_SHOW_RECV) {
+ Log.d(TAG, "recv : sTOKEN : sDATA");
+ }
+ state = sDATA;
+ } else {
+ if(DEBUG_SHOW_RECV) {
+ Log.d(TAG, "recv : sTOKEN : sSTART");
+ }
+ state = sSTART;
+ }
+ break;
+
+ case sDATA:
+ if(DEBUG_SHOW_RECV) {
+ Log.d(TAG, "recv | sDATA | msglen:" + msglen + ", curlen:" + curlen + ", length:" + length + ", c[0]:" + toHexStr(c[0]));
+ }
+ if(curlen < length) {
+ buf[curlen] = c[0];
+ } else {
+ Log.e(TAG, "STK500V2.recv(): buffer too small, received " + curlen
+ + " byte into " + length + " byte buffer");
+ return -2;
+ }
+ if((curlen == 0) && (buf[0] == ANSWER_CKSUM_ERROR)) {
+ Log.e(TAG, "STK500V2.recv(): previous packet sent with wrong checksum");
+ return -3;
+ }
+ curlen++;
+ if(curlen == msglen) {
+ state = sCSUM;
+ }
+ break;
+
+ case sCSUM:
+ if(DEBUG_SHOW_RECV) {
+ Log.d(TAG, "recv | sCSUM");
+ }
+ if(checksum == 0) {
+ state = sDONE;
+ } else {
+ // value never used because we do a return.
+ // state = sSTART;
+ Log.e(TAG, "STK500V2.recv(): checksum error");
+ return -4;
+ }
+ break;
+ default:
+ Log.e(TAG, "STK500V2.recv(): unknown state");
+ return -5;
+ } /*
+ * switch
+ */
+ } /*
+ * while
+ */
+
+ return /*
+ * redundant... (int)
+ */ (msglen + 6);
+ }
- // or if we got a timeout
- } else if (status == -1) {
- if (tries > RETRIES) {
- Log.e(TAG, "STK500V2.getsync(): timeout communicating with programmer");
- return -1;
- } else {
- bRetry = true;
- }
+ int getsync() {
+ int tries = 0;
+ byte[] buf = new byte[1];
+ byte[] resp = new byte[32];
+ int status;
+ boolean bRetry = true;
- // or any other error
- } else {
- if (tries > RETRIES) {
- Log.e(TAG, "STK500V2.getsync(): error communicating with programmer: ("
- + status + ")");
- } else {
- bRetry = true;
- }
+ if(DEBUG_SHOW_GETSYNC) {
+ Log.d(TAG, "STK500V2.getsync()");
+ }
+
+ while(bRetry) {
+ bRetry = false;
+ tries++;
+
+ // send the sync command and see if we can get there
+ buf[0] = CMD_SIGN_ON;
+ send(buf, 1);
+
+ // try to get the response back and see where we got
+ status = recv(resp, resp.length);
+
+ // if we got bytes returned, check to see what came back
+ if(status > 0) {
+ if((resp[0] == CMD_SIGN_ON) && (resp[1] == STATUS_CMD_OK)
+ && (status > 3)) {
+ // success!
+ int siglen = resp[2];
+ if(siglen >= "STK500_2".length()
+ && compareByteArrayWithString(resp, 3, "STK500_2")) {
+ mProgrammerType = PGMTYPE_STK500;
+ } else if(siglen >= "AVRISP_2".length()
+ && compareByteArrayWithString(resp, 3, "AVRISP_2")) {
+ mProgrammerType = PGMTYPE_AVRISP;
+ } else if(siglen >= "AVRISP_MK2".length()
+ && compareByteArrayWithString(resp, 3, "AVRISP_MK2")) {
+ mProgrammerType = PGMTYPE_AVRISP_MKII;
+ } else if(siglen >= "STK600".length()
+ && compareByteArrayWithString(resp, 3, "STK600")) {
+ mProgrammerType = PGMTYPE_STK600;
+ } else {
+ resp[siglen + 3] = 0;
+ byte[] tmpbuf = new byte[siglen];
+ System.arraycopy(buf, 3, tmpbuf, 0, siglen);
+ mProgrammerType = PGMTYPE_STK500;
+ if(DEBUG_SHOW_GETSYNC) {
+ Log.e(TAG,
+ "STK500V2.getsync(): got response from unknown "
+ + "programmer " + PROGRAMMER_NAME[mProgrammerType]
+ + ", assuming STK500");
+ }
+ }
+
+ if(DEBUG_SHOW_GETSYNC) {
+ Log.e(TAG,
+ "STK500V2.getsync(): found " + PROGRAMMER_NAME[mProgrammerType]
+ + " programmer");
+ }
+ } else {
+ if(tries > RETRIES) {
+ Log.e(TAG,
+ "STK500V2.getsync(): can't communicate with device: resp="
+ + Integer.toHexString((int) resp[0]));
+ return -6;
+ } else {
+ bRetry = true;
+ }
+ }
+
+ // or if we got a timeout
+ } else if(status == -1) {
+ if(tries > RETRIES) {
+ Log.e(TAG, "STK500V2.getsync(): timeout communicating with programmer");
+ return -1;
+ } else {
+ bRetry = true;
+ }
+
+ // or any other error
+ } else {
+ if(tries > RETRIES) {
+ Log.e(TAG, "STK500V2.getsync(): error communicating with programmer: ("
+ + status + ")");
+ return -1;
+ } else {
+ bRetry = true;
+ }
+ } // end of if (status > 0)
+ } // end of while(bRetry)
+ return 0;
+ } // end of int getsync()
+
+ public int open() {
+ setDtrRts(false);
+ try {
+ Thread.sleep(50);
+ } catch(InterruptedException e) {
+ }
+ setDtrRts(true);
+ try {
+ Thread.sleep(50);
+ } catch(InterruptedException e) {
+ }
+
+ drain();
+ if(getsync() < 0) {
+ return -1;
}
- } // end of if (status > 0)
- } // end of while(bRetry)
- return 0;
- } // end of int getsync()
-
- public int open() {
- setDtrRts(false);
- try { Thread.sleep(50); } catch (InterruptedException e) {}
- setDtrRts(true);
- try { Thread.sleep(50); } catch (InterruptedException e) {}
-
- drain();
- if(getsync()<0) { return -1; }
- return 0;
- }
-
- public void enable() {
-
- }
-
- public int initialize() {
-/* if ((PDATA(pgm)->pgmtype == PGMTYPE_STK600 ||
- PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII ||
- PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) != 0
- && (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_TPI)) != 0) {
- /*
- * This is an ATxmega device, must use XPROG protocol for the
- * remaining actions.
- *
- stk600_setup_xprog(pgm);
- } else {
-
- stk600_setup_isp(pgm);
-// }
-
- if (p->flags & AVRPART_IS_AT90S1200) {
- /*
- * AT90S1200 needs a positive reset pulse after a chip erase.
- *
- pgm->disable(pgm);
- usleep(10000);
- }
-
- */
- return program_enable();
-
- }
-
- public int program_enable() {
- byte[] buf = new byte[16];
+ return 0;
+ }
+
+ public void enable() {
+ }
+
+ public int initialize() {
+ /*
+ * if ((PDATA(pgm)->pgmtype == PGMTYPE_STK600 ||
+ * PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII ||
+ * PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) != 0 &&
+ * (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_TPI)) != 0) { /*
+ * This is an ATxmega device, must use XPROG protocol for the
+ * remaining actions.
+ *
+ * stk600_setup_xprog(pgm); } else {
+ *
+ * stk600_setup_isp(pgm); // }
+ *
+ * if (p->flags & AVRPART_IS_AT90S1200) { /* AT90S1200 needs a
+ * positive reset pulse after a chip erase.
+ *
+ * pgm->disable(pgm); usleep(10000); }
+ *
+ */
+ return program_enable();
+
+ }
+
+ public int program_enable() {
+ byte[] buf = new byte[16];
// String msg; /* see remarks above about size needed */
- int rv;
+ int rv;
// PDATA(pgm)->lastpart = p;
-/* if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
- fprintf(stderr, "%s: stk500v2_program_enable(): program enable instruction not defined for part \"%s\"\n",
- progname, p->desc);
- return -1;
+ /*
+ * if (p->op[AVR_OP_PGM_ENABLE] == NULL) { fprintf(stderr, "%s:
+ * stk500v2_program_enable(): program enable instruction not
+ * defined for part \"%s\"\n", progname, p->desc); return -1; }
+ */
+ /*
+ * if (PDATA(pgm)->pgmtype == PGMTYPE_STK500 ||
+ * PDATA(pgm)->pgmtype == PGMTYPE_STK600) /* Activate AVR-style
+ * (low active) RESET * stk500v2_setparm_real(pgm,
+ * PARAM_RESET_POLARITY, 0x01);
+ */
+
+ buf[0] = CMD_ENTER_PROGMODE_ISP;
+ buf[1] = mAVRConf.timeout;
+ buf[2] = mAVRConf.stabdelay;
+ buf[3] = mAVRConf.cmdexedelay;
+ buf[4] = mAVRConf.synchloops;
+ buf[5] = mAVRConf.bytedelay;
+ buf[6] = mAVRConf.pollvalue;
+ buf[7] = mAVRConf.pollindex;
+ /*
+ * byte[] tmpbuf = new byte[32];
+ * avr_set_bits(mAVRMem.op[AVRMem.AVR_OP_PGM_ENABLE], tmpbuf);
+ * System.arraycopy(tmpbuf, 0, buf, 8, 2);
+ */
+ buf[8] = (byte) 0xac;
+ buf[9] = 0x53;
+ buf[10] = 0;
+ buf[11] = 0;
+
+ rv = command(buf, 12, buf.length);
+
+ /*
+ * if (rv < 0) { switch (PDATA(pgm)->pgmtype) { case
+ * PGMTYPE_STK600: case PGMTYPE_AVRISP_MKII: if
+ * (stk500v2_getparm(pgm, PARAM_STATUS_TGT_CONN, &buf[0]) != 0)
+ * { fprintf(stderr, "%s: stk500v2_program_enable(): cannot get
+ * connection status\n", progname); } else {
+ * stk500v2_translate_conn_status(buf[0], msg); fprintf(stderr,
+ * "%s: stk500v2_program_enable():" " bad AVRISPmkII connection
+ * status: %s\n", progname, msg); } break;
+ *
+ * default: /* cannot report anything for other pgmtypes *
+ * break; } }
+ */
+
+ return rv;
}
-*/
-/* if (PDATA(pgm)->pgmtype == PGMTYPE_STK500 ||
- PDATA(pgm)->pgmtype == PGMTYPE_STK600)
- /* Activate AVR-style (low active) RESET *
- stk500v2_setparm_real(pgm, PARAM_RESET_POLARITY, 0x01);
-*/
-
- buf[0] = CMD_ENTER_PROGMODE_ISP;
- buf[1] = mAVRConf.timeout;
- buf[2] = mAVRConf.stabdelay;
- buf[3] = mAVRConf.cmdexedelay;
- buf[4] = mAVRConf.synchloops;
- buf[5] = mAVRConf.bytedelay;
- buf[6] = mAVRConf.pollvalue;
- buf[7] = mAVRConf.pollindex;
-/* byte[] tmpbuf = new byte[32];
- avr_set_bits(mAVRMem.op[AVRMem.AVR_OP_PGM_ENABLE], tmpbuf);
- System.arraycopy(tmpbuf, 0, buf, 8, 2);
-*/
- buf[8] = (byte)0xac;
- buf[9] = 0x53;
- buf[10] = 0;
- buf[11] = 0;
-
- rv = command(buf, 12, buf.length);
-
-/* if (rv < 0) {
- switch (PDATA(pgm)->pgmtype)
- {
- case PGMTYPE_STK600:
- case PGMTYPE_AVRISP_MKII:
- if (stk500v2_getparm(pgm, PARAM_STATUS_TGT_CONN, &buf[0]) != 0) {
- fprintf(stderr,
- "%s: stk500v2_program_enable(): cannot get connection status\n",
- progname);
- } else {
- stk500v2_translate_conn_status(buf[0], msg);
- fprintf(stderr, "%s: stk500v2_program_enable():"
- " bad AVRISPmkII connection status: %s\n",
- progname, msg);
- }
- break;
-
- default:
- /* cannot report anything for other pgmtypes *
- break;
- }
- }
-*/
-
- return rv;
- }
-
- private static final int UINT_MAX = 65535;
- /*
- * avr_set_bits()
- *
- * Set instruction bits in the specified command based on the opcode.
- */
- int avr_set_bits(AVRMem.OPCODE op , byte[] cmd) {
- int i, j, bit;
- byte mask;
-
- for (i=0; i<32; i++) {
- if (op.bit[i].type == AVRMem.AVR_CMDBIT_VALUE) {
- j = 3 - i / 8;
- bit = i % 8;
- mask = (byte) (1 << bit);
- if (op.bit[i].value!=0) {
- cmd[j] = (byte) (cmd[j] | mask);
- } else {
- cmd[j] = (byte) (cmd[j] & ~mask);
+ private static final int UINT_MAX = 65535;
+ /*
+ * avr_set_bits()
+ *
+ * Set instruction bits in the specified command based on the opcode.
+ */
+
+ int avr_set_bits(AVRMem.OPCODE op, byte[] cmd) {
+ int i, j, bit;
+ byte mask;
+
+ for(i = 0; i < 32; i++) {
+ if(op.bit[i].type == AVRMem.AVR_CMDBIT_VALUE) {
+ j = 3 - i / 8;
+ bit = i % 8;
+ mask = (byte) (1 << bit);
+ if(op.bit[i].value != 0) {
+ cmd[j] = (byte) (cmd[j] | mask);
+ } else {
+ cmd[j] = (byte) (cmd[j] & ~mask);
+ }
+ }
}
- }
+ return 0;
}
- return 0;
- }
- public int paged_write() {
- int addr;
- int block_size;
- int last_addr;
+ public int paged_write() {
+ int addr;
+ int block_size;
+ int last_addr;
// int hiaddr;
- int addrshift;
- int use_ext_addr;
- byte[] commandbuf = new byte[10];
- byte[] buf = new byte[266];
- byte[] cmds = new byte[4];
- int result;
- AVRMem.OPCODE rop, wop;
+ int addrshift;
+ int use_ext_addr;
+ byte[] commandbuf = new byte[10];
+ byte[] buf = new byte[266];
+ byte[] cmds = new byte[4];
+ int result;
+ AVRMem.OPCODE rop, wop;
- int page_size = mAVRMem.page_size;
- int n_bytes = mAVRMem.buf.length;
+ int page_size = mAVRMem.page_size;
+ int n_bytes = mAVRMem.buf.length;
// Log.d(TAG,"STK500V2: STK500V2.paged_write(..,"+mAVRMem.desc+","+page_size+","+n_bytes+")");
- if (page_size == 0) { page_size = 256; }
+ if(page_size == 0) {
+ page_size = 256;
+ }
// hiaddr = UINT_MAX;
- addrshift = 0;
- use_ext_addr = 0;
-
- // determine which command is to be used
- if (mAVRMem.desc.compareTo("flash")==0) {
- addrshift = 1;
- commandbuf[0] = CMD_PROGRAM_FLASH_ISP;
- /*
- * If bit 31 is set, this indicates that the following read/write
- * operation will be performed on a memory that is larger than
- * 64KBytes. This is an indication to STK500 that a load extended
- * address must be executed.
- */
- if (mAVRMem.op[AVRMem.AVR_OP_LOAD_EXT_ADDR] != null) {
- use_ext_addr = (1 << 31);
- }
- } else if (mAVRMem.desc.compareTo("eeprom") == 0) {
- commandbuf[0] = CMD_PROGRAM_EEPROM_ISP;
- }
- commandbuf[4] = (byte) mAVRMem.delay;
-
- if (addrshift == 0) {
- wop = mAVRMem.op[AVRMem.AVR_OP_WRITE];
- rop = mAVRMem.op[AVRMem.AVR_OP_READ];
- } else {
- wop = mAVRMem.op[AVRMem.AVR_OP_WRITE_LO];
- rop = mAVRMem.op[AVRMem.AVR_OP_READ_LO];
- }
+ addrshift = 0;
+ use_ext_addr = 0;
+
+ // determine which command is to be used
+ if(mAVRMem.desc.compareTo("flash") == 0) {
+ addrshift = 1;
+ commandbuf[0] = CMD_PROGRAM_FLASH_ISP;
+ /*
+ * If bit 31 is set, this indicates that the following
+ * read/write operation will be performed on a memory
+ * that is larger than 64KBytes. This is an indication
+ * to STK500 that a load extended address must be
+ * executed.
+ */
+ if(mAVRMem.op[AVRMem.AVR_OP_LOAD_EXT_ADDR] != null) {
+ use_ext_addr = (1 << 31);
+ }
+ } else if(mAVRMem.desc.compareTo("eeprom") == 0) {
+ commandbuf[0] = CMD_PROGRAM_EEPROM_ISP;
+ }
+ commandbuf[4] = (byte) mAVRMem.delay;
- // if the memory is paged, load the appropriate commands into the buffer
- if ((mAVRMem.mode & 0x01) == 0x01) {
- commandbuf[3] = (byte) (mAVRMem.mode | 0x80); // yes, write the page to flash
-
- if (mAVRMem.op[AVRMem.AVR_OP_LOADPAGE_LO] == null) {
- Log.e(TAG, "STK500V2.paged_write: loadpage instruction not defined for part \""+mAVRMem.desc+"\"");
- return -1;
- }
- avr_set_bits(mAVRMem.op[AVRMem.AVR_OP_LOADPAGE_LO], cmds);
- commandbuf[5] = cmds[0];
-
- if (mAVRMem.op[AVRMem.AVR_OP_WRITEPAGE] == null) {
- Log.e(TAG, "STK500V2.paged_write: write page instruction not defined for part \""+mAVRMem.desc+"\"");
- return -1;
- }
- avr_set_bits(mAVRMem.op[AVRMem.AVR_OP_WRITEPAGE], cmds);
- commandbuf[6] = cmds[0];
-
- // otherwise, we need to load different commands in
- } else {
- commandbuf[3] = (byte) (mAVRMem.mode | 0x80); // yes, write the words to flash
-
- if (wop == null) {
- Log.e(TAG, "STK500V2.paged_write: write instruction not defined for part \""+mAVRMem.desc+"\"");
- return -1;
- }
- avr_set_bits(wop, cmds);
- commandbuf[5] = cmds[0];
- commandbuf[6] = 0;
- }
+ if(addrshift == 0) {
+ wop = mAVRMem.op[AVRMem.AVR_OP_WRITE];
+ rop = mAVRMem.op[AVRMem.AVR_OP_READ];
+ } else {
+ wop = mAVRMem.op[AVRMem.AVR_OP_WRITE_LO];
+ rop = mAVRMem.op[AVRMem.AVR_OP_READ_LO];
+ }
- // the read command is common to both methods
- if (rop == null) {
- Log.e(TAG, "STK500V2.paged_write: read instruction not defined for part \""+mAVRMem.desc+"\"");
- return -1;
- }
- avr_set_bits(rop, cmds);
- commandbuf[7] = cmds[0];
+ // if the memory is paged, load the appropriate commands into the buffer
+ if((mAVRMem.mode & 0x01) == 0x01) {
+ commandbuf[3] = (byte) (mAVRMem.mode | 0x80); // yes, write the page to flash
- commandbuf[8] = mAVRMem.readback[0];
- commandbuf[9] = mAVRMem.readback[1];
+ if(mAVRMem.op[AVRMem.AVR_OP_LOADPAGE_LO] == null) {
+ Log.e(TAG, "STK500V2.paged_write: loadpage instruction not defined for part \"" + mAVRMem.desc + "\"");
+ return -1;
+ }
+ avr_set_bits(mAVRMem.op[AVRMem.AVR_OP_LOADPAGE_LO], cmds);
+ commandbuf[5] = cmds[0];
- last_addr=UINT_MAX; /* impossible address */
+ if(mAVRMem.op[AVRMem.AVR_OP_WRITEPAGE] == null) {
+ Log.e(TAG, "STK500V2.paged_write: write page instruction not defined for part \"" + mAVRMem.desc + "\"");
+ return -1;
+ }
+ avr_set_bits(mAVRMem.op[AVRMem.AVR_OP_WRITEPAGE], cmds);
+ commandbuf[6] = cmds[0];
- for (addr=0; addr < n_bytes; addr += page_size) {
- if(Thread.interrupted()) {
- report_cancel();
- return 0;
- }
+ // otherwise, we need to load different commands in
+ } else {
+ commandbuf[3] = (byte) (mAVRMem.mode | 0x80); // yes, write the words to flash
+
+ if(wop == null) {
+ Log.e(TAG, "STK500V2.paged_write: write instruction not defined for part \"" + mAVRMem.desc + "\"");
+ return -1;
+ }
+ avr_set_bits(wop, cmds);
+ commandbuf[5] = cmds[0];
+ commandbuf[6] = 0;
+ }
+
+ // the read command is common to both methods
+ if(rop == null) {
+ Log.e(TAG, "STK500V2.paged_write: read instruction not defined for part \"" + mAVRMem.desc + "\"");
+ return -1;
+ }
+ avr_set_bits(rop, cmds);
+ commandbuf[7] = cmds[0];
+
+ commandbuf[8] = mAVRMem.readback[0];
+ commandbuf[9] = mAVRMem.readback[1];
+
+ last_addr = UINT_MAX; /*
+ * impossible address
+ */
- report_progress((int)(addr*100/n_bytes));
+ for(addr = 0; addr < n_bytes; addr += page_size) {
+ if(Thread.interrupted()) {
+ report_cancel();
+ return 0;
+ }
+
+ report_progress(/*
+ * redundant ...(int)
+ */(addr * 100 / n_bytes));
- if ((n_bytes-addr) < page_size) {
- block_size = n_bytes - addr;
- } else {
- block_size = page_size;
- }
+ if((n_bytes - addr) < page_size) {
+ block_size = n_bytes - addr;
+ } else {
+ block_size = page_size;
+ }
// Log.d(TAG,"n_bytes "+n_bytes);
// Log.d(TAG,"block_size at addr "+addr+" is "+block_size);
- if(commandbuf[0] == CMD_PROGRAM_FLASH_ISP){
- if (is_page_empty(addr, block_size, mAVRMem.buf)) {
- continue;
- }
- }
+ if(commandbuf[0] == CMD_PROGRAM_FLASH_ISP) {
+ if(is_page_empty(addr, block_size, mAVRMem.buf)) {
+ continue;
+ }
+ }
- System.arraycopy(commandbuf, 0, buf, 0, commandbuf.length);
+ System.arraycopy(commandbuf, 0, buf, 0, commandbuf.length);
- buf[1] = (byte) (block_size >> 8);
- buf[2] = (byte) (block_size & 0xff);
+ buf[1] = (byte) (block_size >> 8);
+ buf[2] = (byte) (block_size & 0xff);
- if((last_addr==UINT_MAX)||(last_addr+block_size != addr)){
- if (loadaddr(use_ext_addr | (addr >> addrshift)) < 0)
- return -1;
- }
- last_addr=addr;
+ if((last_addr == UINT_MAX) || (last_addr + block_size != addr)) {
+ if(loadaddr(use_ext_addr | (addr >> addrshift)) < 0) {
+ return -1;
+ }
+ }
+ last_addr = addr;
- System.arraycopy(mAVRMem.buf, addr, buf, 10, block_size);
+ System.arraycopy(mAVRMem.buf, addr, buf, 10, block_size);
- result = command(buf,block_size+10, buf.length);
- if (result < 0) {
- Log.e(TAG, "STK500V2.paged_write: write command failed");
- return -1;
- }
- }
+ result = command(buf, block_size + 10, buf.length);
+ if(result < 0) {
+ Log.e(TAG, "STK500V2.paged_write: write command failed");
+ return -1;
+ }
+ }
- report_progress((int)(addr*100/n_bytes));
+ report_progress(/*
+ * redundant...(int)
+ */(addr * 100 / n_bytes));
- return n_bytes;
- }
+ return n_bytes;
+ }
- boolean is_page_empty(int address, int page_size, byte[] buf) {
- int i;
+ boolean is_page_empty(int address, int page_size, byte[] buf) {
+ int i;
- for(i = 0; i < page_size; i++) {
- if(buf[address + i] != 0xFF) {
- /* Page is not empty. */
- return false;
- }
+ for(i = 0; i < page_size; i++) {
+ if(buf[address + i] != 0xFF) {
+ /*
+ * Page is not empty.
+ */
+ return false;
+ }
+ }
+ /*
+ * Page is empty.
+ */
+ return true;
}
- /* Page is empty. */
- return true;
- }
- int loadaddr(int addr) {
- byte[] buf = new byte[16];
- int result;
+ int loadaddr(int addr) {
+ byte[] buf = new byte[16];
+ int result;
// Log.d(TAG, "STK500V2.loadaddr("+addr+")");
- buf[0] = CMD_LOAD_ADDRESS;
- buf[1] = (byte) ((addr >> 24) & 0xff);
- buf[2] = (byte) ((addr >> 16) & 0xff);
- buf[3] = (byte) ((addr >> 8) & 0xff);
- buf[4] = (byte) ( addr & 0xff);
+ buf[0] = CMD_LOAD_ADDRESS;
+ buf[1] = (byte) ((addr >> 24) & 0xff);
+ buf[2] = (byte) ((addr >> 16) & 0xff);
+ buf[3] = (byte) ((addr >> 8) & 0xff);
+ buf[4] = (byte) (addr & 0xff);
- result = command(buf, 5, buf.length);
+ result = command(buf, 5, buf.length);
- if (result < 0) {
- Log.e(TAG,"STK500V2.loadaddr(): failed to set load address");
- return -1;
+ if(result < 0) {
+ Log.e(TAG, "STK500V2.loadaddr(): failed to set load address");
+ return -1;
+ }
+ return 0;
}
- return 0;
- }
-
- private int read(byte[] buf, int length) {
- int retval;
- retval = mComm.read(buf,length);
- if(DEBUG_SHOW_READ){
- if(retval>0){
- String str = "";
- for(int i=0; i 0) {
+ String str = "";
+ for(int i = 0; i < retval; i++) {
+ str += Integer.toHexString((int) buf[i]) + " ";
+ }
+ Log.d(TAG, "read(" + retval + ") : " + str);
+ }
}
- Log.d(TAG, "read("+retval+") : "+str);
- }
+ return retval;
}
- return retval;
- }
-
- private int write(byte[] buf, int length) {
- int retval;
- retval = mComm.write(buf, length);
- if(DEBUG_SHOW_WRITE){
- if(retval>0){
- Log.d(TAG, "write("+retval+") : "+toHexStr(buf, retval));
- }
+
+ private int write(byte[] buf, int length) {
+ int retval;
+ retval = mComm.write(buf, length);
+ if(DEBUG_SHOW_WRITE) {
+ if(retval > 0) {
+ Log.d(TAG, "write(" + retval + ") : " + toHexStr(buf, retval));
+ }
+ }
+ return retval;
}
- return retval;
- }
-
- private void setDtrRts(boolean on) {
- if(on) {
- mComm.setDtrRts(true, true);
- } else {
- mComm.setDtrRts(false, false);
+
+ private void setDtrRts(boolean on) {
+ if(on) {
+ mComm.setDtrRts(true, true);
+ } else {
+ mComm.setDtrRts(false, false);
+ }
}
- }
- private String toHexStr(byte b) {
- return String.format("0x%02x", b);
- }
+ private String toHexStr(byte b) {
+ return String.format("0x%02x", b);
+ }
- private String toHexStr(byte[] b, int length) {
- String str="";
- for(int i=0; i= 31) {
+ mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent("USB_PERMISSION"), PendingIntent.FLAG_IMMUTABLE);
+ } else {
+ mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent("USB_PERMISSION"), 0);
+ }
}
}
@@ -255,7 +258,7 @@ public String getSerial(int devNum) {
/**
* Gets an USB permission if no permission
- *
+ *
* @param device
*/
public void getPermission(UsbDevice device) {
diff --git a/PhysicaloidLibrary/src/com/physicaloid/lib/usb/UsbCdcConnection.java b/PhysicaloidLibrary/src/com/physicaloid/lib/usb/UsbCdcConnection.java
index 95d9dad..69e84e2 100644
--- a/PhysicaloidLibrary/src/com/physicaloid/lib/usb/UsbCdcConnection.java
+++ b/PhysicaloidLibrary/src/com/physicaloid/lib/usb/UsbCdcConnection.java
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.physicaloid.lib.usb;
import android.content.Context;
@@ -24,178 +23,232 @@
import android.hardware.usb.UsbInterface;
import android.util.Log;
import android.util.SparseArray;
-
import com.physicaloid.BuildConfig;
public class UsbCdcConnection {
- private static final boolean DEBUG_SHOW = true && BuildConfig.DEBUG;
-
- private static final String TAG = UsbCdcConnection.class.getSimpleName();
-
- private UsbAccessor mUsbAccess;
-
- private int mCdcAcmInterfaceNum;
-
- SparseArray mUsbConnectionEp;
-
- public UsbCdcConnection(Context context) {
- mUsbAccess = UsbAccessor.INSTANCE;
- mUsbAccess.init(context);
- mCdcAcmInterfaceNum = 0;
- mUsbConnectionEp = new SparseArray();
- }
-
- /**
- * Open first device with VID and PID
- * @param ids vid and pid
- * @return true : open successful, false : open fail
- */
- public boolean open(UsbVidPid ids) {
- return open(ids,false, 0);
- }
-
- /**
- * Open first CDC-ACM device with VID and PID
- * @param ids vid and pid
- * @param isCdcAcm true then search only cdc-acm
- * @return true : open successful, false : open fail
- */
- public boolean open(UsbVidPid ids, boolean isCdcAcm) {
- return open(ids, isCdcAcm, 0);
- }
-
- /**
- * Open channel-th device with VID and PID
- * @param ids vid and pid
- * @param ch channel
- * @return true : open successful, false : open fail
- */
- public boolean open(UsbVidPid ids, boolean isCdcAcm, int ch) {
- if(ids == null) return false;
-
- int devNum = 0;
- int chNum = 0;
- for(UsbDevice usbdev : mUsbAccess.manager().getDeviceList().values()) {
- if(usbdev.getVendorId() == ids.getVid()) {
- if(ids.getPid() == 0 || ids.getPid() == usbdev.getProductId()) {
- for(int intfNum=0; intfNum < usbdev.getInterfaceCount(); intfNum++) {
-
- if( (isCdcAcm && (usbdev.getInterface(intfNum).getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA))
- || !isCdcAcm) {
- if(ch == chNum) {
- if(!mUsbAccess.deviceIsConnected(devNum)) {
- if(mUsbAccess.openDevice(devNum,intfNum,ch)) {
- if(DEBUG_SHOW){ Log.d(TAG, "Find VID:"+Integer.toHexString(usbdev.getVendorId())+", PID:"+Integer.toHexString(usbdev.getProductId())+", DevNum:"+devNum+", IntfNum:"+intfNum); }
- mUsbConnectionEp.put(ch,new UsbCdcConnectionEp(mUsbAccess.connection(ch), getEndpoint(devNum, intfNum, UsbConstants.USB_DIR_IN), getEndpoint(devNum, intfNum, UsbConstants.USB_DIR_OUT)));
- mCdcAcmInterfaceNum = intfNum;
- return true;
- }
+
+ private static final boolean DEBUG_SHOW = true && BuildConfig.DEBUG;
+ private static final String TAG = UsbCdcConnection.class.getSimpleName();
+ private UsbAccessor mUsbAccess;
+ private int mCdcAcmInterfaceNum;
+ private int pid;
+ SparseArray mUsbConnectionEp;
+
+ public int getPID() {
+ return pid;
+ }
+
+ public UsbCdcConnection(Context context) {
+ mUsbAccess = UsbAccessor.INSTANCE;
+ mUsbAccess.init(context);
+ mCdcAcmInterfaceNum = 0;
+ mUsbConnectionEp = new SparseArray();
+ }
+
+ /**
+ * Open first device with VID and PID
+ *
+ * @param ids vid and pid
+ *
+ * @return true : open successful, false : open fail
+ */
+ public boolean open(UsbVidPid ids) {
+ return open(ids, false, 0);
+ }
+
+ /**
+ * Open first CDC-ACM device with VID and PID
+ *
+ * @param ids vid and pid
+ * @param isCdcAcm true then search only cdc-acm
+ *
+ * @return true : open successful, false : open fail
+ */
+ public boolean open(UsbVidPid ids, boolean isCdcAcm) {
+ return open(ids, isCdcAcm, 0);
+ }
+
+ /**
+ * Open channel-th device with VID and PID
+ *
+ * @param ids vid and pid
+ * @param ch channel
+ *
+ * @return true : open successful, false : open fail
+ */
+ public boolean open(UsbVidPid ids, boolean isCdcAcm, int ch) {
+ if(ids == null) {
+ return false;
+ }
+
+ int devNum = 0;
+ int chNum = 0;
+ for(UsbDevice usbdev : mUsbAccess.manager().getDeviceList().values()) {
+ if(usbdev.getVendorId() == ids.getVid()) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "VID PASS " + usbdev.getVendorId());
}
- chNum++;
- } // end of if
- }// end of if
- } // end of for
- } // end of if
- } // end of if
- devNum++;
- } //end of for
- if(DEBUG_SHOW){ Log.d(TAG, "Cannot find VID:"+ids.getVid()+", PID:"+ids.getPid()); }
- return false;
- }
-
- private UsbEndpoint getEndpoint(int devNum, int intfNum, int usbDir) {
- UsbInterface intf = mUsbAccess.intface(devNum, intfNum);
- if(intf == null) {return null;}
-
- for(int i=0; i size) {
+ write_size = size - offset;
+ }
+ // optimization!
+ if(offset == 0) {
+ synchronized(DevLock) {
+ written_size = mConnection.bulkTransfer(mEndpointOut, buf, write_size, 100);
+
+ }
+ } else {
+ System.arraycopy(buf, offset, wbuf, 0, write_size);
+ synchronized(DevLock) {
+ written_size = mConnection.bulkTransfer(mEndpointOut, wbuf, write_size, 100);
+ }
+ }
+ if(written_size < 0) {
+ return -1;
+ }
+ offset += written_size;
+ }
- private UsbDeviceConnection mConnection;
- private UsbEndpoint mEndpointIn;
- private UsbEndpoint mEndpointOut;
- private int mInterfaceNum;
+ return offset;
+ }
- private boolean isOpened;
+ private void stopRead() {
+ mReadThreadStop = true;
+ }
- public UartCdcAcm(Context context) {
- super(context);
- mUsbConnetionManager = new UsbCdcConnection(context);
- mUartConfig = new UartConfig();
- mBuffer = new RingBuffer(RING_BUFFER_SIZE);
- isOpened = false;
- }
+ private void startRead() {
+ if(mReadThreadStop) {
+ mReadThreadStop = false;
+ new Thread(mLoop).start();
+ }
+ }
- @Override
- public boolean open() {
- for(UsbVidList id : UsbVidList.values()) {
- if(open(new UsbVidPid(id.getVid(), 0))){
+ private String toHexStr(byte[] b, int length) {
+ String str = "";
+ for(int i = 0; i < length; i++) {
+ str += String.format("%02x ", b[i]);
+ }
+ return str;
+ }
+ private Runnable mLoop = new Runnable() {
+
+ @Override
+ @SuppressWarnings("CallToThreadYield")
+ public void run() {
+ try {
+ android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
+ } catch(Exception e) {
+ }
+ int len;
+ byte[] rbuf = new byte[mEndpointIn.getMaxPacketSize()];
+ UsbRequest response;
+ UsbRequest request = new UsbRequest();
+ request.initialize(mConnection, mEndpointIn);
+ ByteBuffer buf = ByteBuffer.wrap(rbuf);
+ for(;;) {// this is the main loop for transferring
+ len = 0;
+ if(request.queue(buf, rbuf.length)) {
+ response = mConnection.requestWait();
+ if(response != null) {
+ len = buf.position();
+ }
+ if(len > 0) {
+ if(DEBUG_SHOW) {
+ Log.e(TAG, "read(" + len + "): " + toHexStr(rbuf, len));
+ }
+
+ mBuffer.add(rbuf, len);
+ onRead(len);
+ } else if(mBuffer.getBufferdLength() > 0) {
+ onRead(mBuffer.getBufferdLength());
+ }
+
+ } else if(mBuffer.getBufferdLength() > 0) {
+ onRead(mBuffer.getBufferdLength());
+ }
+
+ if(mReadThreadStop) {
+ return;
+ }
+ }
+ } // end of run()
+ }; // end of runnable
+
+ /**
+ * Sets Uart configurations
+ *
+ * @param config configurations
+ *
+ * @return true : successful, false : fail
+ */
+ public boolean setUartConfig(UartConfig config) {
+ boolean res;
+ boolean ret = true;
+ res = setBaudrate(config.baudrate);
+ ret = ret && res;
+
+ res = setDataBits(config.dataBits);
+ ret = ret && res;
+
+ res = setParity(config.parity);
+ ret = ret && res;
+
+ res = setStopBits(config.stopBits);
+ ret = ret && res;
+
+ res = setDtrRts(config.dtrOn, config.rtsOn);
+ ret = ret && res;
+
+ return ret;
+ }
+
+ /**
+ * Initializes CDC communication
+ *
+ * @return true : successful, false : fail
+ */
+ private boolean init() {
+ if(mConnection == null) {
+ return false;
+ }
+ int ret = mConnection.controlTransfer(0x21, 0x22, 0x00, mInterfaceNum, null, 0, 0); // init CDC
+ if(ret < 0) {
+ return false;
+ }
return true;
- }
- }
- return false;
- }
-
- public boolean open(UsbVidPid ids) {
- if(mUsbConnetionManager.open(ids,true)) {
- mConnection = mUsbConnetionManager.getConnection();
- mEndpointIn = mUsbConnetionManager.getEndpointIn();
- mEndpointOut = mUsbConnetionManager.getEndpointOut();
- mInterfaceNum = mUsbConnetionManager.getCdcAcmInterfaceNum();
- if(!init()) { return false; }
- if(!setBaudrate(DEFAULT_BAUDRATE)) {return false;}
- mBuffer.clear();
- startRead();
- isOpened = true;
- return true;
- }
- return false;
- }
-
- @Override
- public boolean close() {
- stopRead();
- isOpened = false;
- return mUsbConnetionManager.close();
- }
-
- @Override
- public int read(byte[] buf, int size) {
- return mBuffer.get(buf, size);
- }
-
- @Override
- public int write(byte[] buf, int size) {
- if(buf == null) { return 0; }
- int offset = 0;
- int write_size;
- int written_size;
- byte[] wbuf = new byte[USB_WRITE_BUFFER_SIZE];
-
- while (offset < size) {
- write_size = USB_WRITE_BUFFER_SIZE;
-
- if (offset + write_size > size) {
- write_size = size - offset;
- }
- System.arraycopy(buf, offset, wbuf, 0, write_size);
-
- written_size = mConnection.bulkTransfer(mEndpointOut, wbuf, write_size, 100);
-
- if (written_size < 0) {
- return -1;
- }
- offset += written_size;
- }
-
- return offset;
- }
-
- private void stopRead() {
- mReadThreadStop = true;
- }
-
- private void startRead() {
- if(mReadThreadStop) {
- mReadThreadStop = false;
- new Thread(mLoop).start();
- }
- }
-
- private Runnable mLoop = new Runnable() {
+ }
+
@Override
- public void run() {
- int len=0;
- byte[] rbuf = new byte[USB_READ_BUFFER_SIZE];
- for (;;) {// this is the main loop for transferring
-
- try {
- len = mConnection.bulkTransfer(mEndpointIn,
- rbuf, rbuf.length, 50);
- } catch(Exception e) {
- Log.e(TAG, e.toString());
+ public boolean isOpened() {
+ return isOpened;
+ }
+
+ /**
+ * Sets baudrate
+ *
+ * @param baudrate baudrate e.g. 9600
+ *
+ * @return true : successful, false : fail
+ */
+ public boolean setBaudrate(int baudrate) {
+ byte[] baudByte = new byte[4];
+
+ baudByte[0] = (byte) (baudrate & 0x000000FF);
+ baudByte[1] = (byte) ((baudrate & 0x0000FF00) >> 8);
+ baudByte[2] = (byte) ((baudrate & 0x00FF0000) >> 16);
+ baudByte[3] = (byte) ((baudrate & 0xFF000000) >> 24);
+ int ret = mConnection.controlTransfer(0x21, 0x20, 0, mInterfaceNum, new byte[] {
+ baudByte[0], baudByte[1], baudByte[2], baudByte[3], 0x00, 0x00,
+ 0x08}, 7, 100);
+ if(ret < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "Fail to setBaudrate");
+ }
+ return false;
}
+ mUartConfig.baudrate = baudrate;
+ return true;
+ }
- if (len > 0) {
- mBuffer.add(rbuf, len);
- onRead(len);
+ /**
+ * Sets Data bits
+ *
+ * @param dataBits data bits e.g. UartConfig.DATA_BITS8
+ *
+ * @return true : successful, false : fail
+ */
+ public boolean setDataBits(int dataBits) {
+ // TODO : implement
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "Fail to setDataBits");
}
+ mUartConfig.dataBits = dataBits;
+ return false;
+ }
- if (mReadThreadStop) {
- return;
+ /**
+ * Sets Parity bit
+ *
+ * @param parity parity bits e.g. UartConfig.PARITY_NONE
+ *
+ * @return true : successful, false : fail
+ */
+ public boolean setParity(int parity) {
+ // TODO : implement
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "Fail to setParity");
}
+ mUartConfig.parity = parity;
+ return false;
+ }
- try {
- Thread.sleep(50);
- } catch (InterruptedException e) {
+ /**
+ * Sets Stop bits
+ *
+ * @param stopBits stop bits e.g. UartConfig.STOP_BITS1
+ *
+ * @return true : successful, false : fail
+ */
+ public boolean setStopBits(int stopBits) {
+ // TODO : implement
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "Fail to setStopBits");
}
+ mUartConfig.stopBits = stopBits;
+ return false;
+ }
- }
- } // end of run()
- }; // end of runnable
-
-
- /**
- * Sets Uart configurations
- * @param config configurations
- * @return true : successful, false : fail
- */
- public boolean setUartConfig(UartConfig config) {
- boolean res = true;
- boolean ret = true;
- if(mUartConfig.baudrate != config.baudrate) {
- res = setBaudrate(config.baudrate);
- ret = ret && res;
- }
-
- if(mUartConfig.dataBits != config.dataBits) {
- res = setDataBits(config.dataBits);
- ret = ret && res;
- }
-
- if(mUartConfig.parity != config.parity) {
- res = setParity(config.parity);
- ret = ret && res;
- }
-
- if(mUartConfig.stopBits != config.stopBits) {
- res = setStopBits(config.stopBits);
- ret = ret && res;
- }
-
- if(mUartConfig.dtrOn != config.dtrOn ||
- mUartConfig.rtsOn != config.rtsOn) {
- res = setDtrRts(config.dtrOn, config.rtsOn);
- ret = ret && res;
- }
-
- return ret;
- }
-
- /**
- * Initializes CDC communication
- * @return true : successful, false : fail
- */
- private boolean init() {
- if(mConnection == null) return false;
- int ret = mConnection.controlTransfer(0x21, 0x22, 0x00, mInterfaceNum, null, 0, 0); // init CDC
- if(ret < 0) { return false; }
- return true;
- }
-
- @Override
- public boolean isOpened() {
- return isOpened;
- }
-
- /**
- * Sets baudrate
- * @param baudrate baudrate e.g. 9600
- * @return true : successful, false : fail
- */
- public boolean setBaudrate(int baudrate) {
- byte[] baudByte = new byte[4];
-
- baudByte[0] = (byte) (baudrate & 0x000000FF);
- baudByte[1] = (byte) ((baudrate & 0x0000FF00) >> 8);
- baudByte[2] = (byte) ((baudrate & 0x00FF0000) >> 16);
- baudByte[3] = (byte) ((baudrate & 0xFF000000) >> 24);
- int ret = mConnection.controlTransfer(0x21, 0x20, 0, mInterfaceNum, new byte[] {
- baudByte[0], baudByte[1], baudByte[2], baudByte[3], 0x00, 0x00,
- 0x08}, 7, 100);
- if(ret < 0) {
- if(DEBUG_SHOW) { Log.d(TAG, "Fail to setBaudrate"); }
- return false;
- }
- mUartConfig.baudrate = baudrate;
- return true;
- }
-
- /**
- * Sets Data bits
- * @param dataBits data bits e.g. UartConfig.DATA_BITS8
- * @return true : successful, false : fail
- */
- public boolean setDataBits(int dataBits) {
- // TODO : implement
- if(DEBUG_SHOW) { Log.d(TAG, "Fail to setDataBits"); }
- mUartConfig.dataBits = dataBits;
- return false;
- }
-
- /**
- * Sets Parity bit
- * @param parity parity bits e.g. UartConfig.PARITY_NONE
- * @return true : successful, false : fail
- */
- public boolean setParity(int parity) {
- // TODO : implement
- if(DEBUG_SHOW) { Log.d(TAG, "Fail to setParity"); }
- mUartConfig.parity = parity;
- return false;
- }
-
- /**
- * Sets Stop bits
- * @param stopBits stop bits e.g. UartConfig.STOP_BITS1
- * @return true : successful, false : fail
- */
- public boolean setStopBits(int stopBits) {
- // TODO : implement
- if(DEBUG_SHOW) { Log.d(TAG, "Fail to setStopBits"); }
- mUartConfig.stopBits = stopBits;
- return false;
- }
-
- @Override
- public boolean setDtrRts(boolean dtrOn, boolean rtsOn) {
- int ctrlValue = 0x0000;
- if(dtrOn) {
- ctrlValue |= 0x0001;
- }
- if(rtsOn) {
- ctrlValue |= 0x0002;
- }
- int ret = mConnection.controlTransfer(0x21, 0x22, ctrlValue, mInterfaceNum, null, 0, 100);
- if(ret < 0) {
- if(DEBUG_SHOW) { Log.d(TAG, "Fail to setDtrRts"); }
- return false;
- }
- mUartConfig.dtrOn = dtrOn;
- mUartConfig.rtsOn = rtsOn;
- return true;
- }
-
- @Override
- public UartConfig getUartConfig() {
- return mUartConfig;
- }
-
- @Override
- public int getBaudrate() {
- return mUartConfig.baudrate;
- }
-
- @Override
- public int getDataBits() {
- return mUartConfig.dataBits;
- }
-
- @Override
- public int getParity() {
- return mUartConfig.parity;
- }
-
- @Override
- public int getStopBits() {
- return mUartConfig.stopBits;
- }
-
- @Override
- public boolean getDtr() {
- return mUartConfig.dtrOn;
- }
-
- @Override
- public boolean getRts() {
- return mUartConfig.rtsOn;
- }
-
- @Override
- public void clearBuffer() {
- mBuffer.clear();
- }
-
- //////////////////////////////////////////////////////////
- // Listener for reading uart
- //////////////////////////////////////////////////////////
- private List uartReadListenerList
- = new ArrayList();
- private boolean mStopReadListener = false;
-
- @Override
- public void addReadListener(ReadLisener listener) {
- uartReadListenerList.add(listener);
- }
-
- @Override
- public void clearReadListener() {
- uartReadListenerList.clear();
- }
-
- @Override
- public void startReadListener() {
- mStopReadListener = false;
- }
-
- @Override
- public void stopReadListener() {
- mStopReadListener = true;
- }
-
- private void onRead(int size) {
- if(mStopReadListener) return;
- for (ReadLisener listener: uartReadListenerList) {
- listener.onRead(size);
- }
- }
- //////////////////////////////////////////////////////////
+ @Override
+ public boolean setDtrRts(boolean dtrOn, boolean rtsOn) {
+ int ctrlValue = 0x0000;
+ if(dtrOn) {
+ ctrlValue |= 0x0001;
+ }
+ if(rtsOn) {
+ ctrlValue |= 0x0002;
+ }
+ int ret = mConnection.controlTransfer(0x21, 0x22, ctrlValue, mInterfaceNum, null, 0, 100);
+ if(ret < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "Fail to setDtrRts");
+ }
+ return false;
+ }
+ mUartConfig.dtrOn = dtrOn;
+ mUartConfig.rtsOn = rtsOn;
+ return true;
+ }
+ @Override
+ public UartConfig getUartConfig() {
+ return mUartConfig;
+ }
+
+ @Override
+ public int getBaudrate() {
+ return mUartConfig.baudrate;
+ }
+
+ @Override
+ public int getDataBits() {
+ return mUartConfig.dataBits;
+ }
+
+ @Override
+ public int getParity() {
+ return mUartConfig.parity;
+ }
+
+ @Override
+ public int getStopBits() {
+ return mUartConfig.stopBits;
+ }
+
+ @Override
+ public boolean getDtr() {
+ return mUartConfig.dtrOn;
+ }
+
+ @Override
+ public boolean getRts() {
+ return mUartConfig.rtsOn;
+ }
+
+ @Override
+ public void clearBuffer() {
+ mBuffer.clear();
+ }
+ //////////////////////////////////////////////////////////
+ // Listener for reading uart
+ //////////////////////////////////////////////////////////
+ private List uartReadListenerList = new ArrayList();
+ private boolean mStopReadListener = false;
+
+ @Override
+ public void addReadListener(ReadListener listener) {
+ uartReadListenerList.add(listener);
+ }
+
+ @Override
+ @Deprecated
+ public void addReadListener(ReadLisener listener) {
+ addReadListener((ReadListener)listener);
+ }
+
+ @Override
+ public void clearReadListener() {
+ uartReadListenerList.clear();
+ }
+
+ @Override
+ public void startReadListener() {
+ mStopReadListener = false;
+ }
+
+ @Override
+ public void stopReadListener() {
+ mStopReadListener = true;
+ }
+
+ private void onRead(int size) {
+ if(mStopReadListener) {
+ return;
+ }
+ for(ReadListener listener : uartReadListenerList) {
+ listener.onRead(size);
+ }
+ }
+ //////////////////////////////////////////////////////////
+
+ @Override
+ public String getPhysicalConnectionName() {
+ return Physicaloid.USB_STRING;
+ }
+
+ @Override
+ public int getPhysicalConnectionType() {
+ return Physicaloid.USB;
+ }
+
+ @Override
+ public void setDebug(boolean flag) {
+ DEBUG_SHOW = flag;
+ }
}
diff --git a/PhysicaloidLibrary/src/com/physicaloid/lib/usb/driver/uart/UartCp210x.java b/PhysicaloidLibrary/src/com/physicaloid/lib/usb/driver/uart/UartCp210x.java
index 1de5202..7a55e3d 100644
--- a/PhysicaloidLibrary/src/com/physicaloid/lib/usb/driver/uart/UartCp210x.java
+++ b/PhysicaloidLibrary/src/com/physicaloid/lib/usb/driver/uart/UartCp210x.java
@@ -3,689 +3,789 @@
import android.content.Context;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
+import android.hardware.usb.UsbRequest;
import android.util.Log;
-
import com.physicaloid.BuildConfig;
+import com.physicaloid.lib.Physicaloid;
import com.physicaloid.lib.UsbVidList;
import com.physicaloid.lib.framework.SerialCommunicator;
import com.physicaloid.lib.usb.UsbCdcConnection;
import com.physicaloid.lib.usb.UsbVidPid;
import com.physicaloid.misc.RingBuffer;
-
+import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
-public class UartCp210x extends SerialCommunicator{
-
- private static final String TAG = UartCp210x.class.getSimpleName();
-
- private static final boolean DEBUG_SHOW = false && BuildConfig.DEBUG;
- private static final int DEFAULT_BAUDRATE = 9600;
-
- private UsbCdcConnection mUsbConnetionManager;
-
- private UartConfig mUartConfig;
- private static final int RING_BUFFER_SIZE = 1024;
- private static final int USB_READ_BUFFER_SIZE = 256;
- private static final int USB_WRITE_BUFFER_SIZE = 256;
- private RingBuffer mBuffer;
-
- private boolean mReadThreadStop = true;
-
- private UsbDeviceConnection mConnection;
- private UsbEndpoint mEndpointIn;
- private UsbEndpoint mEndpointOut;
-
- private boolean isOpened;
-
- /* Config request types */
- private static final byte REQTYPE_HOST_TO_INTERFACE = (byte)0x41;
- private static final byte REQTYPE_INTERFACE_TO_HOST = (byte)0xc1;
- @SuppressWarnings("unused")
- private static final byte REQTYPE_HOST_TO_DEVICE = (byte)0x40;
- @SuppressWarnings("unused")
- private static final byte REQTYPE_DEVICE_TO_HOST = (byte)0xc0;
-
- /* Config request codes */
- private static final byte CP210X_IFC_ENABLE = 0x00;
- @SuppressWarnings("unused")
- private static final byte CP210X_SET_BAUDDIV = 0x01;
- @SuppressWarnings("unused")
- private static final byte CP210X_GET_BAUDDIV = 0x02;
- @SuppressWarnings("unused")
- private static final byte CP210X_SET_LINE_CTL = 0x03;
- private static final byte CP210X_GET_LINE_CTL = 0x04;
- @SuppressWarnings("unused")
- private static final byte CP210X_SET_BREAK = 0x05;
- @SuppressWarnings("unused")
- private static final byte CP210X_IMM_CHAR = 0x06;
- private static final byte CP210X_SET_MHS = 0x07;
- @SuppressWarnings("unused")
- private static final byte CP210X_GET_MDMSTS = 0x08;
- @SuppressWarnings("unused")
- private static final byte CP210X_SET_XON = 0x09;
- @SuppressWarnings("unused")
- private static final byte CP210X_SET_XOFF = 0x0A;
- @SuppressWarnings("unused")
- private static final byte CP210X_SET_EVENTMASK = 0x0B;
- @SuppressWarnings("unused")
- private static final byte CP210X_GET_EVENTMASK = 0x0C;
- @SuppressWarnings("unused")
- private static final byte CP210X_SET_CHAR = 0x0D;
- @SuppressWarnings("unused")
- private static final byte CP210X_GET_CHARS = 0x0E;
- @SuppressWarnings("unused")
- private static final byte CP210X_GET_PROPS = 0x0F;
- @SuppressWarnings("unused")
- private static final byte CP210X_GET_COMM_STATUS = 0x10;
- @SuppressWarnings("unused")
- private static final byte CP210X_RESET = 0x11;
- @SuppressWarnings("unused")
- private static final byte CP210X_PURGE = 0x12;
- @SuppressWarnings("unused")
- private static final byte CP210X_SET_FLOW = 0x13;
- @SuppressWarnings("unused")
- private static final byte CP210X_GET_FLOW = 0x14;
- @SuppressWarnings("unused")
- private static final byte CP210X_EMBED_EVENTS = 0x15;
- @SuppressWarnings("unused")
- private static final byte CP210X_GET_EVENTSTATE = 0x16;
- @SuppressWarnings("unused")
- private static final byte CP210X_SET_CHARS = 0x19;
- @SuppressWarnings("unused")
- private static final byte CP210X_GET_BAUDRATE = 0x1D;
- private static final byte CP210X_SET_BAUDRATE = 0x1E;
-
- /* CP210X_IFC_ENABLE */
- private static final int UART_ENABLE = 0x0001;
- private static final int UART_DISABLE = 0x0000;
-
- /* CP210X_(SET|GET)_BAUDDIV */
- @SuppressWarnings("unused")
- private static final int BAUD_RATE_GEN_FREQ = 0x384000;
-
- /* CP210X_(SET|GET)_LINE_CTL */
- private static final int BITS_DATA_MASK = 0x0f00;
- @SuppressWarnings("unused")
- private static final int BITS_DATA_5 = 0x0500;
- @SuppressWarnings("unused")
- private static final int BITS_DATA_6 = 0x0600;;
- private static final int BITS_DATA_7 = 0x0700;
- private static final int BITS_DATA_8 = 0x0800;
- @SuppressWarnings("unused")
- private static final int BITS_DATA_9 = 0x0900;
-
- private static final int BITS_PARITY_MASK = 0x00f0;
- private static final int BITS_PARITY_NONE = 0x0000;
- private static final int BITS_PARITY_ODD = 0x0010;
- private static final int BITS_PARITY_EVEN = 0x0020;
- private static final int BITS_PARITY_MARK = 0x0030;
- private static final int BITS_PARITY_SPACE = 0x0040;
-
- private static final int BITS_STOP_MASK = 0x000f;
- private static final int BITS_STOP_1 = 0x0000;
- private static final int BITS_STOP_1_5 = 0x0001;
- private static final int BITS_STOP_2 = 0x0002;
-
- /* CP210X_SET_BREAK */
- @SuppressWarnings("unused")
- private static final int BREAK_ON = 0x0001;
- @SuppressWarnings("unused")
- private static final int BREAK_OFF = 0x0000;
-
- /* CP210X_(SET_MHS|GET_MDMSTS) */
- private static final int CONTROL_DTR = 0x0001;
- private static final int CONTROL_RTS = 0x0002;
- @SuppressWarnings("unused")
- private static final int CONTROL_CTS = 0x0010;
- @SuppressWarnings("unused")
- private static final int CONTROL_DSR = 0x0020;
- @SuppressWarnings("unused")
- private static final int CONTROL_RING = 0x0040;
- @SuppressWarnings("unused")
- private static final int CONTROL_DCD = 0x0080;
- private static final int CONTROL_WRITE_DTR = 0x0100;
- private static final int CONTROL_WRITE_RTS = 0x0200;
-
- public UartCp210x(Context context) {
- super(context);
- mUsbConnetionManager = new UsbCdcConnection(context);
- mUartConfig = new UartConfig();
- mBuffer = new RingBuffer(RING_BUFFER_SIZE);
- isOpened = false;
- }
-
- @Override
- public boolean open() {
- for(UsbVidList id : UsbVidList.values()) {
- if(open(new UsbVidPid(id.getVid(), 0))){
+public class UartCp210x extends SerialCommunicator {
+
+ private static final String TAG = UartCp210x.class.getSimpleName();
+ private boolean DEBUG_SHOW = false;
+ private static final int DEFAULT_BAUDRATE = 9600;
+ private UsbCdcConnection mUsbConnetionManager;
+ private UartConfig mUartConfig;
+ private static final int RING_BUFFER_SIZE = 1024;
+ private static final int USB_READ_BUFFER_SIZE = 256;
+ private static final int USB_WRITE_BUFFER_SIZE = 256;
+ private RingBuffer mBuffer;
+ private boolean mReadThreadStop = true;
+ private UsbDeviceConnection mConnection;
+ private UsbEndpoint mEndpointIn;
+ private UsbEndpoint mEndpointOut;
+ private boolean isOpened;
+
+ /*
+ * Config request types
+ */
+ private static final byte REQTYPE_HOST_TO_INTERFACE = (byte) 0x41;
+ private static final byte REQTYPE_INTERFACE_TO_HOST = (byte) 0xc1;
+ @SuppressWarnings("unused")
+ private static final byte REQTYPE_HOST_TO_DEVICE = (byte) 0x40;
+ @SuppressWarnings("unused")
+ private static final byte REQTYPE_DEVICE_TO_HOST = (byte) 0xc0;
+
+ /*
+ * Config request codes
+ */
+ private static final byte CP210X_IFC_ENABLE = 0x00;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_SET_BAUDDIV = 0x01;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_GET_BAUDDIV = 0x02;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_SET_LINE_CTL = 0x03;
+ private static final byte CP210X_GET_LINE_CTL = 0x04;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_SET_BREAK = 0x05;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_IMM_CHAR = 0x06;
+ private static final byte CP210X_SET_MHS = 0x07;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_GET_MDMSTS = 0x08;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_SET_XON = 0x09;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_SET_XOFF = 0x0A;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_SET_EVENTMASK = 0x0B;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_GET_EVENTMASK = 0x0C;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_SET_CHAR = 0x0D;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_GET_CHARS = 0x0E;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_GET_PROPS = 0x0F;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_GET_COMM_STATUS = 0x10;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_RESET = 0x11;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_PURGE = 0x12;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_SET_FLOW = 0x13;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_GET_FLOW = 0x14;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_EMBED_EVENTS = 0x15;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_GET_EVENTSTATE = 0x16;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_SET_CHARS = 0x19;
+ @SuppressWarnings("unused")
+ private static final byte CP210X_GET_BAUDRATE = 0x1D;
+ private static final byte CP210X_SET_BAUDRATE = 0x1E;
+
+ /*
+ * CP210X_IFC_ENABLE
+ */
+ private static final int UART_ENABLE = 0x0001;
+ private static final int UART_DISABLE = 0x0000;
+
+ /*
+ * CP210X_(SET|GET)_BAUDDIV
+ */
+ @SuppressWarnings("unused")
+ private static final int BAUD_RATE_GEN_FREQ = 0x384000;
+
+ /*
+ * CP210X_(SET|GET)_LINE_CTL
+ */
+ private static final int BITS_DATA_MASK = 0x0f00;
+ @SuppressWarnings("unused")
+ private static final int BITS_DATA_5 = 0x0500;
+ @SuppressWarnings("unused")
+ private static final int BITS_DATA_6 = 0x0600;
+ ;
+ private static final int BITS_DATA_7 = 0x0700;
+ private static final int BITS_DATA_8 = 0x0800;
+ @SuppressWarnings("unused")
+ private static final int BITS_DATA_9 = 0x0900;
+ private static final int BITS_PARITY_MASK = 0x00f0;
+ private static final int BITS_PARITY_NONE = 0x0000;
+ private static final int BITS_PARITY_ODD = 0x0010;
+ private static final int BITS_PARITY_EVEN = 0x0020;
+ private static final int BITS_PARITY_MARK = 0x0030;
+ private static final int BITS_PARITY_SPACE = 0x0040;
+ private static final int BITS_STOP_MASK = 0x000f;
+ private static final int BITS_STOP_1 = 0x0000;
+ private static final int BITS_STOP_1_5 = 0x0001;
+ private static final int BITS_STOP_2 = 0x0002;
+
+ /*
+ * CP210X_SET_BREAK
+ */
+ @SuppressWarnings("unused")
+ private static final int BREAK_ON = 0x0001;
+ @SuppressWarnings("unused")
+ private static final int BREAK_OFF = 0x0000;
+
+ /*
+ * CP210X_(SET_MHS|GET_MDMSTS)
+ */
+ private static final int CONTROL_DTR = 0x0001;
+ private static final int CONTROL_RTS = 0x0002;
+ @SuppressWarnings("unused")
+ private static final int CONTROL_CTS = 0x0010;
+ @SuppressWarnings("unused")
+ private static final int CONTROL_DSR = 0x0020;
+ @SuppressWarnings("unused")
+ private static final int CONTROL_RING = 0x0040;
+ @SuppressWarnings("unused")
+ private static final int CONTROL_DCD = 0x0080;
+ private static final int CONTROL_WRITE_DTR = 0x0100;
+ private static final int CONTROL_WRITE_RTS = 0x0200;
+
+ public UartCp210x(Context context) {
+ super(context);
+ mUsbConnetionManager = new UsbCdcConnection(context);
+ mUartConfig = new UartConfig();
+ mBuffer = new RingBuffer(RING_BUFFER_SIZE);
+ isOpened = false;
+ }
+
+ @Override
+ public boolean open() {
+ for(UsbVidList id : UsbVidList.values()) {
+ if(id.getVid() == 0x10C4) {
+ if(open(new UsbVidPid(id.getVid(), 0))) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean open(UsbVidPid ids) {
+ if(mUsbConnetionManager.open(ids)) {
+ mConnection = mUsbConnetionManager.getConnection();
+ mEndpointIn = mUsbConnetionManager.getEndpointIn();
+ mEndpointOut = mUsbConnetionManager.getEndpointOut();
+ if(!init()) {
+ return false;
+ }
+ if(!setBaudrate(DEFAULT_BAUDRATE)) {
+ return false;
+ }
+ mBuffer.clear();
+ startRead();
+ isOpened = true;
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean close() {
+ stopRead();
+ isOpened = false;
+ cp210xUsbDisable();
+ return mUsbConnetionManager.close();
+ }
+
+ @Override
+ public int read(byte[] buf, int size) {
+ return mBuffer.get(buf, size);
+ }
+
+ @Override
+ public int write(byte[] buf, int size) {
+ if(buf == null) {
+ return 0;
+ }
+ int offset = 0;
+ int write_size;
+ int written_size;
+ byte[] wbuf = new byte[USB_WRITE_BUFFER_SIZE];
+
+ while(offset < size) {
+ write_size = USB_WRITE_BUFFER_SIZE;
+
+ if(offset + write_size > size) {
+ write_size = size - offset;
+ }
+ System.arraycopy(buf, offset, wbuf, 0, write_size);
+
+ written_size = mConnection.bulkTransfer(mEndpointOut, wbuf, write_size, 100);
+
+ if(written_size < 0) {
+ return -1;
+ }
+ offset += written_size;
+ }
+
+ return offset;
+ }
+
+ private void stopRead() {
+ mReadThreadStop = true;
+ }
+
+ private void startRead() {
+ if(mReadThreadStop) {
+ mReadThreadStop = false;
+ new Thread(mLoop).start();
+ }
+ }
+ private Runnable mLoop = new Runnable() {
+
+ @Override
+ public void run() {
+ int len;
+ // byte[] rbuf = new byte[USB_READ_BUFFER_SIZE];
+ byte[] rbuf = new byte[mEndpointIn.getMaxPacketSize()];
+ android.os.Process.setThreadPriority(-20);
+ UsbRequest response;
+ UsbRequest request = new UsbRequest();
+ request.initialize(mConnection, mEndpointIn);
+ ByteBuffer buf = ByteBuffer.wrap(rbuf);
+ for(;;) {// this is the main loop for transferring
+ len = 0;
+ if(request.queue(buf, rbuf.length)) {
+ response = mConnection.requestWait();
+ if(response != null) {
+ len = buf.position();
+ }
+ if(len > 0) {
+ mBuffer.add(rbuf, len);
+ onRead(len);
+ } else if(mBuffer.getBufferdLength() > 0) {
+ onRead(mBuffer.getBufferdLength());
+ } else if(mBuffer.getBufferdLength() > 0) {
+ onRead(mBuffer.getBufferdLength());
+ }
+
+
+ }
+
+ if(mReadThreadStop) {
+ return;
+ }
+
+ try {
+ Thread.sleep(1);
+ } catch(InterruptedException e) {
+ }
+
+ }
+ } // end of run()
+ }; // end of runnable
+
+ @Override
+ public boolean setUartConfig(UartConfig config) {
+ boolean res;
+ boolean ret = true;
+ res = setBaudrate(config.baudrate);
+ ret = ret && res;
+
+ res = setDataBits(config.dataBits);
+ ret = ret && res;
+
+ res = setParity(config.parity);
+ ret = ret && res;
+
+ res = setStopBits(config.stopBits);
+ ret = ret && res;
+
+ res = setDtrRts(config.dtrOn, config.rtsOn);
+ ret = ret && res;
+
+ return ret;
+ }
+
+ /**
+ * Initializes CP210x communication
+ *
+ * @return true : successful, false : fail
+ */
+ private boolean init() {
+ int ret = cp210xUsbEnable();
+ if(ret < 0) {
+ return false;
+ }
return true;
- }
- }
- return false;
- }
-
- public boolean open(UsbVidPid ids) {
- if(mUsbConnetionManager.open(ids)) {
- mConnection = mUsbConnetionManager.getConnection();
- mEndpointIn = mUsbConnetionManager.getEndpointIn();
- mEndpointOut = mUsbConnetionManager.getEndpointOut();
- if(!init()) { return false; }
- if(!setBaudrate(DEFAULT_BAUDRATE)) {return false;}
- mBuffer.clear();
- startRead();
- isOpened = true;
- return true;
- }
- return false;
- }
-
- @Override
- public boolean close() {
- stopRead();
- isOpened = false;
- cp210xUsbDisable();
- return mUsbConnetionManager.close();
- }
-
- @Override
- public int read(byte[] buf, int size) {
- return mBuffer.get(buf, size);
- }
-
- @Override
- public int write(byte[] buf, int size) {
- if(buf == null) { return 0; }
- int offset = 0;
- int write_size;
- int written_size;
- byte[] wbuf = new byte[USB_WRITE_BUFFER_SIZE];
-
- while (offset < size) {
- write_size = USB_WRITE_BUFFER_SIZE;
-
- if (offset + write_size > size) {
- write_size = size - offset;
- }
- System.arraycopy(buf, offset, wbuf, 0, write_size);
-
- written_size = mConnection.bulkTransfer(mEndpointOut, wbuf, write_size, 100);
-
- if (written_size < 0) {
- return -1;
- }
- offset += written_size;
- }
-
- return offset;
- }
-
- private void stopRead() {
- mReadThreadStop = true;
- }
-
- private void startRead() {
- if(mReadThreadStop) {
- mReadThreadStop = false;
- new Thread(mLoop).start();
- }
- }
-
- private Runnable mLoop = new Runnable() {
+ }
+
@Override
- public void run() {
- int len=0;
- byte[] rbuf = new byte[USB_READ_BUFFER_SIZE];
- for (;;) {// this is the main loop for transferring
-
- try {
- len = mConnection.bulkTransfer(mEndpointIn,
- rbuf, rbuf.length, 50);
- } catch(Exception e) {
- Log.e(TAG, e.toString());
+ public boolean isOpened() {
+ return isOpened;
+ }
+
+ /**
+ * Enables CP210x
+ *
+ * @return positive value : successful, negative value : fail
+ */
+ private int cp210xUsbEnable() {
+ if(mConnection == null) {
+ return -1;
}
+ return mConnection.controlTransfer(
+ REQTYPE_HOST_TO_INTERFACE,
+ CP210X_IFC_ENABLE,
+ UART_ENABLE,
+ 0,
+ null,
+ 0,
+ 100);
+ }
- if (len > 0) {
- mBuffer.add(rbuf, len);
- onRead(len);
+ /**
+ * Disables CP210x
+ *
+ * @return positive value : successful, negative value : fail
+ */
+ private int cp210xUsbDisable() {
+ if(mConnection == null) {
+ return -1;
}
+ return mConnection.controlTransfer(
+ REQTYPE_HOST_TO_INTERFACE,
+ CP210X_IFC_ENABLE,
+ UART_DISABLE,
+ 0,
+ null,
+ 0,
+ 100);
+ }
- if (mReadThreadStop) {
- return;
+ /**
+ * Gets configurations from CP210x
+ *
+ * @param request request id
+ * @param buf gotten buffer
+ * @param size size of getting buffer
+ * @return positive value : successful, negative value : fail
+ */
+ private int cp210xGetConfig(int request, byte[] buf, int size) {
+ if(mConnection == null) {
+ return -1;
}
+ int ret = mConnection.controlTransfer(
+ REQTYPE_INTERFACE_TO_HOST,
+ request,
+ 0x0000,
+ 0,
+ buf,
+ size,
+ 100);
+ return ret;
+ }
- try {
- Thread.sleep(50);
- } catch (InterruptedException e) {
+ /**
+ * Sets configurations from CP210x
+ *
+ * @param request request id
+ * @param buf set buffer
+ * @param size size of sending buffer
+ * @return
+ */
+ private int cp210xSetConfig(int request, byte[] buf, int size) {
+ if(mConnection == null) {
+ return -1;
}
+ int ret = mConnection.controlTransfer(
+ REQTYPE_HOST_TO_INTERFACE,
+ request,
+ 0x0000,
+ 0,
+ buf,
+ size,
+ 100);
+ return ret;
+ }
- }
- } // end of run()
- }; // end of runnable
-
- @Override
- public boolean setUartConfig(UartConfig config) {
- boolean res = true;
- boolean ret = true;
- if(mUartConfig.baudrate != config.baudrate) {
- res = setBaudrate(config.baudrate);
- ret = ret && res;
- }
-
- if(mUartConfig.dataBits != config.dataBits) {
- res = setDataBits(config.dataBits);
- ret = ret && res;
- }
-
- if(mUartConfig.parity != config.parity) {
- res = setParity(config.parity);
- ret = ret && res;
- }
-
- if(mUartConfig.stopBits != config.stopBits) {
- res = setStopBits(config.stopBits);
- ret = ret && res;
- }
-
- if(mUartConfig.dtrOn != config.dtrOn ||
- mUartConfig.rtsOn != config.rtsOn) {
- res = setDtrRts(config.dtrOn, config.rtsOn);
- ret = ret && res;
- }
-
- return ret;
- }
-
- /**
- * Initializes CP210x communication
- * @return true : successful, false : fail
- */
- private boolean init() {
- int ret = cp210xUsbEnable();
- if(ret < 0) { return false; }
- return true;
- }
-
- @Override
- public boolean isOpened() {
- return isOpened;
- }
-
-
- /**
- * Enables CP210x
- * @return positive value : successful, negative value : fail
- */
- private int cp210xUsbEnable() {
- if(mConnection == null) return -1;
- return mConnection.controlTransfer(
- REQTYPE_HOST_TO_INTERFACE,
- CP210X_IFC_ENABLE,
- UART_ENABLE,
- 0,
- null,
- 0,
- 100);
- }
-
- /**
- * Disables CP210x
- * @return positive value : successful, negative value : fail
- */
- private int cp210xUsbDisable() {
- if(mConnection == null) return -1;
- return mConnection.controlTransfer(
- REQTYPE_HOST_TO_INTERFACE,
- CP210X_IFC_ENABLE,
- UART_DISABLE,
- 0,
- null,
- 0,
- 100);
- }
-
- /**
- * Gets configurations from CP210x
- * @param request request id
- * @param buf gotten buffer
- * @param size size of getting buffer
- * @return positive value : successful, negative value : fail
- */
- private int cp210xGetConfig(int request, byte[] buf, int size) {
- if(mConnection == null) return -1;
- int ret = mConnection.controlTransfer(
- REQTYPE_INTERFACE_TO_HOST,
- request,
- 0x0000,
- 0,
- buf,
- size,
- 100);
- return ret;
- }
-
- /**
- * Sets configurations from CP210x
- * @param request request id
- * @param buf set buffer
- * @param size size of sending buffer
- * @return
- */
- private int cp210xSetConfig(int request, byte[] buf, int size) {
- if(mConnection == null) return -1;
- int ret = mConnection.controlTransfer(
- REQTYPE_HOST_TO_INTERFACE,
- request,
- 0x0000,
- 0,
- buf,
- size,
- 100);
- return ret;
- }
-
- @Override
- public boolean setBaudrate(int baudrate) {
- if (baudrate <= 300) baudrate = 300;
- else if (baudrate <= 600) baudrate = 600;
- else if (baudrate <= 1200) baudrate = 1200;
- else if (baudrate <= 1800) baudrate = 1800;
- else if (baudrate <= 2400) baudrate = 2400;
- else if (baudrate <= 4000) baudrate = 4000;
- else if (baudrate <= 4803) baudrate = 4800;
- else if (baudrate <= 7207) baudrate = 7200;
- else if (baudrate <= 9612) baudrate = 9600;
- else if (baudrate <= 14428) baudrate = 14400;
- else if (baudrate <= 16062) baudrate = 16000;
- else if (baudrate <= 19250) baudrate = 19200;
- else if (baudrate <= 28912) baudrate = 28800;
- else if (baudrate <= 38601) baudrate = 38400;
- else if (baudrate <= 51558) baudrate = 51200;
- else if (baudrate <= 56280) baudrate = 56000;
- else if (baudrate <= 58053) baudrate = 57600;
- else if (baudrate <= 64111) baudrate = 64000;
- else if (baudrate <= 77608) baudrate = 76800;
- else if (baudrate <= 117028) baudrate = 115200;
- else if (baudrate <= 129347) baudrate = 128000;
- else if (baudrate <= 156868) baudrate = 153600;
- else if (baudrate <= 237832) baudrate = 230400;
- else if (baudrate <= 254234) baudrate = 250000;
- else if (baudrate <= 273066) baudrate = 256000;
- else if (baudrate <= 491520) baudrate = 460800;
- else if (baudrate <= 567138) baudrate = 500000;
- else if (baudrate <= 670254) baudrate = 576000;
- else if (baudrate < 1000000) baudrate = 921600;
- else if (baudrate > 2000000) baudrate = 2000000;
-
- byte[] baudBytes = new byte[4];
- intToLittleEndianBytes(baudrate, baudBytes);
- int ret = cp210xSetConfig(CP210X_SET_BAUDRATE, baudBytes, 4);
- if(ret < 0) {
- if(DEBUG_SHOW) { Log.d(TAG, "Fail to setBaudrate"); }
- return false;
- }
- mUartConfig.baudrate = baudrate;
- return true;
- }
-
- @Override
- public boolean setDataBits(int dataBits) {
- int bits;
- byte[] buf = new byte[2];
-
- cp210xGetConfig(CP210X_GET_LINE_CTL, buf, buf.length);
- bits = littleEndianBytesToInt(buf);
- bits &= ~BITS_DATA_MASK;
-
- switch (dataBits) {
- case UartConfig.DATA_BITS7:
- bits |= BITS_DATA_7;
- break;
-
- case UartConfig.DATA_BITS8:
- bits |= BITS_DATA_8;
- break;
-
- default:
- bits |= BITS_DATA_8;
- break;
- }
-
- intToLittleEndianBytes(bits, buf);
- int ret = cp210xSetConfig(CP210X_GET_LINE_CTL, buf, buf.length);
-
- if(ret < 0) {
- if(DEBUG_SHOW) { Log.e(TAG, "Fail to setDataBits"); }
- return false;
- }
-
- mUartConfig.dataBits = dataBits;
- return true;
- }
-
-
- @Override
- public boolean setParity(int parity) {
- int bits;
- byte[] buf = new byte[2];
-
- cp210xGetConfig(CP210X_GET_LINE_CTL, buf, buf.length);
- bits = littleEndianBytesToInt(buf);
- bits &= ~BITS_PARITY_MASK;
-
- switch (parity) {
-
- case UartConfig.PARITY_NONE:
- bits |= BITS_PARITY_NONE;
- break;
-
- case UartConfig.PARITY_ODD:
- bits |= BITS_PARITY_ODD;
- break;
-
- case UartConfig.PARITY_EVEN:
- bits |= BITS_PARITY_EVEN;
- break;
-
- case UartConfig.PARITY_MARK:
- bits |= BITS_PARITY_MARK;
- break;
-
- case UartConfig.PARITY_SPACE:
- bits |= BITS_PARITY_SPACE;
- break;
+ @Override
+ public boolean setBaudrate(int baudrate) {
+ // TO-DO: Allow any baud rate. Why isn't this possible here?
+ if(baudrate <= 300) {
+ baudrate = 300;
+ } else if(baudrate <= 600) {
+ baudrate = 600;
+ } else if(baudrate <= 1200) {
+ baudrate = 1200;
+ } else if(baudrate <= 1800) {
+ baudrate = 1800;
+ } else if(baudrate <= 2400) {
+ baudrate = 2400;
+ } else if(baudrate <= 4000) {
+ baudrate = 4000;
+ } else if(baudrate <= 4803) {
+ baudrate = 4800;
+ } else if(baudrate <= 7207) {
+ baudrate = 7200;
+ } else if(baudrate <= 9612) {
+ baudrate = 9600;
+ } else if(baudrate <= 14428) {
+ baudrate = 14400;
+ } else if(baudrate <= 16062) {
+ baudrate = 16000;
+ } else if(baudrate <= 19250) {
+ baudrate = 19200;
+ } else if(baudrate <= 28912) {
+ baudrate = 28800;
+ } else if(baudrate <= 38601) {
+ baudrate = 38400;
+ } else if(baudrate <= 51558) {
+ baudrate = 51200;
+ } else if(baudrate <= 56280) {
+ baudrate = 56000;
+ } else if(baudrate <= 58053) {
+ baudrate = 57600;
+ } else if(baudrate <= 64111) {
+ baudrate = 64000;
+ } else if(baudrate <= 77608) {
+ baudrate = 76800;
+ } else if(baudrate <= 117028) {
+ baudrate = 115200;
+ } else if(baudrate <= 129347) {
+ baudrate = 128000;
+ } else if(baudrate <= 156868) {
+ baudrate = 153600;
+ } else if(baudrate <= 237832) {
+ baudrate = 230400;
+ } else if(baudrate <= 254234) {
+ baudrate = 250000;
+ } else if(baudrate <= 273066) {
+ baudrate = 256000;
+ } else if(baudrate <= 491520) {
+ baudrate = 460800;
+ } else if(baudrate <= 567138) {
+ baudrate = 500000;
+ } else if(baudrate <= 670254) {
+ baudrate = 576000;
+ } else if(baudrate < 1000000) {
+ baudrate = 921600;
+ } else if(baudrate > 2000000) {
+ baudrate = 2000000;
+ }
- default:
- bits |= BITS_PARITY_NONE;
- break;
+ byte[] baudBytes = new byte[4];
+ intToLittleEndianBytes(baudrate, baudBytes);
+ int ret = cp210xSetConfig(CP210X_SET_BAUDRATE, baudBytes, 4);
+ if(ret < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "Fail to setBaudrate");
+ }
+ return false;
+ }
+ mUartConfig.baudrate = baudrate;
+ return true;
}
- intToLittleEndianBytes(bits, buf);
- int ret = cp210xSetConfig(CP210X_GET_LINE_CTL, buf, buf.length);
+ @Override
+ public boolean setDataBits(int dataBits) {
+ int bits;
+ byte[] buf = new byte[2];
+
+ cp210xGetConfig(CP210X_GET_LINE_CTL, buf, buf.length);
+ bits = littleEndianBytesToInt(buf);
+ bits &= ~BITS_DATA_MASK;
+
+ switch(dataBits) {
+ case UartConfig.DATA_BITS7:
+ bits |= BITS_DATA_7;
+ break;
+
+ case UartConfig.DATA_BITS8:
+ bits |= BITS_DATA_8;
+ break;
+
+ default:
+ bits |= BITS_DATA_8;
+ break;
+ }
- if(ret < 0) {
- if(DEBUG_SHOW) { Log.d(TAG, "Fail to setParity"); }
- return false;
+ intToLittleEndianBytes(bits, buf);
+ int ret = cp210xSetConfig(CP210X_GET_LINE_CTL, buf, buf.length);
+
+ if(ret < 0) {
+ if(DEBUG_SHOW) {
+ Log.e(TAG, "Fail to setDataBits");
+ }
+ return false;
+ }
+
+ mUartConfig.dataBits = dataBits;
+ return true;
}
- mUartConfig.parity = parity;
- return true;
- }
+ @Override
+ public boolean setParity(int parity) {
+ int bits;
+ byte[] buf = new byte[2];
+
+ cp210xGetConfig(CP210X_GET_LINE_CTL, buf, buf.length);
+ bits = littleEndianBytesToInt(buf);
+ bits &= ~BITS_PARITY_MASK;
+ switch(parity) {
- @Override
- public boolean setStopBits(int stopBits) {
- int bits;
- byte[] buf = new byte[2];
+ case UartConfig.PARITY_NONE:
+ bits |= BITS_PARITY_NONE;
+ break;
- cp210xGetConfig(CP210X_GET_LINE_CTL, buf, buf.length);
- bits = littleEndianBytesToInt(buf);
- bits &= ~BITS_STOP_MASK;
+ case UartConfig.PARITY_ODD:
+ bits |= BITS_PARITY_ODD;
+ break;
- switch (stopBits) {
- case UartConfig.STOP_BITS1:
- bits |= BITS_STOP_1;
- break;
+ case UartConfig.PARITY_EVEN:
+ bits |= BITS_PARITY_EVEN;
+ break;
- case UartConfig.STOP_BITS1_5:
- bits |= BITS_STOP_1_5;
- break;
+ case UartConfig.PARITY_MARK:
+ bits |= BITS_PARITY_MARK;
+ break;
- case UartConfig.STOP_BITS2:
- bits |= BITS_STOP_2;
- break;
+ case UartConfig.PARITY_SPACE:
+ bits |= BITS_PARITY_SPACE;
+ break;
- default:
- bits |= BITS_STOP_1;
- break;
+ default:
+ bits |= BITS_PARITY_NONE;
+ break;
+ }
+
+ intToLittleEndianBytes(bits, buf);
+ int ret = cp210xSetConfig(CP210X_GET_LINE_CTL, buf, buf.length);
+
+ if(ret < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "Fail to setParity");
+ }
+ return false;
+ }
+
+ mUartConfig.parity = parity;
+ return true;
}
- intToLittleEndianBytes(bits, buf);
- int ret = cp210xSetConfig(CP210X_GET_LINE_CTL, buf, buf.length);
+ @Override
+ public boolean setStopBits(int stopBits) {
+ int bits;
+ byte[] buf = new byte[2];
+
+ cp210xGetConfig(CP210X_GET_LINE_CTL, buf, buf.length);
+ bits = littleEndianBytesToInt(buf);
+ bits &= ~BITS_STOP_MASK;
+
+ switch(stopBits) {
+ case UartConfig.STOP_BITS1:
+ bits |= BITS_STOP_1;
+ break;
+
+ case UartConfig.STOP_BITS1_5:
+ bits |= BITS_STOP_1_5;
+ break;
+
+ case UartConfig.STOP_BITS2:
+ bits |= BITS_STOP_2;
+ break;
+
+ default:
+ bits |= BITS_STOP_1;
+ break;
+ }
- if(ret < 0) {
- if(DEBUG_SHOW) { Log.d(TAG, "Fail to setStopBits"); }
- return false;
+ intToLittleEndianBytes(bits, buf);
+ int ret = cp210xSetConfig(CP210X_GET_LINE_CTL, buf, buf.length);
+
+ if(ret < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "Fail to setStopBits");
+ }
+ return false;
+ }
+
+ mUartConfig.stopBits = stopBits;
+ return true;
+ }
+
+ @Override
+ public boolean setDtrRts(boolean dtrOn, boolean rtsOn) {
+ int ctrlValue = 0x0000;
+ byte[] buf = new byte[4];
+
+ if(dtrOn) {
+ ctrlValue |= CONTROL_DTR;
+ ctrlValue |= CONTROL_WRITE_DTR;
+ } else {
+ ctrlValue &= ~CONTROL_DTR;
+ ctrlValue |= CONTROL_WRITE_DTR;
+ }
+
+ if(rtsOn) {
+ ctrlValue |= CONTROL_RTS;
+ ctrlValue |= CONTROL_WRITE_RTS;
+ } else {
+ ctrlValue &= ~CONTROL_RTS;
+ ctrlValue |= CONTROL_WRITE_RTS;
+ }
+
+ intToLittleEndianBytes(ctrlValue, buf);
+ int ret = cp210xSetConfig(CP210X_SET_MHS, buf, buf.length);
+
+ if(ret < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "Fail to setDtrRts");
+ }
+ return false;
+ }
+ mUartConfig.dtrOn = dtrOn;
+ mUartConfig.rtsOn = rtsOn;
+ return true;
+ }
+
+ @Override
+ public UartConfig getUartConfig() {
+ return mUartConfig;
+ }
+
+ @Override
+ public int getBaudrate() {
+ return mUartConfig.baudrate;
+ }
+
+ @Override
+ public int getDataBits() {
+ return mUartConfig.dataBits;
+ }
+
+ @Override
+ public int getParity() {
+ return mUartConfig.parity;
+ }
+
+ @Override
+ public int getStopBits() {
+ return mUartConfig.stopBits;
+ }
+
+ @Override
+ public boolean getDtr() {
+ return mUartConfig.dtrOn;
+ }
+
+ @Override
+ public boolean getRts() {
+ return mUartConfig.rtsOn;
+ }
+
+ @Override
+ public void clearBuffer() {
+ mBuffer.clear();
+ }
+ //////////////////////////////////////////////////////////
+ // Listener for reading uart
+ //////////////////////////////////////////////////////////
+ private List uartReadListenerList = new ArrayList();
+ private boolean mStopReadListener = false;
+
+ @Override
+ public void addReadListener(ReadListener listener) {
+ uartReadListenerList.add(listener);
+ }
+
+ @Override
+ @Deprecated
+ public void addReadListener(ReadLisener listener) {
+ addReadListener((ReadListener)listener);
+ }
+
+ @Override
+ public void clearReadListener() {
+ uartReadListenerList.clear();
+ }
+
+ @Override
+ public void startReadListener() {
+ mStopReadListener = false;
+ }
+
+ @Override
+ public void stopReadListener() {
+ mStopReadListener = true;
}
- mUartConfig.stopBits = stopBits;
- return true;
- }
+ private void onRead(int size) {
+ if(mStopReadListener) {
+ return;
+ }
+ for(ReadListener listener : uartReadListenerList) {
+ listener.onRead(size);
+ }
+ }
+ //////////////////////////////////////////////////////////
+
+ /**
+ * Transfers int to little endian byte array
+ *
+ * @param in integer value
+ * @param out 4 or less length byte array
+ */
+ private void intToLittleEndianBytes(int in, byte[] out) {
+ if(out == null) {
+ return;
+ }
+ if(out.length > 4) {
+ return;
+ }
+ for(int i = 0; i < out.length; i++) {
+ out[i] = (byte) ((in >> (i * 8)) & 0x000000FF);
+ }
+ }
- @Override
- public boolean setDtrRts(boolean dtrOn, boolean rtsOn) {
- int ctrlValue = 0x0000;
- byte[] buf = new byte[4];
+ /**
+ * Transfers little endian byte array to int
+ *
+ * @param in 4 or less length byte array
+ * @return integer value
+ */
+ private int littleEndianBytesToInt(byte[] in) {
+ if(in == null) {
+ return 0;
+ }
+ if(in.length > 4) {
+ return 0;
+ }
+ int ret = 0;
+ for(int i = 0; i < in.length; i++) {
+ ret |= (((int) in[i]) & 0x000000FF) << (i * 8);
+ }
+ return ret;
+ }
- if(dtrOn) {
- ctrlValue |= CONTROL_DTR;
- ctrlValue |= CONTROL_WRITE_DTR;
- } else {
- ctrlValue &= ~CONTROL_DTR;
- ctrlValue |= CONTROL_WRITE_DTR;
+ @Override
+ public String getPhysicalConnectionName() {
+ return Physicaloid.USB_STRING;
}
- if(rtsOn) {
- ctrlValue |= CONTROL_RTS;
- ctrlValue |= CONTROL_WRITE_RTS;
- } else {
- ctrlValue &= ~CONTROL_RTS;
- ctrlValue |= CONTROL_WRITE_RTS;
+ @Override
+ public int getPhysicalConnectionType() {
+ return Physicaloid.USB;
}
- intToLittleEndianBytes(ctrlValue, buf);
- int ret = cp210xSetConfig(CP210X_SET_MHS, buf, buf.length);
-
- if(ret < 0) {
- if(DEBUG_SHOW) { Log.d(TAG, "Fail to setDtrRts"); }
- return false;
- }
- mUartConfig.dtrOn = dtrOn;
- mUartConfig.rtsOn = rtsOn;
- return true;
- }
-
- @Override
- public UartConfig getUartConfig() {
- return mUartConfig;
- }
-
- @Override
- public int getBaudrate() {
- return mUartConfig.baudrate;
- }
-
- @Override
- public int getDataBits() {
- return mUartConfig.dataBits;
- }
-
- @Override
- public int getParity() {
- return mUartConfig.parity;
- }
-
- @Override
- public int getStopBits() {
- return mUartConfig.stopBits;
- }
-
- @Override
- public boolean getDtr() {
- return mUartConfig.dtrOn;
- }
-
- @Override
- public boolean getRts() {
- return mUartConfig.rtsOn;
- }
-
- @Override
- public void clearBuffer() {
- mBuffer.clear();
- }
-
- //////////////////////////////////////////////////////////
- // Listener for reading uart
- //////////////////////////////////////////////////////////
- private List uartReadListenerList
- = new ArrayList();
- private boolean mStopReadListener = false;
-
- @Override
- public void addReadListener(ReadLisener listener) {
- uartReadListenerList.add(listener);
- }
-
- @Override
- public void clearReadListener() {
- uartReadListenerList.clear();
- }
-
- @Override
- public void startReadListener() {
- mStopReadListener = false;
- }
-
- @Override
- public void stopReadListener() {
- mStopReadListener = true;
- }
-
- private void onRead(int size) {
- if(mStopReadListener) return;
- for (ReadLisener listener: uartReadListenerList) {
- listener.onRead(size);
- }
- }
- //////////////////////////////////////////////////////////
-
-
- /**
- * Transfers int to little endian byte array
- * @param in integer value
- * @param out 4 or less length byte array
- */
- private void intToLittleEndianBytes(int in, byte[] out) {
- if(out == null) return;
- if(out.length > 4) return;
- for(int i=0; i> (i*8)) & 0x000000FF);
- }
- }
-
- /**
- * Transfers little endian byte array to int
- * @param in 4 or less length byte array
- * @return integer value
- */
- private int littleEndianBytesToInt(byte[] in) {
- if(in == null) return 0;
- if(in.length > 4) return 0;
- int ret=0;
- for(int i=0; i 0) {
- synchronized(ftDev) {
- ftDev = ftD2xx.openByIndex(mContext, USB_OPEN_INDEX);
+ if(mConnection == null) {
+ return false;
+ }
+ int rv;
+ rv = control_out(FTDI_SIO_RESET, 0, 0);
+ if(rv < 0) {
+ return false;
+ }
+ rv = control_out(FTDI_SIO_SET_FLOW_CTRL, 0, 1);
+ if(rv < 0) {
+ return false;
}
- }
+ // set the latency timer to a very low number to improve performance.
+ rv = control_out(FTDI_SIO_SET_LATENCY_TIMER, 0, 1);
+ if(rv < 0) {
+ return false;
+ }
+ return true;
}
- if(ftDev.isOpen()) {
- synchronized(ftDev) {
- ftDev.resetDevice(); // flush any data from the device buffers
- }
- setBaudrate(mUartConfig.baudrate);
- if(DEBUG_SHOW){ Log.d(TAG, "An FTDI device is opened."); }
- startRead();
- return true;
- } else {
- if(DEBUG_SHOW){ Log.e(TAG, "Cannot open an FTDI device."); }
+ @Override
+ public boolean close() {
+ if(mUsbConnetionManager != null) {
+ stopRead();
+ isOpened = false;
+ return mUsbConnetionManager.close();
+ }
+ return true;
}
- return false;
- }
+ @Override
+ public int read(byte[] buf, int size) {
+ return mBuffer.get(buf, size);
+ }
- @Override
- public boolean close() {
- if(ftDev != null) {
- stopRead();
- synchronized (ftDev) {
- ftDev.close();
- }
- if(DEBUG_SHOW){ Log.d(TAG, "An FTDI device is closed."); }
+ private int control_out(int request, int value, int index) {
+ if(mConnection == null) {
+ return -1;
+ }
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "XXXXXXXXXXXXXXXXXXXXXXXXX CTRL r=" + String.format("0x%02X", request) + " v=" + String.format("0x%04X", value) + " i=" + String.format("0x%04X", index));
+ }
+ int ret = mConnection.controlTransfer(REQTYPE_HOST_TO_INTERFACE, request, value, index, null, 0, 100);
+ return ret;
}
- return true;
- }
+ private int control_in(int request, int value, int index, byte buf[], int bufsize) {
+ if(mConnection == null) {
+ return -1;
+ }
+ int ret = mConnection.controlTransfer(REQTYPE_INTERFACE_TO_HOST, request, value, index, buf, bufsize, 100);
+ return ret;
- @Override
- public int read(byte[] buf, int size) {
- return mBuffer.get(buf, size);
- }
+ }
+ @Override
+ public int write(byte[] buf, int size) {
+ if(buf == null) {
+ return 0;
+ }
+ int offset = 0;
+ int write_size;
+ int written_size;
+ int len;
- @Override
- public int write(byte[] buf, int size) {
- if(buf == null) { return 0; }
- int offset = 0;
- int write_size;
- int written_size;
- byte[] wbuf = new byte[USB_WRITE_BUFFER_SIZE];
+ if(DEBUG_SHOW) {
+ Log.e(TAG, "write(" + size + "): " + toHexStr(buf, size));
+ }
- while (offset < size) {
- write_size = USB_WRITE_BUFFER_SIZE;
+ // FTDI is crap, makes us work hard.
+ // We have to treat the chip as if it is an 8250 on the outbound
+ // otherwise it seems that characters don't always seem to make it.
+ while(offset < size) {
+ // check empty
+ while(true) {
+ len = 2;
+ written_size = control_in(FTDI_SIO_GET_MODEM_STATUS, 0, 0, wbuf, len);
+ if(written_size < 1) {
+ return -1;
+ }
+ if(written_size == 1) {
+ wbuf[1] = 0;
+ }
+ if((wbuf[1] & FTDI_RS_TEMT) == FTDI_RS_TEMT) {
+ break;
+ }
+ }
+ write_size = 1;
+ if(offset + write_size > size) {
+ write_size = size - offset;
+ }
+ // optimization!
+ if(offset == 0) {
+ //synchronized(DevLock) {
+ written_size = mConnection.bulkTransfer(mEndpointOut, buf, write_size, 100);
+
+ //}
+ } else {
+ System.arraycopy(buf, offset, wbuf, 0, write_size);
+ //synchronized(DevLock) {
+ written_size = mConnection.bulkTransfer(mEndpointOut, wbuf, write_size, 100);
+ //}
+ }
+ if(written_size < 0) {
+ return -1;
+ }
+ offset += written_size;
+ }
- if (offset + write_size > size) {
- write_size = size - offset;
- }
- System.arraycopy(buf, offset, wbuf, 0, write_size);
+ return offset;
+ }
- synchronized (ftDev) {
- written_size = ftDev.write(wbuf, write_size);
- }
+ private void stopRead() {
+ mReadThreadStop = true;
+ }
- if (written_size < 0) {
- return -1;
- }
- offset += written_size;
+ private void startRead() {
+ if(mReadThreadStop) {
+ mReadThreadStop = false;
+ new Thread(mLoop).start();
+ }
}
+ private Runnable mLoop = new Runnable() {
+
+ @Override
+ @SuppressWarnings("CallToThreadYield")
+ public void run() {
+ try {
+ android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
+ } catch(Exception e) {
+ }
+ int len;
+ //byte[] rbuf = new byte[USB_READ_BUFFER_SIZE];
+ byte[] rbuf = new byte[mEndpointIn.getMaxPacketSize()];
+ byte[] cbuf = new byte[mEndpointIn.getMaxPacketSize()];
+ //android.os.Process.setThreadPriority(-20);
+ UsbRequest response;
+ UsbRequest request = new UsbRequest();
+ request.initialize(mConnection, mEndpointIn);
+ ByteBuffer buf = ByteBuffer.wrap(rbuf);
+ for(;;) {// this is the main loop for transferring
+ len = 0;
+ //synchronized(DevLock) {
+ if(request.queue(buf, rbuf.length)) {
+ response = mConnection.requestWait();
+ if(response != null) {
+ len = buf.position();
+ }
+ }
+ //}
+ if(len > 1) {
+ if(len > 2) {
+ //if(DEBUG_SHOW) {
+ // Log.e(TAG, "read(" + len + "): " + toHexStr(rbuf, len));
+ //}
+ // FTDI stuffs status in the first 2 bytes.
+ len -= 2;
+ System.arraycopy(rbuf, 2, cbuf, 0, len);
+ if(DEBUG_SHOW) {
+ Log.e(TAG, "read(" + len + "): " + toHexStr(cbuf, len));
+ }
+ mBuffer.add(cbuf, len);
+ onRead(mBuffer.getBufferdLength());
+ } else if(mBuffer.getBufferdLength() > 0) {
+ onRead(mBuffer.getBufferdLength());
+ }
+
+ } else if(mBuffer.getBufferdLength() > 0) {
+ onRead(mBuffer.getBufferdLength());
+ }
+
+ if(mReadThreadStop) {
+ return;
+ }
+ }
+ } // end of run()
+ }; // end of runnable
+
+ @Override
+ public boolean setUartConfig(UartConfig config) {
+ boolean res;
+ boolean ret = true;
+ res = setBaudrate(config.baudrate);
+ ret = ret && res;
- return offset;
- }
+ res = setDataBits(config.dataBits);
+ ret = ret && res;
+ res = setParity(config.parity);
+ ret = ret && res;
- private void stopRead() {
- mReadThreadStop = true;
- }
+ res = setStopBits(config.stopBits);
+ ret = ret && res;
+ res = setDtrRts(config.dtrOn, config.rtsOn);
+ ret = ret && res;
- private void startRead() {
- if(mReadThreadStop) {
- mReadThreadStop = false;
- new Thread(mLoop).start();
+ return ret;
}
- }
-
- private Runnable mLoop = new Runnable() {
@Override
- public void run() {
- int len=0;
- byte[] rbuf = new byte[USB_READ_BUFFER_SIZE];
- for (;;) {// this is the main loop for transferring
+ public boolean isOpened() {
+ return isOpened;
+ }
- synchronized (ftDev) {
- len = ftDev.getQueueStatus();
+ @Override
+ public boolean setBaudrate(int baudrate) {
+ if(mUsbConnetionManager == null) {
+ return false;
}
-
- if(len > 0) {
- if(len > MAX_READBUF_SIZE) len = MAX_READBUF_SIZE;
- synchronized (ftDev) {
- len = ftDev.read(rbuf,len,READ_WAIT_MS); // You might want to set wait_ms.
- }
-
- if(DEBUG_SHOW){ Log.e(TAG, "read("+len+"): "+toHexStr(rbuf, len)); }
- mBuffer.add(rbuf, len);
- onRead(len);
-
+ int divfrac[] = {0, 3, 2, 4, 1, 5, 6, 7};
+ int baud_value = 0; // uint16_t
+ int baud_index = 0; // uint16_t
+ int divisor3;
+ divisor3 = 48000000 / 2 / baudrate; // divisor shifted 3 bits to the left
+
+ if(mUsbConnetionManager.getPID() == FT232AM) {
+ if((divisor3 & 0x7) == 7) {
+ divisor3++; // round x.7/8 up to x+1
+ }
+ baud_value = divisor3 >> 3;
+ divisor3 &= 0x7;
+
+ if(divisor3 == 1) {
+ baud_value |= 0xc000;
+ } else // 0.125
+ if(divisor3 >= 4) {
+ baud_value |= 0x4000;
+ } else // 0.5
+ if(divisor3 != 0) {
+ baud_value |= 0x8000; // 0.25
+ }
+ if(baud_value == 1) {
+ baud_value = 0; /* special case for maximum baud rate */
+ }
+ } else {
+
+ baud_value = divisor3 >> 3;
+ baud_value |= divfrac[divisor3 & 0x7] << 14;
+ //baud_index = divindex[divisor3 & 0x7];
+
+ /* Deal with special cases for highest baud rates. */
+ if(baud_value == 1) {
+ baud_value = 0;
+ } else // 1.0
+ if(baud_value == 0x4001) {
+ baud_value = 1; // 1.5
+ }
}
-
- if (mReadThreadStop) {
- return;
+ baud_index = (baud_value >> 16) & 0xFFFF;
+ baud_value &= 0xFFFF;
+
+ int rv = control_out(FTDI_SIO_SET_BAUD_RATE, baud_value, baud_index);
+ if(rv < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "setBaudrate failed " + rv);
+ }
+ return false;
}
+ mUartConfig.baudrate = baudrate;
+ return true;
+ }
- try {
- Thread.sleep(50);
- } catch (InterruptedException e) {
+ @Override
+ public boolean setDataBits(int dataBits) {
+ if(mUsbConnetionManager == null) {
+ return false;
}
-
- }
- } // end of run()
- }; // end of runnable
-
-
- @Override
- public boolean setUartConfig(UartConfig config) {
- boolean res = true;
- boolean ret = true;
- if(mUartConfig.baudrate != config.baudrate) {
- res = setBaudrate(config.baudrate);
- ret = ret && res;
+ int s = ((mUartConfig.stopBits) << 11) | ((mUartConfig.parity) << 8) | dataBits;
+ int rv = control_out(FTDI_SIO_SET_DATA, s, 1);
+ if(rv < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "setDataBits failed " + rv);
+ }
+ return false;
+ }
+ mUartConfig.dataBits = dataBits;
+ return true;
}
- if(mUartConfig.dataBits != config.dataBits) {
- res = setDataBits(config.dataBits);
- ret = ret && res;
+ @Override
+ public boolean setParity(int parity) {
+ if(mUsbConnetionManager == null) {
+ return false;
+ }
+ int s = ((mUartConfig.stopBits) << 11) | ((parity) << 8) | mUartConfig.dataBits;
+ int rv = control_out(FTDI_SIO_SET_DATA, s, 1);
+ if(rv < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "setParity failed " + rv);
+ }
+ return false;
+ }
+ mUartConfig.parity = parity;
+ return true;
}
- if(mUartConfig.parity != config.parity) {
- res = setParity(config.parity);
- ret = ret && res;
+ @Override
+ public boolean setStopBits(int stopBits) {
+ if(mUsbConnetionManager == null) {
+ return false;
+ }
+ int s = ((stopBits) << 11) | ((mUartConfig.parity) << 8) | mUartConfig.dataBits;
+ int rv = control_out(FTDI_SIO_SET_DATA, s, 1);
+ if(rv < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "setStopBits failed " + rv);
+ }
+ return false;
+ }
+ mUartConfig.stopBits = stopBits;
+ return true;
}
- if(mUartConfig.stopBits != config.stopBits) {
- res = setStopBits(config.stopBits);
- ret = ret && res;
+ @Override
+ public boolean setDtrRts(boolean dtrOn, boolean rtsOn) {
+ if(mUsbConnetionManager == null) {
+ return false;
+ }
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "setDtrRts " + Boolean.toString(dtrOn) + ", " + Boolean.toString(rtsOn));
+ }
+ int s = FTDI_SIO_SET_DTR_HIGH;
+ if(!dtrOn) {
+ s = FTDI_SIO_SET_DTR_LOW;
+ }
+ int rv = control_out(FTDI_SIO_MODEM_CTRL, s, 1);
+ if(rv < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "setDtr failed " + rv);
+ }
+ return false;
+ }
+ s = FTDI_SIO_SET_RTS_HIGH;
+ if(!rtsOn) {
+ s = FTDI_SIO_SET_RTS_LOW;
+ }
+ rv = control_out(FTDI_SIO_MODEM_CTRL, s, 1);
+ if(rv < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "setRts failed " + rv);
+ }
+ return false;
+ }
+ mUartConfig.dtrOn = dtrOn;
+ mUartConfig.rtsOn = rtsOn;
+ return true;
}
- if(mUartConfig.dtrOn != config.dtrOn ||
- mUartConfig.rtsOn != config.rtsOn) {
- res = setDtrRts(config.dtrOn, config.rtsOn);
- ret = ret && res;
+ @Override
+ public UartConfig getUartConfig() {
+ return mUartConfig;
}
- return ret;
- }
-
-
- @Override
- public boolean isOpened() {
- if(ftDev == null) { return false; }
- synchronized (ftDev) {
- return ftDev.isOpen();
+ @Override
+ public int getBaudrate() {
+ return mUartConfig.baudrate;
}
- }
-
- @Override
- public boolean setBaudrate(int baudrate) {
- if(ftDev == null) { return false; }
- boolean ret=false;
- synchronized (ftDev) {
- ret = ftDev.setBaudRate(baudrate);
- }
- if(ret) {
- mUartConfig.baudrate = baudrate;
+ @Override
+ public int getDataBits() {
+ return mUartConfig.dataBits;
}
- return ret;
- }
-
- @Override
- public boolean setDataBits(int dataBits) {
- if(ftDev == null) { return false; }
- boolean ret = false;
- byte ftdiDataBits = convertFtdiDataBits(dataBits);
- byte ftdiStopBits = convertFtdiStopBits(mUartConfig.stopBits);
- byte ftdiParity = convertFtdiParity(mUartConfig.parity);
- synchronized (ftDev) {
- ret = ftDev.setDataCharacteristics(ftdiDataBits, ftdiStopBits, ftdiParity);
- }
- if(ret) {
- mUartConfig.dataBits = dataBits;
+ @Override
+ public int getParity() {
+ return mUartConfig.parity;
}
- return ret;
- }
-
- @Override
- public boolean setParity(int parity) {
- if(ftDev == null) { return false; }
- boolean ret = false;
- byte ftdiDataBits = convertFtdiDataBits(mUartConfig.dataBits);
- byte ftdiStopBits = convertFtdiStopBits(mUartConfig.stopBits);
- byte ftdiParity = convertFtdiParity(parity);
- synchronized (ftDev) {
- ret = ftDev.setDataCharacteristics(ftdiDataBits, ftdiStopBits, ftdiParity);
- }
- if(ret) {
- mUartConfig.parity = parity;
+ @Override
+ public int getStopBits() {
+ return mUartConfig.stopBits;
}
- return ret;
- }
-
- @Override
- public boolean setStopBits(int stopBits) {
- if(ftDev == null) { return false; }
- boolean ret = false;
- byte ftdiDataBits = convertFtdiDataBits(mUartConfig.dataBits);
- byte ftdiStopBits = convertFtdiStopBits(stopBits);
- byte ftdiParity = convertFtdiParity(mUartConfig.parity);
- synchronized (ftDev) {
- ret = ftDev.setDataCharacteristics(ftdiDataBits, ftdiStopBits, ftdiParity);
+ @Override
+ public boolean getDtr() {
+ return mUartConfig.dtrOn;
}
- if(ret) {
- mUartConfig.stopBits = stopBits;
+
+ @Override
+ public boolean getRts() {
+ return mUartConfig.rtsOn;
}
- return ret;
- }
+ @Override
+ public void clearBuffer() {
+ // clear ftdi chip buffer
+ //synchronized(ftDevLock) {
+ // ftDev.purge((byte) (D2xxManager.FT_PURGE_TX | D2xxManager.FT_PURGE_RX));
+ //}
- @Override
- public boolean setDtrRts(boolean dtrOn, boolean rtsOn) {
- if(ftDev == null) { return false; }
- boolean retDtr = false;
- boolean retRts = false;
- if(dtrOn) {
- synchronized (ftDev) {
- retDtr = ftDev.setDtr();
- }
- } else {
- synchronized (ftDev) {
- retDtr = ftDev.clrDtr();
- }
- }
- if(retDtr) {
- mUartConfig.dtrOn = dtrOn;
+ mBuffer.clear();
}
+ //////////////////////////////////////////////////////////
+ // Listener for reading uart
+ //////////////////////////////////////////////////////////
+ private List uartReadListenerList = new ArrayList();
+ private boolean mStopReadListener = false;
- if(rtsOn) {
- synchronized (ftDev) {
- retRts = ftDev.setRts();
- }
- } else {
- synchronized (ftDev) {
- retRts = ftDev.clrRts();
- }
- }
- if(retRts) {
- mUartConfig.rtsOn = rtsOn;
+ @Override
+ public void addReadListener(ReadListener listener) {
+ uartReadListenerList.add(listener);
}
- return retDtr&&retRts;
- }
-
-
- @Override
- public UartConfig getUartConfig() {
- return mUartConfig;
- }
-
-
- @Override
- public int getBaudrate() {
- return mUartConfig.baudrate;
- }
-
- @Override
- public int getDataBits() {
- return mUartConfig.dataBits;
- }
-
-
- @Override
- public int getParity() {
- return mUartConfig.parity;
- }
-
-
- @Override
- public int getStopBits() {
- return mUartConfig.stopBits;
- }
-
-
- @Override
- public boolean getDtr() {
- return mUartConfig.dtrOn;
- }
-
-
- @Override
- public boolean getRts() {
- return mUartConfig.rtsOn;
- }
-
-
- @Override
- public void clearBuffer() {
- // clear ftdi chip buffer
- synchronized (ftDev) {
- ftDev.purge((byte) (D2xxManager.FT_PURGE_TX | D2xxManager.FT_PURGE_RX));
+ @Override
+ @Deprecated
+ public void addReadListener(ReadLisener listener) {
+ addReadListener((ReadListener) listener);
}
- mBuffer.clear();
- }
-
-
- //////////////////////////////////////////////////////////
- // Listener for reading uart
- //////////////////////////////////////////////////////////
- private List uartReadListenerList
- = new ArrayList();
- private boolean mStopReadListener = false;
-
- @Override
- public void addReadListener(ReadLisener listener) {
- uartReadListenerList.add(listener);
- }
-
- @Override
- public void clearReadListener() {
- uartReadListenerList.clear();
- }
-
- @Override
- public void startReadListener() {
- mStopReadListener = false;
- }
-
- @Override
- public void stopReadListener() {
- mStopReadListener = true;
- }
- private void onRead(int size) {
- if(mStopReadListener) return;
- for (ReadLisener listener: uartReadListenerList) {
- listener.onRead(size);
+ @Override
+ public void clearReadListener() {
+ uartReadListenerList.clear();
}
- }
- //////////////////////////////////////////////////////////
-
- private byte convertFtdiDataBits(int dataBits) {
- switch (dataBits) {
- case UartConfig.DATA_BITS7:
- return D2xxManager.FT_DATA_BITS_7;
- case UartConfig.DATA_BITS8:
- return D2xxManager.FT_DATA_BITS_8;
- default:
- return D2xxManager.FT_DATA_BITS_8;
+ @Override
+ public void startReadListener() {
+ mStopReadListener = false;
}
- }
+ @Override
+ public void stopReadListener() {
+ mStopReadListener = true;
+ }
- private byte convertFtdiStopBits(int stopBits) {
- switch (stopBits) {
- case UartConfig.STOP_BITS1:
- return D2xxManager.FT_STOP_BITS_1;
- case UartConfig.STOP_BITS2:
- return D2xxManager.FT_STOP_BITS_2;
- default:
- return D2xxManager.FT_STOP_BITS_1;
+ private void onRead(int size) {
+ if(mStopReadListener) {
+ return;
+ }
+ for(ReadListener listener : uartReadListenerList) {
+ listener.onRead(size);
+ }
}
- }
+ //////////////////////////////////////////////////////////
+ private String toHexStr(byte[] b, int length) {
+ String str = "";
+ for(int i = 0; i < length; i++) {
+ str += String.format("%02x ", b[i]);
+ }
+ return str;
+ }
- private byte convertFtdiParity(int parity) {
- switch (parity) {
- case UartConfig.PARITY_NONE:
- return D2xxManager.FT_PARITY_NONE;
- case UartConfig.PARITY_ODD:
- return D2xxManager.FT_PARITY_ODD;
- case UartConfig.PARITY_EVEN:
- return D2xxManager.FT_PARITY_EVEN;
- case UartConfig.PARITY_MARK:
- return D2xxManager.FT_PARITY_MARK;
- case UartConfig.PARITY_SPACE:
- return D2xxManager.FT_PARITY_SPACE;
- default:
- return D2xxManager.FT_PARITY_NONE;
+ @Override
+ public String getPhysicalConnectionName() {
+ return Physicaloid.USB_STRING;
}
- }
- private String toHexStr(byte[] b, int length) {
- String str="";
- for(int i=0; i size) {
+ write_size = size - offset;
+ }
+ System.arraycopy(buf, offset, wbuf, 0, write_size);
+
+ written_size = mConnection.bulkTransfer(mEndpointOut, wbuf, write_size, 100);
+
+ if(written_size < 0) {
+ return -1;
+ }
+ offset += written_size;
+ }
+
+ return offset;
+ }
+
+ private void stopRead() {
+ mReadThreadStop = true;
+ }
+
+ private void startRead() {
+ if(mReadThreadStop) {
+ mReadThreadStop = false;
+ new Thread(mLoop).start();
+ }
+ }
+ private Runnable mLoop = new Runnable() {
+
+ @Override
+ public void run() {
+ int len;
+ byte[] rbuf = new byte[mEndpointIn.getMaxPacketSize()];
+ android.os.Process.setThreadPriority(-20);
+ UsbRequest response;
+ UsbRequest request = new UsbRequest();
+ request.initialize(mConnection, mEndpointIn);
+ ByteBuffer buf = ByteBuffer.wrap(rbuf);
+ for(;;) {// this is the main loop for transferring
+ len = 0;
+ if(request.queue(buf, rbuf.length)) {
+ response = mConnection.requestWait();
+ if(response != null) {
+ len = buf.position();
+ }
+ if(len > 0) {
+ mBuffer.add(rbuf, len);
+ onRead(len);
+ } else if(mBuffer.getBufferdLength() > 0) {
+ onRead(mBuffer.getBufferdLength());
+ } else if(mBuffer.getBufferdLength() > 0) {
+ onRead(mBuffer.getBufferdLength());
+ }
+
+
+ }
+
+ if(mReadThreadStop) {
+ return;
+ }
+
+ }
+ } // end of run()
+ }; // end of runnable
+
+ @Override
+ public boolean setUartConfig(UartConfig config) {
+ boolean res;
+ boolean ret = true;
+ res = setBaudrate(config.baudrate);
+ ret = ret && res;
+
+ res = setDataBits(config.dataBits);
+ ret = ret && res;
+
+ res = setParity(config.parity);
+ ret = ret && res;
+
+ res = setStopBits(config.stopBits);
+ ret = ret && res;
+
+ res = setDtrRts(config.dtrOn, config.rtsOn);
+ ret = ret && res;
+
+ return ret;
+ }
+
+ /**
+ * Initializes UART communication
+ *
+ * @return true : successful, false : fail
+ */
+ private boolean init() {
+
+ int size = 8;
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "init");
+ }
+ byte[] buffer = new byte[size];
+
+ if(mConnection == null) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "init mConnection == null");
+ }
+ return false;
+ }
+
+ /* expect two bytes */
+ int r = ch341_control_in(CH341_REQ_READ_VERSION, 0, 0, buffer, size);
+ if(r != 2) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "init r !=2 for 0x5f");
+ }
+ return false;
+ }
+
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "Chip version " + buffer[0]);
+ }
+
+ r = ch341_control_out(CH341_REQ_SERIAL_INIT, 0, 0);
+ if(r < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "init fail on chip init");
+ }
+ return false;
+ }
+
+ r = ch341_get_status();
+ if(r < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "init status failed");
+ }
+ return false;
+ }
+
+
+ if(!setBaudrate(mUartConfig.baudrate)) {
+ return false;
+ }
+
+ if(!setDtrRts(mUartConfig.dtrOn, mUartConfig.rtsOn)) {
+ return false;
+ }
+
+ /* expect 0x9f 0xee, not checked */
+ r = ch341_get_status();
+ if(r < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "init final status failed");
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean isOpened() {
+ return isOpened;
+ }
+
+ private int ch341_control_out(int request, int value, int index) {
+ if(mConnection == null) {
+ return -1;
+ }
+ int ret = mConnection.controlTransfer(REQTYPE_HOST_TO_INTERFACE, request, value, index, null, 0, 100);
+ return ret;
+ }
+ /*
+ * int requestType,
+ * int request,
+ * int value,
+ * int index,
+ * byte[] buffer,
+ * int length,
+ * int timeout
+ */
+
+ private int ch341_control_in(int request, int value, int index, byte buf[], int bufsize) {
+ if(mConnection == null) {
+ return -1;
+ }
+ int ret = mConnection.controlTransfer(REQTYPE_INTERFACE_TO_HOST, request, value, index, buf, bufsize, 100);
+ return ret;
+
+ }
+
+ private int ch341_get_status() {
+ int size = 8;
+ long flags;
+ byte[] buffer = new byte[size];
+ int r = ch341_control_in(0x95, 0x0706, 0, buffer, size);
+ if(r < 0) {
+ return r;
+ }
+ if(r == 2) {
+ r = 0;
+ line_status = (~buffer[0]) & CH341_BITS_MODEM_STAT;
+ } else {
+ r = -1;
+ }
+ return r;
+ }
+
+ @Override
+ public boolean setBaudrate(int baudrate) {
+
+ if(mConnection == null) {
+ return false;
+ }
+ long factor = CH341_BAUDBASE_FACTOR / baudrate;
+ short divisor = CH341_BAUDBASE_DIVMAX;
+
+ while((factor > 0xfff0) && divisor != 0) {
+ factor >>= 3;
+ divisor--;
+ }
+
+ if(factor > 0xfff0) {
+ return false;
+ }
+ factor = 0x10000 - factor;
+ int a = (int) (factor & 0xff00) | divisor | 0x80; // bit 7 needed for 341
+
+ int r = ch341_control_out(CH341_REQ_WRITE_REG, 0x1312, a);
+ if(r < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "Fail to setBaudrate");
+ }
+ return false;
+ }
+
+ r = ch341_control_out(CH341_REQ_WRITE_REG, 0x2518, lcr);
+ if(r < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "Fail to setBaudrate lcr");
+ }
+ return false;
+ }
+ mUartConfig.baudrate = baudrate;
+ return true;
+ }
+
+ @Override
+ public boolean setDataBits(int dataBits) {
+ int p;
+ switch(dataBits) {
+ case 5:
+ p = CH341_LCR_CS5;
+ break;
+ case 6:
+ p = CH341_LCR_CS6;
+ break;
+ case 7:
+ p = CH341_LCR_CS7;
+ break;
+ case 8:
+ p = CH341_LCR_CS8;
+ break;
+ default:
+ return false;
+ }
+ lcr &= ~(CH341_LCR_CS8);
+ lcr |= p;
+ int r = ch341_control_out(CH341_REQ_WRITE_REG, 0x2518, lcr);
+ if(r < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "Fail to set data bits");
+ }
+ return false;
+ }
+ mUartConfig.dataBits = dataBits;
+ return true;
+ }
+
+ @Override
+ public boolean setParity(int parity) {
+ int p;
+ switch(parity) {
+ case UartConfig.PARITY_NONE:
+ p = 0x00;
+ break;
+ case UartConfig.PARITY_ODD:
+ p = CH341_LCR_ENABLE_PAR;
+ break;
+ case UartConfig.PARITY_EVEN:
+ p = CH341_LCR_ENABLE_PAR | CH341_LCR_PAR_EVEN;
+ break;
+ case UartConfig.PARITY_MARK:
+ p = CH341_LCR_ENABLE_PAR | CH341_LCR_MARK_SPACE;
+ break;
+ case UartConfig.PARITY_SPACE:
+ p = CH341_LCR_ENABLE_PAR | CH341_LCR_PAR_EVEN | CH341_LCR_MARK_SPACE;
+ break;
+ default:
+ return false;
+ }
+ lcr &= CH341_LCR_PAR_MASK;
+ lcr |= p;
+ int r = ch341_control_out(CH341_REQ_WRITE_REG, 0x2518, lcr);
+ if(r < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "Fail to set parity");
+ }
+ return false;
+ }
+ mUartConfig.parity = parity;
+ return true;
+ }
+
+ @Override
+ public boolean setStopBits(int stopBits) {
+ if(stopBits < 1 || stopBits > 2) {
+ return false;
+ }
+ if(stopBits == 1) {
+ lcr &= ~CH341_LCR_STOP_BITS_2;
+ } else {
+ lcr |= CH341_LCR_STOP_BITS_2;
+ }
+
+ int r = ch341_control_out(CH341_REQ_WRITE_REG, 0x2518, lcr);
+ if(r < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "Fail to set stop bits");
+ }
+ return false;
+ }
+
+ mUartConfig.stopBits = stopBits;
+ return true;
+ }
+
+ @Override
+ public boolean setDtrRts(boolean dtrOn, boolean rtsOn) {
+ int ctrlValue = 0x0000;
+
+ if(dtrOn) {
+ ctrlValue |= CH341_BIT_DTR;
+ }
+
+ if(rtsOn) {
+ ctrlValue |= CH341_BIT_RTS;
+ }
+
+ int r = ch341_control_out(0xa4, ~ctrlValue, 0);
+
+ if(r < 0) {
+ if(DEBUG_SHOW) {
+ Log.d(TAG, "Fail to setDtrRts");
+ }
+ return false;
+ }
+ mUartConfig.dtrOn = dtrOn;
+ mUartConfig.rtsOn = rtsOn;
+ return true;
+ }
+
+ @Override
+ public UartConfig getUartConfig() {
+ return mUartConfig;
+ }
+
+ @Override
+ public int getBaudrate() {
+ return mUartConfig.baudrate;
+ }
+
+ @Override
+ public int getDataBits() {
+ return mUartConfig.dataBits;
+ }
+
+ @Override
+ public int getParity() {
+ return mUartConfig.parity;
+ }
+
+ @Override
+ public int getStopBits() {
+ return mUartConfig.stopBits;
+ }
+
+ @Override
+ public boolean getDtr() {
+ return mUartConfig.dtrOn;
+ }
+
+ @Override
+ public boolean getRts() {
+ return mUartConfig.rtsOn;
+ }
+
+ @Override
+ public void clearBuffer() {
+ mBuffer.clear();
+ }
+ //////////////////////////////////////////////////////////
+ // Listener for reading uart
+ //////////////////////////////////////////////////////////
+ private List uartReadListenerList = new ArrayList();
+ private boolean mStopReadListener = false;
+
+ @Override
+ public void addReadListener(ReadListener listener) {
+ uartReadListenerList.add(listener);
+ }
+
+ @Override
+ @Deprecated
+ public void addReadListener(ReadLisener listener) {
+ addReadListener((ReadListener) listener);
+ }
+
+ @Override
+ public void clearReadListener() {
+ uartReadListenerList.clear();
+ }
+
+ @Override
+ public void startReadListener() {
+ mStopReadListener = false;
+ }
+
+ @Override
+ public void stopReadListener() {
+ mStopReadListener = true;
+ }
+
+ private void onRead(int size) {
+ if(mStopReadListener) {
+ return;
+ }
+ for(ReadListener listener : uartReadListenerList) {
+ listener.onRead(size);
+ }
+ }
+ //////////////////////////////////////////////////////////
+
+ @Override
+ public String getPhysicalConnectionName() {
+ return Physicaloid.USB_STRING;
+ }
+
+ @Override
+ public int getPhysicalConnectionType() {
+ return Physicaloid.USB;
+ }
+
+ @Override
+ public void setDebug(boolean flag) {
+ DEBUG_SHOW = flag;
+ }
+}
diff --git a/PhysicaloidLibrary/src/com/physicaloid/lib/wifi/driver/uart/UartWifi.java b/PhysicaloidLibrary/src/com/physicaloid/lib/wifi/driver/uart/UartWifi.java
new file mode 100644
index 0000000..b0a01ce
--- /dev/null
+++ b/PhysicaloidLibrary/src/com/physicaloid/lib/wifi/driver/uart/UartWifi.java
@@ -0,0 +1,548 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.physicaloid.lib.wifi.driver.uart;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.util.Log;
+import com.physicaloid.BuildConfig;
+import com.physicaloid.lib.Physicaloid;
+import com.physicaloid.lib.framework.SerialCommunicator;
+import com.physicaloid.lib.usb.driver.uart.ReadLisener;
+import com.physicaloid.lib.usb.driver.uart.ReadListener;
+import com.physicaloid.lib.usb.driver.uart.UartConfig;
+import com.physicaloid.misc.RingBuffer;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author xxxajk@gmail.com
+ */
+public class UartWifi extends SerialCommunicator {
+
+ private static final String TAG = UartWifi.class.getSimpleName();
+ private boolean DEBUG_SHOW = false;
+ private static final int DEFAULT_BAUDRATE = 9600;
+ private UartConfig mUartConfig;
+ private static final int RING_BUFFER_SIZE = 1024;
+ private static final int READ_BUFFER_SIZE = 256;
+ private static final int WRITE_BUFFER_SIZE = 256;
+ private RingBuffer mBuffer;
+ private boolean mReadThreadStop = true;
+ private boolean isOpened;
+ private String SERVER_IP = null;
+ private int DATA_PORT = 0;
+ private int CTRL_PORT = 0;
+ private Socket DATA_socket;
+ private Socket CTRL_socket;
+ private DataOutputStream CTRL_OUT;
+ private DataOutputStream DATA_OUT;
+ private DataInputStream DATA_IN;
+ volatile boolean CTRL_keep_going = false;
+ volatile boolean CTRL_still_going = false;
+ volatile boolean DATA_keep_going = false;
+ volatile boolean DATA_still_going = false;
+ volatile Context me;
+
+ private boolean isNetworkConnected(Context context) {
+ //Log.d(TAG, "Network available?");
+ ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo netInfo = cm.getActiveNetworkInfo();
+ if(netInfo == null) {
+ return false;
+ }
+ return (netInfo.isConnected() && netInfo.getType() == ConnectivityManager.TYPE_WIFI);
+ //return cm.getActiveNetworkInfo() != null;
+ }
+
+ public UartWifi(Context context, String host, int Dport, int Cport) {
+ super(context);
+ SERVER_IP = host;
+ DATA_PORT = Dport;
+ CTRL_PORT = Cport;
+ mUartConfig = new UartConfig();
+ mBuffer = new RingBuffer(RING_BUFFER_SIZE);
+ isOpened = false;
+ CTRL_socket = null;
+ DATA_socket = null;
+ CTRL_OUT = null;
+ DATA_OUT = null;
+ DATA_IN = null;
+ me = context;
+ }
+
+ @Override
+ public boolean open() {
+ if(!isOpened) {
+ if(!init()) {
+ close();
+ return false;
+ }
+ if(!setBaudrate(DEFAULT_BAUDRATE)) {
+ close();
+ return false;
+ }
+ mBuffer.clear();
+ startRead();
+ isOpened = true;
+ }
+ return true;
+ }
+ private Runnable connect_CTRL = new Runnable() {
+
+ InetAddress serverAddr;
+
+ @Override
+ @SuppressWarnings("CallToThreadDumpStack")
+ public void run() {
+ Log.d(TAG, "Network? " + isNetworkConnected(me));
+ while(CTRL_keep_going && isNetworkConnected(me)) {
+ try {
+ serverAddr = InetAddress.getByName(SERVER_IP);
+ CTRL_socket = new Socket(serverAddr, CTRL_PORT);
+ CTRL_socket.setKeepAlive(true);
+ CTRL_socket.setTcpNoDelay(true);
+ CTRL_still_going = false;
+ CTRL_keep_going = false;
+ return;
+ } catch(Exception ex) {
+ //Log.d(TAG, ex.toString());
+ //ex.printStackTrace();
+ }
+ }
+ CTRL_still_going = false;
+ }
+ };
+ private Runnable connect_DATA = new Runnable() {
+
+ InetAddress serverAddr;
+
+ @Override
+ @SuppressWarnings("CallToThreadDumpStack")
+ public void run() {
+ while(DATA_keep_going && isNetworkConnected(me)) {
+ try {
+ serverAddr = InetAddress.getByName(SERVER_IP);
+ DATA_socket = new Socket(serverAddr, DATA_PORT);
+ DATA_socket.setKeepAlive(true);
+ DATA_socket.setTcpNoDelay(true);
+ DATA_keep_going = false;
+ DATA_still_going = false;
+ return;
+ } catch(Exception ex) {
+ //Log.d(TAG, ex.toString());
+ //ex.printStackTrace();
+ }
+ }
+ DATA_still_going = false;
+ }
+ };
+
+ @SuppressWarnings({"SleepWhileInLoop", "CallToThreadDumpStack"})
+ private boolean init() {
+
+ CTRL_keep_going = true;
+ CTRL_still_going = true;
+ DATA_keep_going = true;
+ DATA_still_going = true;
+ Log.d(TAG, "********************* WiFi Connecting CTRL **************");
+ new Thread(connect_CTRL).start();
+ Log.d(TAG, "********************* WiFi Connecting DATA **************");
+ new Thread(connect_DATA).start();
+ Log.d(TAG, "********************* WiFi WAITING **************");
+
+ // timeout after how many seconds? How about 30?
+ int timeout = (30 * 1000) / 50;
+ while(CTRL_still_going && DATA_still_going && (timeout > 0) && isNetworkConnected(me)) {
+ try {
+ // STALL APP :-)
+ Thread.sleep(50);
+ timeout--;
+ } catch(InterruptedException ex) {
+ }
+ }
+ if(timeout <= 0) {
+ // did not connect, kill threads.
+ DATA_keep_going = false;
+ CTRL_keep_going = false;
+ while(DATA_still_going && CTRL_still_going) {
+ try {
+ Thread.sleep(50);
+ } catch(InterruptedException ex) {
+ }
+ }
+ Log.d(TAG, "********************* WiFi Timed out! **************");
+ return false;
+ }
+ try {
+ CTRL_OUT = new DataOutputStream(CTRL_socket.getOutputStream());
+ DATA_OUT = new DataOutputStream(DATA_socket.getOutputStream());
+ DATA_IN = new DataInputStream(DATA_socket.getInputStream());
+ } catch(Exception ex) {
+ Log.d(TAG, "********************* WiFi DIED! **************");
+ Log.d(TAG, ex.toString());
+ ex.printStackTrace();
+ return false;
+ }
+ Log.d(TAG, "********************* WiFi Connected! **************");
+ return true;
+ }
+
+ @Override
+ @SuppressWarnings({"CallToThreadDumpStack", "SleepWhileInLoop"})
+ public boolean close() {
+ stopRead();
+ isOpened = false;
+ CTRL_keep_going = false;
+ DATA_keep_going = false;
+ while(DATA_still_going || CTRL_still_going) {
+ try {
+ Thread.sleep(50);
+ } catch(InterruptedException ex) {
+ }
+ }
+ if(CTRL_OUT != null) {
+ try {
+ CTRL_OUT.close();
+ } catch(Exception ex) {
+ Log.d(TAG, ex.toString());
+ ex.printStackTrace();
+ }
+ CTRL_OUT = null;
+
+ }
+ if(DATA_OUT != null) {
+ try {
+ DATA_OUT.close();
+ } catch(Exception ex) {
+ Log.d(TAG, ex.toString());
+ ex.printStackTrace();
+ }
+ DATA_OUT = null;
+ }
+ if(DATA_IN != null) {
+ try {
+ DATA_IN.close();
+ } catch(Exception ex) {
+ Log.d(TAG, ex.toString());
+ ex.printStackTrace();
+ }
+ DATA_IN = null;
+ }
+ if(CTRL_socket != null) {
+ try {
+ CTRL_socket.close();
+ } catch(Exception ex) {
+ Log.d(TAG, ex.toString());
+ ex.printStackTrace();
+ }
+ CTRL_socket = null;
+ }
+ if(DATA_socket != null) {
+ try {
+ DATA_socket.close();
+ } catch(Exception ex) {
+ Log.d(TAG, ex.toString());
+ ex.printStackTrace();
+ }
+ DATA_socket = null;
+ }
+ return true;
+ }
+
+ @Override
+ public int read(byte[] buf, int size) {
+ return mBuffer.get(buf, size);
+ }
+
+ @Override
+ @SuppressWarnings("CallToThreadDumpStack")
+ public int write(byte[] buf, int size) {
+ if(buf == null) {
+ return 0;
+ }
+ try {
+ DATA_OUT.write(buf, 0, size);
+ DATA_OUT.flush();
+ } catch(Exception ex) {
+ close();
+ Log.d(TAG, ex.toString());
+ ex.printStackTrace();
+ return -1;
+ }
+ return size;
+ }
+
+ @Override
+ @SuppressWarnings("CallToThreadDumpStack")
+ public boolean setBaudrate(int baudrate) {
+ byte b[] = {0x40, (byte) (baudrate & 0xff), (byte) ((baudrate >> 8) & 0xff), (byte) ((baudrate >> 16) & 0xff), (byte) ((baudrate >> 24) & 0xff)};
+ try {
+ CTRL_OUT.write(b, 0, 5);
+ CTRL_OUT.flush();
+ } catch(Exception ex) {
+ close();
+ Log.d(TAG, ex.toString());
+ ex.printStackTrace();
+ return false;
+ }
+ mUartConfig.baudrate = baudrate;
+ return true;
+ }
+
+ @Override
+ public boolean setDataBits(int dataBits) {
+ // We don't do this...
+ mUartConfig.dataBits = dataBits;
+ return true;
+ }
+
+ @Override
+ public boolean setParity(int parity) {
+ // We don't do this...
+ mUartConfig.parity = parity;
+ return true;
+ }
+
+ @Override
+ public boolean setStopBits(int stopBits) {
+ // We don't do this...
+ mUartConfig.stopBits = stopBits;
+ return true;
+ }
+
+ @Override
+ @SuppressWarnings("CallToThreadDumpStack")
+ public boolean setDtrRts(boolean dtrOn, boolean rtsOn) {
+ try {
+ // TO-DO: rts... This is good enough for now, though.
+ if(dtrOn) {
+ byte b[] = {1};
+ CTRL_OUT.write(b, 0, 1);
+ } else {
+ byte b[] = {0};
+ CTRL_OUT.write(b, 0, 1);
+ }
+ CTRL_OUT.flush();
+ } catch(Exception ex) {
+ close();
+ Log.d(TAG, ex.toString());
+ ex.printStackTrace();
+ return false;
+ }
+ mUartConfig.dtrOn = dtrOn;
+ mUartConfig.rtsOn = rtsOn;
+ return true;
+ }
+
+ //////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////
+ /**
+ * Sets Uart configurations
+ *
+ * @param config configurations
+ * @return true : successful, false : fail
+ */
+ public boolean setUartConfig(UartConfig config) {
+ boolean res;
+ boolean ret = true;
+ if(mUartConfig.baudrate != config.baudrate) {
+ res = setBaudrate(config.baudrate);
+ ret = ret && res;
+ }
+
+ if(mUartConfig.dataBits != config.dataBits) {
+ res = setDataBits(config.dataBits);
+ ret = ret && res;
+ }
+
+ if(mUartConfig.parity != config.parity) {
+ res = setParity(config.parity);
+ ret = ret && res;
+ }
+
+ if(mUartConfig.stopBits != config.stopBits) {
+ res = setStopBits(config.stopBits);
+ ret = ret && res;
+ }
+
+ if(mUartConfig.dtrOn != config.dtrOn
+ || mUartConfig.rtsOn != config.rtsOn) {
+ res = setDtrRts(config.dtrOn, config.rtsOn);
+ ret = ret && res;
+ }
+
+ return ret;
+ }
+
+ @Override
+ public boolean isOpened() {
+ return isOpened;
+ }
+
+ @Override
+ public UartConfig getUartConfig() {
+ return mUartConfig;
+ }
+
+ @Override
+ public int getBaudrate() {
+ return mUartConfig.baudrate;
+ }
+
+ @Override
+ public int getDataBits() {
+ return mUartConfig.dataBits;
+ }
+
+ @Override
+ public int getParity() {
+ return mUartConfig.parity;
+ }
+
+ @Override
+ public int getStopBits() {
+ return mUartConfig.stopBits;
+ }
+
+ @Override
+ public boolean getDtr() {
+ return mUartConfig.dtrOn;
+ }
+
+ @Override
+ public boolean getRts() {
+ return mUartConfig.rtsOn;
+ }
+
+ @Override
+ public void clearBuffer() {
+ mBuffer.clear();
+ }
+ //////////////////////////////////////////////////////////
+ // Listener for reading uart
+ //////////////////////////////////////////////////////////
+ private List uartReadListenerList = new ArrayList();
+ private boolean mStopReadListener = false;
+
+ @Override
+ public void addReadListener(ReadListener listener) {
+ uartReadListenerList.add(listener);
+ }
+
+ @Override
+ @Deprecated
+ public void addReadListener(ReadLisener listener) {
+ addReadListener((ReadListener)listener);
+ }
+
+
+ @Override
+ public void clearReadListener() {
+ uartReadListenerList.clear();
+ }
+
+ @Override
+ public void startReadListener() {
+ mStopReadListener = false;
+ }
+
+ @Override
+ public void stopReadListener() {
+ mStopReadListener = true;
+ }
+
+ private void onRead(int size) {
+ if(mStopReadListener) {
+ return;
+ }
+ for(ReadListener listener : uartReadListenerList) {
+ listener.onRead(size);
+ }
+ }
+ //////////////////////////////////////////////////////////
+
+ private void stopRead() {
+ mReadThreadStop = true;
+ }
+
+ private void startRead() {
+ if(mReadThreadStop) {
+ mReadThreadStop = false;
+ new Thread(mLoop).start();
+ }
+ }
+ private Runnable mLoop = new Runnable() {
+
+ @Override
+ @SuppressWarnings("SleepWhileInLoop")
+ public void run() {
+ int len;
+ byte[] rbuf = new byte[READ_BUFFER_SIZE];
+ android.os.Process.setThreadPriority(-20);
+ for(;;) {
+ if(mReadThreadStop) {
+ return;
+ }
+ if(CTRL_socket.isClosed() || DATA_socket.isClosed()) {
+ close();
+ try {
+ Thread.sleep(50);
+ } catch(InterruptedException ex) {
+ }
+ } else {
+ try {
+ // this is the main loop for transferring
+ len = 0;
+
+ while(DATA_IN.available() > 0 && len < READ_BUFFER_SIZE) {
+ DATA_IN.read(rbuf, len, 1);
+ len++;
+ }
+ if(len > 0) {
+ mBuffer.add(rbuf, len);
+ onRead(len);
+ }
+
+ } catch(IOException ex) {
+ close();
+ // TO-DO: Needs to broadcast that it has died
+ try {
+ Thread.sleep(50);
+ } catch(InterruptedException exx) {
+ }
+ return;
+ }
+ }
+ }
+ } // end of run()
+ }; // end of runnable
+
+ @Override
+ public String getPhysicalConnectionName() {
+ return Physicaloid.WIFI_STRING;
+ }
+
+ @Override
+ public int getPhysicalConnectionType() {
+ return Physicaloid.WIFI;
+ }
+
+ @Override
+ public void setDebug(boolean flag) {
+ DEBUG_SHOW = flag;
+ }
+}
diff --git a/PhysicaloidLibrary/src/com/physicaloid/misc/RingBuffer.java b/PhysicaloidLibrary/src/com/physicaloid/misc/RingBuffer.java
index 68b838a..8f31eb3 100644
--- a/PhysicaloidLibrary/src/com/physicaloid/misc/RingBuffer.java
+++ b/PhysicaloidLibrary/src/com/physicaloid/misc/RingBuffer.java
@@ -13,174 +13,272 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.physicaloid.misc;
import android.util.Log;
-
import com.physicaloid.BuildConfig;
-public class RingBuffer{
- private static final String TAG = RingBuffer.class.getSimpleName();
-
- private static final boolean DEBUG_SHOW_ADD = false && BuildConfig.DEBUG;
- private static final boolean DEBUG_SHOW_GET = false && BuildConfig.DEBUG;
-
- private int mRingBufSize;
- private byte[] mRingBuf;
- private int mAddIndex; // top of data index
- private int mGetIndex; // tail of data index
-
- /**
- * Ring buffer
- * @param bufferSize buffer size. It needs enough size e.g.1024
- */
- public RingBuffer(int bufferSize) {
- mRingBufSize = bufferSize+1;
- mRingBuf = new byte[mRingBufSize];
- mAddIndex = 0;
- mGetIndex = 0;
- }
-
- /**
- * Gets ring buffer size
- * @return ring buffer size
- */
- public int getRingBufferSize() {
- return mRingBufSize-1;
- }
-
- /**
- * Gets buffered length
- * @return buffered length
- */
- public int getBufferdLength() {
- if(mAddIndex >= mGetIndex) {
- return mAddIndex - mGetIndex;
- } else {
- return mAddIndex + (mRingBufSize - mGetIndex);
- }
- }
-
- /**
- * Adds byte array to ring buffer
- * @param buf byte array
- * @param length added length
- * @return actually added length
- */
- public synchronized int add(byte[] buf, int length) {
- int addLen = length;
-
- if(mAddIndex > mGetIndex) {
- if((mAddIndex + length) >= mRingBufSize) { // addした結果1周をまたぐ場合
- if((mRingBufSize - mAddIndex) + (mGetIndex - 1) < length ) { // 1周をまたいでなおlength以上になる場合
- addLen = (mRingBufSize - mAddIndex) + (mGetIndex-1); // 追い抜かないサイズに修正
- }
- }
- } else if(mAddIndex < mGetIndex){ // 1周をまたいでいる場合
- if((mGetIndex - 1) - mAddIndex < length) {
- addLen = (mGetIndex - 1) - mAddIndex;
- }
+public class RingBuffer {
+
+ private static final String TAG = RingBuffer.class.getSimpleName();
+ private static final boolean DEBUG_SHOW_ADD = false && BuildConfig.DEBUG;
+ private static final boolean DEBUG_SHOW_GET = false && BuildConfig.DEBUG;
+ private int mRingBufSize;
+ private byte[] mRingBuf;
+ private int mAddIndex; // top of data index
+ private int mGetIndex; // tail of data index
+
+ /**
+ * Ring buffer
+ *
+ * @param bufferSize buffer size. It needs enough size e.g.1024
+ */
+ public RingBuffer(int bufferSize) {
+ mRingBufSize = bufferSize + 1;
+ mRingBuf = new byte[mRingBufSize];
+ mAddIndex = 0;
+ mGetIndex = 0;
}
- if(buf.length < addLen) {
- addLen = buf.length;
+ /**
+ * Gets ring buffer size
+ *
+ * @return ring buffer size
+ */
+ public int getRingBufferSize() {
+ return mRingBufSize - 1;
}
- if((mAddIndex+addLen) >= mRingBufSize) { // storeがバッファ終端をまたぐ場合
- int remain = mAddIndex + addLen - mRingBufSize;
- int copyLen = addLen-remain;
- if(copyLen != 0) {
- System.arraycopy(buf, 0, mRingBuf, mAddIndex, copyLen);
- if(DEBUG_SHOW_ADD){ Log.d(TAG,"add("+length+") : copy buf[0:"+(copyLen-1)+"] to mRingBuf["+mAddIndex+":"+(mAddIndex+copyLen-1)+"]"); }
- }
-
- mAddIndex = 0;
-
- if(remain != 0) {
- System.arraycopy(buf, copyLen, mRingBuf, mAddIndex, remain);
- if(DEBUG_SHOW_ADD){ Log.d(TAG,"add("+length+") : copy buf["+(copyLen)+":"+(addLen-1)+"] to mRingBuf[0:"+(remain-1)+"]"); }
- mAddIndex = remain;
- }
-
- if(DEBUG_SHOW_ADD){ Log.d(TAG,"add("+length+") : addOffset = "+mAddIndex+", getOffset = "+mGetIndex); }
-
- return addLen;
- } else {
- System.arraycopy(buf, 0, mRingBuf, mAddIndex, addLen);
-
- if(DEBUG_SHOW_ADD){ Log.d(TAG,"add("+length+") : copy buf[0:"+(addLen-1)+"] to mRingBuf["+mAddIndex+":"+(mAddIndex+addLen-1)+"]"); }
-
- mAddIndex += addLen;
-
- if(DEBUG_SHOW_ADD){ Log.d(TAG,"add("+length+") : addOffset = "+mAddIndex+", getOffset = "+mGetIndex);}
-
- return addLen;
- }
- }
-
- /**
- * Gets ring buffer to byte array
- * @param buf byte array
- * @param length gotten length
- * @return actually gotten length
- */
- public synchronized int get(byte[] buf, int length) {
- int getLen = length;
- if(mAddIndex == mGetIndex) {
- return 0;
- } else if(mGetIndex < mAddIndex) { // 通常
- if(mAddIndex - mGetIndex < length) { // get要求サイズがバッファされているサイズより大きい場合
- getLen = mAddIndex - mGetIndex; // 今バッファされているサイズを返す
- }
- } else {// インデックスが1周をまたいでいる場合
- if(mAddIndex + (mRingBufSize-mGetIndex) < length) { // get要求サイズがバッファされているサイズより大きい場合
- getLen = mAddIndex + (mRingBufSize - mGetIndex); // 今バッファされているサイズを返す
- }
- }
-
- if(buf.length < getLen) {
- getLen = buf.length;
+ /**
+ * Gets buffered length
+ *
+ * @return buffered length
+ */
+ public int getBufferdLength() {
+ if(mAddIndex >= mGetIndex) {
+ return mAddIndex - mGetIndex;
+ } else {
+ return mAddIndex + (mRingBufSize - mGetIndex);
+ }
}
- if((mGetIndex+getLen) >= mRingBufSize) {
- int remain = mGetIndex + getLen - mRingBufSize;
- int copyLen = getLen - remain;
- if( copyLen != 0) {
- System.arraycopy(mRingBuf, mGetIndex, buf, 0, copyLen);
- if(DEBUG_SHOW_GET){ Log.d(TAG,"get("+length+") : copy mRingBuf["+mGetIndex+":"+(mGetIndex+copyLen-1)+"] to buf[0:"+(copyLen-1)+"]"); }
- }
+ /**
+ * Adds byte array to ring buffer
+ *
+ * @param buf byte array
+ * @param length added length
+ *
+ * @return actually added length
+ */
+ public synchronized int add(byte[] buf, int length) {
+ int addLen = length;
+ if(buf == null) {
+ return 0;
+ }
+ if(mAddIndex > mGetIndex) {
+ if((mAddIndex + length) >= mRingBufSize) { // addした結果1周をまたぐ場合
+ if((mRingBufSize - mAddIndex) + (mGetIndex - 1) < length) { // 1周をまたいでなおlength以上になる場合
+ addLen = (mRingBufSize - mAddIndex) + (mGetIndex - 1); // 追い抜かないサイズに修正
+ }
+ }
+ } else if(mAddIndex < mGetIndex) { // 1周をまたいでいる場合
+ if((mGetIndex - 1) - mAddIndex < length) {
+ addLen = (mGetIndex - 1) - mAddIndex;
+ }
+ }
- mGetIndex = 0;
+ if(buf.length < addLen) {
+ addLen = buf.length;
+ }
- if(remain !=0) {
- System.arraycopy(mRingBuf, mGetIndex, buf, copyLen, remain);
- if(DEBUG_SHOW_GET){ Log.d(TAG,"get("+length+") : copy mRingBuf[0:"+(remain-1)+"] to buf["+copyLen+":"+(remain-1)+"]"); }
- mGetIndex = remain;
- }
+ if((mAddIndex + addLen) >= mRingBufSize) { // storeがバッファ終端をまたぐ場合
+ int remain = mAddIndex + addLen - mRingBufSize;
+ int copyLen = addLen - remain;
+ if(copyLen != 0) {
+ System.arraycopy(buf, 0, mRingBuf, mAddIndex, copyLen);
+ if(DEBUG_SHOW_ADD) {
+ Log.d(TAG, "add(" + length + ") : copy buf[0:" + (copyLen - 1) + "] to mRingBuf[" + mAddIndex + ":" + (mAddIndex + copyLen - 1) + "]");
+ }
+ }
+
+ mAddIndex = 0;
+
+ if(remain != 0) {
+ System.arraycopy(buf, copyLen, mRingBuf, mAddIndex, remain);
+ if(DEBUG_SHOW_ADD) {
+ Log.d(TAG, "add(" + length + ") : copy buf[" + (copyLen) + ":" + (addLen - 1) + "] to mRingBuf[0:" + (remain - 1) + "]");
+ }
+ mAddIndex = remain;
+ }
+
+ if(DEBUG_SHOW_ADD) {
+ Log.d(TAG, "add(" + length + ") : addOffset = " + mAddIndex + ", getOffset = " + mGetIndex);
+ }
+
+ return addLen;
+ } else {
+ System.arraycopy(buf, 0, mRingBuf, mAddIndex, addLen);
+
+ if(DEBUG_SHOW_ADD) {
+ Log.d(TAG, "add(" + length + ") : copy buf[0:" + (addLen - 1) + "] to mRingBuf[" + mAddIndex + ":" + (mAddIndex + addLen - 1) + "]");
+ }
+
+ mAddIndex += addLen;
+
+ if(DEBUG_SHOW_ADD) {
+ Log.d(TAG, "add(" + length + ") : addOffset = " + mAddIndex + ", getOffset = " + mGetIndex);
+ }
+
+ return addLen;
+ }
+ }
+ /**
+ * Adds byte array to ring buffer with starting offset
+ *
+ * @param buf byte array
+ * @param length added length
+ * @param off offset to start from
+ *
+ * @return actually added length
+ */
+ public synchronized int add(byte[] buf, int length, int off) {
+ int addLen = length;
+ if(buf == null) {
+ return 0;
+ }
+ if(mAddIndex > mGetIndex) {
+ if((mAddIndex + length) >= mRingBufSize) { // addした結果1周をまたぐ場合
+ if((mRingBufSize - mAddIndex) + (mGetIndex - 1) < length) { // 1周をまたいでなおlength以上になる場合
+ addLen = (mRingBufSize - mAddIndex) + (mGetIndex - 1); // 追い抜かないサイズに修正
+ }
+ }
+ } else if(mAddIndex < mGetIndex) { // 1周をまたいでいる場合
+ if((mGetIndex - 1) - mAddIndex < length) {
+ addLen = (mGetIndex - 1) - mAddIndex;
+ }
+ }
- if(DEBUG_SHOW_GET){ Log.d(TAG,"get("+length+") : addOffset = "+mAddIndex+", getOffset = "+mGetIndex); }
- return getLen;
- } else {
- System.arraycopy(mRingBuf, mGetIndex, buf, 0, getLen);
+ if(buf.length < addLen) {
+ addLen = buf.length;
+ }
- if(DEBUG_SHOW_GET){ Log.d(TAG,"get("+length+") : copy mRingBuf["+mGetIndex+":"+(mGetIndex+getLen-1)+"] to buf[0:"+(getLen-1)+"]");}
+ if((mAddIndex + addLen) >= mRingBufSize) { // storeがバッファ終端をまたぐ場合
+ int remain = mAddIndex + addLen - mRingBufSize;
+ int copyLen = addLen - remain;
+ if(copyLen != 0) {
+ System.arraycopy(buf, off, mRingBuf, mAddIndex, copyLen);
+ if(DEBUG_SHOW_ADD) {
+ Log.d(TAG, "add(" + length + ") : copy buf[0:" + (copyLen - 1) + "] to mRingBuf[" + mAddIndex + ":" + (mAddIndex + copyLen - 1) + "]");
+ }
+ }
+
+ mAddIndex = 0;
+
+ if(remain != 0) {
+ System.arraycopy(buf, copyLen+off, mRingBuf, mAddIndex, remain);
+ if(DEBUG_SHOW_ADD) {
+ Log.d(TAG, "add(" + length + ") : copy buf[" + (copyLen) + ":" + (addLen - 1) + "] to mRingBuf[0:" + (remain - 1) + "]");
+ }
+ mAddIndex = remain;
+ }
+
+ if(DEBUG_SHOW_ADD) {
+ Log.d(TAG, "add(" + length + ") : addOffset = " + mAddIndex + ", getOffset = " + mGetIndex);
+ }
+
+ return addLen;
+ } else {
+ System.arraycopy(buf, 0, mRingBuf, mAddIndex, addLen);
+
+ if(DEBUG_SHOW_ADD) {
+ Log.d(TAG, "add(" + length + ") : copy buf[0:" + (addLen - 1) + "] to mRingBuf[" + mAddIndex + ":" + (mAddIndex + addLen - 1) + "]");
+ }
+
+ mAddIndex += addLen;
+
+ if(DEBUG_SHOW_ADD) {
+ Log.d(TAG, "add(" + length + ") : addOffset = " + mAddIndex + ", getOffset = " + mGetIndex);
+ }
+
+ return addLen;
+ }
+ }
- mGetIndex += getLen;
+ /**
+ * Gets ring buffer to byte array
+ *
+ * @param buf byte array
+ * @param length gotten length
+ *
+ * @return actually gotten length
+ */
+ public synchronized int get(byte[] buf, int length) {
+ if(buf == null) {
+ return 0;
+ }
+ int getLen = length;
+ if(mAddIndex == mGetIndex) {
+ return 0;
+ } else if(mGetIndex < mAddIndex) { // 通常
+ if(mAddIndex - mGetIndex < length) { // get要求サイズがバッファされているサイズより大きい場合
+ getLen = mAddIndex - mGetIndex; // 今バッファされているサイズを返す
+ }
+ } else {// インデックスが1周をまたいでいる場合
+ if(mAddIndex + (mRingBufSize - mGetIndex) < length) { // get要求サイズがバッファされているサイズより大きい場合
+ getLen = mAddIndex + (mRingBufSize - mGetIndex); // 今バッファされているサイズを返す
+ }
+ }
- if(DEBUG_SHOW_GET){ Log.d(TAG,"get("+length+") : addOffset = "+mAddIndex+", getOffset = "+mGetIndex); }
+ if(buf.length < getLen) {
+ getLen = buf.length;
+ }
- return getLen;
+ if((mGetIndex + getLen) >= mRingBufSize) {
+ int remain = mGetIndex + getLen - mRingBufSize;
+ int copyLen = getLen - remain;
+ if(copyLen != 0) {
+ System.arraycopy(mRingBuf, mGetIndex, buf, 0, copyLen);
+ if(DEBUG_SHOW_GET) {
+ Log.d(TAG, "get(" + length + ") : copy mRingBuf[" + mGetIndex + ":" + (mGetIndex + copyLen - 1) + "] to buf[0:" + (copyLen - 1) + "]");
+ }
+ }
+
+ mGetIndex = 0;
+
+ if(remain != 0) {
+ System.arraycopy(mRingBuf, mGetIndex, buf, copyLen, remain);
+ if(DEBUG_SHOW_GET) {
+ Log.d(TAG, "get(" + length + ") : copy mRingBuf[0:" + (remain - 1) + "] to buf[" + copyLen + ":" + (remain - 1) + "]");
+ }
+ mGetIndex = remain;
+ }
+
+ if(DEBUG_SHOW_GET) {
+ Log.d(TAG, "get(" + length + ") : addOffset = " + mAddIndex + ", getOffset = " + mGetIndex);
+ }
+ return getLen;
+ } else {
+ System.arraycopy(mRingBuf, mGetIndex, buf, 0, getLen);
+
+ if(DEBUG_SHOW_GET) {
+ Log.d(TAG, "get(" + length + ") : copy mRingBuf[" + mGetIndex + ":" + (mGetIndex + getLen - 1) + "] to buf[0:" + (getLen - 1) + "]");
+ }
+
+ mGetIndex += getLen;
+
+ if(DEBUG_SHOW_GET) {
+ Log.d(TAG, "get(" + length + ") : addOffset = " + mAddIndex + ", getOffset = " + mGetIndex);
+ }
+
+ return getLen;
+ }
}
- }
-
-
- /**
- * Clear ring buffer
- */
- public synchronized void clear() {
- mAddIndex = 0;
- mGetIndex = 0;
- }
+ /**
+ * Clear ring buffer
+ */
+ public synchronized void clear() {
+ mAddIndex = 0;
+ mGetIndex = 0;
+ }
}
diff --git a/PhysicaloidLibrary/src/cz/jaybee/intelhex/IntelHexParser.java b/PhysicaloidLibrary/src/cz/jaybee/intelhex/IntelHexParser.java
index 6341bbb..2523b8c 100644
--- a/PhysicaloidLibrary/src/cz/jaybee/intelhex/IntelHexParser.java
+++ b/PhysicaloidLibrary/src/cz/jaybee/intelhex/IntelHexParser.java
@@ -1,175 +1,177 @@
/**
- * @license
- * Copyright (c) 2012, Jan Breuer
- * All rights reserved.
- *
+ * @license Copyright (c) 2012, Jan Breuer All rights reserved.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
* * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
+ * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER 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
+ * 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 THE COPYRIGHT HOLDER 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.
*/
package cz.jaybee.intelhex;
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
/**
*
- * @author Jan Breuer
- * @license BSD 2-Clause
+ * @author Jan Breuer @license BSD 2-Clause
*/
public class IntelHexParser {
- private BufferedReader reader = null;
- private IntelHexDataListener dataListener = null;
- private static final int HEX = 16;
- private boolean eof = false;
- private int recordIdx = 0;
- private long upperAddress = 0;
-
- private class Record {
-
- int length;
- int address;
- IntelHexRecordType type;
- byte[] data;
- }
-
- public IntelHexParser(Reader reader) {
- if (reader instanceof BufferedReader) {
- this.reader = (BufferedReader) reader;
- } else {
- this.reader = new BufferedReader(reader);
- }
- }
-
- public IntelHexParser(InputStream stream) {
- this.reader = new BufferedReader(new InputStreamReader(stream));
- }
-
- public void setDataListener(IntelHexDataListener listener) {
- this.dataListener = listener;
- }
-
- private Record parseRecord(String record) throws Exception {
- Record result = new Record();
- // check, if there wasn an accidential EOF record
- if (eof) {
- throw new Exception("Data after eof (" + recordIdx + ")");
- }
-
- // every IntelHEX record must start with ":"
- if (!record.startsWith(":")) {
- throw new Exception("Invalid Intel HEX record (" + recordIdx + ")");
- }
+ private BufferedReader reader = null;
+ private IntelHexDataListener dataListener = null;
+ private static final int HEX = 16;
+ private boolean eof = false;
+ private int recordIdx = 0;
+ private long upperAddress = 0;
- int lineLength = record.length();
- byte[] hexRecord = new byte[lineLength / 2];
+ private class Record {
- // sum of all bytes modulo 256 (including checksum) shuld be 0
- int sum = 0;
- for (int i = 0; i < hexRecord.length; i++) {
- String num = record.substring(2 * i + 1, 2 * i + 3);
- hexRecord[i] = (byte) Integer.parseInt(num, HEX);
- sum += hexRecord[i] & 0xff;
+ int length;
+ int address;
+ IntelHexRecordType type;
+ byte[] data;
}
- sum &= 0xff;
- if (sum != 0) {
- throw new Exception("Invalid checksum (" + recordIdx + ")");
+ public IntelHexParser(Reader reader) {
+ if(reader instanceof BufferedReader) {
+ this.reader = (BufferedReader) reader;
+ } else {
+ this.reader = new BufferedReader(reader);
+ }
}
- // if the length field does not correspond with line length
- result.length = hexRecord[0];
- if ((result.length + 5) != hexRecord.length) {
- throw new Exception("Invalid record length (" + recordIdx + ")");
+ public IntelHexParser(InputStream stream) {
+ this.reader = new BufferedReader(new InputStreamReader(stream));
}
- // length is OK, copy data
- result.data = new byte[result.length];
- System.arraycopy(hexRecord, 4, result.data, 0, result.length);
-
- // build lower part of data address
- result.address = ((hexRecord[1] & 0xFF) << 8) + (hexRecord[2] & 0xFF);
- // determine record type
- result.type = IntelHexRecordType.fromInt(hexRecord[3] & 0xFF);
- if (result.type == IntelHexRecordType.UNKNOWN) {
- throw new Exception("Unsupported record type " + (hexRecord[3] & 0xFF) + " (" + recordIdx + ")");
+ public void setDataListener(IntelHexDataListener listener) {
+ this.dataListener = listener;
}
- return result;
- }
+ private Record parseRecord(String record) throws Exception {
+ Record result = new Record();
+ // Check if there was an EOF record. If so, ignore the remainder of the file as per spec.
+ if(eof) {
+ // throw new Exception("Data after eof (" + recordIdx + ")");
+ result.type = IntelHexRecordType.EOF;
- private void processRecord(Record record) throws Exception {
- // build full address
- long addr = record.address | upperAddress;
- switch (record.type) {
- case DATA:
- if (dataListener != null) {
- dataListener.data(addr, record.data);
- }
- break;
- case EOF:
- if (dataListener != null) {
- dataListener.eof();
- }
- eof = true;
- break;
- case EXT_LIN:
- if (record.length == 2) {
- upperAddress = ((record.data[0] & 0xFF) << 8) + (record.data[1] & 0xFF);
- upperAddress <<= 16; // ELA is bits 16-31 of the segment base address (SBA), so shift left 16 bits
} else {
- throw new Exception("Invalid EXT_LIN record (" + recordIdx + ")");
+ // every IntelHEX record must start with ":"
+ if(!record.startsWith(":")) {
+ throw new Exception("Invalid Intel HEX record (" + recordIdx + ")");
+ }
+
+ int lineLength = record.length();
+ byte[] hexRecord = new byte[lineLength / 2];
+
+ // sum of all bytes modulo 256 (including checksum) should be 0
+ int sum = 0;
+ for(int i = 0; i < hexRecord.length; i++) {
+ String num = record.substring(2 * i + 1, 2 * i + 3);
+ hexRecord[i] = (byte) Integer.parseInt(num, HEX);
+ sum += hexRecord[i] & 0xff;
+ }
+ sum &= 0xff;
+
+ if(sum != 0) {
+ throw new Exception("Invalid checksum (" + recordIdx + ")");
+ }
+
+ // if the length field does not correspond with line length
+ result.length = hexRecord[0];
+ if((result.length + 5) != hexRecord.length) {
+ throw new Exception("Invalid record length (" + recordIdx + ")");
+ }
+ // length is OK, copy data
+ result.data = new byte[result.length];
+ System.arraycopy(hexRecord, 4, result.data, 0, result.length);
+
+ // build lower part of data address
+ result.address = ((hexRecord[1] & 0xFF) << 8) + (hexRecord[2] & 0xFF);
+
+ // determine record type
+ result.type = IntelHexRecordType.fromInt(hexRecord[3] & 0xFF);
+ if(result.type == IntelHexRecordType.UNKNOWN) {
+ throw new Exception("Unsupported record type " + (hexRecord[3] & 0xFF) + " (" + recordIdx + ")");
+ }
}
+ return result;
+ }
- break;
- case EXT_SEG:
- if (record.length == 2) {
- upperAddress = ((record.data[0] & 0xFF) << 8) + (record.data[1] & 0xFF);
- upperAddress <<= 4; // ESA is bits 4-19 of the segment base address (SBA), so shift left 4 bits
- } else {
- throw new Exception("Invalid EXT_SEG record (" + recordIdx + ")");
+ private void processRecord(Record record) throws Exception {
+ // build full address
+ long addr = record.address | upperAddress;
+ switch(record.type) {
+ case DATA:
+ if(dataListener != null) {
+ dataListener.data(addr, record.data);
+ }
+ break;
+ case EOF:
+ if(dataListener != null) {
+ dataListener.eof();
+ }
+ eof = true;
+ break;
+ case EXT_LIN:
+ if(record.length == 2) {
+ upperAddress = ((record.data[0] & 0xFF) << 8) + (record.data[1] & 0xFF);
+ upperAddress <<= 16; // ELA is bits 16-31 of the segment base address (SBA), so shift left 16 bits
+ } else {
+ throw new Exception("Invalid EXT_LIN record (" + recordIdx + ")");
+ }
+
+ break;
+ case EXT_SEG:
+ if(record.length == 2) {
+ upperAddress = ((record.data[0] & 0xFF) << 8) + (record.data[1] & 0xFF);
+ upperAddress <<= 4; // ESA is bits 4-19 of the segment base address (SBA), so shift left 4 bits
+ } else {
+ throw new Exception("Invalid EXT_SEG record (" + recordIdx + ")");
+ }
+ break;
+ case START_SEG:
+ throw new Exception(record.type + " record not implemented (" + recordIdx + ")");
+ case START_LIN:
+ case UNKNOWN:
+ break;
}
- break;
- case START_SEG:
- case START_LIN:
- throw new Exception(record.type + " record not implemented (" + recordIdx + ")");
- case UNKNOWN:
- break;
+
}
- }
+ public void parse() throws IOException, Exception {
+ recordIdx = 1;
+ upperAddress = 0;
+ String recordStr;
- public void parse() throws IOException, Exception {
- recordIdx = 1;
- upperAddress = 0;
- String recordStr;
+ while((recordStr = reader.readLine()) != null) {
+ Record record = parseRecord(recordStr);
+ processRecord(record);
+ recordIdx++;
+ }
- while ((recordStr = reader.readLine()) != null) {
- Record record = parseRecord(recordStr);
- processRecord(record);
- recordIdx++;
- }
-
- if (!eof) {
- throw new Exception("No eof at the end of file");
+ if(!eof) {
+ throw new Exception("No eof at the end of file");
+ }
}
- }
}
diff --git a/PhysicaloidLibrary/src/cz/jaybee/intelhex/IntelHexParserRun.java b/PhysicaloidLibrary/src/cz/jaybee/intelhex/IntelHexParserRun.java
index 9ecb074..d793451 100644
--- a/PhysicaloidLibrary/src/cz/jaybee/intelhex/IntelHexParserRun.java
+++ b/PhysicaloidLibrary/src/cz/jaybee/intelhex/IntelHexParserRun.java
@@ -2,27 +2,27 @@
* @license
* Copyright (c) 2012, Jan Breuer
* All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice, this
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
- *
+ *
* * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
+ * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER 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
+ * 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 THE COPYRIGHT HOLDER 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.
*/
package cz.jaybee.intelhex;
@@ -32,7 +32,7 @@
/**
*
* @author Jan Breuer
- * @license BSD 2-Clause
+ * @license BSD 2-Clause
*/
public class IntelHexParserRun implements IntelHexDataListener {
@@ -72,12 +72,12 @@ public boolean isEOF() {
@Override
public void data(long address, byte[] data) {
if ((address >= addressStart) && (address <= addressStop)) {
- int length = data.length;
- if ((address + length) > addressStop) {
- length = (int) (addressStop - address + 1);
+ int dlength = data.length;
+ if ((address + dlength) > addressStop) {
+ dlength = (int) (addressStop - address + 1);
}
- System.arraycopy(data, 0, buffer, (int) (address - addressStart), length);
- totalLength += length;
+ System.arraycopy(data, 0, buffer, (int) (address - addressStart), dlength);
+ totalLength += dlength;
}
}
diff --git a/README.md b/README.md
index 2975df8..054df08 100644
--- a/README.md
+++ b/README.md
@@ -3,29 +3,31 @@ Physicaloid Library
Android Library for communicating with physical-computing boards (e.g.Arduino, mbed)
-![Android x Arduino](https://lh5.googleusercontent.com/-weC-lA-1rdw/UeaCzIrWR3I/AAAAAAAACno/u-ZapAmzkz8/s640/android_arduino.jpg)
-
-
-Users does not need to download an Arduino sketch from a web site.
-![Download sketch](https://lh3.googleusercontent.com/-Hh-vISkTL6w/UeaC5moml2I/AAAAAAAACn8/g7Dozio1QrE/s640/physicaloid_download.png)
-
-
-You (developer) can include Arduino firmwares in your Android app and upload to Google Play.
-![Upload to Google Play](https://lh6.googleusercontent.com/-lzDrLOSohUY/UeaC5p7Z0uI/AAAAAAAACoA/hcqRjLUe6JQ/s640/physicaloid_upload.png)
-
-
Features
-----------------
+- **NEW! No closed source slow and buggy D2XX drivers are required.**
- Android Java library project
- USB-Serial communication
+- WiFi-Serial communication to ESP8266
- upload a firmware to an Arduino
- support on Android 3.1 or higher (need USB Host API feature)
- **does not require ROOT**
-- support USB-Serial protocols : CDC-ACM, FTDI, Silicon Labs CP210x
-- support uploading firmware protocols : STK500, STK500V2
+- supports USB-Serial protocols : CDC-ACM, FTDI, Silicon Labs CP210x and WinChipHead CH34X
+- supports uploading firmware protocols : STK500, STK500V2, Binary blob ESP8266 OTA
- open-source(Apache License 2.0)
+![Android x Arduino](https://lh5.googleusercontent.com/-weC-lA-1rdw/UeaCzIrWR3I/AAAAAAAACno/u-ZapAmzkz8/s640/android_arduino.jpg)
+
+
+Users do not need to download an Arduino sketch from a web site.
+![Download sketch](https://lh3.googleusercontent.com/-Hh-vISkTL6w/UeaC5moml2I/AAAAAAAACn8/g7Dozio1QrE/s640/physicaloid_download.png)
+
+
+You (developer) can include Arduino firmwares in your Android app and upload to Google Play.
+![Upload to Google Play](https://lh6.googleusercontent.com/-lzDrLOSohUY/UeaC5p7Z0uI/AAAAAAAACoA/hcqRjLUe6JQ/s640/physicaloid_upload.png)
+
+
Code example
-----------------
@@ -40,9 +42,9 @@ mPhysicaloid.upload(Boards.ARDUINO_UNO, "/sdcard/arduino/Blink.hex");
```java
Physicaloid mPhysicaloid = new Physicaloid(this);
if(mPhysicaloid.open()) {
- byte[] buf = "moemoe".getBytes();
- mPhysicaloid.write(buf, buf.length);
- mPhysicaloid.close()
+ byte[] buf = "moemoe".getBytes();
+ mPhysicaloid.write(buf, buf.length);
+ mPhysicaloid.close()
}
```
@@ -53,13 +55,13 @@ Physicaloid mPhysicaloid = new Physicaloid(this);
TextView TextView1 = (TextView) findViewById(R.id.TextView1);// Android TextView
if(mPhysicaloid.open()) {
- byte[] buf = new byte[256];
+ byte[] buf = new byte[256];
- mPhysicaloid.read(buf, buf.length);
- String str = new String(buf);
- TextView1.append(str);
+ mPhysicaloid.read(buf, buf.length);
+ String str = new String(buf);
+ TextView1.append(str);
- mPhysicaloid.close();
+ mPhysicaloid.close();
}
```
diff --git a/SampleProjects/PhysicaloidTest/build.properties b/SampleProjects/PhysicaloidTest/build.properties
new file mode 100644
index 0000000..e69de29
diff --git a/SampleProjects/PhysicaloidTest/build.xml b/SampleProjects/PhysicaloidTest/build.xml
new file mode 100644
index 0000000..9b7a1f0
--- /dev/null
+++ b/SampleProjects/PhysicaloidTest/build.xml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SampleProjects/PhysicaloidTest/default.properties b/SampleProjects/PhysicaloidTest/default.properties
new file mode 100644
index 0000000..e69de29
diff --git a/SampleProjects/PhysicaloidTest/nbandroid/private.properties b/SampleProjects/PhysicaloidTest/nbandroid/private.properties
new file mode 100644
index 0000000..9d0798f
--- /dev/null
+++ b/SampleProjects/PhysicaloidTest/nbandroid/private.properties
@@ -0,0 +1,5 @@
+auxiliary.config.active=
+auxiliary.config.names=
+auxiliary.emulator.options.=
+auxiliary.launch.action.=main
+auxiliary.launch.target.=AUTO
diff --git a/SampleProjects/PhysicaloidTest/project.properties b/SampleProjects/PhysicaloidTest/project.properties
index 01e5cf6..a29a07f 100644
--- a/SampleProjects/PhysicaloidTest/project.properties
+++ b/SampleProjects/PhysicaloidTest/project.properties
@@ -11,5 +11,5 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
-target=android-12
+target=android-18
android.library.reference.1=../../PhysicaloidLibrary
diff --git a/SampleProjects/PhysicaloidTest/src/com/example/physicaloidtest/PhysicaloidTestActivity.java b/SampleProjects/PhysicaloidTest/src/com/example/physicaloidtest/PhysicaloidTestActivity.java
index 2d18429..fc99a70 100644
--- a/SampleProjects/PhysicaloidTest/src/com/example/physicaloidtest/PhysicaloidTestActivity.java
+++ b/SampleProjects/PhysicaloidTest/src/com/example/physicaloidtest/PhysicaloidTestActivity.java
@@ -1,9 +1,5 @@
package com.example.physicaloidtest;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
@@ -21,341 +17,342 @@
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
-
import com.physicaloid.lib.Boards;
import com.physicaloid.lib.Physicaloid;
import com.physicaloid.lib.Physicaloid.UploadCallBack;
import com.physicaloid.lib.fpga.PhysicaloidFpga;
import com.physicaloid.lib.programmer.avr.UploadErrors;
-import com.physicaloid.lib.usb.driver.uart.ReadLisener;
+import com.physicaloid.lib.usb.driver.uart.ReadListener;
+import com.physicaloid.lib.usb.driver.uart.UartConfig;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
public class PhysicaloidTestActivity extends Activity {
- private static final String TAG = PhysicaloidTestActivity.class.getSimpleName();
-
- // The serialtest.*.hex is an echo-back program.
- // http://www.physicaloid.com/hexfiles/serialtest.ino
- // You can download those hex files from
- // http://www.physicaloid.com/hexfiles/serialtest.uno.hex
- // http://www.physicaloid.com/hexfiles/serialtest.mega.hex
- @SuppressLint("SdCardPath")
- private static final String UPLOAD_FILE_UNO = "/sdcard/arduino/serialtest.uno.hex";
- @SuppressLint("SdCardPath")
- private static final String UPLOAD_FILE_MEGA = "/sdcard/arduino/serialtest.mega.hex";
- @SuppressLint("SdCardPath")
- private static final String UPLOAD_FILE_BALANDUINO = "/sdcard/arduino/serialtest.balanduino.hex";
- @SuppressLint("SdCardPath")
- private static final String UPLOAD_FILE_FPGA = "/sdcard/fpga/testtop.rbf";
-
- private static final String ASSET_FILE_NAME_UNO = "Blink.uno.hex";
- private static final String ASSET_FILE_NAME_MEGA = "Blink.mega.hex";
- private static final String ASSET_FILE_NAME_BALANDUINO = "Blink.balanduino.hex";
- private static final String ASSET_FILE_NAME_FPGA = "testtop.rbf";
-
- Physicaloid mPhysicaloid;
- PhysicaloidFpga mPhysicaloidFpga;
- Boards mSelectedBoard;
-
- Button btOpen;
- Button btClose;
- Button btWrite;
- Button btRead;
- Button btReadCallback;
- Button btUpload;
- EditText etWrite;
- TextView tvRead;
- TextView tvSelectedBoard;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_physicaloid_test);
-
- btOpen = (Button) findViewById(R.id.btOpen);
- btClose = (Button) findViewById(R.id.btClose);
- btWrite = (Button) findViewById(R.id.btWrite);
- btRead = (Button) findViewById(R.id.btRead);
- btReadCallback = (Button) findViewById(R.id.btReadCallback);
- btUpload = (Button) findViewById(R.id.btUpload);
- etWrite = (EditText) findViewById(R.id.etWrite);
- tvRead = (TextView) findViewById(R.id.tvRead);
- tvSelectedBoard = (TextView) findViewById(R.id.tvSelectedBoard);
-
- updateViews(false);
-
- mPhysicaloid = new Physicaloid(this);
-
- // Shows last selected board
- mBoardList = new ArrayList();
- for(Boards board : Boards.values()) {
- if(board.support>0) {
- mBoardList.add(board);
- }
+
+ private static final String TAG = PhysicaloidTestActivity.class.getSimpleName();
+ // The serialtest.*.hex is an echo-back program.
+ // http://www.physicaloid.com/hexfiles/serialtest.ino
+ // You can download those hex files from
+ // http://www.physicaloid.com/hexfiles/serialtest.uno.hex
+ // http://www.physicaloid.com/hexfiles/serialtest.mega.hex
+ @SuppressLint("SdCardPath")
+ private static final String UPLOAD_FILE_UNO = "/sdcard/arduino/serialtest.uno.hex";
+ @SuppressLint("SdCardPath")
+ private static final String UPLOAD_FILE_MEGA = "/sdcard/arduino/serialtest.mega.hex";
+ @SuppressLint("SdCardPath")
+ private static final String UPLOAD_FILE_BALANDUINO = "/sdcard/arduino/serialtest.balanduino.hex";
+ @SuppressLint("SdCardPath")
+ private static final String UPLOAD_FILE_FPGA = "/sdcard/fpga/testtop.rbf";
+ private static final String ASSET_FILE_NAME_UNO = "Blink.uno.hex";
+ private static final String ASSET_FILE_NAME_MEGA = "Blink.mega.hex";
+ private static final String ASSET_FILE_NAME_BALANDUINO = "Blink.balanduino.hex";
+ private static final String ASSET_FILE_NAME_FPGA = "testtop.rbf";
+ Physicaloid mPhysicaloid;
+ PhysicaloidFpga mPhysicaloidFpga;
+ Boards mSelectedBoard;
+ Button btOpen;
+ Button btClose;
+ Button btWrite;
+ Button btRead;
+ Button btReadCallback;
+ Button btUpload;
+ EditText etWrite;
+ TextView tvRead;
+ TextView tvSelectedBoard;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_physicaloid_test);
+
+ btOpen = (Button) findViewById(R.id.btOpen);
+ btClose = (Button) findViewById(R.id.btClose);
+ btWrite = (Button) findViewById(R.id.btWrite);
+ btRead = (Button) findViewById(R.id.btRead);
+ btReadCallback = (Button) findViewById(R.id.btReadCallback);
+ btUpload = (Button) findViewById(R.id.btUpload);
+ etWrite = (EditText) findViewById(R.id.etWrite);
+ tvRead = (TextView) findViewById(R.id.tvRead);
+ tvSelectedBoard = (TextView) findViewById(R.id.tvSelectedBoard);
+
+ updateViews(false);
+
+ mPhysicaloid = new Physicaloid(this);
+
+ // Shows last selected board
+ mBoardList = new ArrayList();
+ for(Boards board : Boards.values()) {
+ if(board.support > 0) {
+ mBoardList.add(board);
+ }
+ }
+ int lastBoard = getSelectedBoard();
+ tvSelectedBoard.setText(mBoardList.get(lastBoard).text);
+ mSelectedBoard = mBoardList.get(lastBoard);
}
- int lastBoard = getSelectedBoard();
- tvSelectedBoard.setText(mBoardList.get(lastBoard).text);
- mSelectedBoard = mBoardList.get(lastBoard);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- close();
- }
-
- public void onClickOpen(View v) {
- if(mPhysicaloid.open()) {
- updateViews(true);
- } else {
- Toast.makeText(this, "Cannot open", Toast.LENGTH_LONG).show();
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ close();
}
- }
- public void onClickClose(View v) {
- close();
- }
+ public void onClickOpen(View v) {
+ UartConfig uartConfig = new UartConfig(115200, UartConfig.DATA_BITS8, UartConfig.STOP_BITS1, UartConfig.PARITY_NONE, true, false);
+ if(mPhysicaloid.open()) {
+ mPhysicaloid.setConfig(uartConfig);
+ updateViews(true);
+ } else {
+ Toast.makeText(this, "Cannot open", Toast.LENGTH_LONG).show();
+ }
+ }
- private void close() {
- if(mPhysicaloid.close()) {
- updateViews(false);
+ public void onClickClose(View v) {
+ close();
}
- }
-
- public void onClickWrite(View v) {
- String str = etWrite.getText().toString();
- byte[] buf = str.getBytes();
- mPhysicaloid.write(buf, buf.length);
- }
-
- public void onClickRead(View v) {
- byte[] buf = new byte[256];
- mPhysicaloid.read(buf, buf.length);
- String str = new String(buf);
- tvRead.append(Html.fromHtml(""+str+""));
- }
-
- private boolean readCallbackOn = false;
- public void onClickReadCallback(View v) {
- if(readCallbackOn) {
- mPhysicaloid.clearReadListener();
- btReadCallback.setText("ReadCallbackOff");
- btRead.setEnabled(true);
- readCallbackOn = false;
- } else {
- mPhysicaloid.addReadListener(new ReadLisener() {
- @Override
- public void onRead(int size) {
- byte[] buf = new byte[size];
- mPhysicaloid.read(buf, size);
- tvAppend(tvRead, Html.fromHtml(""+new String(buf)+""));
+
+ private void close() {
+ if(mPhysicaloid.close()) {
+ updateViews(false);
}
- });
- btReadCallback.setText("ReadCallbackOn");
- btRead.setEnabled(false);
- readCallbackOn = true;
}
- }
-
- public void onClickUpload(View v) {
- String fileName;
- if(mSelectedBoard == Boards.ARDUINO_MEGA_2560_ADK) {
- fileName = UPLOAD_FILE_MEGA;
- } else if(mSelectedBoard == Boards.BALANDUINO) {
- fileName = UPLOAD_FILE_BALANDUINO;
- } else {
- fileName = UPLOAD_FILE_UNO;
+
+ public void onClickWrite(View v) {
+ String str = etWrite.getText().toString();
+ byte[] buf = str.getBytes();
+ mPhysicaloid.write(buf, buf.length);
}
- mPhysicaloid.upload(mSelectedBoard, fileName,
- mUploadCallback);
- }
-
- public void onClickUploadAsset(View v) {
- String assetFileName;
- if(mSelectedBoard == Boards.ARDUINO_MEGA_2560_ADK) {
- assetFileName = ASSET_FILE_NAME_MEGA;
- } else if(mSelectedBoard == Boards.BALANDUINO) {
- assetFileName = ASSET_FILE_NAME_BALANDUINO;
- } else if(mSelectedBoard == Boards.PERIDOT) {
- assetFileName = ASSET_FILE_NAME_FPGA;
- PhysicaloidFpga physicaloidFpga = new PhysicaloidFpga(this);
- try {
- physicaloidFpga.upload(mSelectedBoard, getResources().getAssets().open(assetFileName), mUploadCallback);
- } catch (RuntimeException e) {
- Log.e(TAG, e.toString());
- } catch (IOException e) {
- Log.e(TAG, e.toString());
- }
- return;
- } else {
- assetFileName = ASSET_FILE_NAME_UNO;
+
+ public void onClickRead(View v) {
+ byte[] buf = new byte[256];
+ mPhysicaloid.read(buf, buf.length);
+ String str = new String(buf);
+ tvRead.append(Html.fromHtml("" + str + ""));
}
- try {
- mPhysicaloid.upload(mSelectedBoard, getResources().getAssets().open(assetFileName), mUploadCallback);
- } catch (RuntimeException e) {
- Log.e(TAG, e.toString());
- } catch (IOException e) {
- Log.e(TAG, e.toString());
+ private boolean readCallbackOn = false;
+
+ public void onClickReadCallback(View v) {
+ if(readCallbackOn) {
+ mPhysicaloid.clearReadListener();
+ btReadCallback.setText("ReadCallbackOff");
+ btRead.setEnabled(true);
+ readCallbackOn = false;
+ } else {
+ mPhysicaloid.addReadListener(new ReadListener() {
+
+ @Override
+ public void onRead(int size) {
+ byte[] buf = new byte[size];
+ mPhysicaloid.read(buf, size);
+ tvAppend(tvRead, Html.fromHtml("" + new String(buf) + ""));
+ //Log.d(TAG, "*********** " +new String(buf));
+ }
+ });
+ btReadCallback.setText("ReadCallbackOn");
+ btRead.setEnabled(false);
+ readCallbackOn = true;
+ }
}
- }
-
- public void onClickCancelUpload(View v) {
- mPhysicaloid.cancelUpload();
- }
- UploadCallBack mUploadCallback = new UploadCallBack() {
-
- @Override
- public void onUploading(int value) {
- tvAppend(tvRead, "Upload : "+value+" %\n");
- }
-
- @Override
- public void onPreUpload() {
- tvAppend(tvRead, "Upload : Start\n");
+ public void onClickUpload(View v) {
+ String fileName;
+ if(mSelectedBoard == Boards.ARDUINO_MEGA_2560_ADK) {
+ fileName = UPLOAD_FILE_MEGA;
+ } else if(mSelectedBoard == Boards.BALANDUINO) {
+ fileName = UPLOAD_FILE_BALANDUINO;
+ } else {
+ fileName = UPLOAD_FILE_UNO;
+ }
+ mPhysicaloid.upload(mSelectedBoard, fileName,
+ mUploadCallback);
}
-
- @Override
- public void onPostUpload(boolean success) {
- if(success) {
- tvAppend(tvRead, "Upload : Successful\n");
- } else {
- tvAppend(tvRead, "Upload fail\n");
- }
+
+ public void onClickUploadAsset(View v) {
+ String assetFileName;
+ if(mSelectedBoard == Boards.ARDUINO_MEGA_2560_ADK) {
+ assetFileName = ASSET_FILE_NAME_MEGA;
+ } else if(mSelectedBoard == Boards.BALANDUINO) {
+ assetFileName = ASSET_FILE_NAME_BALANDUINO;
+ } else if(mSelectedBoard == Boards.PERIDOT) {
+ assetFileName = ASSET_FILE_NAME_FPGA;
+ PhysicaloidFpga physicaloidFpga = new PhysicaloidFpga(this);
+ try {
+ physicaloidFpga.upload(mSelectedBoard, getResources().getAssets().open(assetFileName), mUploadCallback);
+ } catch(RuntimeException e) {
+ Log.e(TAG, e.toString());
+ } catch(IOException e) {
+ Log.e(TAG, e.toString());
+ }
+ return;
+ } else {
+ assetFileName = ASSET_FILE_NAME_UNO;
+ }
+ try {
+ mPhysicaloid.upload(mSelectedBoard, getResources().getAssets().open(assetFileName), mUploadCallback);
+ } catch(RuntimeException e) {
+ Log.e(TAG, e.toString());
+ } catch(IOException e) {
+ Log.e(TAG, e.toString());
+ }
}
- @Override
- public void onCancel() {
- tvAppend(tvRead, "Cancel uploading\n");
+ public void onClickCancelUpload(View v) {
+ mPhysicaloid.cancelUpload();
}
+ UploadCallBack mUploadCallback = new UploadCallBack() {
- @Override
- public void onError(UploadErrors err) {
- tvAppend(tvRead, "Error : "+err.toString()+"\n");
+ @Override
+ public void onUploading(int value) {
+ tvAppend(tvRead, "Upload : " + value + " %\n");
+ }
+
+ @Override
+ public void onPreUpload() {
+ tvAppend(tvRead, "Upload : Start\n");
+ }
+
+ @Override
+ public void onPostUpload(boolean success) {
+ if(success) {
+ tvAppend(tvRead, "Upload : Successful\n");
+ } else {
+ tvAppend(tvRead, "Upload fail\n");
+ }
+ }
+
+ @Override
+ public void onCancel() {
+ tvAppend(tvRead, "Cancel uploading\n");
+ }
+
+ @Override
+ public void onError(UploadErrors err) {
+ tvAppend(tvRead, "Error : " + err.toString() + "\n");
+ }
+ };
+
+ private void updateViews(boolean on) {
+ if(on) {
+ btOpen.setEnabled(false);
+ btClose.setEnabled(true);
+ btWrite.setEnabled(true);
+ btRead.setEnabled(true);
+ btReadCallback.setEnabled(true);
+ etWrite.setEnabled(true);
+ } else {
+ btOpen.setEnabled(true);
+ btClose.setEnabled(false);
+ btWrite.setEnabled(false);
+ btRead.setEnabled(false);
+ btReadCallback.setEnabled(false);
+ etWrite.setEnabled(false);
+ }
}
- };
-
- private void updateViews(boolean on) {
- if(on) {
- btOpen.setEnabled(false);
- btClose.setEnabled(true);
- btWrite.setEnabled(true);
- btRead.setEnabled(true);
- btReadCallback.setEnabled(true);
- etWrite.setEnabled(true);
- } else {
- btOpen.setEnabled(true);
- btClose.setEnabled(false);
- btWrite.setEnabled(false);
- btRead.setEnabled(false);
- btReadCallback.setEnabled(false);
- etWrite.setEnabled(false);
+ Handler mHandler = new Handler();
+
+ private void tvAppend(TextView tv, CharSequence text) {
+ final TextView ftv = tv;
+ final CharSequence ftext = text;
+ mHandler.post(new Runnable() {
+
+ @Override
+ public void run() {
+ ftv.append(ftext);
+ }
+ });
}
- }
-
- Handler mHandler = new Handler();
- private void tvAppend(TextView tv, CharSequence text) {
- final TextView ftv = tv;
- final CharSequence ftext = text;
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- ftv.append(ftext);
- }
- });
- }
-
-
- @SuppressWarnings("unused")
- private String toHexStr(byte[] b, int length) {
- String str="";
- for(int i=0; i mBoardList;
- private int mItemPos = 0;
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId()) {
+ case MENU_ID_BOARD:
+ showSelectBoardDialog();
+ return true;
+ default:
+ return false;
+ }
+ }
+ private ArrayList mBoardList;
+ private int mItemPos = 0;
- private void showSelectBoardDialog() {
+ private void showSelectBoardDialog() {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle("Select a board");
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle("Select a board");
- // get from Boards list
- List items = new ArrayList();
- for(Boards board : Boards.values()) {
- if(board.support>0) {
- items.add(board.text);
- }
- }
- String[] itemStr = (String[])items.toArray(new String[0]);
- builder.setSingleChoiceItems(itemStr, getSelectedBoard(), mItemListener);
-
- builder.setPositiveButton("OK", mButtonListener );
- builder.setNeutralButton ("Cancel", mButtonListener );
+ // get from Boards list
+ List items = new ArrayList();
+ for(Boards board : Boards.values()) {
+ if(board.support > 0) {
+ items.add(board.text);
+ }
+ }
+ String[] itemStr = (String[]) items.toArray(new String[0]);
+ builder.setSingleChoiceItems(itemStr, getSelectedBoard(), mItemListener);
- AlertDialog dialog = builder.create();
- dialog.show();
- }
+ builder.setPositiveButton("OK", mButtonListener);
+ builder.setNeutralButton("Cancel", mButtonListener);
- DialogInterface.OnClickListener mItemListener = new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- mItemPos = which;
+ AlertDialog dialog = builder.create();
+ dialog.show();
}
- };
-
- DialogInterface.OnClickListener mButtonListener = new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- switch( which ){
- case AlertDialog.BUTTON_POSITIVE: // OK pressed
- saveSelectedBoard(mItemPos);
- mSelectedBoard = mBoardList.get(mItemPos);
- tvSelectedBoard.setText(mBoardList.get(mItemPos).text);
- break;
- case AlertDialog.BUTTON_NEUTRAL: // Cancel pressed
- break;
- }
+ DialogInterface.OnClickListener mItemListener = new DialogInterface.OnClickListener() {
+
+ public void onClick(DialogInterface dialog, int which) {
+ mItemPos = which;
+ }
+ };
+ DialogInterface.OnClickListener mButtonListener = new DialogInterface.OnClickListener() {
+
+ public void onClick(DialogInterface dialog, int which) {
+ switch(which) {
+ case AlertDialog.BUTTON_POSITIVE: // OK pressed
+ saveSelectedBoard(mItemPos);
+ mSelectedBoard = mBoardList.get(mItemPos);
+ tvSelectedBoard.setText(mBoardList.get(mItemPos).text);
+ break;
+ case AlertDialog.BUTTON_NEUTRAL: // Cancel pressed
+ break;
+ }
+ }
+ };
+
+ // Saves selected board position
+ private void saveSelectedBoard(int pos) {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
+ sp.edit().putInt("SelectedBoardPosition", pos).commit();
}
- };
-
- // Saves selected board position
- private void saveSelectedBoard(int pos) {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
- sp.edit().putInt("SelectedBoardPosition", pos).commit();
- }
-
- // Gets selected board position
- private int getSelectedBoard() {
- int pos;
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
- pos = sp.getInt("SelectedBoardPosition", 0);
- return pos;
- }
- /////////////////////////////////////////////////////////////////
- // End of board select menu
- /////////////////////////////////////////////////////////////////
+ // Gets selected board position
+ private int getSelectedBoard() {
+ int pos;
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
+ pos = sp.getInt("SelectedBoardPosition", 0);
+ return pos;
+ }
+ /////////////////////////////////////////////////////////////////
+ // End of board select menu
+ /////////////////////////////////////////////////////////////////
}