kopia lustrzana https://github.com/mik3y/usb-serial-for-android
rodzic
a1e58b9843
commit
8eaf3f5c5f
|
@ -6,7 +6,7 @@ buildscript {
|
|||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.0.0'
|
||||
classpath 'com.android.tools.build:gradle:4.0.1'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ android {
|
|||
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
testInstrumentationRunnerArguments = [ // Raspi Windows LinuxVM ...
|
||||
'rfc2217_server_host': '192.168.0.110',
|
||||
'rfc2217_server_host': '192.168.0.100',
|
||||
'rfc2217_server_nonstandard_baudrates': 'true', // true false false
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* test multiple devices or multiple ports on same device
|
||||
*
|
||||
* TxD and RxD have to be cross connected
|
||||
*/
|
||||
package com.hoho.android.usbserial;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.util.Log;
|
||||
|
||||
import com.hoho.android.usbserial.driver.UsbSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.UsbSerialPort;
|
||||
import com.hoho.android.usbserial.driver.UsbSerialProber;
|
||||
import com.hoho.android.usbserial.util.UsbWrapper;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.rules.TestWatcher;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class CrossoverTest {
|
||||
|
||||
private final static String TAG = CrossoverTest.class.getSimpleName();
|
||||
|
||||
private Context context;
|
||||
private UsbManager usbManager;
|
||||
private UsbWrapper usb1, usb2;
|
||||
|
||||
@Rule
|
||||
public TestRule watcher = new TestWatcher() {
|
||||
protected void starting(Description description) {
|
||||
Log.i(TAG, "===== starting test: " + description.getMethodName()+ " =====");
|
||||
}
|
||||
};
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
context = InstrumentationRegistry.getContext();
|
||||
usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
|
||||
List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(usbManager);
|
||||
assertNotEquals("no USB device found", 0, availableDrivers.size());
|
||||
if (availableDrivers.size() == 0) {
|
||||
fail("no USB device found");
|
||||
} else if (availableDrivers.size() == 1) {
|
||||
assertEquals(2, availableDrivers.get(0).getPorts().size());
|
||||
usb1 = new UsbWrapper(context, availableDrivers.get(0), 0);
|
||||
usb2 = new UsbWrapper(context, availableDrivers.get(0), 1);
|
||||
} else {
|
||||
assertEquals(1, availableDrivers.get(0).getPorts().size());
|
||||
assertEquals(1, availableDrivers.get(1).getPorts().size());
|
||||
usb1 = new UsbWrapper(context, availableDrivers.get(0), 0);
|
||||
usb2 = new UsbWrapper(context, availableDrivers.get(1), 0);
|
||||
}
|
||||
usb1.setUp();
|
||||
usb2.setUp();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reopen() throws Exception {
|
||||
byte[] buf;
|
||||
|
||||
usb1.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_IOMANAGER_THREAD));
|
||||
usb2.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_IOMANAGER_THREAD));
|
||||
usb1.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||
usb2.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||
|
||||
usb1.write("x".getBytes());
|
||||
buf = usb2.read(1);
|
||||
assertThat(buf, equalTo("x".getBytes()));
|
||||
|
||||
usb2.write("y".getBytes());
|
||||
buf = usb1.read(1);
|
||||
assertThat(buf, equalTo("y".getBytes()));
|
||||
|
||||
usb2.close(); // does not affect usb1 with individual UsbDeviceConnection on same device
|
||||
|
||||
usb2.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_IOMANAGER_THREAD));
|
||||
usb2.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||
|
||||
usb1.write("x".getBytes());
|
||||
buf = usb2.read(1);
|
||||
assertThat(buf, equalTo("x".getBytes()));
|
||||
|
||||
usb2.write("y".getBytes());
|
||||
buf = usb1.read(1);
|
||||
assertThat(buf, equalTo("y".getBytes()));
|
||||
|
||||
usb1.close();
|
||||
usb2.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ioManager() throws Exception {
|
||||
byte[] buf;
|
||||
|
||||
// each SerialInputOutputManager thread runs in it's own SingleThreadExecutor
|
||||
usb1.open();
|
||||
usb2.open();
|
||||
usb1.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||
usb2.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||
|
||||
usb1.write("x".getBytes());
|
||||
buf = usb2.read(1);
|
||||
assertThat(buf, equalTo("x".getBytes()));
|
||||
|
||||
usb2.write("y".getBytes());
|
||||
buf = usb1.read(1);
|
||||
assertThat(buf, equalTo("y".getBytes()));
|
||||
|
||||
usb1.close();
|
||||
usb2.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void baudRate() throws Exception {
|
||||
byte[] buf;
|
||||
|
||||
usb1.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_IOMANAGER_THREAD));
|
||||
usb2.open(EnumSet.of(UsbWrapper.OpenCloseFlags.NO_IOMANAGER_THREAD));
|
||||
usb1.setParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||
usb2.setParameters(9600, 8, 1, UsbSerialPort.PARITY_NONE);
|
||||
|
||||
// a - start bit (0)
|
||||
// o - stop bit (1)
|
||||
// 0/1 - data bit
|
||||
|
||||
// out 19k2: a00011001o
|
||||
// in 9k6: a 0 1 0 1 1 1 1 1 o
|
||||
usb1.write(new byte[]{(byte)0x98});
|
||||
buf = usb2.read(1);
|
||||
assertThat(buf, equalTo(new byte[]{(byte)0xfa}));
|
||||
|
||||
// out 9k6: a 1 0 1 1 1 1 1 1 o
|
||||
// in 19k2: a01100111o
|
||||
usb2.write(new byte[]{(byte)0xfd});
|
||||
buf = usb1.read(1);
|
||||
assertThat(buf, equalTo(new byte[]{(byte)0xe6}));
|
||||
|
||||
usb1.close();
|
||||
usb2.close();
|
||||
}
|
||||
|
||||
}
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,155 @@
|
|||
package com.hoho.android.usbserial.util;
|
||||
|
||||
import org.apache.commons.net.telnet.InvalidTelnetOptionException;
|
||||
import org.apache.commons.net.telnet.TelnetClient;
|
||||
import org.apache.commons.net.telnet.TelnetCommand;
|
||||
import org.apache.commons.net.telnet.TelnetOptionHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class TelnetWrapper {
|
||||
private final static String TAG = TelnetWrapper.class.getSimpleName();
|
||||
|
||||
private final static int TELNET_READ_WAIT = 500;
|
||||
private final static int TELNET_COMMAND_WAIT = 2000;
|
||||
|
||||
private final static byte RFC2217_COM_PORT_OPTION = 0x2c;
|
||||
private final static byte RFC2217_SET_BAUDRATE = 1;
|
||||
private final static byte RFC2217_SET_DATASIZE = 2;
|
||||
private final static byte RFC2217_SET_PARITY = 3;
|
||||
private final static byte RFC2217_SET_STOPSIZE = 4;
|
||||
private final static byte RFC2217_PURGE_DATA = 12;
|
||||
|
||||
private final String host;
|
||||
private final int port;
|
||||
|
||||
private TelnetClient telnetClient;
|
||||
private InputStream readStream;
|
||||
private OutputStream writeStream;
|
||||
private Integer[] comPortOptionCounter = {0};
|
||||
public int writeDelay = 0;
|
||||
|
||||
public TelnetWrapper(String host, int port) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
telnetClient = null;
|
||||
}
|
||||
|
||||
private void setUpFixtureInt() throws Exception {
|
||||
if(telnetClient != null)
|
||||
return;
|
||||
telnetClient = new TelnetClient();
|
||||
telnetClient.addOptionHandler(new TelnetOptionHandler(RFC2217_COM_PORT_OPTION, false, false, false, false) {
|
||||
@Override
|
||||
public int[] answerSubnegotiation(int[] suboptionData, int suboptionLength) {
|
||||
comPortOptionCounter[0] += 1;
|
||||
return super.answerSubnegotiation(suboptionData, suboptionLength);
|
||||
}
|
||||
});
|
||||
|
||||
telnetClient.setConnectTimeout(2000);
|
||||
telnetClient.connect(host, port);
|
||||
telnetClient.setTcpNoDelay(true);
|
||||
writeStream = telnetClient.getOutputStream();
|
||||
readStream = telnetClient.getInputStream();
|
||||
}
|
||||
|
||||
public void setUp() throws Exception {
|
||||
setUpFixtureInt();
|
||||
telnetClient.sendAYT(1000); // not correctly handled by rfc2217_server.py, but WARNING output "ignoring Telnet command: '\xf6'" is a nice separator between tests
|
||||
comPortOptionCounter[0] = 0;
|
||||
telnetClient.sendCommand((byte)TelnetCommand.SB);
|
||||
writeStream.write(new byte[] {RFC2217_COM_PORT_OPTION, RFC2217_PURGE_DATA, 3});
|
||||
telnetClient.sendCommand((byte)TelnetCommand.SE);
|
||||
for(int i=0; i<TELNET_COMMAND_WAIT; i++) {
|
||||
if(comPortOptionCounter[0] == 1) break;
|
||||
Thread.sleep(1);
|
||||
}
|
||||
assertEquals("telnet connection lost", 1, comPortOptionCounter[0].intValue());
|
||||
writeDelay = 0;
|
||||
}
|
||||
|
||||
public void tearDown() {
|
||||
try {
|
||||
read(0);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public void tearDownFixture() throws Exception {
|
||||
try {
|
||||
telnetClient.disconnect();
|
||||
} catch (Exception ignored) {}
|
||||
readStream = null;
|
||||
writeStream = null;
|
||||
telnetClient = null;
|
||||
}
|
||||
|
||||
// wait full time
|
||||
public byte[] read() throws Exception {
|
||||
return read(-1);
|
||||
}
|
||||
|
||||
public byte[] read(int expectedLength) throws Exception {
|
||||
long end = System.currentTimeMillis() + TELNET_READ_WAIT;
|
||||
ByteBuffer buf = ByteBuffer.allocate(65536);
|
||||
while(System.currentTimeMillis() < end) {
|
||||
if(readStream.available() > 0) {
|
||||
buf.put((byte) readStream.read());
|
||||
} else {
|
||||
if (expectedLength >= 0 && buf.position() >= expectedLength)
|
||||
break;
|
||||
Thread.sleep(1);
|
||||
}
|
||||
}
|
||||
byte[] data = new byte[buf.position()];
|
||||
buf.flip();
|
||||
buf.get(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
public void write(byte[] data) throws Exception{
|
||||
if(writeDelay != 0) {
|
||||
for(byte b : data) {
|
||||
writeStream.write(b);
|
||||
writeStream.flush();
|
||||
Thread.sleep(writeDelay);
|
||||
}
|
||||
} else {
|
||||
writeStream.write(data);
|
||||
writeStream.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void setParameters(int baudRate, int dataBits, int stopBits, int parity) throws IOException, InterruptedException, InvalidTelnetOptionException {
|
||||
comPortOptionCounter[0] = 0;
|
||||
|
||||
telnetClient.sendCommand((byte) TelnetCommand.SB);
|
||||
writeStream.write(new byte[] {RFC2217_COM_PORT_OPTION, RFC2217_SET_BAUDRATE, (byte)(baudRate>>24), (byte)(baudRate>>16), (byte)(baudRate>>8), (byte)baudRate});
|
||||
telnetClient.sendCommand((byte)TelnetCommand.SE);
|
||||
|
||||
telnetClient.sendCommand((byte)TelnetCommand.SB);
|
||||
writeStream.write(new byte[] {RFC2217_COM_PORT_OPTION, RFC2217_SET_DATASIZE, (byte)dataBits});
|
||||
telnetClient.sendCommand((byte)TelnetCommand.SE);
|
||||
|
||||
telnetClient.sendCommand((byte)TelnetCommand.SB);
|
||||
writeStream.write(new byte[] {RFC2217_COM_PORT_OPTION, RFC2217_SET_STOPSIZE, (byte)stopBits});
|
||||
telnetClient.sendCommand((byte)TelnetCommand.SE);
|
||||
|
||||
telnetClient.sendCommand((byte)TelnetCommand.SB);
|
||||
writeStream.write(new byte[] {RFC2217_COM_PORT_OPTION, RFC2217_SET_PARITY, (byte)(parity+1)});
|
||||
telnetClient.sendCommand((byte)TelnetCommand.SE);
|
||||
|
||||
// windows does not like nonstandard baudrates. rfc2217_server.py terminates w/o response
|
||||
for(int i=0; i<TELNET_COMMAND_WAIT; i++) {
|
||||
if(comPortOptionCounter[0] == 4) break;
|
||||
Thread.sleep(1);
|
||||
}
|
||||
assertEquals("telnet connection lost", 4, comPortOptionCounter[0].intValue());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,256 @@
|
|||
package com.hoho.android.usbserial.util;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.hardware.usb.UsbDevice;
|
||||
import android.hardware.usb.UsbDeviceConnection;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.os.Process;
|
||||
import android.util.Log;
|
||||
|
||||
import com.hoho.android.usbserial.driver.CdcAcmSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.UsbSerialDriver;
|
||||
import com.hoho.android.usbserial.driver.UsbSerialPort;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Deque;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
|
||||
|
||||
public class UsbWrapper implements SerialInputOutputManager.Listener {
|
||||
|
||||
private final static int USB_READ_WAIT = 500;
|
||||
private final static int USB_WRITE_WAIT = 500;
|
||||
private final static Integer SERIAL_INPUT_OUTPUT_MANAGER_THREAD_PRIORITY = Process.THREAD_PRIORITY_URGENT_AUDIO;
|
||||
private static final String TAG = UsbWrapper.class.getSimpleName();
|
||||
|
||||
public enum OpenCloseFlags { NO_IOMANAGER_THREAD, NO_CONTROL_LINE_INIT, NO_DEVICE_CONNECTION };
|
||||
|
||||
// constructor
|
||||
final Context context;
|
||||
public final UsbSerialDriver serialDriver;
|
||||
public final int devicePort;
|
||||
public final UsbSerialPort serialPort;
|
||||
// open
|
||||
public UsbDeviceConnection deviceConnection;
|
||||
public SerialInputOutputManager ioManager;
|
||||
// read
|
||||
final Deque<byte[]> readBuffer = new LinkedList<>();
|
||||
Exception readError;
|
||||
public boolean readBlock = false;
|
||||
long readTime = 0;
|
||||
|
||||
|
||||
public UsbWrapper(Context context, UsbSerialDriver serialDriver, int devicePort) {
|
||||
this.context = context;
|
||||
this.serialDriver = serialDriver;
|
||||
this.devicePort = devicePort;
|
||||
serialPort = serialDriver.getPorts().get(devicePort);
|
||||
}
|
||||
|
||||
public void setUp() throws Exception {
|
||||
UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
|
||||
if (!usbManager.hasPermission(serialDriver.getDevice())) {
|
||||
Log.d(TAG,"USB permission ...");
|
||||
final Boolean[] granted = {null};
|
||||
BroadcastReceiver usbReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
granted[0] = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false);
|
||||
}
|
||||
};
|
||||
PendingIntent permissionIntent = PendingIntent.getBroadcast(context, 0, new Intent("com.android.example.USB_PERMISSION"), 0);
|
||||
IntentFilter filter = new IntentFilter("com.android.example.USB_PERMISSION");
|
||||
context.registerReceiver(usbReceiver, filter);
|
||||
usbManager.requestPermission(serialDriver.getDevice(), permissionIntent);
|
||||
for(int i=0; i<5000; i++) {
|
||||
if(granted[0] != null) break;
|
||||
Thread.sleep(1);
|
||||
}
|
||||
Log.d(TAG,"USB permission "+granted[0]);
|
||||
assertTrue("USB permission dialog not confirmed", granted[0]==null?false:granted[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public void tearDown() {
|
||||
try {
|
||||
if (ioManager != null)
|
||||
read(0);
|
||||
else
|
||||
serialPort.purgeHwBuffers(true, true);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
close();
|
||||
//usb.serialDriver = null;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
close(EnumSet.noneOf(OpenCloseFlags.class));
|
||||
}
|
||||
|
||||
public void close(EnumSet<OpenCloseFlags> flags) {
|
||||
if (ioManager != null) {
|
||||
ioManager.setListener(null);
|
||||
ioManager.stop();
|
||||
}
|
||||
if (serialPort != null) {
|
||||
try {
|
||||
if(!flags.contains(OpenCloseFlags.NO_CONTROL_LINE_INIT)) {
|
||||
serialPort.setDTR(false);
|
||||
serialPort.setRTS(false);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
try {
|
||||
serialPort.close();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
//usbSerialPort = null;
|
||||
}
|
||||
if(!flags.contains(OpenCloseFlags.NO_DEVICE_CONNECTION)) {
|
||||
deviceConnection = null; // closed in usbSerialPort.close()
|
||||
}
|
||||
if(ioManager != null) {
|
||||
for (int i = 0; i < 2000; i++) {
|
||||
if (SerialInputOutputManager.State.STOPPED == ioManager.getState()) break;
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
assertEquals(SerialInputOutputManager.State.STOPPED, ioManager.getState());
|
||||
ioManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void open() throws Exception {
|
||||
open(EnumSet.noneOf(OpenCloseFlags.class), 0);
|
||||
}
|
||||
|
||||
public void open(EnumSet<OpenCloseFlags> flags) throws Exception {
|
||||
open(flags, 0);
|
||||
}
|
||||
|
||||
public void open(EnumSet<OpenCloseFlags> flags, int ioManagerTimeout) throws Exception {
|
||||
if(!flags.contains(OpenCloseFlags.NO_DEVICE_CONNECTION)) {
|
||||
UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
|
||||
deviceConnection = usbManager.openDevice(serialDriver.getDevice());
|
||||
}
|
||||
//serialPort = serialDriver.getPorts().get(devicePort);
|
||||
serialPort.open(deviceConnection);
|
||||
if(!flags.contains(OpenCloseFlags.NO_CONTROL_LINE_INIT)) {
|
||||
serialPort.setDTR(true);
|
||||
serialPort.setRTS(true);
|
||||
}
|
||||
if(!flags.contains(OpenCloseFlags.NO_IOMANAGER_THREAD)) {
|
||||
ioManager = new SerialInputOutputManager(serialPort, this) {
|
||||
@Override
|
||||
public void run() {
|
||||
if (SERIAL_INPUT_OUTPUT_MANAGER_THREAD_PRIORITY != null)
|
||||
Process.setThreadPriority(SERIAL_INPUT_OUTPUT_MANAGER_THREAD_PRIORITY);
|
||||
super.run();
|
||||
}
|
||||
};
|
||||
ioManager.setReadTimeout(ioManagerTimeout);
|
||||
ioManager.setWriteTimeout(ioManagerTimeout);
|
||||
Executors.newSingleThreadExecutor().submit(ioManager);
|
||||
}
|
||||
synchronized (readBuffer) {
|
||||
readBuffer.clear();
|
||||
}
|
||||
readError = null;
|
||||
}
|
||||
|
||||
// wait full time
|
||||
public byte[] read() throws Exception {
|
||||
return read(-1);
|
||||
}
|
||||
|
||||
public byte[] read(int expectedLength) throws Exception {
|
||||
long end = System.currentTimeMillis() + USB_READ_WAIT;
|
||||
ByteBuffer buf = ByteBuffer.allocate(16*1024);
|
||||
if(ioManager != null) {
|
||||
while (System.currentTimeMillis() < end) {
|
||||
if(readError != null)
|
||||
throw readError;
|
||||
synchronized (readBuffer) {
|
||||
while(readBuffer.peek() != null)
|
||||
buf.put(readBuffer.remove());
|
||||
}
|
||||
if (expectedLength >= 0 && buf.position() >= expectedLength)
|
||||
break;
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
} else {
|
||||
byte[] b1 = new byte[256];
|
||||
while (System.currentTimeMillis() < end) {
|
||||
int len = serialPort.read(b1, USB_READ_WAIT);
|
||||
if (len > 0)
|
||||
buf.put(b1, 0, len);
|
||||
if (expectedLength >= 0 && buf.position() >= expectedLength)
|
||||
break;
|
||||
}
|
||||
}
|
||||
byte[] data = new byte[buf.position()];
|
||||
buf.flip();
|
||||
buf.get(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
public void write(byte[] data) throws IOException {
|
||||
serialPort.write(data, USB_WRITE_WAIT);
|
||||
}
|
||||
|
||||
public void setParameters(int baudRate, int dataBits, int stopBits, int parity) throws IOException, InterruptedException {
|
||||
serialPort.setParameters(baudRate, dataBits, stopBits, parity);
|
||||
if(serialDriver instanceof CdcAcmSerialDriver)
|
||||
Thread.sleep(10); // arduino_leonardeo_bridge.ini needs some time
|
||||
else
|
||||
Thread.sleep(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewData(byte[] data) {
|
||||
long now = System.currentTimeMillis();
|
||||
if(readTime == 0)
|
||||
readTime = now;
|
||||
if(data.length > 64) {
|
||||
Log.d(TAG, "usb read: time+=" + String.format("%-3d",now- readTime) + " len=" + String.format("%-4d",data.length) + " data=" + new String(data, 0, 32) + "..." + new String(data, data.length-32, 32));
|
||||
} else {
|
||||
Log.d(TAG, "usb read: time+=" + String.format("%-3d",now- readTime) + " len=" + String.format("%-4d",data.length) + " data=" + new String(data));
|
||||
}
|
||||
readTime = now;
|
||||
|
||||
while(readBlock)
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
synchronized (readBuffer) {
|
||||
readBuffer.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRunError(Exception e) {
|
||||
readError = e;
|
||||
//fail("usb connection lost");
|
||||
}
|
||||
|
||||
}
|
|
@ -130,8 +130,6 @@ public class SerialInputOutputManager implements Runnable {
|
|||
/**
|
||||
* Continuously services the read and write buffers until {@link #stop()} is
|
||||
* called, or until a driver exception is raised.
|
||||
*
|
||||
* NOTE(mikey): Uses inefficient read/write-with-timeout.
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
|
|
Ładowanie…
Reference in New Issue