├── examplesync
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ ├── values
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── layout
│ │ │ └── activity_main.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── com
│ │ └── felhr
│ │ └── serialportexamplesync
│ │ └── MainActivity.java
├── proguard-rules.pro
└── build.gradle
├── usbserial
├── .gitignore
├── src
│ ├── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── felhr
│ │ │ ├── usbserial
│ │ │ ├── SerialPortCallback.java
│ │ │ ├── AbstractWorkerThread.java
│ │ │ ├── UsbSpiInterface.java
│ │ │ ├── SerialOutputStream.java
│ │ │ ├── UsbSerialDebugger.java
│ │ │ ├── SerialInputStream.java
│ │ │ ├── UsbSerialInterface.java
│ │ │ ├── SerialBuffer.java
│ │ │ └── UsbSpiDevice.java
│ │ │ ├── deviceids
│ │ │ ├── CP2130Ids.java
│ │ │ ├── CH34xIds.java
│ │ │ ├── XdcVcpIds.java
│ │ │ ├── Helpers.java
│ │ │ ├── PL2303Ids.java
│ │ │ └── CP210xIds.java
│ │ │ └── utils
│ │ │ ├── Utils.java
│ │ │ ├── SafeUsbRequest.java
│ │ │ ├── HexData.java
│ │ │ └── ProtocolBuffer.java
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── felhr
│ │ │ ├── deviceids
│ │ │ └── DeviceIdTest.java
│ │ │ └── usbserial
│ │ │ └── FTDISerialDeviceTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── felhr
│ │ └── tests
│ │ ├── usbserial
│ │ └── SerialBufferTest.java
│ │ └── utils
│ │ └── ProtocolBufferTest.java
├── eclipse_lib
│ └── usbserial.jar
├── proguard-rules.pro
└── build.gradle
├── examplestreams
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── values
│ │ │ │ ├── colors.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ │ ├── layout
│ │ │ │ └── activity_main.xml
│ │ │ └── drawable
│ │ │ │ └── ic_launcher_background.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── felhr
│ │ │ └── examplestreams
│ │ │ └── MainActivity.java
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── felhr
│ │ │ └── examplestreams
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── felhr
│ │ └── examplestreams
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── integrationapp
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ │ ├── layout
│ │ │ │ └── activity_main.xml
│ │ │ └── drawable
│ │ │ │ └── ic_launcher_background.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── felhr
│ │ │ └── integrationapp
│ │ │ └── MainActivity.java
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── felhr
│ │ │ └── integrationapp
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── felhr
│ │ └── integrationapp
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── examplemultipleports
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ │ ├── layout
│ │ │ │ └── activity_main.xml
│ │ │ └── drawable
│ │ │ │ └── ic_launcher_background.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── felhr
│ │ │ └── examplemultipleports
│ │ │ └── MainActivity.java
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── felhr
│ │ │ └── examplemultipleports
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── felhr
│ │ └── examplemultipleports
│ │ └── ExampleInstrumentedTest.java
├── proguard-rules.pro
└── build.gradle
├── example
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ ├── values
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-w820dp
│ │ │ └── dimens.xml
│ │ └── layout
│ │ │ └── activity_main.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── com
│ │ └── felhr
│ │ └── serialportexample
│ │ └── MainActivity.java
├── proguard-rules.pro
└── build.gradle
├── settings.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── integration
├── send_packet.py
├── validate_serial_tx.py
├── send_packet.sh
├── integration_sync.py
├── integration.py
└── README.md
├── .gitignore
├── RELEASING.md
├── .travis.yml
├── LICENSE
├── release.sh
├── CHANGELOG.md
├── gradlew.bat
├── gradlew
└── README.md
/examplesync/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/usbserial/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/examplestreams/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/integrationapp/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/examplemultipleports/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | *.jks
3 | signing.properties
--------------------------------------------------------------------------------
/usbserial/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':usbserial', ':example', ':examplesync', ':examplestreams', ':examplemultipleports', ':integrationapp'
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/usbserial/eclipse_lib/usbserial.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/usbserial/eclipse_lib/usbserial.jar
--------------------------------------------------------------------------------
/integrationapp/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | IntegrationApp
3 |
4 |
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Example multiple ports
3 |
4 |
--------------------------------------------------------------------------------
/example/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/example/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examplesync/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplesync/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examplesync/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplesync/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examplestreams/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplestreams/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examplestreams/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplestreams/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examplesync/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplesync/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examplesync/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplesync/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examplesync/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplesync/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | VERSION_NAME=6.1.0
2 | VERSION_CODE=1
3 | ANDROID_BUILD_MIN_SDK_VERSION=12
4 | ANDROID_BUILD_TARGET_SDK_VERSION=27
5 | ANDROID_BUILD_SDK_VERSION=27
6 |
--------------------------------------------------------------------------------
/integrationapp/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/integrationapp/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/integrationapp/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/integrationapp/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examplestreams/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplestreams/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examplestreams/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplestreams/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/integrationapp/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/integrationapp/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/integrationapp/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/integrationapp/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examplestreams/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplestreams/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/integrationapp/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/integrationapp/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplemultipleports/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplemultipleports/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplemultipleports/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examplestreams/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplestreams/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examplestreams/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplestreams/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examplestreams/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplestreams/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/integrationapp/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/integrationapp/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/integrationapp/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/integrationapp/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/integrationapp/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/integrationapp/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplemultipleports/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplemultipleports/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examplestreams/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplestreams/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examplestreams/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplestreams/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/integrationapp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/integrationapp/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/integrationapp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/integrationapp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplemultipleports/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplemultipleports/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplemultipleports/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplemultipleports/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/green-green-avk/UsbSerial/master/examplemultipleports/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/usbserial/SerialPortCallback.java:
--------------------------------------------------------------------------------
1 | package com.felhr.usbserial;
2 |
3 | import java.util.List;
4 |
5 |
6 | public interface SerialPortCallback {
7 | void onSerialPortsDetected(List serialPorts);
8 | }
9 |
--------------------------------------------------------------------------------
/examplestreams/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/examplesync/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/integrationapp/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/example/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 14 15:18:57 PST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
7 |
--------------------------------------------------------------------------------
/examplesync/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ExampleSync
3 | Hello world!
4 | Settings
5 | Synchronous Serial Port
6 |
7 |
--------------------------------------------------------------------------------
/examplestreams/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/examplestreams/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ExampleInputOutputStream
3 | Hello world!
4 | Settings
5 | InputStream and OutputStream Serial Port
6 |
7 |
--------------------------------------------------------------------------------
/integrationapp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/examplestreams/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/integrationapp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/example/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SerialPortExample
5 | Hello world!
6 | Settings
7 | Serial Port
8 |
9 |
10 |
--------------------------------------------------------------------------------
/example/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 | 64dp
9 |
10 |
11 |
--------------------------------------------------------------------------------
/examplesync/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examplestreams/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/integration/send_packet.py:
--------------------------------------------------------------------------------
1 | # UsbSerial test: Sending single packet
2 | # args:
3 | # port (eg /dev/ttyUSB0)
4 | # size in bytes (eg 1024)
5 | # speed in bauds (eg 115200)
6 |
7 | import serial
8 | import sys
9 | import os
10 |
11 | port = sys.argv[1]
12 | size = sys.argv[2]
13 | speed = sys.argv[3]
14 |
15 | comm = serial.Serial(port, int(speed))
16 |
17 | data_tx = os.urandom(int(size))
18 |
19 | bytes_sent = comm.write(data_tx)
20 |
21 | print(str(bytes_sent))
--------------------------------------------------------------------------------
/integrationapp/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/integrationapp/src/test/java/com/felhr/integrationapp/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.felhr.integrationapp;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # built application files
2 | *.apk
3 | *.ap_
4 |
5 | # files for the dex VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # generated files
12 | bin/
13 | gen/
14 |
15 | # Key
16 | *.jks
17 |
18 | # Local configuration file (sdk path, etc)
19 | local.properties
20 |
21 | # Intellij project files
22 | *.iml
23 | *.ipr
24 | *.iws
25 | .idea/
26 | *.prefs
27 |
28 | # Gradle
29 | build/
30 | .gradle
31 |
32 | # Byte-compiled / optimized / DLL files
33 | __pycache__/
34 | *.pyc
35 | *.py[cod]
36 | *$py.class
37 |
--------------------------------------------------------------------------------
/examplemultipleports/src/test/java/com/felhr/examplemultipleports/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.felhr.examplemultipleports;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/examplestreams/src/test/java/com/felhr/examplestreams/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.felhr.examplestreams;
2 |
3 | import org.junit.Test;
4 |
5 | import static junit.framework.Assert.assertEquals;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/deviceids/CP2130Ids.java:
--------------------------------------------------------------------------------
1 | package com.felhr.deviceids;
2 |
3 | import static com.felhr.deviceids.Helpers.createTable;
4 | import static com.felhr.deviceids.Helpers.createDevice;
5 |
6 | public class CP2130Ids
7 | {
8 | private static final long[] cp2130Devices = createTable(
9 | createDevice(0x10C4, 0x87a0)
10 | );
11 |
12 | public static boolean isDeviceSupported(int vendorId, int productId)
13 | {
14 | return Helpers.exists(cp2130Devices, vendorId, productId);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/utils/Utils.java:
--------------------------------------------------------------------------------
1 | package com.felhr.utils;
2 |
3 | import com.annimon.stream.Collectors;
4 | import com.annimon.stream.Stream;
5 | import com.annimon.stream.function.Predicate;
6 |
7 | import java.util.Collection;
8 | import java.util.List;
9 |
10 |
11 | public class Utils {
12 | public static List removeIf(Collection c, Predicate super T> predicate) {
13 | return Stream.of(c.iterator())
14 | .filterNot(predicate)
15 | .collect(Collectors.toList());
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/integration/validate_serial_tx.py:
--------------------------------------------------------------------------------
1 | # UsbSerial test: Validate single packet
2 | # args:
3 | # port (eg /dev/ttyUSB0)
4 | # size in bytes (eg 1024)
5 | # speed in bauds (eg 115200)
6 |
7 | import serial
8 | import sys
9 | import os
10 |
11 | port = sys.argv[1]
12 | size = sys.argv[2]
13 | speed = sys.argv[3]
14 |
15 | comm = serial.Serial(port, int(speed))
16 |
17 | data_tx = os.urandom(int(size))
18 |
19 | comm.write(data_tx)
20 |
21 | data_rx = comm.read(int(size))
22 |
23 | if data_tx == data_rx:
24 | print("Success: Data was transmitted correctly")
25 | else:
26 | print("Error: Data was not transmitted")
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/deviceids/CH34xIds.java:
--------------------------------------------------------------------------------
1 | package com.felhr.deviceids;
2 |
3 | import static com.felhr.deviceids.Helpers.createTable;
4 | import static com.felhr.deviceids.Helpers.createDevice;
5 |
6 | public class CH34xIds
7 | {
8 | private CH34xIds()
9 | {
10 |
11 | }
12 |
13 | private static final long[] ch34xDevices = createTable(
14 | createDevice(0x4348, 0x5523),
15 | createDevice(0x1a86, 0x7523),
16 | createDevice(0x1a86, 0x5523),
17 | createDevice(0x1a86, 0x0445)
18 | );
19 |
20 | public static boolean isDeviceSupported(int vendorId, int productId)
21 | {
22 | return Helpers.exists(ch34xDevices, vendorId, productId);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/example/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\Program Files (x86)\Android\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/examplesync/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Applications/AndroidSDK/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/example/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/usbserial/AbstractWorkerThread.java:
--------------------------------------------------------------------------------
1 | package com.felhr.usbserial;
2 |
3 | abstract class AbstractWorkerThread extends Thread {
4 | boolean firstTime = true;
5 | private volatile boolean keep = true;
6 | private volatile Thread workingThread;
7 |
8 | void stopThread() {
9 | keep = false;
10 | if (this.workingThread != null) {
11 | this.workingThread.interrupt();
12 | }
13 | }
14 |
15 | public final void run() {
16 | if (!this.keep) {
17 | return;
18 | }
19 | this.workingThread = Thread.currentThread();
20 | while (this.keep && (!this.workingThread.isInterrupted())) {
21 | doRun();
22 | }
23 | }
24 |
25 | abstract void doRun();
26 | }
27 |
--------------------------------------------------------------------------------
/RELEASING.md:
--------------------------------------------------------------------------------
1 | Releasing
2 | ========
3 |
4 | 1. Change the `VERSION_NAME` value in `gradle.properties` to the version number to be released.
5 | 2. Update the `README.md` with the new version and update `CHANGELOG.md`
6 | 3. `./gradlew clean build`
7 | 4. `git commit -am "Prepare for release X.Y.Z."` (where X.Y.Z is the new version)
8 | 5. `git tag -a X.Y.Z -m "Version X.Y.Z"` `-m "Changelog message 1"` `-m "Changelog message 2"` `-m "Changelog message 3"`
9 | 6. `git push && git push --tags`
10 |
11 | *Note:* To get the changelog messages from the commit history, issue
12 |
13 | ```shell
14 | git log "$(git tag | tail -n2 | head -n1)..$(git tag | tail -n1)" --oneline --invert-grep --grep="Merge pull request" --grep="Prepare for release" | cut -d' ' -f2- | sed -E -e 's/^/-m "/' | sed -E -e 's/$/"/'
15 | ```
16 |
17 |
--------------------------------------------------------------------------------
/examplestreams/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/integrationapp/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/examplemultipleports/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/deviceids/XdcVcpIds.java:
--------------------------------------------------------------------------------
1 | package com.felhr.deviceids;
2 |
3 | import static com.felhr.deviceids.Helpers.createTable;
4 | import static com.felhr.deviceids.Helpers.createDevice;
5 |
6 | public class XdcVcpIds
7 | {
8 | /*
9 | * Werner Wolfrum (w.wolfrum@wolfrum-elektronik.de)
10 | */
11 |
12 | /* Different products and vendors of XdcVcp family
13 | */
14 | private static final long[] xdcvcpDevices = createTable(
15 | createDevice(0x264D, 0x0232), // VCP (Virtual Com Port)
16 | createDevice(0x264D, 0x0120), // USI (Universal Sensor Interface)
17 | createDevice(0x0483, 0x5740) //CC3D (STM)
18 | );
19 |
20 | public static boolean isDeviceSupported(int vendorId, int productId)
21 | {
22 | return Helpers.exists(xdcvcpDevices, vendorId, productId);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/deviceids/Helpers.java:
--------------------------------------------------------------------------------
1 | package com.felhr.deviceids;
2 |
3 | import java.util.Arrays;
4 |
5 | class Helpers {
6 |
7 | /**
8 | * Create a device id, since they are 4 bytes each, we can pack the pair in an long.
9 | */
10 | static long createDevice(int vendorId, int productId) {
11 | return ((long) vendorId) << 32 | (productId & 0xFFFF_FFFFL);
12 | }
13 |
14 | /**
15 | * Creates a sorted table.
16 | * This way, we can use binarySearch to find whether the entry exists.
17 | */
18 | static long[] createTable(long ... entries) {
19 | Arrays.sort(entries);
20 | return entries;
21 | }
22 |
23 | static boolean exists(long[] devices, int vendorId, int productId) {
24 | return Arrays.binarySearch(devices, createDevice(vendorId, productId)) >= 0;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/integration/send_packet.sh:
--------------------------------------------------------------------------------
1 | #!bin/bash
2 |
3 | # UsbSerial
4 | #
5 | # This test generates a number of files specified by the user and send them through the serial port.
6 | #
7 | # args:
8 | # -p: serial port (ttyUSB0, ttyUSB1..)
9 | # -b: baud rate
10 | # -t: number of times this test will be repeated
11 | # -s: size of the random files generated for testing purposes
12 |
13 | while getopts p:t:s:b: OPTION;
14 | do
15 | case $OPTION
16 | in
17 | p) PORT=$OPTARG;;
18 | t) TIMES=$OPTARG;;
19 | s) SIZE=$OPTARG;;
20 | b) BAUD=$OPTARG;;
21 | esac
22 | done
23 |
24 | stty -F $PORT $BAUD
25 |
26 | for i in $(seq 1 $TIMES);
27 | do
28 | dd if=/dev/urandom of=$i bs=$SIZE count=1 status=none
29 | echo "Packet $i of $SIZE was created"
30 | cat $i > $PORT
31 | echo "Packet $i of $SIZE was sent"
32 |
33 | done
34 |
35 | rm [0-9]*
36 |
--------------------------------------------------------------------------------
/usbserial/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\Program Files (x86)\Android\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
20 | -dontwarn org.codehaus.mojo.animal_sniffer.*
--------------------------------------------------------------------------------
/integrationapp/src/androidTest/java/com/felhr/integrationapp/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.felhr.integrationapp;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.felhr.integrationapp", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/examplemultipleports/src/androidTest/java/com/felhr/examplemultipleports/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.felhr.examplemultipleports;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.felhr.examplemultipleports", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/usbserial/UsbSpiInterface.java:
--------------------------------------------------------------------------------
1 | package com.felhr.usbserial;
2 |
3 |
4 | public interface UsbSpiInterface
5 | {
6 | // Clock dividers;
7 | int DIVIDER_2 = 2;
8 | int DIVIDER_4 = 4;
9 | int DIVIDER_8 = 8;
10 | int DIVIDER_16 = 16;
11 | int DIVIDER_32 = 32;
12 | int DIVIDER_64 = 64;
13 | int DIVIDER_128 = 128;
14 |
15 | // Common SPI operations
16 | boolean connectSPI();
17 | void writeMOSI(byte[] buffer);
18 | void readMISO(int lengthBuffer);
19 | void writeRead(byte[] buffer, int lenghtRead);
20 | void setClock(int clockDivider);
21 | void selectSlave(int nSlave);
22 | void setMISOCallback(UsbMISOCallback misoCallback);
23 | void closeSPI();
24 |
25 | // Status information
26 | int getClockDivider();
27 | int getSelectedSlave();
28 |
29 | interface UsbMISOCallback
30 | {
31 | int onReceivedData(byte[] data);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/examplestreams/src/androidTest/java/com/felhr/examplestreams/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.felhr.examplestreams;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static junit.framework.Assert.assertEquals;
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getTargetContext();
24 |
25 | assertEquals("com.felhr.examplestreams", appContext.getPackageName());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: android
2 | android:
3 | components:
4 | - tools
5 | - platform-tools
6 | # Note that the tools section appears twice on purpose as it’s required to get the newest Android SDK tools.
7 | # See: https://docs.travis-ci.com/user/languages/android/#Overview
8 | - tools
9 | - build-tools-27.0.3
10 | - build-tools-27.0.2
11 | - build-tools-26.0.2
12 | - android-27
13 | - android-26
14 | before_cache:
15 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
16 | before_install:
17 | - yes | sdkmanager "platforms;android-27"
18 | cache:
19 | directories:
20 | - $HOME/.gradle/caches/
21 | - $HOME/.gradle/wrapper/
22 | before_script:
23 | - export VERSION_TO_BUILD="$TRAVIS_TAG"
24 | script: ./gradlew clean build
25 | deploy:
26 | provider: releases
27 | api_key: $GITHUB_OAUTH_TOKEN
28 | file: usbserial/build/outputs/aar/usbserial-${VERSION_TO_BUILD}-release.aar
29 | skip_cleanup: true
30 | on:
31 | tags: true
--------------------------------------------------------------------------------
/example/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
7 |
8 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/examplesync/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
6 |
7 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/examplestreams/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
7 |
8 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/examplemultipleports/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
7 |
8 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Felipe Herranz
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/utils/SafeUsbRequest.java:
--------------------------------------------------------------------------------
1 | package com.felhr.utils;
2 |
3 | import android.hardware.usb.UsbRequest;
4 |
5 | import java.lang.reflect.Field;
6 | import java.nio.ByteBuffer;
7 |
8 |
9 | public class SafeUsbRequest extends UsbRequest
10 | {
11 | static final String usbRqBufferField = "mBuffer";
12 | static final String usbRqLengthField = "mLength";
13 |
14 | @Override
15 | public boolean queue(ByteBuffer buffer, int length)
16 | {
17 | Field usbRequestBuffer;
18 | Field usbRequestLength;
19 | try
20 | {
21 | usbRequestBuffer = UsbRequest.class.getDeclaredField(usbRqBufferField);
22 | usbRequestLength = UsbRequest.class.getDeclaredField(usbRqLengthField);
23 | usbRequestBuffer.setAccessible(true);
24 | usbRequestLength.setAccessible(true);
25 | usbRequestBuffer.set(this, buffer);
26 | usbRequestLength.set(this, length);
27 | } catch (Exception e)
28 | {
29 | throw new RuntimeException(e);
30 | }
31 |
32 | return super.queue(buffer, length);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/integration/integration_sync.py:
--------------------------------------------------------------------------------
1 | # UsbSerial test: Integration test
2 | # args:
3 | # port (eg /dev/ttyUSB0)
4 | # speed in bauds (eg 115200)
5 |
6 | import serial
7 | import sys
8 | import os
9 |
10 | class style():
11 | RED = lambda x: '\033[31m' + str(x)
12 | GREEN = lambda x: '\033[32m' + str(x)
13 | BLUE = lambda x: '\033[34m' + str(x)
14 | RESET = lambda x: '\033[0m' + str(x)
15 |
16 | port = sys.argv[1]
17 | speed = sys.argv[2]
18 |
19 | test_sizes = [1024, 2048, 16384]
20 |
21 | for i in range(0,3):
22 | comm = serial.Serial(port, int(speed))
23 | print("Creating " + str(test_sizes[i]) + " bytes buffer")
24 | data_tx = os.urandom(test_sizes[i])
25 | print("Sending buffer of " + str(test_sizes[i]) + " bytes")
26 | comm.write(data_tx)
27 | print("Receiving " + str(test_sizes[i]) + " bytes buffer")
28 | data_rx = comm.read(test_sizes[i])
29 |
30 | if data_tx == data_rx:
31 | print(style.GREEN("Success: " + str(test_sizes[i]) + " bytes buffer was transmitted correctly"))
32 | else:
33 | print(style.RED("Error: " + str(test_sizes[i]) + " bytes buffer was not transmitted correctly"))
34 | print(style.RESET(""))
35 |
--------------------------------------------------------------------------------
/integration/integration.py:
--------------------------------------------------------------------------------
1 | # UsbSerial test: Integration test
2 | # args:
3 | # port (eg /dev/ttyUSB0)
4 | # speed in bauds (eg 115200)
5 |
6 | import serial
7 | import sys
8 | import os
9 |
10 | class style():
11 | RED = lambda x: '\033[31m' + str(x)
12 | GREEN = lambda x: '\033[32m' + str(x)
13 | BLUE = lambda x: '\033[34m' + str(x)
14 | RESET = lambda x: '\033[0m' + str(x)
15 |
16 | port = sys.argv[1]
17 | speed = sys.argv[2]
18 |
19 | test_sizes = [1024, 2048, 16384, 65535, 131072]
20 |
21 | for i in range(0,5):
22 | comm = serial.Serial(port, int(speed))
23 | print("Creating " + str(test_sizes[i]) + " bytes buffer")
24 | data_tx = os.urandom(test_sizes[i])
25 | print("Sending buffer of " + str(test_sizes[i]) + " bytes")
26 | comm.write(data_tx)
27 | print("Receiving " + str(test_sizes[i]) + " bytes buffer")
28 | data_rx = comm.read(test_sizes[i])
29 |
30 | if data_tx == data_rx:
31 | print(style.GREEN("Success: " + str(test_sizes[i]) + " bytes buffer was transmitted correctly"))
32 | else:
33 | print(style.RED("Error: " + str(test_sizes[i]) + " bytes buffer was not transmitted correctly"))
34 | print(style.RESET(""))
35 |
--------------------------------------------------------------------------------
/integrationapp/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
7 |
8 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/examplestreams/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 |
5 | compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
6 |
7 | defaultConfig {
8 | applicationId "com.felhr.examplestreams"
9 | minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION)
10 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
11 | versionName project.VERSION_NAME
12 | versionCode Integer.parseInt(project.VERSION_CODE)
13 | }
14 |
15 | compileOptions {
16 | encoding "UTF-8"
17 | sourceCompatibility JavaVersion.VERSION_1_8
18 | targetCompatibility JavaVersion.VERSION_1_8
19 | }
20 | }
21 |
22 | dependencies {
23 | implementation 'com.android.support:support-v4:23.1.1'
24 | implementation 'com.android.support:appcompat-v7:23.1.1'
25 | implementation 'com.android.support:design:23.1.1'
26 |
27 | implementation 'com.android.support:support-annotations:28.0.0'
28 |
29 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
30 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
31 | androidTestImplementation 'junit:junit:4.12'
32 |
33 | testImplementation 'junit:junit:4.12'
34 |
35 | implementation project(':usbserial')
36 | }
37 |
--------------------------------------------------------------------------------
/examplesync/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 |
5 | compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
6 |
7 | defaultConfig {
8 | applicationId "com.felhr.serialportexamplesync"
9 | minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION)
10 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
11 | versionName project.VERSION_NAME
12 | versionCode Integer.parseInt(project.VERSION_CODE)
13 | }
14 |
15 | compileOptions {
16 | encoding "UTF-8"
17 | sourceCompatibility JavaVersion.VERSION_1_8
18 | targetCompatibility JavaVersion.VERSION_1_8
19 | }
20 | }
21 |
22 | dependencies {
23 | implementation 'com.android.support:support-v4:23.1.1'
24 | implementation 'com.android.support:appcompat-v7:23.1.1'
25 | implementation 'com.android.support:design:23.1.1'
26 |
27 | implementation 'com.android.support:support-annotations:28.0.0'
28 |
29 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
30 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
31 | androidTestImplementation 'junit:junit:4.12'
32 |
33 | testImplementation 'junit:junit:4.12'
34 |
35 | implementation project(':usbserial')
36 | }
37 |
--------------------------------------------------------------------------------
/example/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 |
5 | compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
6 |
7 | defaultConfig {
8 | applicationId "com.felhr.serialportexample"
9 | minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION)
10 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
11 | versionName project.VERSION_NAME
12 | versionCode Integer.parseInt(project.VERSION_CODE)
13 | }
14 |
15 | compileOptions {
16 | encoding "UTF-8"
17 | sourceCompatibility JavaVersion.VERSION_1_8
18 | targetCompatibility JavaVersion.VERSION_1_8
19 | }
20 | }
21 |
22 | dependencies {
23 | implementation 'com.android.support:support-v4:23.1.1'
24 | implementation 'com.android.support:appcompat-v7:23.1.1'
25 | implementation 'com.android.support:design:23.1.1'
26 |
27 | implementation 'com.android.support:support-annotations:28.0.0'
28 |
29 | implementation 'com.android.support:support-annotations:28.0.0'
30 |
31 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
32 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
33 | androidTestImplementation 'junit:junit:4.12'
34 |
35 | testImplementation 'junit:junit:4.12'
36 |
37 | implementation project(':usbserial')
38 | }
39 |
--------------------------------------------------------------------------------
/release.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #Arguments:
3 | # -v version eg 6.0.3
4 | # -m 6.0.3
5 | set -e
6 |
7 | while getopts v:m: OPTION;
8 | do
9 | case $OPTION
10 | in
11 | v) VERSION=$OPTARG;;
12 | m) MESSAGE=$OPTARG;;
13 | esac
14 | done
15 |
16 | # Show error message if no version was provided
17 | if [[ -z ${VERSION} ]];
18 | then
19 | echo "UsbSerial: Error!! No version was provided"
20 | exit 0
21 | fi
22 |
23 | # Show error message if no message was provided
24 | if [[ -z ${MESSAGE} ]];
25 | then
26 | echo "UsbSerial: Error!! No message was provided"
27 | exit 0
28 | fi
29 |
30 | echo "UsbSerial: Starting Release $VERSION with commit message $MESSAGE"
31 |
32 | VERSION_NAME="VERSION_NAME=$VERSION"
33 |
34 | # Updating gradle.properties with version
35 | ex -sc '1d|x' gradle.properties
36 | ex -sc "1i|$VERSION_NAME" -cx gradle.properties
37 |
38 | # Updating README file
39 | GRADLE_LINE="implementation 'com.github.felHR85:UsbSerial:${VERSION}'"
40 | LINE=$(cat README.md | grep -nr implementation\ \'com.github.felHR85:UsbSerial: | awk -F ":" '{print $2}')
41 | ex -sc "${LINE}d|x" README.md
42 | ex -sc "${LINE}i|$GRADLE_LINE" -cx README.md
43 |
44 | # Gradle clean and build
45 | ./gradlew clean build
46 |
47 | # Git stuff
48 | git add .
49 | git commit -m "${MESSAGE}"
50 | git tag ${VERSION}
51 | git push origin master
52 | git push --tags
53 |
54 | echo "UsbSerial: Release Finished!!!"
55 |
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/usbserial/SerialOutputStream.java:
--------------------------------------------------------------------------------
1 | package com.felhr.usbserial;
2 |
3 | import java.io.OutputStream;
4 |
5 | public class SerialOutputStream extends OutputStream
6 | {
7 | private int timeout = 0;
8 |
9 | protected final UsbSerialInterface device;
10 |
11 | public SerialOutputStream(UsbSerialInterface device)
12 | {
13 | this.device = device;
14 | }
15 |
16 | @Override
17 | public void write(int b)
18 | {
19 | device.syncWrite(new byte[] { (byte)b }, timeout);
20 | }
21 |
22 | @Override
23 | public void write(byte[] b)
24 | {
25 | device.syncWrite(b, timeout);
26 | }
27 |
28 | @Override
29 | public void write(byte b[], int off, int len)
30 | {
31 | if(off < 0 ){
32 | throw new IndexOutOfBoundsException("Offset must be >= 0");
33 | }
34 |
35 | if(len < 0){
36 | throw new IndexOutOfBoundsException("Length must positive");
37 | }
38 |
39 | if(off + len > b.length) {
40 | throw new IndexOutOfBoundsException("off + length greater than buffer length");
41 | }
42 |
43 | if (off == 0 && len == b.length) {
44 | write(b);
45 | return;
46 | }
47 |
48 | device.syncWrite(b, off, len, timeout);
49 | }
50 |
51 | public void setTimeout(int timeout) {
52 | this.timeout = timeout;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/integrationapp/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
5 |
6 | defaultConfig {
7 | applicationId "com.felhr.integrationapp"
8 | minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION)
9 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
10 | versionName project.VERSION_NAME
11 | versionCode Integer.parseInt(project.VERSION_CODE)
12 | }
13 |
14 | compileOptions {
15 | encoding "UTF-8"
16 | sourceCompatibility JavaVersion.VERSION_1_8
17 | targetCompatibility JavaVersion.VERSION_1_8
18 | }
19 | }
20 |
21 | dependencies {
22 | implementation 'com.android.support:support-v4:23.1.1'
23 | implementation 'com.android.support:appcompat-v7:23.1.1'
24 | implementation 'com.android.support:design:23.1.1'
25 |
26 | implementation 'com.android.support:support-annotations:28.0.0'
27 |
28 | implementation 'com.android.support:support-annotations:28.0.0'
29 |
30 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
31 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
32 | androidTestImplementation 'junit:junit:4.12'
33 |
34 | testImplementation 'junit:junit:4.12'
35 |
36 | implementation 'com.squareup.okio:okio:2.1.0'
37 |
38 | implementation project(':usbserial')
39 | }
40 |
--------------------------------------------------------------------------------
/integration/README.md:
--------------------------------------------------------------------------------
1 | UsbSerial Integration Tests
2 | ===========================
3 | For the purpose of helping people contributing to UsbSerial a little set of integration tests have been added. It consists in two parts.
4 | - Python script integration.py that sends a series packets (1kb, 2kb, 8kb, 64kb and 128kb) and validates that those packets are received back correctly.
5 | - Integration Android app that implements UsbSerial and just receives and sends back the packets sent by the python script.
6 |
7 | Requirements
8 | --------------------------------------
9 | - Windows/OSX/Linux with Python 3 installed
10 | - [PySerial](https://pypi.org/project/pyserial/)
11 | - Android phone with Android 3.1 and with USB OTG capabilities
12 |
13 | Steps
14 | --------------------------------------
15 | Let's say we want to test UsbSerial transmitting at 115200 bauds and our PC port is /dev/ttyUSB0
16 | - [Modify UsbService in Integration app to 115200 bauds](https://github.com/felHR85/UsbSerial/blob/integration_tests/integrationapp/src/main/java/com/felhr/integrationapp/UsbService.java#L61).
17 | - Compile and install Integration app on your device.
18 | - Connect your phone to a serial device at one end and your PC at the other end.
19 | - Run python integration.py /dev/ttyUSB0 115200
20 |
21 | Other Scripts
22 | --------------------------------------
23 | - send_packet.py (python send_packet.py /dev/ttyUSB0 1024 115200)
24 | - validate_serial_tx.py (python validate_serial_tx.py /dev/ttyUSB0 1024 115200)
--------------------------------------------------------------------------------
/examplemultipleports/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 |
5 | compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
6 |
7 | defaultConfig {
8 | applicationId "com.felhr.examplemultipleports"
9 | minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION)
10 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
11 | versionName project.VERSION_NAME
12 | versionCode Integer.parseInt(project.VERSION_CODE)
13 | }
14 |
15 | compileOptions {
16 | encoding "UTF-8"
17 | sourceCompatibility JavaVersion.VERSION_1_8
18 | targetCompatibility JavaVersion.VERSION_1_8
19 | }
20 |
21 | buildTypes {
22 | release {
23 | minifyEnabled false
24 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
25 | }
26 | }
27 |
28 | }
29 |
30 | dependencies {
31 | implementation 'com.android.support:support-v4:23.1.1'
32 | implementation 'com.android.support:appcompat-v7:23.1.1'
33 | implementation 'com.android.support:design:23.1.1'
34 |
35 | implementation 'com.android.support:support-annotations:28.0.0'
36 |
37 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
38 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
39 | androidTestImplementation 'junit:junit:4.12'
40 |
41 | testImplementation 'junit:junit:4.12'
42 |
43 | implementation project(':usbserial')
44 | implementation 'com.annimon:stream:1.2.1'
45 | }
46 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | CHANGELOG
2 | =========
3 |
4 | Release 6.1.0
5 | --------------------------------------
6 | - Added 1228800 and 2000000 baud rates to CH34xx driver.
7 | - Microchip pid/vid correclty determined.
8 | - FTDI sync method back to previous implementation.
9 | - setBreak method implemented in CP210x devices.
10 | - Added chunked stream methods.
11 |
12 | Release 6.0.6
13 | --------------------------------------
14 | - Added custom baud rates in FTDI devices.
15 | - Added setBreak method. Currently only working in FTDI devices.
16 |
17 | Release 6.0.5
18 | --------------------------------------
19 | - Solved issue with CDC.
20 | - Added new pair of VID/PID pairs for CP2102.
21 | - Threads closing in a safer way.
22 |
23 | Release 6.0.4
24 | --------------------------------------
25 | - Proguard rules.
26 | - FTDI driver improved again.
27 |
28 | Release 6.0.3
29 | --------------------------------------
30 | - VID/PID pairs are sorted and searched in a faster way.
31 | - FTDI driver improved.
32 |
33 | Release 6.0.2
34 | --------------------------------------
35 | - Solved issue when disconnecting multiple serial ports.
36 |
37 | Release 6.0.1
38 | --------------------------------------
39 | - Internal serial buffer now uses [Okio](https://github.com/square/okio). This erases the 16kb write
40 | limitation from previous versions and reduces memory footprint.
41 | - Improved CP2102 driver and added more VID/PID pairs.
42 | - Added a [utility class for handling the common problem of split received information in some chipsets](https://github.com/felHR85/UsbSerial/blob/master/usbserial/src/main/java/com/felhr/utils/ProtocolBuffer.java).
43 |
44 |
--------------------------------------------------------------------------------
/usbserial/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | def artifact = "usbserial.jar"
4 |
5 | android {
6 |
7 | group = 'com.felhr.usbserial'
8 | version = project.VERSION_NAME
9 |
10 | compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
11 |
12 | compileOptions {
13 | encoding "UTF-8"
14 | sourceCompatibility JavaVersion.VERSION_1_8
15 | targetCompatibility JavaVersion.VERSION_1_8
16 | }
17 |
18 | defaultConfig {
19 | minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION)
20 | targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
21 | archivesBaseName = "${project.name}-${project.VERSION_NAME}"
22 | consumerProguardFiles 'proguard-rules.pro'
23 | }
24 |
25 | //noinspection GroovyAssignabilityCheck
26 | task deleteJar(type: Delete) {
27 | delete "eclipse_lib/${artifact}"
28 | }
29 |
30 | //noinspection GroovyAssignabilityCheck
31 | task createJar(type: org.gradle.api.tasks.Copy) {
32 | from('build/intermediates/bundles/release/')
33 | into('eclipse_lib/')
34 | include('classes.jar')
35 | rename('classes.jar', artifact)
36 | }
37 |
38 | dependencies {
39 | implementation 'com.annimon:stream:1.2.1'
40 | implementation 'com.squareup.okio:okio:2.1.0'
41 |
42 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
43 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
44 | androidTestImplementation 'junit:junit:4.12'
45 |
46 | testImplementation 'junit:junit:4.12'
47 |
48 | }
49 |
50 | createJar.dependsOn(deleteJar, build)
51 | }
52 |
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/utils/HexData.java:
--------------------------------------------------------------------------------
1 | package com.felhr.utils;
2 |
3 | public class HexData
4 | {
5 | private static final String HEXES = "0123456789ABCDEF";
6 | private static final String HEX_INDICATOR = "0x";
7 | private static final String SPACE = " ";
8 |
9 | private HexData()
10 | {
11 |
12 | }
13 |
14 | public static String hexToString(byte[] data)
15 | {
16 | if(data != null)
17 | {
18 | StringBuilder hex = new StringBuilder(2*data.length);
19 | for(int i=0;i<=data.length-1;i++)
20 | {
21 | byte dataAtIndex = data[i];
22 | hex.append(HEX_INDICATOR);
23 | hex.append(HEXES.charAt((dataAtIndex & 0xF0) >> 4))
24 | .append(HEXES.charAt((dataAtIndex & 0x0F)));
25 | hex.append(SPACE);
26 | }
27 | return hex.toString();
28 | }else
29 | {
30 | return null;
31 | }
32 | }
33 |
34 | public static byte[] stringTobytes(String hexString)
35 | {
36 | String stringProcessed = hexString.trim().replaceAll("0x", "");
37 | stringProcessed = stringProcessed.replaceAll("\\s+","");
38 | byte[] data = new byte[stringProcessed.length()/2];
39 | int i = 0;
40 | int j = 0;
41 | while(i <= stringProcessed.length()-1)
42 | {
43 | byte character = (byte) Integer.parseInt(stringProcessed.substring(i, i+2), 16);
44 | data[j] = character;
45 | j++;
46 | i += 2;
47 | }
48 | return data;
49 | }
50 |
51 | public static String hex4digits(String id)
52 | {
53 | if(id.length() == 1) return "000" + id;
54 | if(id.length() == 2) return "00" + id;
55 | if(id.length() == 3) return "0" + id;
56 | else return id;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/examplestreams/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/integrationapp/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/example/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
19 |
20 |
29 |
30 |
39 |
40 |
41 |
42 |
43 |
53 |
--------------------------------------------------------------------------------
/integrationapp/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
16 |
17 |
23 |
24 |
30 |
31 |
37 |
38 |
44 |
45 |
51 |
52 |
60 |
61 |
--------------------------------------------------------------------------------
/usbserial/src/test/java/com/felhr/deviceids/DeviceIdTest.java:
--------------------------------------------------------------------------------
1 | package com.felhr.deviceids;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 | import org.junit.runner.RunWith;
6 | import org.junit.runners.JUnit4;
7 |
8 | @RunWith(JUnit4.class)
9 | public class DeviceIdTest {
10 |
11 | @Test
12 | public void testLongPacking() {
13 | TestCase[] cases = {
14 | new TestCase(0x08FD, 0x000A),
15 | new TestCase(0x0BED, 0x1100),
16 | new TestCase(0x0BED, 0x1101),
17 | new TestCase(0x0FCF, 0x1003),
18 | new TestCase(0x0FCF, 0x1004),
19 | new TestCase(0x0FCF, 0x1006),
20 | new TestCase(0x0FDE, 0xCA05),
21 | new TestCase(0x10A6, 0xAA26),
22 | new TestCase(0x10AB, 0x10C5),
23 | new TestCase(0x10B5, 0xAC70),
24 | new TestCase(0x10C4, 0x0F91),
25 | new TestCase(0x10C4, 0x1101),
26 | new TestCase(0x10C4, 0x1601),
27 | new TestCase(0x10C4, 0x800A),
28 | new TestCase(0x10C4, 0x803B),
29 | new TestCase(0x10C4, 0x8044),
30 | new TestCase(0x10C4, 0x804E),
31 | new TestCase(0x10C4, 0x8053),
32 | new TestCase(0x10C4, 0x8054),
33 | new TestCase(0x10C4, 0x8066),
34 | new TestCase(0x10C4, 0x806F),
35 | new TestCase(0x10C4, 0x807A),
36 | new TestCase(0x10C4, 0x80C4),
37 | new TestCase(0x10C4, 0x80CA),
38 | new TestCase(0x10C4, 0x80DD),
39 | new TestCase(0x10C4, 0x80F6),
40 | new TestCase(0x10C4, 0x8115),
41 | new TestCase(0x10C4, 0x813D),
42 | new TestCase(0x10C4, 0x813F),
43 | new TestCase(0x10C4, 0x814A),
44 | new TestCase(0x10C4, 0x814B),
45 | new TestCase(0x2405, 0x0003),
46 | new TestCase(0x10C4, 0x8156)
47 | };
48 |
49 | for (TestCase tc : cases) {
50 | Assert.assertTrue(CP210xIds.isDeviceSupported(tc.vendor, tc.product));
51 | Assert.assertFalse(FTDISioIds.isDeviceIdSupported(tc.vendor, tc.product));
52 | }
53 | }
54 |
55 |
56 | class TestCase {
57 | final int vendor, product;
58 |
59 | TestCase(int vendor, int product) {
60 | this.vendor = vendor;
61 | this.product = product;
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/usbserial/UsbSerialDebugger.java:
--------------------------------------------------------------------------------
1 | package com.felhr.usbserial;
2 |
3 | import com.felhr.utils.HexData;
4 |
5 | import android.util.Log;
6 |
7 | public class UsbSerialDebugger
8 | {
9 | private static final String CLASS_ID = UsbSerialDebugger.class.getSimpleName();
10 | public static final String ENCODING = "UTF-8";
11 |
12 | private UsbSerialDebugger()
13 | {
14 |
15 | }
16 |
17 | public static void printLogGet(byte[] src, boolean verbose)
18 | {
19 | if(!verbose)
20 | {
21 | Log.i(CLASS_ID, "Data obtained from write buffer: " + new String(src));
22 | }else
23 | {
24 | Log.i(CLASS_ID, "Data obtained from write buffer: " + new String(src));
25 | Log.i(CLASS_ID, "Raw data from write buffer: " + HexData.hexToString(src));
26 | Log.i(CLASS_ID, "Number of bytes obtained from write buffer: " + src.length);
27 | }
28 | }
29 |
30 | public static void printLogPut(byte[] src, boolean verbose)
31 | {
32 | if(!verbose)
33 | {
34 | Log.i(CLASS_ID, "Data obtained pushed to write buffer: " + new String(src));
35 | }else
36 | {
37 | Log.i(CLASS_ID, "Data obtained pushed to write buffer: " + new String(src));
38 | Log.i(CLASS_ID, "Raw data pushed to write buffer: " + HexData.hexToString(src));
39 | Log.i(CLASS_ID, "Number of bytes pushed from write buffer: " + src.length);
40 | }
41 | }
42 |
43 | public static void printReadLogGet(byte[] src, boolean verbose)
44 | {
45 | if(!verbose)
46 | {
47 | Log.i(CLASS_ID, "Data obtained from Read buffer: " + new String(src));
48 | }else
49 | {
50 | Log.i(CLASS_ID, "Data obtained from Read buffer: " + new String(src));
51 | Log.i(CLASS_ID, "Raw data from Read buffer: " + HexData.hexToString(src));
52 | Log.i(CLASS_ID, "Number of bytes obtained from Read buffer: " + src.length);
53 | }
54 | }
55 |
56 | public static void printReadLogPut(byte[] src, boolean verbose)
57 | {
58 | if(!verbose)
59 | {
60 | Log.i(CLASS_ID, "Data obtained pushed to read buffer: " + new String(src));
61 | }else
62 | {
63 | Log.i(CLASS_ID, "Data obtained pushed to read buffer: " + new String(src));
64 | Log.i(CLASS_ID, "Raw data pushed to read buffer: " + HexData.hexToString(src));
65 | Log.i(CLASS_ID, "Number of bytes pushed from read buffer: " + src.length);
66 | }
67 | }
68 |
69 |
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/usbserial/SerialInputStream.java:
--------------------------------------------------------------------------------
1 | package com.felhr.usbserial;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 |
6 | public class SerialInputStream extends InputStream
7 | {
8 | private int timeout = 0;
9 |
10 | private int maxBufferSize = 16 * 1024;
11 |
12 | private final byte[] buffer;
13 | private int pointer;
14 | private int bufferSize;
15 |
16 | protected final UsbSerialInterface device;
17 |
18 | public SerialInputStream(UsbSerialInterface device)
19 | {
20 | this.device = device;
21 | this.buffer = new byte[maxBufferSize];
22 | this.pointer = 0;
23 | this.bufferSize = -1;
24 | }
25 |
26 | public SerialInputStream(UsbSerialInterface device, int maxBufferSize)
27 | {
28 | this.device = device;
29 | this.maxBufferSize = maxBufferSize;
30 | this.buffer = new byte[this.maxBufferSize];
31 | this.pointer = 0;
32 | this.bufferSize = -1;
33 | }
34 |
35 | @Override
36 | public int read()
37 | {
38 | int value = checkFromBuffer();
39 | if(value >= 0)
40 | return value;
41 |
42 | int ret = device.syncRead(buffer, timeout);
43 | if(ret >= 0) {
44 | bufferSize = ret;
45 | return buffer[pointer++] & 0xff;
46 | }else {
47 | return -1;
48 | }
49 | }
50 |
51 | @Override
52 | public int read(byte[] b)
53 | {
54 | return device.syncRead(b, timeout);
55 | }
56 |
57 | @Override
58 | public int read(byte b[], int off, int len)
59 | {
60 | if(off < 0 ){
61 | throw new IndexOutOfBoundsException("Offset must be >= 0");
62 | }
63 |
64 | if(len < 0){
65 | throw new IndexOutOfBoundsException("Length must positive");
66 | }
67 |
68 | if(len > b.length - off) {
69 | throw new IndexOutOfBoundsException("Length greater than b.length - off");
70 | }
71 |
72 | if (off == 0 && len == b.length) {
73 | return read(b);
74 | }
75 |
76 | return device.syncRead(b, off, len, timeout);
77 | }
78 |
79 | @Override
80 | public int available() throws IOException {
81 | if(bufferSize > 0)
82 | return bufferSize - pointer;
83 | else
84 | return 0;
85 | }
86 |
87 | public void setTimeout(int timeout) {
88 | this.timeout = timeout;
89 | }
90 |
91 | private int checkFromBuffer(){
92 | if(bufferSize > 0 && pointer < bufferSize){
93 | return buffer[pointer++] & 0xff;
94 | }else{
95 | pointer = 0;
96 | bufferSize = -1;
97 | return -1;
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/usbserial/UsbSerialInterface.java:
--------------------------------------------------------------------------------
1 | package com.felhr.usbserial;
2 |
3 | /**
4 | * Interface to handle a serial port
5 | * @author felhr (felhr85@gmail.com)
6 | *
7 | */
8 | public interface UsbSerialInterface
9 | {
10 | // Common values
11 | int DATA_BITS_5 = 5;
12 | int DATA_BITS_6 = 6;
13 | int DATA_BITS_7 = 7;
14 | int DATA_BITS_8 = 8;
15 |
16 | int STOP_BITS_1 = 1;
17 | int STOP_BITS_15 = 3;
18 | int STOP_BITS_2 = 2;
19 |
20 | int PARITY_NONE = 0;
21 | int PARITY_ODD = 1;
22 | int PARITY_EVEN = 2;
23 | int PARITY_MARK = 3;
24 | int PARITY_SPACE = 4;
25 |
26 | int FLOW_CONTROL_OFF = 0;
27 | int FLOW_CONTROL_RTS_CTS= 1;
28 | int FLOW_CONTROL_DSR_DTR = 2;
29 | int FLOW_CONTROL_XON_XOFF = 3;
30 |
31 | // Common Usb Serial Operations (I/O Asynchronous)
32 | boolean open();
33 | void write(byte[] buffer);
34 | int read(UsbReadCallback mCallback);
35 | void close();
36 |
37 | // Common Usb Serial Operations (I/O Synchronous)
38 | boolean syncOpen();
39 | int syncWrite(byte[] buffer, int timeout);
40 | int syncRead(byte[] buffer, int timeout);
41 | int syncWrite(byte[] buffer, int offset, int length, int timeout);
42 | int syncRead(byte[] buffer, int offset, int length, int timeout);
43 | void syncClose();
44 |
45 | // Serial port configuration
46 | void setBaudRate(int baudRate);
47 | void setDataBits(int dataBits);
48 | void setStopBits(int stopBits);
49 | void setParity(int parity);
50 | void setFlowControl(int flowControl);
51 | void setBreak(boolean state);
52 |
53 | // Flow control commands and interface callback
54 | void setRTS(boolean state);
55 | void setDTR(boolean state);
56 | void getCTS(UsbCTSCallback ctsCallback);
57 | void getDSR(UsbDSRCallback dsrCallback);
58 |
59 | // Status methods
60 | void getBreak(UsbBreakCallback breakCallback);
61 | void getFrame(UsbFrameCallback frameCallback);
62 | void getOverrun(UsbOverrunCallback overrunCallback);
63 | void getParity(UsbParityCallback parityCallback);
64 |
65 | interface UsbCTSCallback
66 | {
67 | void onCTSChanged(boolean state);
68 | }
69 |
70 | interface UsbDSRCallback
71 | {
72 | void onDSRChanged(boolean state);
73 | }
74 |
75 | // Error signals callbacks
76 | interface UsbBreakCallback
77 | {
78 | void onBreakInterrupt();
79 | }
80 |
81 | interface UsbFrameCallback
82 | {
83 | void onFramingError();
84 | }
85 |
86 | interface UsbOverrunCallback
87 | {
88 | void onOverrunError();
89 | }
90 |
91 | interface UsbParityCallback
92 | {
93 | void onParityError();
94 | }
95 |
96 | // Usb Read Callback
97 | interface UsbReadCallback
98 | {
99 | void onReceivedData(byte[] data);
100 | }
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/deviceids/PL2303Ids.java:
--------------------------------------------------------------------------------
1 | package com.felhr.deviceids;
2 |
3 | import static com.felhr.deviceids.Helpers.createTable;
4 | import static com.felhr.deviceids.Helpers.createDevice;
5 |
6 | public class PL2303Ids
7 | {
8 | private PL2303Ids()
9 | {
10 |
11 | }
12 |
13 | private static final long[] pl2303Devices = createTable(
14 | createDevice(0x04a5, 0x4027),
15 | createDevice(0x067b, 0x2303),
16 | createDevice(0x067b, 0x04bb),
17 | createDevice(0x067b, 0x1234),
18 | createDevice(0x067b, 0xaaa0),
19 | createDevice(0x067b, 0xaaa2),
20 | createDevice(0x067b, 0x0611),
21 | createDevice(0x067b, 0x0612),
22 | createDevice(0x067b, 0x0609),
23 | createDevice(0x067b, 0x331a),
24 | createDevice(0x067b, 0x0307),
25 | createDevice(0x067b, 0x0463),
26 | createDevice(0x0557, 0x2008),
27 | createDevice(0x0547, 0x2008),
28 | createDevice(0x04bb, 0x0a03),
29 | createDevice(0x04bb, 0x0a0e),
30 | createDevice(0x056e, 0x5003),
31 | createDevice(0x056e, 0x5004),
32 | createDevice(0x0eba, 0x1080),
33 | createDevice(0x0eba, 0x2080),
34 | createDevice(0x0df7, 0x0620),
35 | createDevice(0x0584, 0xb000),
36 | createDevice(0x2478, 0x2008),
37 | createDevice(0x1453, 0x4026),
38 | createDevice(0x0731, 0x0528),
39 | createDevice(0x6189, 0x2068),
40 | createDevice(0x11f7, 0x02df),
41 | createDevice(0x04e8, 0x8001),
42 | createDevice(0x11f5, 0x0001),
43 | createDevice(0x11f5, 0x0003),
44 | createDevice(0x11f5, 0x0004),
45 | createDevice(0x11f5, 0x0005),
46 | createDevice(0x0745, 0x0001),
47 | createDevice(0x078b, 0x1234),
48 | createDevice(0x10b5, 0xac70),
49 | createDevice(0x079b, 0x0027),
50 | createDevice(0x0413, 0x2101),
51 | createDevice(0x0e55, 0x110b),
52 | createDevice(0x0731, 0x2003),
53 | createDevice(0x050d, 0x0257),
54 | createDevice(0x058f, 0x9720),
55 | createDevice(0x11f6, 0x2001),
56 | createDevice(0x07aa, 0x002a),
57 | createDevice(0x05ad, 0x0fba),
58 | createDevice(0x5372, 0x2303),
59 | createDevice(0x03f0, 0x0b39),
60 | createDevice(0x03f0, 0x3139),
61 | createDevice(0x03f0, 0x3239),
62 | createDevice(0x03f0, 0x3524),
63 | createDevice(0x04b8, 0x0521),
64 | createDevice(0x04b8, 0x0522),
65 | createDevice(0x054c, 0x0437),
66 | createDevice(0x11ad, 0x0001),
67 | createDevice(0x0b63, 0x6530),
68 | createDevice(0x0b8c, 0x2303),
69 | createDevice(0x110a, 0x1150),
70 | createDevice(0x0557, 0x2008)
71 | );
72 |
73 | public static boolean isDeviceSupported(int vendorId, int productId)
74 | {
75 | return Helpers.exists(pl2303Devices, vendorId, productId);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/usbserial/src/test/java/com/felhr/usbserial/FTDISerialDeviceTest.java:
--------------------------------------------------------------------------------
1 | package com.felhr.usbserial;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 | import org.junit.runner.RunWith;
6 | import org.junit.runners.JUnit4;
7 |
8 | import java.util.Arrays;
9 |
10 | @RunWith(JUnit4.class)
11 | public class FTDISerialDeviceTest {
12 |
13 | @Test
14 | public void adaptEmptyByteArray() {
15 | byte[] onlyHeaders = {1, 2};
16 | byte[] adapted = FTDISerialDevice.adaptArray(onlyHeaders);
17 | Assert.assertEquals("Should be empty", 0, adapted.length);
18 | byte[] adaptAgain = FTDISerialDevice.adaptArray(onlyHeaders);
19 | Assert.assertSame("Should be the same instance of empty array", adapted, adaptAgain);
20 | }
21 |
22 | @Test
23 | public void withHeaders() {
24 | byte[] withHeaders = {1, 2, 3, 4, 5, 6};
25 | byte[] wanted = {3,4,5,6};
26 | Assert.assertArrayEquals(wanted, FTDISerialDevice.adaptArray(withHeaders));
27 | }
28 |
29 | @Test
30 | public void fullWithHeaders() {
31 | byte[] withHeaders = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64};
32 | byte[] wanted = Arrays.copyOfRange(withHeaders, 2, 64);
33 | Assert.assertArrayEquals(wanted, FTDISerialDevice.adaptArray(withHeaders));
34 | }
35 |
36 | @Test
37 | public void testMultipleFull() {
38 | byte[] withHeaders = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64};
39 | byte[] wanted = {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64, 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64};
40 | Assert.assertArrayEquals(wanted, FTDISerialDevice.adaptArray(withHeaders));
41 | }
42 |
43 | @Test
44 | public void testMultiplePartial() {
45 | byte[] withHeaders = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62};
46 | byte[] wanted = {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64, 3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62};
47 | Assert.assertArrayEquals(wanted, FTDISerialDevice.adaptArray(withHeaders));
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/examplesync/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
19 |
20 |
29 |
30 |
39 |
40 |
41 |
42 |
43 |
52 |
53 |
62 |
63 |
71 |
72 |
82 |
83 |
--------------------------------------------------------------------------------
/examplestreams/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
20 |
21 |
30 |
31 |
40 |
41 |
42 |
43 |
44 |
53 |
54 |
63 |
64 |
72 |
73 |
83 |
84 |
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
15 |
16 |
27 |
28 |
40 |
41 |
51 |
52 |
53 |
67 |
68 |
78 |
79 |
80 |
94 |
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/usbserial/SerialBuffer.java:
--------------------------------------------------------------------------------
1 | package com.felhr.usbserial;
2 |
3 | import java.io.EOFException;
4 | import java.nio.ByteBuffer;
5 | import java.util.Arrays;
6 |
7 | import okio.Buffer;
8 |
9 | public class SerialBuffer
10 | {
11 | static final int DEFAULT_READ_BUFFER_SIZE = 16 * 1024;
12 | static final int MAX_BULK_BUFFER = 16 * 1024;
13 | private ByteBuffer readBuffer;
14 |
15 | private final SynchronizedBuffer writeBuffer;
16 | private byte[] readBufferCompatible; // Read buffer for android < 4.2
17 | private boolean debugging = false;
18 |
19 | public SerialBuffer(boolean version)
20 | {
21 | writeBuffer = new SynchronizedBuffer();
22 | if(version)
23 | {
24 | readBuffer = ByteBuffer.allocate(DEFAULT_READ_BUFFER_SIZE);
25 |
26 | }else
27 | {
28 | readBufferCompatible = new byte[DEFAULT_READ_BUFFER_SIZE];
29 | }
30 | }
31 |
32 | /*
33 | * Print debug messages
34 | */
35 | public void debug(boolean value)
36 | {
37 | debugging = value;
38 | }
39 |
40 | public ByteBuffer getReadBuffer()
41 | {
42 | synchronized(this)
43 | {
44 | return readBuffer;
45 | }
46 | }
47 |
48 |
49 | public byte[] getDataReceived()
50 | {
51 | synchronized(this)
52 | {
53 | byte[] dst = new byte[readBuffer.position()];
54 | readBuffer.position(0);
55 | readBuffer.get(dst, 0, dst.length);
56 | if(debugging)
57 | UsbSerialDebugger.printReadLogGet(dst, true);
58 | return dst;
59 | }
60 | }
61 |
62 | public void clearReadBuffer()
63 | {
64 | synchronized(this)
65 | {
66 | readBuffer.clear();
67 | }
68 | }
69 |
70 | public byte[] getWriteBuffer()
71 | {
72 | return writeBuffer.get();
73 | }
74 |
75 | public void putWriteBuffer(byte[]data)
76 | {
77 | writeBuffer.put(data);
78 | }
79 |
80 |
81 | public byte[] getBufferCompatible()
82 | {
83 | return readBufferCompatible;
84 | }
85 |
86 | public byte[] getDataReceivedCompatible(int numberBytes)
87 | {
88 | return Arrays.copyOfRange(readBufferCompatible, 0, numberBytes);
89 | }
90 |
91 | private class SynchronizedBuffer
92 | {
93 | private final Buffer buffer;
94 |
95 | SynchronizedBuffer()
96 | {
97 | this.buffer = new Buffer();
98 | }
99 |
100 | synchronized void put(byte[] src)
101 | {
102 | if(src == null || src.length == 0) return;
103 |
104 | if(debugging)
105 | UsbSerialDebugger.printLogPut(src, true);
106 |
107 | buffer.write(src);
108 | notify();
109 | }
110 |
111 | synchronized byte[] get()
112 | {
113 | if(buffer.size() == 0)
114 | {
115 | try
116 | {
117 | wait();
118 | } catch (InterruptedException e)
119 | {
120 | e.printStackTrace();
121 | Thread.currentThread().interrupt();
122 | }
123 | }
124 | byte[] dst;
125 | if(buffer.size() <= MAX_BULK_BUFFER){
126 | dst = buffer.readByteArray();
127 | }else{
128 | try {
129 | dst = buffer.readByteArray(MAX_BULK_BUFFER);
130 | } catch (EOFException e) {
131 | e.printStackTrace();
132 | return new byte[0];
133 | }
134 | }
135 |
136 | if(debugging)
137 | UsbSerialDebugger.printLogGet(dst, true);
138 |
139 | return dst;
140 | }
141 | }
142 |
143 | }
144 |
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/utils/ProtocolBuffer.java:
--------------------------------------------------------------------------------
1 | package com.felhr.utils;
2 |
3 | import com.annimon.stream.IntStream;
4 | import com.annimon.stream.function.IntPredicate;
5 |
6 | import java.io.UnsupportedEncodingException;
7 | import java.util.ArrayList;
8 | import java.util.Arrays;
9 | import java.util.List;
10 |
11 | // Thanks to Thomas Moorhead for improvements and suggestions
12 |
13 | public class ProtocolBuffer {
14 |
15 | public static final String BINARY = "binary";
16 | public static final String TEXT = "text";
17 |
18 | private String mode;
19 |
20 | private static final int DEFAULT_BUFFER_SIZE = 16 * 1024;
21 |
22 | private byte[] rawBuffer;
23 | private int bufferPointer = 0;
24 |
25 | private byte[] separator;
26 | private String delimiter;
27 | private StringBuilder stringBuffer;
28 |
29 | private List commands = new ArrayList<>();
30 | private List rawCommands = new ArrayList<>();
31 |
32 | public ProtocolBuffer(String mode){
33 | this.mode = mode;
34 | if(mode.equals(BINARY)){
35 | rawBuffer = new byte[DEFAULT_BUFFER_SIZE];
36 | }else{
37 | stringBuffer = new StringBuilder(DEFAULT_BUFFER_SIZE);
38 | }
39 | }
40 |
41 | public ProtocolBuffer(String mode, int bufferSize){
42 | this.mode = mode;
43 | if(mode.equals(BINARY)){
44 | rawBuffer = new byte[bufferSize];
45 | }else{
46 | stringBuffer = new StringBuilder(bufferSize);
47 | }
48 | }
49 |
50 | public void setDelimiter(String delimiter){
51 | this.delimiter = delimiter;
52 | }
53 |
54 | public void setDelimiter(byte[] delimiter){
55 | this.separator = delimiter;
56 | }
57 |
58 | public synchronized void appendData(byte[] data){
59 | // Ignore the frequent empty calls
60 | if (data.length == 0) return;
61 |
62 | if(mode.equals(TEXT)){
63 | try {
64 | String dataStr = new String(data, "UTF-8");
65 | stringBuffer.append(dataStr);
66 |
67 | String buffer = stringBuffer.toString();
68 | int prevIndex = 0;
69 | int index = buffer.indexOf(delimiter);
70 | while (index >= 0) {
71 | String tempStr = buffer.substring(prevIndex, index + delimiter.length());
72 | commands.add(tempStr);
73 | prevIndex = index + delimiter.length();
74 | index = stringBuffer.toString().indexOf(delimiter, prevIndex);
75 | }
76 |
77 | if( /*prevIndex < buffer.length() &&*/ prevIndex > 0){
78 | String tempStr = buffer.substring(prevIndex, buffer.length());
79 | stringBuffer.setLength(0);
80 | stringBuffer.append(tempStr);
81 | }
82 |
83 | } catch (UnsupportedEncodingException e) {
84 | e.printStackTrace();
85 | }
86 | }else if(mode.equals(BINARY)){
87 | appendRawData(data);
88 | }
89 | }
90 |
91 | public boolean hasMoreCommands(){
92 | if(mode.equals(TEXT)) {
93 | return commands.size() > 0;
94 | }else {
95 | return rawCommands.size() > 0;
96 | }
97 | }
98 |
99 | public String nextTextCommand(){
100 | if(commands.size() > 0){
101 | return commands.remove(0);
102 | }else{
103 | return null;
104 | }
105 | }
106 |
107 | public byte[] nextBinaryCommand(){
108 | if(rawCommands.size() > 0){
109 | return rawCommands.remove(0);
110 | }else{
111 | return null;
112 | }
113 | }
114 |
115 | private void appendRawData(byte[] rawData){
116 |
117 | System.arraycopy(rawData, 0, rawBuffer, bufferPointer, rawData.length);
118 | bufferPointer += rawData.length;
119 |
120 | SeparatorPredicate predicate = new SeparatorPredicate();
121 | int[] indexes =
122 | IntStream.range(0, bufferPointer)
123 | .filter(predicate)
124 | .toArray();
125 |
126 | int prevIndex = 0;
127 | for(Integer i : indexes){
128 | byte[] command = Arrays.copyOfRange(rawBuffer, prevIndex, i + separator.length);
129 | rawCommands.add(command);
130 | prevIndex = i + separator.length;
131 | }
132 |
133 | if(prevIndex < rawBuffer.length
134 | && prevIndex > 0){
135 | byte[] tempBuffer = Arrays.copyOfRange(rawBuffer, prevIndex, rawBuffer.length);
136 | bufferPointer = 0;
137 | System.arraycopy(tempBuffer, 0, rawBuffer, bufferPointer, rawData.length);
138 | bufferPointer += rawData.length;
139 | }
140 |
141 | }
142 |
143 | private class SeparatorPredicate implements IntPredicate{
144 | @Override
145 | public boolean test(int value) {
146 | if(rawBuffer[value] == separator[0]){
147 | for(int i=1;i<=separator.length-1;i++){
148 | if(rawBuffer[value + i] != separator[i]){
149 | return false;
150 | }
151 | }
152 | return true;
153 | }
154 | return false;
155 | }
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/usbserial/UsbSpiDevice.java:
--------------------------------------------------------------------------------
1 | package com.felhr.usbserial;
2 |
3 | import android.hardware.usb.UsbDevice;
4 | import android.hardware.usb.UsbDeviceConnection;
5 | import android.hardware.usb.UsbEndpoint;
6 |
7 | import com.felhr.deviceids.CP2130Ids;
8 |
9 | public abstract class UsbSpiDevice implements UsbSpiInterface
10 | {
11 |
12 | protected static final int USB_TIMEOUT = 5000;
13 |
14 | protected final UsbDevice device;
15 | protected final UsbDeviceConnection connection;
16 |
17 | protected SerialBuffer serialBuffer;
18 |
19 | protected WriteThread writeThread;
20 | protected ReadThread readThread;
21 |
22 | // Endpoints for synchronous read and write operations
23 | private UsbEndpoint inEndpoint;
24 | private UsbEndpoint outEndpoint;
25 |
26 | public UsbSpiDevice(UsbDevice device, UsbDeviceConnection connection)
27 | {
28 | this.device = device;
29 | this.connection = connection;
30 | this.serialBuffer = new SerialBuffer(false);
31 | }
32 |
33 | public static UsbSpiDevice createUsbSerialDevice(UsbDevice device, UsbDeviceConnection connection)
34 | {
35 | return createUsbSerialDevice(device, connection, -1);
36 | }
37 |
38 | public static UsbSpiDevice createUsbSerialDevice(UsbDevice device, UsbDeviceConnection connection, int iface)
39 | {
40 | int vid = device.getVendorId();
41 | int pid = device.getProductId();
42 |
43 | if(CP2130Ids.isDeviceSupported(vid, pid))
44 | return new CP2130SpiDevice(device, connection, iface);
45 | else
46 | return null;
47 | }
48 |
49 |
50 | @Override
51 | public abstract boolean connectSPI();
52 |
53 | @Override
54 | public abstract void writeMOSI(byte[] buffer);
55 |
56 | @Override
57 | public abstract void readMISO(int lengthBuffer);
58 |
59 | @Override
60 | public abstract void writeRead(byte[] buffer, int lengthRead);
61 |
62 | @Override
63 | public abstract void setClock(int clockDivider);
64 |
65 | @Override
66 | public abstract void selectSlave(int nSlave);
67 |
68 | @Override
69 | public void setMISOCallback(UsbMISOCallback misoCallback)
70 | {
71 | readThread.setCallback(misoCallback);
72 | }
73 |
74 | @Override
75 | public abstract int getClockDivider();
76 |
77 | @Override
78 | public abstract int getSelectedSlave();
79 |
80 | @Override
81 | public abstract void closeSPI();
82 |
83 | protected class WriteThread extends AbstractWorkerThread
84 | {
85 | private UsbEndpoint outEndpoint;
86 |
87 | @Override
88 | public void doRun()
89 | {
90 | byte[] data = serialBuffer.getWriteBuffer();
91 | if(data.length > 0)
92 | connection.bulkTransfer(outEndpoint, data, data.length, USB_TIMEOUT);
93 | }
94 |
95 | public void setUsbEndpoint(UsbEndpoint outEndpoint)
96 | {
97 | this.outEndpoint = outEndpoint;
98 | }
99 | }
100 |
101 | protected class ReadThread extends AbstractWorkerThread
102 | {
103 | private UsbMISOCallback misoCallback;
104 | private UsbEndpoint inEndpoint;
105 |
106 | public void setCallback(UsbMISOCallback misoCallback)
107 | {
108 | this.misoCallback = misoCallback;
109 | }
110 |
111 | @Override
112 | public void doRun()
113 | {
114 | byte[] dataReceived = null;
115 | int numberBytes;
116 | if(inEndpoint != null)
117 | numberBytes = connection.bulkTransfer(inEndpoint, serialBuffer.getBufferCompatible(),
118 | SerialBuffer.DEFAULT_READ_BUFFER_SIZE, 0);
119 | else
120 | numberBytes = 0;
121 |
122 | if(numberBytes > 0)
123 | {
124 | dataReceived = serialBuffer.getDataReceivedCompatible(numberBytes);
125 | onReceivedData(dataReceived);
126 | }
127 |
128 | }
129 |
130 | public void setUsbEndpoint(UsbEndpoint inEndpoint)
131 | {
132 | this.inEndpoint = inEndpoint;
133 | }
134 |
135 | private void onReceivedData(byte[] data)
136 | {
137 | if(misoCallback != null)
138 | misoCallback.onReceivedData(data);
139 | }
140 | }
141 |
142 | protected void setThreadsParams(UsbEndpoint inEndpoint, UsbEndpoint outEndpoint)
143 | {
144 | if(writeThread != null)
145 | writeThread.setUsbEndpoint(outEndpoint);
146 |
147 | if(readThread != null)
148 | readThread.setUsbEndpoint(inEndpoint);
149 | }
150 |
151 | /*
152 | * Kill workingThread; This must be called when closing a device
153 | */
154 | protected void killWorkingThread()
155 | {
156 | if(readThread != null)
157 | {
158 | readThread.stopThread();
159 | readThread = null;
160 | }
161 | }
162 |
163 | /*
164 | * Restart workingThread if it has been killed before
165 | */
166 | protected void restartWorkingThread()
167 | {
168 | readThread = new ReadThread();
169 | readThread.start();
170 | while(!readThread.isAlive()){} // Busy waiting
171 | }
172 |
173 | protected void killWriteThread()
174 | {
175 | if(writeThread != null)
176 | {
177 | writeThread.stopThread();
178 | writeThread = null;
179 | }
180 | }
181 |
182 | protected void restartWriteThread()
183 | {
184 | if(writeThread == null)
185 | {
186 | writeThread = new WriteThread();
187 | writeThread.start();
188 | while(!writeThread.isAlive()){} // Busy waiting
189 | }
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/examplestreams/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
11 |
16 |
21 |
26 |
31 |
36 |
41 |
46 |
51 |
56 |
61 |
66 |
71 |
76 |
81 |
86 |
91 |
96 |
101 |
106 |
111 |
116 |
121 |
126 |
131 |
136 |
141 |
146 |
151 |
156 |
161 |
166 |
171 |
172 |
--------------------------------------------------------------------------------
/integrationapp/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
11 |
16 |
21 |
26 |
31 |
36 |
41 |
46 |
51 |
56 |
61 |
66 |
71 |
76 |
81 |
86 |
91 |
96 |
101 |
106 |
111 |
116 |
121 |
126 |
131 |
136 |
141 |
146 |
151 |
156 |
161 |
166 |
171 |
172 |
--------------------------------------------------------------------------------
/examplemultipleports/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
11 |
16 |
21 |
26 |
31 |
36 |
41 |
46 |
51 |
56 |
61 |
66 |
71 |
76 |
81 |
86 |
91 |
96 |
101 |
106 |
111 |
116 |
121 |
126 |
131 |
136 |
141 |
146 |
151 |
156 |
161 |
166 |
171 |
172 |
--------------------------------------------------------------------------------
/examplemultipleports/src/main/java/com/felhr/examplemultipleports/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.felhr.examplemultipleports;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.ComponentName;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.IntentFilter;
8 | import android.content.ServiceConnection;
9 | import android.os.Handler;
10 | import android.os.IBinder;
11 | import android.os.Message;
12 | import android.support.v7.app.AppCompatActivity;
13 | import android.os.Bundle;
14 | import android.view.View;
15 | import android.widget.Button;
16 | import android.widget.EditText;
17 | import android.widget.TextView;
18 | import android.widget.Toast;
19 |
20 | import com.felhr.utils.HexData;
21 |
22 | import java.lang.ref.WeakReference;
23 | import java.util.Set;
24 |
25 | public class MainActivity extends AppCompatActivity {
26 |
27 |
28 | /*
29 | * Notifications from UsbService will be received here.
30 | */
31 | private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
32 | @Override
33 | public void onReceive(Context context, Intent intent) {
34 | switch (intent.getAction()) {
35 | case UsbService.ACTION_USB_PERMISSION_GRANTED: // USB PERMISSION GRANTED
36 | Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show();
37 | break;
38 | case UsbService.ACTION_USB_PERMISSION_NOT_GRANTED: // USB PERMISSION NOT GRANTED
39 | Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show();
40 | break;
41 | case UsbService.ACTION_NO_USB: // NO USB CONNECTED
42 | Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show();
43 | break;
44 | case UsbService.ACTION_USB_DISCONNECTED: // USB DISCONNECTED
45 | Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show();
46 | break;
47 | case UsbService.ACTION_USB_NOT_SUPPORTED: // USB NOT SUPPORTED
48 | Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show();
49 | break;
50 | }
51 | }
52 | };
53 | private UsbService usbService;
54 | private TextView display1, display2;
55 | private EditText editText1, editText2;
56 | private Button button1, button2;
57 | private MyHandler mHandler;
58 |
59 | private final ServiceConnection usbConnection = new ServiceConnection() {
60 | @Override
61 | public void onServiceConnected(ComponentName arg0, IBinder arg1) {
62 | usbService = ((UsbService.UsbBinder) arg1).getService();
63 | usbService.setHandler(mHandler);
64 | }
65 |
66 | @Override
67 | public void onServiceDisconnected(ComponentName arg0) {
68 | usbService = null;
69 | }
70 | };
71 |
72 | @Override
73 | protected void onCreate(Bundle savedInstanceState) {
74 | super.onCreate(savedInstanceState);
75 | setContentView(R.layout.activity_main);
76 |
77 | display1 = findViewById(R.id.textView1);
78 | display2 = findViewById(R.id.textView2);
79 |
80 | editText1 = findViewById(R.id.editText1);
81 | editText2 = findViewById(R.id.editText2);
82 |
83 | button1 = findViewById(R.id.buttonSend1);
84 | button2 = findViewById(R.id.buttonSend2);
85 |
86 | button1.setOnClickListener((View v) -> {
87 | byte[] data = editText1.getText().toString().getBytes();
88 | usbService.write(data, 0);
89 |
90 | });
91 |
92 | button2.setOnClickListener((View v) -> {
93 | byte[] data = editText2.getText().toString().getBytes();
94 | usbService.write(data, 1);
95 | });
96 |
97 | mHandler = new MyHandler(this);
98 | }
99 |
100 | @Override
101 | public void onResume() {
102 | super.onResume();
103 | setFilters(); // Start listening notifications from UsbService
104 | startService(UsbService.class, usbConnection, null); // Start UsbService(if it was not started before) and Bind it
105 | }
106 |
107 | @Override
108 | public void onPause() {
109 | super.onPause();
110 | unregisterReceiver(mUsbReceiver);
111 | unbindService(usbConnection);
112 | }
113 |
114 | private void startService(Class> service, ServiceConnection serviceConnection, Bundle extras) {
115 | if (!UsbService.SERVICE_CONNECTED) {
116 | Intent startService = new Intent(this, service);
117 | if (extras != null && !extras.isEmpty()) {
118 | Set keys = extras.keySet();
119 | for (String key : keys) {
120 | String extra = extras.getString(key);
121 | startService.putExtra(key, extra);
122 | }
123 | }
124 | startService(startService);
125 | }
126 | Intent bindingIntent = new Intent(this, service);
127 | bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE);
128 | }
129 |
130 | private void setFilters() {
131 | IntentFilter filter = new IntentFilter();
132 | filter.addAction(UsbService.ACTION_USB_PERMISSION_GRANTED);
133 | filter.addAction(UsbService.ACTION_NO_USB);
134 | filter.addAction(UsbService.ACTION_USB_DISCONNECTED);
135 | filter.addAction(UsbService.ACTION_USB_NOT_SUPPORTED);
136 | filter.addAction(UsbService.ACTION_USB_PERMISSION_NOT_GRANTED);
137 | registerReceiver(mUsbReceiver, filter);
138 | }
139 |
140 | /*
141 | * This handler will be passed to UsbService. Data received from serial port is displayed through this handler
142 | */
143 | private static class MyHandler extends Handler {
144 | private final WeakReference mActivity;
145 |
146 | public MyHandler(MainActivity activity) {
147 | mActivity = new WeakReference<>(activity);
148 | }
149 |
150 | @Override
151 | public void handleMessage(Message msg) {
152 | switch (msg.what) {
153 | case UsbService.SYNC_READ:
154 | String buffer = (String) msg.obj;
155 | if(msg.arg1 == 0){
156 | mActivity.get().display1.append(buffer);
157 | }else if(msg.arg1 == 1){
158 | mActivity.get().display2.append(buffer);
159 | }
160 |
161 | break;
162 | }
163 | }
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/example/src/main/java/com/felhr/serialportexample/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.felhr.serialportexample;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.ComponentName;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.IntentFilter;
8 | import android.content.ServiceConnection;
9 | import android.os.Bundle;
10 | import android.os.Handler;
11 | import android.os.IBinder;
12 | import android.os.Message;
13 | import android.support.v7.app.AppCompatActivity;
14 | import android.view.View;
15 | import android.widget.Button;
16 | import android.widget.EditText;
17 | import android.widget.TextView;
18 | import android.widget.Toast;
19 |
20 | import java.lang.ref.WeakReference;
21 | import java.util.Set;
22 |
23 | public class MainActivity extends AppCompatActivity {
24 |
25 | /*
26 | * Notifications from UsbService will be received here.
27 | */
28 | private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
29 | @Override
30 | public void onReceive(Context context, Intent intent) {
31 | switch (intent.getAction()) {
32 | case UsbService.ACTION_USB_PERMISSION_GRANTED: // USB PERMISSION GRANTED
33 | Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show();
34 | break;
35 | case UsbService.ACTION_USB_PERMISSION_NOT_GRANTED: // USB PERMISSION NOT GRANTED
36 | Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show();
37 | break;
38 | case UsbService.ACTION_NO_USB: // NO USB CONNECTED
39 | Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show();
40 | break;
41 | case UsbService.ACTION_USB_DISCONNECTED: // USB DISCONNECTED
42 | Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show();
43 | break;
44 | case UsbService.ACTION_USB_NOT_SUPPORTED: // USB NOT SUPPORTED
45 | Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show();
46 | break;
47 | }
48 | }
49 | };
50 | private UsbService usbService;
51 | private TextView display;
52 | private EditText editText;
53 | private MyHandler mHandler;
54 | private final ServiceConnection usbConnection = new ServiceConnection() {
55 | @Override
56 | public void onServiceConnected(ComponentName arg0, IBinder arg1) {
57 | usbService = ((UsbService.UsbBinder) arg1).getService();
58 | usbService.setHandler(mHandler);
59 | }
60 |
61 | @Override
62 | public void onServiceDisconnected(ComponentName arg0) {
63 | usbService = null;
64 | }
65 | };
66 |
67 | @Override
68 | protected void onCreate(Bundle savedInstanceState) {
69 | super.onCreate(savedInstanceState);
70 | setContentView(R.layout.activity_main);
71 |
72 | mHandler = new MyHandler(this);
73 |
74 | display = (TextView) findViewById(R.id.textView1);
75 | editText = (EditText) findViewById(R.id.editText1);
76 | Button sendButton = (Button) findViewById(R.id.buttonSend);
77 | sendButton.setOnClickListener(new View.OnClickListener() {
78 | @Override
79 | public void onClick(View v) {
80 | if (!editText.getText().toString().equals("")) {
81 | String data = editText.getText().toString();
82 | if (usbService != null) { // if UsbService was correctly binded, Send data
83 | usbService.write(data.getBytes());
84 | }
85 | }
86 | }
87 | });
88 | }
89 |
90 | @Override
91 | public void onResume() {
92 | super.onResume();
93 | setFilters(); // Start listening notifications from UsbService
94 | startService(UsbService.class, usbConnection, null); // Start UsbService(if it was not started before) and Bind it
95 | }
96 |
97 | @Override
98 | public void onPause() {
99 | super.onPause();
100 | unregisterReceiver(mUsbReceiver);
101 | unbindService(usbConnection);
102 | }
103 |
104 | private void startService(Class> service, ServiceConnection serviceConnection, Bundle extras) {
105 | if (!UsbService.SERVICE_CONNECTED) {
106 | Intent startService = new Intent(this, service);
107 | if (extras != null && !extras.isEmpty()) {
108 | Set keys = extras.keySet();
109 | for (String key : keys) {
110 | String extra = extras.getString(key);
111 | startService.putExtra(key, extra);
112 | }
113 | }
114 | startService(startService);
115 | }
116 | Intent bindingIntent = new Intent(this, service);
117 | bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE);
118 | }
119 |
120 | private void setFilters() {
121 | IntentFilter filter = new IntentFilter();
122 | filter.addAction(UsbService.ACTION_USB_PERMISSION_GRANTED);
123 | filter.addAction(UsbService.ACTION_NO_USB);
124 | filter.addAction(UsbService.ACTION_USB_DISCONNECTED);
125 | filter.addAction(UsbService.ACTION_USB_NOT_SUPPORTED);
126 | filter.addAction(UsbService.ACTION_USB_PERMISSION_NOT_GRANTED);
127 | registerReceiver(mUsbReceiver, filter);
128 | }
129 |
130 | /*
131 | * This handler will be passed to UsbService. Data received from serial port is displayed through this handler
132 | */
133 | private static class MyHandler extends Handler {
134 | private final WeakReference mActivity;
135 |
136 | public MyHandler(MainActivity activity) {
137 | mActivity = new WeakReference<>(activity);
138 | }
139 |
140 | @Override
141 | public void handleMessage(Message msg) {
142 | switch (msg.what) {
143 | case UsbService.MESSAGE_FROM_SERIAL_PORT:
144 | String data = (String) msg.obj;
145 | mActivity.get().display.append(data);
146 | break;
147 | case UsbService.CTS_CHANGE:
148 | Toast.makeText(mActivity.get(), "CTS_CHANGE",Toast.LENGTH_LONG).show();
149 | break;
150 | case UsbService.DSR_CHANGE:
151 | Toast.makeText(mActivity.get(), "DSR_CHANGE",Toast.LENGTH_LONG).show();
152 | break;
153 | }
154 | }
155 | }
156 | }
--------------------------------------------------------------------------------
/usbserial/src/androidTest/java/com/felhr/tests/usbserial/SerialBufferTest.java:
--------------------------------------------------------------------------------
1 | package com.felhr.tests.usbserial;
2 |
3 | import com.felhr.usbserial.SerialBuffer;
4 |
5 | import junit.framework.TestCase;
6 |
7 | import org.junit.Assert;
8 | import org.junit.Test;
9 |
10 | import java.io.ByteArrayOutputStream;
11 | import java.io.IOException;
12 | import java.nio.ByteBuffer;
13 | import java.util.Random;
14 |
15 |
16 | public class SerialBufferTest extends TestCase {
17 |
18 | private static final int BIG_BUFFER_1_SIZE = 64 * 1024;
19 | private static final int BIG_BUFFER_2_SIZE = 1024 * 1024;
20 | private static final int READ_BUFFER_SIZE = 16 * 1024;
21 |
22 | private static final String text1 = "HOLA";
23 | private static final byte[] bigBuffer = new byte[BIG_BUFFER_1_SIZE];
24 | private static final byte[] bigBuffer2 = new byte[BIG_BUFFER_2_SIZE];
25 | private static final byte[] bigReadBuffer = new byte[READ_BUFFER_SIZE];
26 |
27 | private SerialBuffer serialBuffer;
28 |
29 | // Testing Write buffer
30 |
31 | @Test
32 | public void testSimpleWriteBuffer(){
33 | serialBuffer = new SerialBuffer(true);
34 | serialBuffer.putWriteBuffer(text1.getBytes());
35 | byte[] dataReceived = serialBuffer.getWriteBuffer();
36 | assertEquals(text1, new String(dataReceived));
37 | }
38 |
39 | @Test
40 | public void testBigSimpleWriteBuffer(){
41 | try {
42 | new Random().nextBytes(bigBuffer);
43 | serialBuffer = new SerialBuffer(true);
44 | serialBuffer.putWriteBuffer(bigBuffer);
45 |
46 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
47 |
48 | while(outputStream.size() < bigBuffer.length){
49 | byte[] srcData = serialBuffer.getWriteBuffer();
50 | outputStream.write(srcData);
51 | }
52 |
53 | byte[] srcBuffered = outputStream.toByteArray();
54 |
55 | Assert.assertArrayEquals(bigBuffer, srcBuffered);
56 | } catch (IOException e) {
57 | e.printStackTrace();
58 | }
59 | }
60 |
61 | @Test
62 | public void testSuperBigSimpleWriteBuffer(){
63 | try {
64 | new Random().nextBytes(bigBuffer2);
65 | serialBuffer = new SerialBuffer(true);
66 | serialBuffer.putWriteBuffer(bigBuffer2);
67 |
68 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
69 |
70 | while(outputStream.size() < bigBuffer2.length){
71 | byte[] srcData = serialBuffer.getWriteBuffer();
72 | outputStream.write(srcData);
73 | }
74 |
75 | byte[] srcBuffered = outputStream.toByteArray();
76 |
77 | Assert.assertArrayEquals(bigBuffer2, srcBuffered);
78 | } catch (IOException e) {
79 | e.printStackTrace();
80 | }
81 | }
82 |
83 | @Test
84 | public void testSimpleWriteBufferAsync1(){
85 | try {
86 | new Random().nextBytes(bigBuffer2);
87 | serialBuffer = new SerialBuffer(true);
88 |
89 | WriterThread writerThread = new WriterThread(serialBuffer, bigBuffer2);
90 | writerThread.start();
91 |
92 | while(writerThread.getState() != Thread.State.TERMINATED){/*Busy waiting*/}
93 |
94 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
95 |
96 | while(outputStream.size() < bigBuffer2.length){
97 | byte[] srcData = serialBuffer.getWriteBuffer();
98 | outputStream.write(srcData);
99 | }
100 |
101 | byte[] dataReceived = outputStream.toByteArray();
102 |
103 | Assert.assertArrayEquals(bigBuffer2, dataReceived);
104 | } catch (IOException e) {
105 | e.printStackTrace();
106 | }
107 | }
108 |
109 | @Test
110 | public void testSimpleWriteBufferAsync2(){
111 | try {
112 | new Random().nextBytes(bigBuffer2);
113 | serialBuffer = new SerialBuffer(true);
114 |
115 | WriterThread writerThread = new WriterThread(serialBuffer, bigBuffer2, Thread.currentThread());
116 | writerThread.start();
117 |
118 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
119 |
120 | while(outputStream.size() < bigBuffer2.length){
121 | byte[] srcData = serialBuffer.getWriteBuffer();
122 | outputStream.write(srcData);
123 | }
124 |
125 | byte[] dataReceived = outputStream.toByteArray();
126 |
127 | Assert.assertArrayEquals(bigBuffer2, dataReceived);
128 | } catch (IOException e) {
129 | e.printStackTrace();
130 | }
131 | }
132 |
133 | // Testing ReadBuffer
134 |
135 | @Test
136 | public void testReadBuffer(){
137 | new Random().nextBytes(bigReadBuffer);
138 | serialBuffer = new SerialBuffer(true);
139 |
140 | ByteBuffer readBuffer = serialBuffer.getReadBuffer();
141 | readBuffer.put(bigReadBuffer);
142 |
143 | byte[] buffered = serialBuffer.getDataReceived();
144 | Assert.assertArrayEquals(bigReadBuffer, buffered);
145 | }
146 |
147 | @Test
148 | public void testReadBufferCompatible(){
149 | new Random().nextBytes(bigReadBuffer);
150 | serialBuffer = new SerialBuffer(false);
151 |
152 | byte[] readBuffer = serialBuffer.getBufferCompatible();
153 | System.arraycopy(bigReadBuffer, 0, readBuffer, 0, bigReadBuffer.length);
154 |
155 | byte[] buffered = serialBuffer.getDataReceivedCompatible(bigReadBuffer.length);
156 | Assert.assertArrayEquals(bigReadBuffer, buffered);
157 | }
158 |
159 |
160 | private class WriterThread extends Thread{
161 |
162 | private SerialBuffer serialBuffer;
163 | private byte[] data;
164 | private Thread callerThread;
165 |
166 | public WriterThread(SerialBuffer serialBuffer, byte[] data){
167 | this.serialBuffer = serialBuffer;
168 | this.data = data;
169 | }
170 |
171 | public WriterThread(SerialBuffer serialBuffer, byte[] data, Thread callerThread){
172 | this.serialBuffer = serialBuffer;
173 | this.data = data;
174 | this.callerThread = callerThread;
175 | }
176 |
177 | @Override
178 | public void run() {
179 | if(callerThread == null) {
180 | serialBuffer.putWriteBuffer(data);
181 | }else{
182 | while(callerThread.getState() != State.WAITING){/*Busy waiting*/ }
183 | serialBuffer.putWriteBuffer(data);
184 | }
185 | }
186 | }
187 |
188 | }
189 |
--------------------------------------------------------------------------------
/usbserial/src/main/java/com/felhr/deviceids/CP210xIds.java:
--------------------------------------------------------------------------------
1 | package com.felhr.deviceids;
2 |
3 | import static com.felhr.deviceids.Helpers.createTable;
4 | import static com.felhr.deviceids.Helpers.createDevice;
5 |
6 | public class CP210xIds
7 | {
8 | /* Different products and vendors of CP210x family
9 | // From current cp210x linux driver:
10 | https://github.com/torvalds/linux/blob/164c09978cebebd8b5fc198e9243777dbaecdfa0/drivers/usb/serial/cp210x.c
11 | */
12 | private static final long[] cp210xDevices = createTable(
13 | createDevice(0x045B, 0x0053),
14 | createDevice(0x0471, 0x066A),
15 | createDevice(0x0489, 0xE000),
16 | createDevice(0x0489, 0xE003),
17 | createDevice(0x0745, 0x1000),
18 | createDevice(0x0846, 0x1100),
19 | createDevice(0x08e6, 0x5501),
20 | createDevice(0x08FD, 0x000A),
21 | createDevice(0x0BED, 0x1100),
22 | createDevice(0x0BED, 0x1101),
23 | createDevice(0x0FCF, 0x1003),
24 | createDevice(0x0FCF, 0x1004),
25 | createDevice(0x0FCF, 0x1006),
26 | createDevice(0x0FDE, 0xCA05),
27 | createDevice(0x10A6, 0xAA26),
28 | createDevice(0x10AB, 0x10C5),
29 | createDevice(0x10B5, 0xAC70),
30 | createDevice(0x10C4, 0x0F91),
31 | createDevice(0x10C4, 0x1101),
32 | createDevice(0x10C4, 0x1601),
33 | createDevice(0x10C4, 0x800A),
34 | createDevice(0x10C4, 0x803B),
35 | createDevice(0x10C4, 0x8044),
36 | createDevice(0x10C4, 0x804E),
37 | createDevice(0x10C4, 0x8053),
38 | createDevice(0x10C4, 0x8054),
39 | createDevice(0x10C4, 0x8066),
40 | createDevice(0x10C4, 0x806F),
41 | createDevice(0x10C4, 0x807A),
42 | createDevice(0x10C4, 0x80C4),
43 | createDevice(0x10C4, 0x80CA),
44 | createDevice(0x10C4, 0x80DD),
45 | createDevice(0x10C4, 0x80F6),
46 | createDevice(0x10C4, 0x8115),
47 | createDevice(0x10C4, 0x813D),
48 | createDevice(0x10C4, 0x813F),
49 | createDevice(0x10C4, 0x814A),
50 | createDevice(0x10C4, 0x814B),
51 | createDevice(0x2405, 0x0003),
52 | createDevice(0x10C4, 0x8156),
53 | createDevice(0x10C4, 0x815E),
54 | createDevice(0x10C4, 0x815F),
55 | createDevice(0x10C4, 0x818B),
56 | createDevice(0x10C4, 0x819F),
57 | createDevice(0x10C4, 0x81A6),
58 | createDevice(0x10C4, 0x81A9),
59 | createDevice(0x10C4, 0x81AC),
60 | createDevice(0x10C4, 0x81AD),
61 | createDevice(0x10C4, 0x81C8),
62 | createDevice(0x10C4, 0x81E2),
63 | createDevice(0x10C4, 0x81E7),
64 | createDevice(0x10C4, 0x81E8),
65 | createDevice(0x10C4, 0x81F2),
66 | createDevice(0x10C4, 0x8218),
67 | createDevice(0x10C4, 0x822B),
68 | createDevice(0x10C4, 0x826B),
69 | createDevice(0x10C4, 0x8281),
70 | createDevice(0x10C4, 0x8293),
71 | createDevice(0x10C4, 0x82F9),
72 | createDevice(0x10C4, 0x8341),
73 | createDevice(0x10C4, 0x8382),
74 | createDevice(0x10C4, 0x83A8),
75 | createDevice(0x10C4, 0x83D8),
76 | createDevice(0x10C4, 0x8411),
77 | createDevice(0x10C4, 0x8418),
78 | createDevice(0x10C4, 0x846E),
79 | createDevice(0x10C4, 0x8477),
80 | createDevice(0x10C4, 0x85EA),
81 | createDevice(0x10C4, 0x85EB),
82 | createDevice(0x10C4, 0x85F8),
83 | createDevice(0x10C4, 0x8664),
84 | createDevice(0x10C4, 0x8665),
85 | createDevice(0x10C4, 0x875C),
86 | createDevice(0x10C4, 0x88A4),
87 | createDevice(0x10C4, 0x88A5),
88 | createDevice(0x10C4, 0xEA60),
89 | createDevice(0x10C4, 0xEA61),
90 | createDevice(0x10C4, 0xEA63),
91 | createDevice(0x10C4, 0xEA70),
92 | createDevice(0x10C4, 0xEA71),
93 | createDevice(0x10C4, 0xEA7A),
94 | createDevice(0x10C4, 0xEA7B),
95 | createDevice(0x10C4, 0xEA80),
96 | createDevice(0x10C4, 0xF001),
97 | createDevice(0x10C4, 0xF002),
98 | createDevice(0x10C4, 0xF003),
99 | createDevice(0x10C4, 0xF004),
100 | createDevice(0x10C5, 0xEA61),
101 | createDevice(0x10CE, 0xEA6A),
102 | createDevice(0x13AD, 0x9999),
103 | createDevice(0x1555, 0x0004),
104 | createDevice(0x166A, 0x0201),
105 | createDevice(0x166A, 0x0301),
106 | createDevice(0x166A, 0x0303),
107 | createDevice(0x166A, 0x0304),
108 | createDevice(0x166A, 0x0305),
109 | createDevice(0x166A, 0x0401),
110 | createDevice(0x166A, 0x0101),
111 | createDevice(0x16D6, 0x0001),
112 | createDevice(0x16DC, 0x0010),
113 | createDevice(0x16DC, 0x0011),
114 | createDevice(0x16DC, 0x0012),
115 | createDevice(0x16DC, 0x0015),
116 | createDevice(0x17A8, 0x0001),
117 | createDevice(0x17A8, 0x0005),
118 | createDevice(0x17F4, 0xAAAA),
119 | createDevice(0x1843, 0x0200),
120 | createDevice(0x18EF, 0xE00F),
121 | createDevice(0x1ADB, 0x0001),
122 | createDevice(0x1BE3, 0x07A6),
123 | createDevice(0x1E29, 0x0102),
124 | createDevice(0x1E29, 0x0501),
125 | createDevice(0x1FB9, 0x0100),
126 | createDevice(0x1FB9, 0x0200),
127 | createDevice(0x1FB9, 0x0201),
128 | createDevice(0x1FB9, 0x0202),
129 | createDevice(0x1FB9, 0x0203),
130 | createDevice(0x1FB9, 0x0300),
131 | createDevice(0x1FB9, 0x0301),
132 | createDevice(0x1FB9, 0x0302),
133 | createDevice(0x1FB9, 0x0303),
134 | createDevice(0x1FB9, 0x0400),
135 | createDevice(0x1FB9, 0x0401),
136 | createDevice(0x1FB9, 0x0402),
137 | createDevice(0x1FB9, 0x0403),
138 | createDevice(0x1FB9, 0x0404),
139 | createDevice(0x1FB9, 0x0600),
140 | createDevice(0x1FB9, 0x0601),
141 | createDevice(0x1FB9, 0x0602),
142 | createDevice(0x1FB9, 0x0700),
143 | createDevice(0x1FB9, 0x0701),
144 | createDevice(0x3195, 0xF190),
145 | createDevice(0x3195, 0xF280),
146 | createDevice(0x3195, 0xF281),
147 | createDevice(0x413C, 0x9500),
148 | createDevice(0x1908, 0x2311) //serial of CMOS camera
149 | );
150 |
151 | public static boolean isDeviceSupported(int vendorId, int productId)
152 | {
153 | return Helpers.exists(cp210xDevices, vendorId, productId);
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/usbserial/src/androidTest/java/com/felhr/tests/utils/ProtocolBufferTest.java:
--------------------------------------------------------------------------------
1 | package com.felhr.tests.utils;
2 |
3 | import com.felhr.utils.ProtocolBuffer;
4 |
5 | import junit.framework.TestCase;
6 |
7 | import org.junit.Assert;
8 | import org.junit.Test;
9 |
10 |
11 | public class ProtocolBufferTest extends TestCase {
12 |
13 | private final String onePacket = "$GPAAM,A,A,0.10,N,WPTNME*32\r\n";
14 | private final String twoPackets = "$GPAAM,A,A,0.10,N,WPTNME*32\r\n$GPGGA,092750.000,5321.6802,N,00630.3372,W,1,8,1.03,61.7,M,55.2,M,,*76\r\n";
15 | private final String splitPacket = "$GPAAM,A,A,0.10,N,WPTN";
16 | private final String oneHalfPacket = "$GPAAM,A,A,0.10,N,WPTNME*32\r\n$GPGGA,092750.000";
17 |
18 | private final String[] verySplit ={"$GPAAM,",
19 | "A",
20 | ",",
21 | "A,",
22 | "0",
23 | ".",
24 | "10,N",
25 | ",WPTNME*32\r\n"};
26 |
27 | private final byte[] rawPacket = new byte[]{0x21, 0x3b, 0x20, 0x40};
28 | private final byte[] twoRawPackets = new byte[]{0x21, 0x3b, 0x20, 0x40, 0x4a, 0x20, 0x40};
29 | private final byte[] splitRawPacket = new byte[]{0x21, 0x3b, 0x20, 0x40, 0x4a};
30 |
31 | private final byte[][] verySplitRawPacket = {
32 | new byte[]{0x21},
33 | new byte[]{0x3b},
34 | new byte[]{0x20},
35 | new byte[]{0x40}};
36 |
37 | private ProtocolBuffer protocolBuffer;
38 | private final String modeText = ProtocolBuffer.TEXT;
39 | private final String modeBinary = ProtocolBuffer.BINARY;
40 |
41 | @Test
42 | public void testOnePacket(){
43 | protocolBuffer = new ProtocolBuffer(modeText);
44 | protocolBuffer.setDelimiter("\r\n");
45 | protocolBuffer.appendData(onePacket.getBytes());
46 |
47 | boolean hasMoreData = protocolBuffer.hasMoreCommands();
48 | assertTrue(hasMoreData);
49 | String nextCommand = protocolBuffer.nextTextCommand();
50 | assertEquals(onePacket, nextCommand);
51 | }
52 |
53 | @Test
54 | public void testTwoPackets(){
55 | protocolBuffer = new ProtocolBuffer(modeText);
56 | protocolBuffer.setDelimiter("\r\n");
57 | protocolBuffer.appendData(twoPackets.getBytes());
58 |
59 | StringBuilder builder = new StringBuilder();
60 |
61 | while(protocolBuffer.hasMoreCommands()){
62 | builder.append(protocolBuffer.nextTextCommand());
63 | }
64 | assertEquals(twoPackets, builder.toString());
65 | }
66 |
67 | @Test
68 | public void testSplitPackets(){
69 | protocolBuffer = new ProtocolBuffer(modeText);
70 | protocolBuffer.setDelimiter("\r\n");
71 | protocolBuffer.appendData(splitPacket.getBytes());
72 |
73 | boolean hasMoreData = protocolBuffer.hasMoreCommands();
74 | assertFalse(hasMoreData);
75 | }
76 |
77 | @Test
78 | public void testOneHalfPacket(){
79 | protocolBuffer = new ProtocolBuffer(modeText);
80 | protocolBuffer.setDelimiter("\r\n");
81 | protocolBuffer.appendData(oneHalfPacket.getBytes());
82 |
83 | boolean hasMoreData = protocolBuffer.hasMoreCommands();
84 | assertTrue(hasMoreData);
85 | String nextCommand = protocolBuffer.nextTextCommand();
86 | assertEquals("$GPAAM,A,A,0.10,N,WPTNME*32\r\n", nextCommand);
87 |
88 | hasMoreData = protocolBuffer.hasMoreCommands();
89 | assertFalse(hasMoreData);
90 |
91 | nextCommand = protocolBuffer.nextTextCommand();
92 | assertNull(nextCommand);
93 | }
94 |
95 | @Test
96 | public void testVerySplit(){
97 | protocolBuffer = new ProtocolBuffer(modeText);
98 | protocolBuffer.setDelimiter("\r\n");
99 |
100 | protocolBuffer.appendData(verySplit[0].getBytes());
101 | boolean hasMoreData = protocolBuffer.hasMoreCommands();
102 | assertFalse(hasMoreData);
103 |
104 | protocolBuffer.appendData(verySplit[1].getBytes());
105 | hasMoreData = protocolBuffer.hasMoreCommands();
106 | assertFalse(hasMoreData);
107 |
108 | protocolBuffer.appendData(verySplit[2].getBytes());
109 | hasMoreData = protocolBuffer.hasMoreCommands();
110 | assertFalse(hasMoreData);
111 |
112 | protocolBuffer.appendData(verySplit[3].getBytes());
113 | hasMoreData = protocolBuffer.hasMoreCommands();
114 | assertFalse(hasMoreData);
115 |
116 | protocolBuffer.appendData(verySplit[4].getBytes());
117 | hasMoreData = protocolBuffer.hasMoreCommands();
118 | assertFalse(hasMoreData);
119 |
120 | protocolBuffer.appendData(verySplit[5].getBytes());
121 | hasMoreData = protocolBuffer.hasMoreCommands();
122 | assertFalse(hasMoreData);
123 |
124 | protocolBuffer.appendData(verySplit[6].getBytes());
125 | hasMoreData = protocolBuffer.hasMoreCommands();
126 | assertFalse(hasMoreData);
127 |
128 | protocolBuffer.appendData(verySplit[7].getBytes());
129 | hasMoreData = protocolBuffer.hasMoreCommands();
130 | assertTrue(hasMoreData);
131 |
132 | String command = protocolBuffer.nextTextCommand();
133 | assertEquals("$GPAAM,A,A,0.10,N,WPTNME*32\r\n", command);
134 | }
135 |
136 | @Test
137 | public void testRawPacket(){
138 | protocolBuffer = new ProtocolBuffer(modeBinary);
139 | protocolBuffer.setDelimiter(new byte[]{0x20, 0x40});
140 | protocolBuffer.appendData(rawPacket);
141 |
142 | boolean hasMoreData = protocolBuffer.hasMoreCommands();
143 | assertTrue(hasMoreData);
144 |
145 | byte[] command = protocolBuffer.nextBinaryCommand();
146 | Assert.assertArrayEquals(command, rawPacket);
147 |
148 | command = protocolBuffer.nextBinaryCommand();
149 | assertNull(command);
150 | }
151 |
152 | @Test
153 | public void testTwoRawPackets(){
154 | protocolBuffer = new ProtocolBuffer(modeBinary);
155 | protocolBuffer.setDelimiter(new byte[]{0x20, 0x40});
156 | protocolBuffer.appendData(twoRawPackets);
157 |
158 | boolean hasMoreData = protocolBuffer.hasMoreCommands();
159 | assertTrue(hasMoreData);
160 |
161 | byte[] command1 = protocolBuffer.nextBinaryCommand();
162 | Assert.assertArrayEquals(command1, new byte[]{0x21, 0x3b, 0x20, 0x40});
163 |
164 | hasMoreData = protocolBuffer.hasMoreCommands();
165 | assertTrue(hasMoreData);
166 |
167 | byte[] command2 = protocolBuffer.nextBinaryCommand();
168 | Assert.assertArrayEquals(command2, new byte[]{0x4a, 0x20, 0x40});
169 |
170 | command2 = protocolBuffer.nextBinaryCommand();
171 | assertNull(command2);
172 | }
173 |
174 | @Test
175 | public void testSplitRawPacket(){
176 | protocolBuffer = new ProtocolBuffer(modeBinary);
177 | protocolBuffer.setDelimiter(new byte[]{0x20, 0x40});
178 | protocolBuffer.appendData(splitRawPacket);
179 |
180 | boolean hasMoreData = protocolBuffer.hasMoreCommands();
181 | assertTrue(hasMoreData);
182 |
183 | byte[] command1 = protocolBuffer.nextBinaryCommand();
184 | Assert.assertArrayEquals(command1, new byte[]{0x21, 0x3b, 0x20, 0x40});
185 |
186 | hasMoreData = protocolBuffer.hasMoreCommands();
187 | assertFalse(hasMoreData);
188 | }
189 |
190 | @Test
191 | public void testVerySplitRawPacket(){
192 | protocolBuffer = new ProtocolBuffer(modeBinary);
193 | protocolBuffer.setDelimiter(new byte[]{0x20, 0x40});
194 |
195 | protocolBuffer.appendData(verySplitRawPacket[0]);
196 | boolean hasMoreData = protocolBuffer.hasMoreCommands();
197 | assertFalse(hasMoreData);
198 |
199 | protocolBuffer.appendData(verySplitRawPacket[1]);
200 | hasMoreData = protocolBuffer.hasMoreCommands();
201 | assertFalse(hasMoreData);
202 |
203 | protocolBuffer.appendData(verySplitRawPacket[2]);
204 | hasMoreData = protocolBuffer.hasMoreCommands();
205 | assertFalse(hasMoreData);
206 |
207 | protocolBuffer.appendData(verySplitRawPacket[3]);
208 | hasMoreData = protocolBuffer.hasMoreCommands();
209 | assertTrue(hasMoreData);
210 |
211 | byte[] command = protocolBuffer.nextBinaryCommand();
212 | Assert.assertArrayEquals(command, new byte[]{0x21, 0x3b, 0x20, 0x40});
213 | }
214 | }
215 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | UsbSerial [](https://travis-ci.org/felHR85/UsbSerial) [](https://jitpack.io/#felHR85/UsbSerial) [](https://android-arsenal.com/details/1/4162) [](https://gitter.im/UsbSerial/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
2 | =========
3 |
4 | UsbSerial wiki available. Read it first
5 | --------------------------------------
6 | [**Getting started**](https://github.com/felHR85/UsbSerial/wiki/2.-Getting-Started)\
7 | [**Create UsbSerialDevice objects**](https://github.com/felHR85/UsbSerial/wiki/3.-Create-UsbSerialDevice)\
8 | [**Asynchronous api**](https://github.com/felHR85/UsbSerial/wiki/4.-Asynchronous-api)\
9 | [**Synchronous api**](https://github.com/felHR85/UsbSerial/wiki/5.-Synchronous-api)\
10 | [**InputStream and OutputStream I/O**](https://github.com/felHR85/UsbSerial/wiki/6.-InputStream-and-OutputStream-I-O)\
11 | [**Multiple Serial ports**](https://github.com/felHR85/UsbSerial/wiki/7.-Multiple-Serial-ports)\
12 | [**Projects using UsbSerial**](https://github.com/felHR85/UsbSerial/wiki/8.-Projects-using-UsbSerial)\
13 | [**Debugging over Wifi**](https://github.com/felHR85/UsbSerial/wiki/9.-Debugging-over-Wifi)\
14 | [**UsbSerial video tutorials**](https://github.com/felHR85/UsbSerial/wiki/10.-UsbSerial-video-tutorials)
15 |
16 | [I am looking for collaborators to keep this project updated](https://github.com/felHR85/UsbSerial/issues/313)
17 | --------------------------------------
18 |
19 | Support UsbSerial
20 | --------------------------------------
21 | [If UsbSerial helped you with your projects please consider donating a little sum](https://www.paypal.me/felhr)\
22 | [Or consider buying DroidTerm Pro: A Usb serial port terminal using UsbSerial](https://play.google.com/store/apps/details?id=com.felhr.droidtermpro)
23 |
24 | Devices Supported
25 | --------------------------------------
26 | [CP210X devices](http://www.silabs.com/products/mcu/pages/usbtouartbridgevcpdrivers.aspx) Default: 9600,8,1,None,flow off
27 |
28 | [CDC devices](https://en.wikipedia.org/wiki/USB_communications_device_class) Default 115200,8,1,None,flow off
29 |
30 | [FTDI devices](http://www.ftdichip.com/FTProducts.htm) Default: 9600,8,1,None,flow off
31 |
32 | [PL2303 devices](http://www.prolific.com.tw/US/ShowProduct.aspx?p_id=225&pcid=41) Default 9600,8,1,None,flow off
33 |
34 | [CH34x devices](https://www.olimex.com/Products/Breadboarding/BB-CH340T/resources/CH340DS1.PDF) Default 9600,8,1,None,flow off
35 |
36 | [CP2130 SPI-USB](http://www.silabs.com/products/interface/usb-bridges/classic-usb-bridges/Pages/usb-to-spi-bridge.aspx)
37 |
38 | Known Issue
39 | --------------------------------------
40 | Due to a bug in Android itself, it's highly recommended to **not** use it with a device running [Android 5.1.1 Lollipop](https://en.wikipedia.org/wiki/Android_version_history#Android_5.1_Lollipop_(API_22)). See issue [#142](https://github.com/felHR85/UsbSerial/issues/142) for more details.
41 |
42 | How to use it?
43 | --------------------------------------
44 | Instantiate a new object of the UsbSerialDevice class
45 | ```java
46 | UsbDevice device;
47 | UsbDeviceConnection usbConnection;
48 | ...
49 | UsbSerialDevice serial = UsbSerialDevice.createUsbSerialDevice(device, usbConnection);
50 | ```
51 |
52 | Open the device and set it up as desired
53 | ```java
54 | serial.open();
55 | serial.setBaudRate(115200);
56 | serial.setDataBits(UsbSerialInterface.DATA_BITS_8);
57 | serial.setParity(UsbSerialInterface.PARITY_ODD);
58 | serial.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
59 | ```
60 |
61 | If flow control is needed (currently only supported in CP201x and FTDI devices)
62 | ```java
63 | /**
64 | Values:
65 | UsbSerialInterface.FLOW_CONTROL_OFF
66 | UsbSerialInterface.FLOW_CONTROL_RTS_CTS
67 | UsbSerialInterface.FLOW_CONTROL_DSR_DTR
68 | **/
69 | serial.setFlowControl(UsbSerialInterface.FLOW_CONTROL_RTS_CTS);
70 | ```
71 |
72 | There is no need to be polling if you want to perform a bulk transaction to a IN endpoint. Define a simply callback
73 | ```java
74 | private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
75 |
76 | @Override
77 | public void onReceivedData(byte[] arg0)
78 | {
79 | // Code here :)
80 | }
81 |
82 | };
83 | ```
84 |
85 | And pass a reference of it
86 | ```java
87 | serial.read(mCallback);
88 | ```
89 |
90 | Changes in the CTS and DSR lines will be received in the same manner. Define a callback and pass a reference of it.
91 | ```java
92 | private UsbSerialInterface.UsbCTSCallback ctsCallback = new UsbSerialInterface.UsbCTSCallback() {
93 | @Override
94 | public void onCTSChanged(boolean state) {
95 | // Code here :)
96 | }
97 | };
98 |
99 | private UsbSerialInterface.UsbDSRCallback dsrCallback = new UsbSerialInterface.UsbDSRCallback() {
100 | @Override
101 | public void onDSRChanged(boolean state) {
102 | // Code here :)
103 | }
104 | };
105 |
106 | serial.getCTS(ctsCallback);
107 | //serial.getDSR(dsrCallback);
108 | ```
109 |
110 |
111 |
112 | Write something
113 | ```java
114 | serial.write("DATA".getBytes()); // Async-like operation now! :)
115 | ```
116 |
117 | Raise the state of the RTS or DTR lines
118 | ```java
119 | serial.setRTS(true); // Raised
120 | serial.setRTS(false); // Not Raised
121 | serial.setDTR(true); // Raised
122 | serial.setDTR(false); // Not Raised
123 | ```
124 |
125 | Close the device:
126 | ```java
127 | serial.close();
128 | ```
129 |
130 | I recommend using UsbSerial as shown above but if you want to perform write and read operations in synchronous way it is possible using these methods:
131 | ```java
132 | public boolean syncOpen();
133 | public int syncWrite(byte[] buffer, int timeout)
134 | public int syncRead(byte[] buffer, int timeout)
135 | public void syncClose();
136 | ```
137 |
138 |
139 | In Android usb api, when a usb device has been close it must be reopened
140 | ```java
141 | UsbDevice device;
142 | ...
143 | UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
144 | manager.openDevice(UsbDevice device)
145 | ```
146 | How to use the SPI interface (BETA)
147 | --------------------------------------
148 | Support for USB to SPI devices was added recently but it is still in beta. Although I tried to keep the api as close to standard UsbSerial api as possible, be aware because the beta nature of this feature this api may change in the future. Only CP2130 chipset is supported at the moment.
149 |
150 | ```java
151 | UsbSpiDevice spi = UsbSpiDevice.createUsbSerialDevice(device, connection);
152 | spi.connectSPI();
153 | spi.selectSlave(0);
154 | spi.setClock(CP2130SpiDevice.CLOCK_3MHz);
155 | ```
156 | Define the usual callback
157 |
158 | ```java
159 | private UsbSpiInterface.UsbMISOCallback misoCallback = new UsbSpiInterface.UsbMISOCallback()
160 | {
161 | @Override
162 | public int onReceivedData(byte[] data) {
163 | // Your code here :)
164 | }
165 | };
166 | //...
167 | spi.setMISOCallback(misoCallback);
168 | ```
169 |
170 | ```java
171 | spi.writeMOSI("Hola!".getBytes()); // Write "Hola!" to the selected slave through MOSI (MASTER OUTPUT SLAVE INPUT)
172 | spi.readMISO(5); // Read 5 bytes from the MISO (MASTER INPUT SLAVE OUTPUT) line. Data will be received through UsbMISOCallback
173 | spi.writeRead("Hola!".getBytes(), 15); // Write "Hola!" and read 15 bytes synchronously
174 | ```
175 |
176 | Close the device when done
177 |
178 | ```java
179 | spi.closeSPI();
180 | ```
181 |
182 | Gradle
183 | --------------------------------------
184 | Add the jitpack repo to your your project's build.gradle at the end of repositories
185 |
186 | /build.gradle
187 | ```groovy
188 | allprojects {
189 | repositories {
190 | jcenter()
191 | maven { url "https://jitpack.io" }
192 | }
193 | }
194 | ```
195 |
196 | Then add the dependency to your module's build.gradle:
197 |
198 | /app/build.gradle
199 | ```groovy
200 | implementation 'com.github.felHR85:UsbSerial:6.1.0'
201 | ```
202 |
203 | TO-DO
204 | --------------------------------------
205 | - RTS/CTS and DSR/DTR implementations for PL2303 and CDC
206 |
207 |
208 |
209 |
210 |
211 |
212 |
--------------------------------------------------------------------------------
/examplestreams/src/main/java/com/felhr/examplestreams/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.felhr.examplestreams;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.ComponentName;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.IntentFilter;
8 | import android.content.ServiceConnection;
9 | import android.os.Handler;
10 | import android.os.IBinder;
11 | import android.os.Message;
12 | import android.support.v7.app.AppCompatActivity;
13 | import android.os.Bundle;
14 | import android.view.View;
15 | import android.widget.Button;
16 | import android.widget.CheckBox;
17 | import android.widget.CompoundButton;
18 | import android.widget.EditText;
19 | import android.widget.TextView;
20 | import android.widget.Toast;
21 |
22 | import java.lang.ref.WeakReference;
23 | import java.util.Set;
24 |
25 | public class MainActivity extends AppCompatActivity {
26 |
27 | /*
28 | * Notifications from UsbService will be received here.
29 | */
30 | private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
31 | @Override
32 | public void onReceive(Context context, Intent intent) {
33 | switch (intent.getAction()) {
34 | case UsbService.ACTION_USB_PERMISSION_GRANTED: // USB PERMISSION GRANTED
35 | Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show();
36 | break;
37 | case UsbService.ACTION_USB_PERMISSION_NOT_GRANTED: // USB PERMISSION NOT GRANTED
38 | Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show();
39 | break;
40 | case UsbService.ACTION_NO_USB: // NO USB CONNECTED
41 | Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show();
42 | break;
43 | case UsbService.ACTION_USB_DISCONNECTED: // USB DISCONNECTED
44 | Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show();
45 | break;
46 | case UsbService.ACTION_USB_NOT_SUPPORTED: // USB NOT SUPPORTED
47 | Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show();
48 | break;
49 | }
50 | }
51 | };
52 | private UsbService usbService;
53 | private TextView display;
54 | private EditText editText;
55 | private CheckBox box9600, box38400;
56 | private MyHandler mHandler;
57 | private final ServiceConnection usbConnection = new ServiceConnection() {
58 | @Override
59 | public void onServiceConnected(ComponentName arg0, IBinder arg1) {
60 | usbService = ((UsbService.UsbBinder) arg1).getService();
61 | usbService.setHandler(mHandler);
62 | }
63 |
64 | @Override
65 | public void onServiceDisconnected(ComponentName arg0) {
66 | usbService = null;
67 | }
68 | };
69 |
70 | @Override
71 | protected void onCreate(Bundle savedInstanceState) {
72 | super.onCreate(savedInstanceState);
73 | setContentView(R.layout.activity_main);
74 |
75 | mHandler = new MyHandler(this);
76 |
77 | display = (TextView) findViewById(R.id.textView1);
78 | editText = (EditText) findViewById(R.id.editText1);
79 | Button sendButton = (Button) findViewById(R.id.buttonSend);
80 | sendButton.setOnClickListener(new View.OnClickListener() {
81 | @Override
82 | public void onClick(View v) {
83 | if (!editText.getText().toString().equals("")) {
84 | String data = editText.getText().toString();
85 | if (usbService != null) { // if UsbService was correctly binded, Send data
86 | usbService.write(data.getBytes());
87 | }
88 | }
89 | }
90 | });
91 |
92 | box9600 = (CheckBox) findViewById(R.id.checkBox);
93 | box9600.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
94 | @Override
95 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
96 | if(box9600.isChecked())
97 | box38400.setChecked(false);
98 | else
99 | box38400.setChecked(true);
100 | }
101 | });
102 |
103 | box38400 = (CheckBox) findViewById(R.id.checkBox2);
104 | box38400.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
105 | @Override
106 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
107 | if(box38400.isChecked())
108 | box9600.setChecked(false);
109 | else
110 | box9600.setChecked(true);
111 | }
112 | });
113 |
114 | Button baudrateButton = (Button) findViewById(R.id.buttonBaudrate);
115 | baudrateButton.setOnClickListener(new View.OnClickListener() {
116 | @Override
117 | public void onClick(View v) {
118 | if(box9600.isChecked())
119 | usbService.changeBaudRate(9600);
120 | else
121 | usbService.changeBaudRate(38400);
122 | }
123 | });
124 | }
125 |
126 | @Override
127 | public void onResume() {
128 | super.onResume();
129 | setFilters(); // Start listening notifications from UsbService
130 | startService(UsbService.class, usbConnection, null); // Start UsbService(if it was not started before) and Bind it
131 | }
132 |
133 | @Override
134 | public void onPause() {
135 | super.onPause();
136 | unregisterReceiver(mUsbReceiver);
137 | unbindService(usbConnection);
138 | }
139 |
140 | private void startService(Class> service, ServiceConnection serviceConnection, Bundle extras) {
141 | if (!UsbService.SERVICE_CONNECTED) {
142 | Intent startService = new Intent(this, service);
143 | if (extras != null && !extras.isEmpty()) {
144 | Set keys = extras.keySet();
145 | for (String key : keys) {
146 | String extra = extras.getString(key);
147 | startService.putExtra(key, extra);
148 | }
149 | }
150 | startService(startService);
151 | }
152 | Intent bindingIntent = new Intent(this, service);
153 | bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE);
154 | }
155 |
156 | private void setFilters() {
157 | IntentFilter filter = new IntentFilter();
158 | filter.addAction(UsbService.ACTION_USB_PERMISSION_GRANTED);
159 | filter.addAction(UsbService.ACTION_NO_USB);
160 | filter.addAction(UsbService.ACTION_USB_DISCONNECTED);
161 | filter.addAction(UsbService.ACTION_USB_NOT_SUPPORTED);
162 | filter.addAction(UsbService.ACTION_USB_PERMISSION_NOT_GRANTED);
163 | registerReceiver(mUsbReceiver, filter);
164 | }
165 |
166 | /*
167 | * This handler will be passed to UsbService. Data received from serial port is displayed through this handler
168 | */
169 | private static class MyHandler extends Handler {
170 | private final WeakReference mActivity;
171 |
172 | public MyHandler(MainActivity activity) {
173 | mActivity = new WeakReference<>(activity);
174 | }
175 |
176 | @Override
177 | public void handleMessage(Message msg) {
178 | switch (msg.what) {
179 | case UsbService.MESSAGE_FROM_SERIAL_PORT:
180 | String data = (String) msg.obj;
181 | mActivity.get().display.append(data);
182 | break;
183 | case UsbService.CTS_CHANGE:
184 | Toast.makeText(mActivity.get(), "CTS_CHANGE",Toast.LENGTH_LONG).show();
185 | break;
186 | case UsbService.DSR_CHANGE:
187 | Toast.makeText(mActivity.get(), "DSR_CHANGE",Toast.LENGTH_LONG).show();
188 | break;
189 | case UsbService.SYNC_READ:
190 | String buffer = (String) msg.obj;
191 | mActivity.get().display.append(buffer);
192 | break;
193 | }
194 | }
195 | }
196 | }
--------------------------------------------------------------------------------
/examplesync/src/main/java/com/felhr/serialportexamplesync/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.felhr.serialportexamplesync;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.ComponentName;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.IntentFilter;
8 | import android.content.ServiceConnection;
9 | import android.os.Bundle;
10 | import android.os.Handler;
11 | import android.os.IBinder;
12 | import android.os.Message;
13 | import android.support.v7.app.AppCompatActivity;
14 | import android.view.View;
15 | import android.widget.Button;
16 | import android.widget.CheckBox;
17 | import android.widget.CompoundButton;
18 | import android.widget.EditText;
19 | import android.widget.TextView;
20 | import android.widget.Toast;
21 |
22 | import java.lang.ref.WeakReference;
23 | import java.util.Set;
24 |
25 | public class MainActivity extends AppCompatActivity {
26 |
27 | /*
28 | * Notifications from UsbService will be received here.
29 | */
30 | private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
31 | @Override
32 | public void onReceive(Context context, Intent intent) {
33 | switch (intent.getAction()) {
34 | case UsbService.ACTION_USB_PERMISSION_GRANTED: // USB PERMISSION GRANTED
35 | Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show();
36 | break;
37 | case UsbService.ACTION_USB_PERMISSION_NOT_GRANTED: // USB PERMISSION NOT GRANTED
38 | Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show();
39 | break;
40 | case UsbService.ACTION_NO_USB: // NO USB CONNECTED
41 | Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show();
42 | break;
43 | case UsbService.ACTION_USB_DISCONNECTED: // USB DISCONNECTED
44 | Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show();
45 | break;
46 | case UsbService.ACTION_USB_NOT_SUPPORTED: // USB NOT SUPPORTED
47 | Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show();
48 | break;
49 | }
50 | }
51 | };
52 | private UsbService usbService;
53 | private TextView display;
54 | private EditText editText;
55 | private CheckBox box9600, box38400;
56 | private MyHandler mHandler;
57 | private final ServiceConnection usbConnection = new ServiceConnection() {
58 | @Override
59 | public void onServiceConnected(ComponentName arg0, IBinder arg1) {
60 | usbService = ((UsbService.UsbBinder) arg1).getService();
61 | usbService.setHandler(mHandler);
62 | }
63 |
64 | @Override
65 | public void onServiceDisconnected(ComponentName arg0) {
66 | usbService = null;
67 | }
68 | };
69 |
70 | @Override
71 | protected void onCreate(Bundle savedInstanceState) {
72 | super.onCreate(savedInstanceState);
73 | setContentView(R.layout.activity_main);
74 |
75 | mHandler = new MyHandler(this);
76 |
77 | display = (TextView) findViewById(R.id.textView1);
78 | editText = (EditText) findViewById(R.id.editText1);
79 | Button sendButton = (Button) findViewById(R.id.buttonSend);
80 | sendButton.setOnClickListener(new View.OnClickListener() {
81 | @Override
82 | public void onClick(View v) {
83 | if (!editText.getText().toString().equals("")) {
84 | String data = editText.getText().toString();
85 | if (usbService != null) { // if UsbService was correctly binded, Send data
86 | usbService.write(data.getBytes());
87 | }
88 | }
89 | }
90 | });
91 |
92 | box9600 = (CheckBox) findViewById(R.id.checkBox);
93 | box9600.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
94 | @Override
95 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
96 | if(box9600.isChecked())
97 | box38400.setChecked(false);
98 | else
99 | box38400.setChecked(true);
100 | }
101 | });
102 |
103 | box38400 = (CheckBox) findViewById(R.id.checkBox2);
104 | box38400.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
105 | @Override
106 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
107 | if(box38400.isChecked())
108 | box9600.setChecked(false);
109 | else
110 | box9600.setChecked(true);
111 | }
112 | });
113 |
114 | Button baudrateButton = (Button) findViewById(R.id.buttonBaudrate);
115 | baudrateButton.setOnClickListener(new View.OnClickListener() {
116 | @Override
117 | public void onClick(View v) {
118 | if(box9600.isChecked())
119 | usbService.changeBaudRate(9600);
120 | else
121 | usbService.changeBaudRate(38400);
122 | }
123 | });
124 | }
125 |
126 | @Override
127 | public void onResume() {
128 | super.onResume();
129 | setFilters(); // Start listening notifications from UsbService
130 | startService(UsbService.class, usbConnection, null); // Start UsbService(if it was not started before) and Bind it
131 | }
132 |
133 | @Override
134 | public void onPause() {
135 | super.onPause();
136 | unregisterReceiver(mUsbReceiver);
137 | unbindService(usbConnection);
138 | }
139 |
140 | private void startService(Class> service, ServiceConnection serviceConnection, Bundle extras) {
141 | if (!UsbService.SERVICE_CONNECTED) {
142 | Intent startService = new Intent(this, service);
143 | if (extras != null && !extras.isEmpty()) {
144 | Set keys = extras.keySet();
145 | for (String key : keys) {
146 | String extra = extras.getString(key);
147 | startService.putExtra(key, extra);
148 | }
149 | }
150 | startService(startService);
151 | }
152 | Intent bindingIntent = new Intent(this, service);
153 | bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE);
154 | }
155 |
156 | private void setFilters() {
157 | IntentFilter filter = new IntentFilter();
158 | filter.addAction(UsbService.ACTION_USB_PERMISSION_GRANTED);
159 | filter.addAction(UsbService.ACTION_NO_USB);
160 | filter.addAction(UsbService.ACTION_USB_DISCONNECTED);
161 | filter.addAction(UsbService.ACTION_USB_NOT_SUPPORTED);
162 | filter.addAction(UsbService.ACTION_USB_PERMISSION_NOT_GRANTED);
163 | registerReceiver(mUsbReceiver, filter);
164 | }
165 |
166 | /*
167 | * This handler will be passed to UsbService. Data received from serial port is displayed through this handler
168 | */
169 | private static class MyHandler extends Handler {
170 | private final WeakReference mActivity;
171 |
172 | public MyHandler(MainActivity activity) {
173 | mActivity = new WeakReference<>(activity);
174 | }
175 |
176 | @Override
177 | public void handleMessage(Message msg) {
178 | switch (msg.what) {
179 | case UsbService.MESSAGE_FROM_SERIAL_PORT:
180 | String data = (String) msg.obj;
181 | mActivity.get().display.append(data);
182 | break;
183 | case UsbService.CTS_CHANGE:
184 | Toast.makeText(mActivity.get(), "CTS_CHANGE",Toast.LENGTH_LONG).show();
185 | break;
186 | case UsbService.DSR_CHANGE:
187 | Toast.makeText(mActivity.get(), "DSR_CHANGE",Toast.LENGTH_LONG).show();
188 | break;
189 | case UsbService.SYNC_READ:
190 | String buffer = (String) msg.obj;
191 | mActivity.get().display.append(buffer);
192 | break;
193 | }
194 | }
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/integrationapp/src/main/java/com/felhr/integrationapp/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.felhr.integrationapp;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.ComponentName;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.content.IntentFilter;
8 | import android.content.ServiceConnection;
9 | import android.os.Bundle;
10 | import android.os.Handler;
11 | import android.os.IBinder;
12 | import android.os.Message;
13 | import android.support.v7.app.AppCompatActivity;
14 | import android.widget.TextView;
15 | import android.widget.Toast;
16 |
17 | import java.lang.ref.WeakReference;
18 | import java.util.Set;
19 |
20 | import static com.felhr.integrationapp.UsbService.MESSAGE_TEST_1;
21 | import static com.felhr.integrationapp.UsbService.MESSAGE_TEST_2;
22 | import static com.felhr.integrationapp.UsbService.MESSAGE_TEST_3;
23 | import static com.felhr.integrationapp.UsbService.MESSAGE_TEST_4;
24 | import static com.felhr.integrationapp.UsbService.MESSAGE_TEST_5;
25 |
26 | public class MainActivity extends AppCompatActivity {
27 |
28 | private static final int MODE = 0; // 0: Async, 1: Sync, 2: Streams
29 |
30 | /*
31 | * Notifications from UsbService will be received here.
32 | */
33 | private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
34 | @Override
35 | public void onReceive(Context context, Intent intent) {
36 | switch (intent.getAction()) {
37 | case UsbService.ACTION_USB_PERMISSION_GRANTED: // USB PERMISSION GRANTED
38 | Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show();
39 | statusText.setText("USB connected. Run Python tests");
40 | break;
41 | case UsbService.ACTION_USB_PERMISSION_NOT_GRANTED: // USB PERMISSION NOT GRANTED
42 | Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show();
43 | resetTestTextViews();
44 | statusText.setText("Connect USB Device");
45 | break;
46 | case UsbService.ACTION_NO_USB: // NO USB CONNECTED
47 | Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show();
48 | resetTestTextViews();
49 | statusText.setText("Connect USB Device");
50 | break;
51 | case UsbService.ACTION_USB_DISCONNECTED: // USB DISCONNECTED
52 | Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show();
53 | resetTestTextViews();
54 | statusText.setText("Connect USB Device");
55 | break;
56 | case UsbService.ACTION_USB_NOT_SUPPORTED: // USB NOT SUPPORTED
57 | Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show();
58 | resetTestTextViews();
59 | statusText.setText("Connect USB Device");
60 | break;
61 | }
62 | }
63 | };
64 | private UsbService usbService;
65 | private UsbSyncService usbSyncService;
66 | private TextView test1, test2, test3, test4, test5;
67 | private TextView statusText;
68 | private MyHandler mHandler;
69 |
70 | private final ServiceConnection usbConnection = new ServiceConnection() {
71 | @Override
72 | public void onServiceConnected(ComponentName arg0, IBinder arg1) {
73 | usbService = ((UsbService.UsbBinder) arg1).getService();
74 | usbService.setHandler(mHandler);
75 | }
76 |
77 | @Override
78 | public void onServiceDisconnected(ComponentName arg0) {
79 | usbService = null;
80 | }
81 | };
82 |
83 | private final ServiceConnection usbSyncConnection = new ServiceConnection() {
84 | @Override
85 | public void onServiceConnected(ComponentName arg0, IBinder arg1) {
86 | usbSyncService = ((UsbSyncService.UsbBinder) arg1).getService();
87 | usbSyncService.setHandler(mHandler);
88 | }
89 |
90 | @Override
91 | public void onServiceDisconnected(ComponentName arg0) {
92 | usbSyncService = null;
93 | }
94 | };
95 |
96 | @Override
97 | protected void onCreate(Bundle savedInstanceState) {
98 | super.onCreate(savedInstanceState);
99 | setContentView(R.layout.activity_main);
100 | test1 = findViewById(R.id.test_1_result);
101 | test2 = findViewById(R.id.test_2_result);
102 | test3 = findViewById(R.id.test_3_result);
103 | test4 = findViewById(R.id.test_4_result);
104 | test5 = findViewById(R.id.test_5_result);
105 | statusText = findViewById(R.id.status);
106 | mHandler = new MyHandler(this);
107 | }
108 |
109 | @Override
110 | public void onResume() {
111 | super.onResume();
112 | setFilters(); // Start listening notifications from UsbService
113 | Toast.makeText(this, "Mode: " + String.valueOf(MODE), Toast.LENGTH_LONG).show();
114 | if (MODE == 0) {
115 | startService(UsbService.class, usbConnection, null); // Start UsbService(if it was not started before) and Bind it
116 | }else if (MODE == 1) {
117 | startService(UsbSyncService.class, usbSyncConnection, null);
118 | }
119 | }
120 |
121 | @Override
122 | public void onPause() {
123 | super.onPause();
124 | unregisterReceiver(mUsbReceiver);
125 | if(MODE == 0) {
126 | unbindService(usbConnection);
127 | }else{
128 | unbindService(usbSyncConnection);
129 | }
130 | }
131 |
132 | private void startService(Class> service, ServiceConnection serviceConnection, Bundle extras) {
133 | if (!UsbService.SERVICE_CONNECTED) {
134 | Intent startService = new Intent(this, service);
135 | if (extras != null && !extras.isEmpty()) {
136 | Set keys = extras.keySet();
137 | for (String key : keys) {
138 | String extra = extras.getString(key);
139 | startService.putExtra(key, extra);
140 | }
141 | }
142 | startService(startService);
143 | }
144 | Intent bindingIntent = new Intent(this, service);
145 | bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE);
146 | }
147 |
148 | private void setFilters() {
149 | IntentFilter filter = new IntentFilter();
150 | filter.addAction(UsbService.ACTION_USB_PERMISSION_GRANTED);
151 | filter.addAction(UsbService.ACTION_NO_USB);
152 | filter.addAction(UsbService.ACTION_USB_DISCONNECTED);
153 | filter.addAction(UsbService.ACTION_USB_NOT_SUPPORTED);
154 | filter.addAction(UsbService.ACTION_USB_PERMISSION_NOT_GRANTED);
155 | registerReceiver(mUsbReceiver, filter);
156 | }
157 |
158 | private void resetTestTextViews(){
159 | test1.setText("TEST1: Not Passed");
160 | test2.setText("TEST2: Not Passed");
161 | test3.setText("TEST3: Not Passed");
162 | test4.setText("TEST4: Not Passed");
163 | test5.setText("TEST5: Not Passed");
164 | }
165 |
166 | /*
167 | * This handler will be passed to UsbService. Data received from serial port is displayed through this handler
168 | */
169 | private static class MyHandler extends Handler {
170 | private final WeakReference mActivity;
171 |
172 | public MyHandler(MainActivity activity) {
173 | mActivity = new WeakReference<>(activity);
174 | }
175 |
176 | @Override
177 | public void handleMessage(Message msg) {
178 | String data = (String) msg.obj;
179 | switch (msg.what) {
180 | case MESSAGE_TEST_1:
181 | mActivity.get().test1.setText(data);
182 | break;
183 |
184 | case MESSAGE_TEST_2:
185 | mActivity.get().test2.setText(data);
186 | break;
187 |
188 | case MESSAGE_TEST_3:
189 | mActivity.get().test3.setText(data);
190 | break;
191 |
192 | case MESSAGE_TEST_4:
193 | mActivity.get().test4.setText(data);
194 | break;
195 |
196 | case MESSAGE_TEST_5:
197 | mActivity.get().test5.setText(data);
198 | break;
199 | }
200 | }
201 | }
202 | }
203 |
--------------------------------------------------------------------------------