mirror of
https://github.com/mik3y/usb-serial-for-android
synced 2025-06-20 22:36:09 +00:00
Add setParameters() method and deprecate setBaudRate().
Interface is similar to javax.comm.
This commit is contained in:
parent
0424133e58
commit
3f271aab81
@ -15,6 +15,9 @@ import java.util.Map;
|
||||
* USB CDC/ACM serial driver implementation.
|
||||
*
|
||||
* @author mike wakerly (opensource@hoho.com)
|
||||
* @see <a
|
||||
* href="http://www.usb.org/developers/devclass_docs/usbcdc11.pdf">Universal
|
||||
* Serial Bus Class Definitions for Communication Devices, v1.1</a>
|
||||
*/
|
||||
public class CdcAcmSerialDriver extends UsbSerialDriver {
|
||||
|
||||
@ -27,6 +30,22 @@ public class CdcAcmSerialDriver extends UsbSerialDriver {
|
||||
private UsbEndpoint mReadEndpoint;
|
||||
private UsbEndpoint mWriteEndpoint;
|
||||
|
||||
private int mBaudRate;
|
||||
private int mDataBits;
|
||||
private int mStopBits;
|
||||
private int mParity;
|
||||
|
||||
private boolean mRts = false;
|
||||
private boolean mDtr = false;
|
||||
|
||||
private static final int USB_RECIP_INTERFACE = 0x01;
|
||||
private static final int USB_RT_ACM = UsbConstants.USB_TYPE_CLASS | USB_RECIP_INTERFACE;
|
||||
|
||||
private static final int SET_LINE_CODING = 0x20; // USB CDC 1.1 section 6.2
|
||||
private static final int GET_LINE_CODING = 0x21;
|
||||
private static final int SET_CONTROL_LINE_STATE = 0x22;
|
||||
private static final int SEND_BREAK = 0x23;
|
||||
|
||||
public CdcAcmSerialDriver(UsbDevice device, UsbDeviceConnection connection) {
|
||||
super(device, connection);
|
||||
}
|
||||
@ -59,31 +78,17 @@ public class CdcAcmSerialDriver extends UsbSerialDriver {
|
||||
mWriteEndpoint = mDataInterface.getEndpoint(0);
|
||||
Log.d(TAG, "Write endpoint direction: " + mWriteEndpoint.getDirection());
|
||||
|
||||
Log.d(TAG, "Setting line coding");
|
||||
setBaudRate(115200);
|
||||
|
||||
Log.d(TAG, "Setting line coding to 115200/8N1");
|
||||
mBaudRate = 115200;
|
||||
mDataBits = DATABITS_8;
|
||||
mParity = PARITY_NONE;
|
||||
mStopBits = STOPBITS_1;
|
||||
setParameters(mBaudRate, mDataBits, mStopBits, mParity);
|
||||
}
|
||||
|
||||
private static final int USB_RECIP_INTERFACE = 0x01;
|
||||
private static final int USB_RT_ACM = UsbConstants.USB_TYPE_CLASS | USB_RECIP_INTERFACE;
|
||||
|
||||
private static final int SET_LINE_CODING = 0x20; // USB CDC 1.1 section 6.2
|
||||
|
||||
private int sendAcmControlMessage(int request, int value, byte[] buf) {
|
||||
return mConnection.controlTransfer(USB_RT_ACM, request, value, 0, buf, buf != null ? buf.length : 0, 5000);
|
||||
}
|
||||
|
||||
private int setAcmLineCoding(int bitRate, int stopBits, int parity, int dataBits) {
|
||||
byte[] msg = {
|
||||
(byte) ( bitRate & 0xff),
|
||||
(byte) ((bitRate >> 8 ) & 0xff),
|
||||
(byte) ((bitRate >> 16) & 0xff),
|
||||
(byte) ((bitRate >> 24) & 0xff),
|
||||
|
||||
(byte) stopBits,
|
||||
(byte) parity,
|
||||
(byte) dataBits};
|
||||
return sendAcmControlMessage(SET_LINE_CODING, 0, msg);
|
||||
return mConnection.controlTransfer(
|
||||
USB_RT_ACM, request, value, 0, buf, buf != null ? buf.length : 0, 5000);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -145,50 +150,90 @@ public class CdcAcmSerialDriver extends UsbSerialDriver {
|
||||
return offset;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public int setBaudRate(int baudRate) throws IOException {
|
||||
setAcmLineCoding(baudRate, 0, 0, 8);
|
||||
return baudRate;
|
||||
mBaudRate = baudRate;
|
||||
setParameters(mBaudRate, mDataBits, mStopBits, mParity);
|
||||
return mBaudRate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParameters(int baudRate, int dataBits, int stopBits, int parity) {
|
||||
byte stopBitsByte;
|
||||
switch (stopBits) {
|
||||
case STOPBITS_1: stopBitsByte = 1; break;
|
||||
case STOPBITS_1_5: stopBitsByte = 2; break;
|
||||
case STOPBITS_2: stopBitsByte = 3; break;
|
||||
default: throw new IllegalArgumentException("Bad value for stopBits: " + stopBits);
|
||||
}
|
||||
|
||||
byte parityBitesByte;
|
||||
switch (parity) {
|
||||
case PARITY_NONE: parityBitesByte = 0; break;
|
||||
case PARITY_ODD: parityBitesByte = 1; break;
|
||||
case PARITY_EVEN: parityBitesByte = 2; break;
|
||||
case PARITY_MARK: parityBitesByte = 3; break;
|
||||
case PARITY_SPACE: parityBitesByte = 4; break;
|
||||
default: throw new IllegalArgumentException("Bad value for parity: " + parity);
|
||||
}
|
||||
|
||||
byte[] msg = {
|
||||
(byte) ( baudRate & 0xff),
|
||||
(byte) ((baudRate >> 8 ) & 0xff),
|
||||
(byte) ((baudRate >> 16) & 0xff),
|
||||
(byte) ((baudRate >> 24) & 0xff),
|
||||
stopBitsByte,
|
||||
parityBitesByte,
|
||||
(byte) dataBits};
|
||||
sendAcmControlMessage(SET_LINE_CODING, 0, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getCD() throws IOException {
|
||||
return false;
|
||||
return false; // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getCTS() throws IOException {
|
||||
return false;
|
||||
return false; // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getDSR() throws IOException {
|
||||
return false;
|
||||
return false; // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getDTR() throws IOException {
|
||||
return false;
|
||||
return mDtr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setDTR(boolean value) throws IOException {
|
||||
return false;
|
||||
public void setDTR(boolean value) throws IOException {
|
||||
mDtr = value;
|
||||
setDtrRts();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRI() throws IOException {
|
||||
return false;
|
||||
return false; // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRTS() throws IOException {
|
||||
return false;
|
||||
return mRts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setRTS(boolean value) throws IOException {
|
||||
return false;
|
||||
public void setRTS(boolean value) throws IOException {
|
||||
mRts = value;
|
||||
setDtrRts();
|
||||
}
|
||||
|
||||
private void setDtrRts() {
|
||||
int value = (mRts ? 0x2 : 0) | (mDtr ? 0x1 : 0);
|
||||
sendAcmControlMessage(SET_CONTROL_LINE_STATE, value, null);
|
||||
}
|
||||
|
||||
public static Map<Integer, int[]> getSupportedDevices() {
|
||||
|
@ -90,6 +90,9 @@ import java.util.Map;
|
||||
public class FtdiSerialDriver extends UsbSerialDriver {
|
||||
|
||||
private static final int DEFAULT_BAUD_RATE = 115200;
|
||||
private static final int DEFAULT_DATA_BITS = DATABITS_8;
|
||||
private static final int DEFAULT_PARITY = PARITY_NONE;
|
||||
private static final int DEFAULT_STOP_BITS = STOPBITS_1;
|
||||
|
||||
public static final int USB_TYPE_STANDARD = 0x00 << 5;
|
||||
public static final int USB_TYPE_CLASS = 0x00 << 5;
|
||||
@ -161,6 +164,11 @@ public class FtdiSerialDriver extends UsbSerialDriver {
|
||||
|
||||
private int mMaxPacketSize = 64; // TODO(mikey): detect
|
||||
|
||||
private int mBaudRate;
|
||||
private int mDataBits;
|
||||
private int mParity;
|
||||
private int mStopBits;
|
||||
|
||||
/**
|
||||
* Due to http://b.android.com/28023 , we cannot use UsbRequest async reads
|
||||
* since it gives no indication of number of bytes read. Set this to
|
||||
@ -204,7 +212,7 @@ public class FtdiSerialDriver extends UsbSerialDriver {
|
||||
}
|
||||
}
|
||||
reset();
|
||||
setBaudRate(DEFAULT_BAUD_RATE);
|
||||
setParameters(DEFAULT_BAUD_RATE, DEFAULT_DATA_BITS, DEFAULT_STOP_BITS, DEFAULT_PARITY);
|
||||
opened = true;
|
||||
} finally {
|
||||
if (!opened) {
|
||||
@ -307,13 +315,12 @@ public class FtdiSerialDriver extends UsbSerialDriver {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public int setBaudRate(int baudRate) throws IOException {
|
||||
long[] vals = convertBaudrate(baudRate);
|
||||
long actualBaudrate = vals[0];
|
||||
long index = vals[1];
|
||||
long value = vals[2];
|
||||
Log.i(TAG, "Requested baudrate=" + baudRate + ", actual=" + actualBaudrate);
|
||||
|
||||
int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE,
|
||||
SIO_SET_BAUD_RATE_REQUEST, (int) value, (int) index,
|
||||
null, 0, USB_WRITE_TIMEOUT_MILLIS);
|
||||
@ -323,6 +330,59 @@ public class FtdiSerialDriver extends UsbSerialDriver {
|
||||
return (int) actualBaudrate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParameters(int baudRate, int dataBits, int stopBits, int parity)
|
||||
throws IOException {
|
||||
mBaudRate = setBaudRate(baudRate);
|
||||
|
||||
int config = dataBits;
|
||||
|
||||
switch (parity) {
|
||||
case PARITY_NONE:
|
||||
config |= (0x00 << 8);
|
||||
break;
|
||||
case PARITY_ODD:
|
||||
config |= (0x01 << 8);
|
||||
break;
|
||||
case PARITY_EVEN:
|
||||
config |= (0x02 << 8);
|
||||
break;
|
||||
case PARITY_MARK:
|
||||
config |= (0x03 << 8);
|
||||
break;
|
||||
case PARITY_SPACE:
|
||||
config |= (0x04 << 8);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown parity value: " + parity);
|
||||
}
|
||||
|
||||
switch (stopBits) {
|
||||
case STOPBITS_1:
|
||||
config |= (0x00 << 11);
|
||||
break;
|
||||
case STOPBITS_1_5:
|
||||
config |= (0x01 << 11);
|
||||
break;
|
||||
case STOPBITS_2:
|
||||
config |= (0x02 << 11);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown stopBits value: " + stopBits);
|
||||
}
|
||||
|
||||
int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE,
|
||||
SIO_SET_DATA_REQUEST, config, 0 /* index */,
|
||||
null, 0, USB_WRITE_TIMEOUT_MILLIS);
|
||||
if (result != 0) {
|
||||
throw new IOException("Setting parameters failed: result=" + result);
|
||||
}
|
||||
|
||||
mParity = parity;
|
||||
mStopBits = stopBits;
|
||||
mDataBits = dataBits;
|
||||
}
|
||||
|
||||
private long[] convertBaudrate(int baudrate) {
|
||||
// TODO(mikey): Braindead transcription of libfti method. Clean up,
|
||||
// using more idiomatic Java where possible.
|
||||
@ -430,8 +490,7 @@ public class FtdiSerialDriver extends UsbSerialDriver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setDTR(boolean value) throws IOException {
|
||||
return false;
|
||||
public void setDTR(boolean value) throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -445,8 +504,7 @@ public class FtdiSerialDriver extends UsbSerialDriver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setRTS(boolean value) throws IOException {
|
||||
return false;
|
||||
public void setRTS(boolean value) throws IOException {
|
||||
}
|
||||
|
||||
public static Map<Integer, int[]> getSupportedDevices() {
|
||||
|
@ -47,6 +47,30 @@ public abstract class UsbSerialDriver {
|
||||
/** Internal write buffer. Guarded by {@link #mWriteBufferLock}. */
|
||||
protected byte[] mWriteBuffer;
|
||||
|
||||
public static final int DATABITS_5 = 5;
|
||||
public static final int DATABITS_6 = 6;
|
||||
public static final int DATABITS_7 = 7;
|
||||
public static final int DATABITS_8 = 8;
|
||||
|
||||
public static final int FLOWCONTROL_NONE = 0;
|
||||
public static final int FLOWCONTROL_RTSCTS_IN = 1;
|
||||
public static final int FLOWCONTROL_RTSCTS_OUT = 2;
|
||||
public static final int FLOWCONTROL_XONXOFF_IN = 4;
|
||||
public static final int FLOWCONTROL_XONXOFF_OUT = 8;
|
||||
|
||||
public static final int PARITY_EVEN = 2;
|
||||
public static final int PARITY_MARK = 3;
|
||||
public static final int PARITY_NONE = 0;
|
||||
public static final int PARITY_ODD = 1;
|
||||
public static final int PARITY_SPACE = 4;
|
||||
|
||||
/** 1 stop bit. */
|
||||
public static final int STOPBITS_1 = 1;
|
||||
/** 1.5 stop bits. */
|
||||
public static final int STOPBITS_1_5 = 3;
|
||||
/** 2 stop bits. */
|
||||
public static final int STOPBITS_2 = 2;
|
||||
|
||||
public UsbSerialDriver(UsbDevice device, UsbDeviceConnection connection) {
|
||||
mDevice = device;
|
||||
mConnection = connection;
|
||||
@ -96,9 +120,27 @@ public abstract class UsbSerialDriver {
|
||||
* @param baudRate the desired baud rate, in bits per second
|
||||
* @return the actual rate set
|
||||
* @throws IOException on error setting the baud rate
|
||||
* @deprecated Use {@link #setParameters(int, int, int, int)} instead of this method.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract int setBaudRate(final int baudRate) throws IOException;
|
||||
|
||||
/**
|
||||
* Sets various serial port parameters.
|
||||
*
|
||||
* @param baudRate baud rate as an integer, for example {@code 115200}.
|
||||
* @param dataBits one of {@link #DATABITS_5}, {@link #DATABITS_6},
|
||||
* {@link #DATABITS_7}, or {@link #DATABITS_8}.
|
||||
* @param stopBits one of {@link #STOPBITS_1}, {@link #STOPBITS_1_5}, or
|
||||
* {@link #STOPBITS_2}.
|
||||
* @param parity one of {@link #PARITY_NONE}, {@link #PARITY_ODD},
|
||||
* {@link #PARITY_EVEN}, {@link #PARITY_MARK}, or
|
||||
* {@link #PARITY_SPACE}.
|
||||
* @throws IOException on error setting the port parameters
|
||||
*/
|
||||
public abstract void setParameters(
|
||||
int baudRate, int dataBits, int stopBits, int parity) throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the CD (Carrier Detect) bit from the underlying UART.
|
||||
*
|
||||
@ -138,7 +180,7 @@ public abstract class UsbSerialDriver {
|
||||
* @param value the value to set
|
||||
* @throws IOException if an error occurred during writing
|
||||
*/
|
||||
public abstract boolean setDTR(boolean value) throws IOException;
|
||||
public abstract void setDTR(boolean value) throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the RI (Ring Indicator) bit from the underlying UART.
|
||||
@ -160,10 +202,10 @@ public abstract class UsbSerialDriver {
|
||||
* Sets the RTS (Request To Send) bit on the underlying UART, if
|
||||
* supported.
|
||||
*
|
||||
* @param value thje value to set
|
||||
* @param value the value to set
|
||||
* @throws IOException if an error occurred during writing
|
||||
*/
|
||||
public abstract boolean setRTS(boolean value) throws IOException;
|
||||
public abstract void setRTS(boolean value) throws IOException;
|
||||
|
||||
/**
|
||||
* Returns the currently-bound USB device.
|
||||
|
Loading…
x
Reference in New Issue
Block a user