Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CH340G Usb-to-Serial support (Arduino-based clones) #1

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions PhysicaloidLibrary/build.gradle
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
apply plugin: 'android-library'
apply plugin: 'com.android.library'

dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
}

android {
compileSdkVersion 18
buildToolsVersion '18.1.0'
buildToolsVersion '19.1.0'

defaultConfig {
minSdkVersion 12
Expand Down
120 changes: 120 additions & 0 deletions PhysicaloidLibrary/src/com/physicaloid/lib/Physicaloid.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.physicaloid.lib;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.physicaloid.BuildConfig;
Expand All @@ -29,6 +30,7 @@

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Physicaloid {
Expand Down Expand Up @@ -176,6 +178,124 @@ public int write(byte[] buf, int size) throws RuntimeException {
}
}

public int write(String str) throws RuntimeException{
String sendStr=changeEscapeSequence(str, null);
return write(sendStr.getBytes(),sendStr.length());
}

public int write(String str,String linefeedCode) throws RuntimeException{
String sendStr=changeEscapeSequence(str, linefeedCode);
return write(sendStr.getBytes(),sendStr.length());
}

/**
* 加入成贞符号
* @param in
* @param linefeedCode
* @return
*/
private String changeEscapeSequence(String in,String linefeedCode) {
String out = new String();
try {
out = unescapeJava(in);
} catch (IOException e) {
return "";
}
if(!TextUtils.isEmpty(linefeedCode))out = out + linefeedCode;
return out;
}

/**
* 转码
* @param str
* @return
* @throws IOException
*/
private String unescapeJava(String str) throws IOException {
if (str == null) {
return "";
}
int sz = str.length();
StringBuffer unicode = new StringBuffer(4);

StringBuilder strout = new StringBuilder();
boolean hadSlash = false;
boolean inUnicode = false;
for (int i = 0; i < sz; i++) {
char ch = str.charAt(i);
if (inUnicode) {
// if in unicode, then we're reading unicode
// values in somehow
unicode.append(ch);
if (unicode.length() == 4) {
// unicode now contains the four hex digits
// which represents our unicode character
try {
int value = Integer.parseInt(unicode.toString(), 16);
strout.append((char) value);
unicode.setLength(0);
inUnicode = false;
hadSlash = false;
} catch (NumberFormatException nfe) {
// throw new NestableRuntimeException("Unable to parse unicode value: " + unicode, nfe);
throw new IOException("Unable to parse unicode value: " + unicode, nfe);
}
}
continue;
}
if (hadSlash) {
// handle an escaped value
hadSlash = false;
switch (ch) {
case '\\':
strout.append('\\');
break;
case '\'':
strout.append('\'');
break;
case '\"':
strout.append('"');
break;
case 'r':
strout.append('\r');
break;
case 'f':
strout.append('\f');
break;
case 't':
strout.append('\t');
break;
case 'n':
strout.append('\n');
break;
case 'b':
strout.append('\b');
break;
case 'u':
{
// uh-oh, we're in unicode country....
inUnicode = true;
break;
}
default :
strout.append(ch);
break;
}
continue;
} else if (ch == '\\') {
hadSlash = true;
continue;
}
strout.append(ch);
}
if (hadSlash) {
// then we're in the weird case of a \ at the end of the
// string, let's output it anyway.
strout.append('\\');
}
return new String(strout.toString());
}

/**
* Uploads a binary file to a device on background process. No need to open().
* @param board board profile e.g. Boards.ARDUINO_UNO
Expand Down
177 changes: 177 additions & 0 deletions PhysicaloidLibrary/src/com/physicaloid/lib/SerialReceiver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package com.physicaloid.lib;

import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;

/**
* Created by ideni_000 on 2016/1/10.
*/
public class SerialReceiver {

Physicaloid mSerial;
SerialReceiverListener mSerialReceiverListener;
public SerialReceiver(Physicaloid mSerial, SerialReceiverListener mSerialReceiverListener) {
this.mSerial = mSerial;
this.mSerialReceiverListener = mSerialReceiverListener;
}

// occurs USB packet loss if TEXT_MAX_SIZE is over 6000
private static final int TEXT_MAX_SIZE = 8192;
// Linefeed
private final static String BR = System.getProperty("line.separator");
// Linefeed Code Settings
private static final int LINEFEED_CODE_CR = 0;
private static final int LINEFEED_CODE_CRLF = 1;
private static final int LINEFEED_CODE_LF = 2;
// Defines of Display Settings
private static final int DISP_CHAR = 0;
private static final int DISP_DEC = 1;
private static final int DISP_HEX = 2;

//配置
private int mReadLinefeedCode = LINEFEED_CODE_LF;
private int mDisplayType = DISP_CHAR;

Handler mHandler=new Handler(){
@Override
public void handleMessage(Message msg) {
// String line=mText.toString();
String line = (String) msg.obj;
if(!TextUtils.isEmpty(line)&&line.contains("\n")){
String[] lines=line.split("\n");
for (int i=0;i<lines.length;i++){
if(null!=mSerialReceiverListener)mSerialReceiverListener.onReceive(lines[i]);
}
}else{
if(null!=mSerialReceiverListener)mSerialReceiverListener.onReceive(line);
}
}
};
StringBuilder mText = new StringBuilder();
boolean lastDataIs0x0D = false;
boolean mStop=true;
boolean mRunningMainLoop = false;

private Runnable mLoop = new Runnable() {
@Override
public void run() {
int len;
byte[] rbuf = new byte[4096];
while (true) {//循环
len = mSerial.read(rbuf);
rbuf[len] = 0;
if (len > 0) {
switch (mDisplayType) {
case DISP_CHAR:
setSerialDataToTextView(mDisplayType, rbuf, len, "", "");
break;
case DISP_DEC:
setSerialDataToTextView(mDisplayType, rbuf, len, "013", "010");
break;
case DISP_HEX:
setSerialDataToTextView(mDisplayType, rbuf, len, "0d", "0a");
break;
}
mHandler.sendMessage(mHandler.obtainMessage(0,mText.toString()));
mText.setLength(0);
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (mStop) {
mRunningMainLoop = false;
return;
}
}
}
};

void setSerialDataToTextView(int disp, byte[] rbuf, int len, String sCr, String sLf) {
int tmpbuf;
for (int i = 0; i < len; ++i) {
// "\r":CR(0x0D) "\n":LF(0x0A)
if ((mReadLinefeedCode == LINEFEED_CODE_CR) && (rbuf[i] == 0x0D)) {
mText.append(sCr);
mText.append(BR);
} else if ((mReadLinefeedCode == LINEFEED_CODE_LF) && (rbuf[i] == 0x0A)) {
mText.append(sLf);
mText.append(BR);
} else if ((mReadLinefeedCode == LINEFEED_CODE_CRLF) && (rbuf[i] == 0x0D)
&& (rbuf[i + 1] == 0x0A)) {
mText.append(sCr);
if (disp != DISP_CHAR) {
mText.append(" ");
}
mText.append(sLf);
mText.append(BR);
++i;
} else if ((mReadLinefeedCode == LINEFEED_CODE_CRLF) && (rbuf[i] == 0x0D)) {
// case of rbuf[last] == 0x0D and rbuf[0] == 0x0A
mText.append(sCr);
lastDataIs0x0D = true;
} else if (lastDataIs0x0D && (rbuf[0] == 0x0A)) {
if (disp != DISP_CHAR) {
mText.append(" ");
}
mText.append(sLf);
mText.append(BR);
lastDataIs0x0D = false;
} else if (lastDataIs0x0D && (i != 0)) {
// only disable flag
lastDataIs0x0D = false;
--i;
} else {
switch (disp) {
case DISP_CHAR:
mText.append((char) rbuf[i]);
break;
case DISP_DEC:
tmpbuf = rbuf[i];
if (tmpbuf < 0) {
tmpbuf += 256;
}
mText.append(String.format("%1$03d", tmpbuf));
mText.append(" ");
break;
case DISP_HEX:
mText.append(IntToHex2((int) rbuf[i]));
mText.append(" ");
break;
default:
break;
}
}
}
}

private String IntToHex2(int Value) {
char HEX2[] = {
Character.forDigit((Value >> 4) & 0x0F, 16),
Character.forDigit(Value & 0x0F, 16)
};
String Hex2Str = new String(HEX2);
return Hex2Str;
}

public void start(){
mStop=false;
mRunningMainLoop = true;
new Thread(mLoop).start();
}

public void stop(){
mStop=true;
}

public boolean isRunning(){
return mRunningMainLoop;
}

public interface SerialReceiverListener{
void onReceive(String line);
}

}
1 change: 1 addition & 0 deletions PhysicaloidLibrary/src/com/physicaloid/lib/UsbVidList.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

public enum UsbVidList {
ARDUINO (0x2341),
DCCDUINO (0x1A86),
FTDI (0x0403),
MBED_LPC1768 (0x0d28),
MBED_LPC11U24 (0x0d28),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import com.physicaloid.lib.UsbVidList;
import com.physicaloid.lib.usb.UsbAccessor;
import com.physicaloid.lib.usb.driver.uart.UartCH340;
import com.physicaloid.lib.usb.driver.uart.UartCdcAcm;
import com.physicaloid.lib.usb.driver.uart.UartCp210x;
import com.physicaloid.lib.usb.driver.uart.UartFtdi;
Expand All @@ -44,6 +45,8 @@ public SerialCommunicator getSerialCommunicator(Context context) {
return new UartFtdi(context);
} else if(vid == UsbVidList.CP210X.getVid()) {
return new UartCp210x(context);
}else if(vid == UsbVidList.DCCDUINO.getVid()){
return new UartCH340(context);
}
}
}
Expand Down
Loading