kopia lustrzana https://github.com/felHR85/UsbSerial
added encoded baudrates in ftdi driver
rodzic
3e889f646f
commit
ac88abca1a
|
@ -9,6 +9,7 @@ import android.hardware.usb.UsbDeviceConnection;
|
|||
import android.hardware.usb.UsbEndpoint;
|
||||
import android.hardware.usb.UsbInterface;
|
||||
import android.hardware.usb.UsbRequest;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import com.felhr.utils.SafeUsbRequest;
|
||||
|
@ -92,7 +93,6 @@ public class FTDISerialDevice extends UsbSerialDevice
|
|||
private UsbSerialInterface.UsbOverrunCallback overrunCallback;
|
||||
private UsbSerialInterface.UsbBreakCallback breakCallback;
|
||||
|
||||
|
||||
public FTDISerialDevice(UsbDevice device, UsbDeviceConnection connection)
|
||||
{
|
||||
this(device, connection, -1);
|
||||
|
@ -707,4 +707,115 @@ public class FTDISerialDevice extends UsbSerialDevice
|
|||
|
||||
return read;
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/47303802/how-is-androids-string-usbdevice-getversion-encoded-from-word-bcddevice
|
||||
private short getBcdDevice() {
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
|
||||
byte[] descriptors = connection.getRawDescriptors();
|
||||
return (short) ((descriptors[12] << 8) + descriptors[13]);
|
||||
}else{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private byte getISerialNumber(){
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
|
||||
byte[] descriptors = connection.getRawDescriptors();
|
||||
return descriptors[16];
|
||||
}else{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isBaudTolerated(long speed, long target) {
|
||||
return ((speed >= (target * 100) / 103) &&
|
||||
(speed <= (target * 100) / 97));
|
||||
}
|
||||
|
||||
// Encoding baudrate as freebsd driver:
|
||||
// https://github.com/freebsd/freebsd/blob/1d6e4247415d264485ee94b59fdbc12e0c566fd0/sys/dev/usb/serial/uftdi.c
|
||||
private short[] encodeBaudRate(int baudRate){
|
||||
boolean isFT232A = false;
|
||||
boolean clk12MHz = false;
|
||||
boolean hIndex = false;
|
||||
|
||||
short[] ret = new short[2];
|
||||
int clk, divisor, fastClk, frac, hwSpeed;
|
||||
|
||||
byte[] encodedFraction = new byte[]{
|
||||
0, 3, 2, 4, 1, 5, 6, 7
|
||||
};
|
||||
|
||||
byte[] roundoff232a = new byte[]{
|
||||
0, 1, 0, 1, 0, -1, 2, 1,
|
||||
0, -1, -2, -3, 4, 3, 2, 1,
|
||||
};
|
||||
|
||||
short bcdDevice = getBcdDevice();
|
||||
|
||||
if(bcdDevice == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if(bcdDevice == 0x200 && getISerialNumber() == 0) {
|
||||
isFT232A = true;
|
||||
}
|
||||
|
||||
if(bcdDevice == 0x500 || bcdDevice == 0x700 || bcdDevice == 0x800 || bcdDevice == 0x900 || bcdDevice == 0x1000) {
|
||||
hIndex = true;
|
||||
}
|
||||
|
||||
if(bcdDevice == 0x700 || bcdDevice == 0x800 || bcdDevice == 0x900 ) {
|
||||
clk12MHz = true;
|
||||
}
|
||||
|
||||
if(baudRate >= 1200 && clk12MHz) {
|
||||
clk = 12000000;
|
||||
fastClk = (1 << 17);
|
||||
}else {
|
||||
clk = 3000000;
|
||||
fastClk = 0;
|
||||
}
|
||||
|
||||
if(baudRate < (clk >> 14) || baudRate > clk) {
|
||||
return null;
|
||||
}
|
||||
|
||||
divisor = (clk << 4) / baudRate;
|
||||
if((divisor & 0xf) == 1) {
|
||||
divisor &= 0xfffffff8;
|
||||
}else if (isFT232A) {
|
||||
divisor += roundoff232a[divisor & 0x0f];
|
||||
}else {
|
||||
divisor += 1; /* Rounds odd 16ths up to next 8th. */
|
||||
}
|
||||
divisor >>= 1;
|
||||
|
||||
hwSpeed = (clk << 3) / divisor;
|
||||
|
||||
if(!isBaudTolerated(hwSpeed, baudRate)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
frac = divisor & 0x07;
|
||||
divisor >>= 3;
|
||||
if (divisor == 1) {
|
||||
if (frac == 0) {
|
||||
divisor = 0; /* 1.0 becomes 0.0 */
|
||||
}else {
|
||||
frac = 0; /* 1.5 becomes 1.0 */
|
||||
}
|
||||
}
|
||||
divisor |= (encodedFraction[frac] << 14) | fastClk;
|
||||
|
||||
ret[0] = (short) divisor;
|
||||
ret[1] = (short) (divisor >> 16);
|
||||
|
||||
|
||||
if(hIndex) {
|
||||
ret[1] <<= 8;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue