如何将Linux C USB读取转换为Android



我有可插入USB的胎压管理系统(TPMS)适配器(http://store.mp3car.com/USB_TPMS_Version_2_20_4_Sensor_Kit_p/com-090.htm)。我让它与原始的Windows软件以及Linux C代码一起工作,以读取轮胎压力和温度。我现在正在尝试在Android上使用这个适配器,遇到了一些困难。我可以很好地检测到设备,但无论我尝试什么,我的读取都会返回-1字节的读取。这是我试图转换的C代码:

int TpmsPlugin::readUsbSensor(int sid, unsigned char *buf)
{
int r, transferred;
buf[0] = 0x20 + sid;
r = libusb_interrupt_transfer(mDeviceHandle, ENDPOINT_OUT, buf, 1, &transferred, INTR_TIMEOUT);
if (r < 0) {
DebugOut() << "TPMS: USB write interrupt failed, code " << r << endl;
}
r = libusb_interrupt_transfer(mDeviceHandle, ENDPOINT_IN, buf, 4, &transferred, INTR_TIMEOUT);
if (r < 0) {
DebugOut() << "TPMS: USB read interrupt failed, code " << r << endl;
}
return r;

sid的值为1、2、3或4,具体取决于车轮。然后使用提取值

lfPressure = ((float)buf[0]-40) * PRESSURE_SCALE * KPA_MULTIPLIER;
lfTemperature = (float)buf[1]-40;

您也可以在此处看到此驱动程序的完整实现:https://github.com/otcshare/automotive-message-broker/blob/master/plugins/tpms/tpmsplugin.cpp

我的Android版本能够找到USB设备,获得使用权限,连接到它,获得UsbEndpoints(它列出了两个),但无论是bulkTransfer()还是controlTransfer(),我都失败了。特别是,我根据我能找到的所有文档,尝试了很多不同的controlTransfer值。以下是我尝试过的一些代码:

UsbInterface intf = TpmsSectionFragment.device.getInterface(0);
UsbEndpoint endpoint_in = null, endpoint_out = null;
for (int i = 0; i < intf.getEndpointCount(); i++) {
UsbEndpoint ep = intf.getEndpoint(i);
if (ep.getDirection() == UsbConstants.USB_DIR_IN)
endpoint_in = ep;
else if (ep.getDirection() == UsbConstants.USB_DIR_OUT)
endpoint_out = ep;
}
UsbDeviceConnection connection = gUsbManager.openDevice(TpmsSectionFragment.device); 
connection.claimInterface(intf, false);
int timeout = 1000;
int length = 4;
while (true) {
for (int sensorId = 1; sensorId <= 4 && mReadThreadActive; sensorId++) {
byte[] tpmsRaw = new byte[length];
tpmsRaw[0] = (byte) (0x20 + sensorId);
int out_len = connection.bulkTransfer(endpoint_out, tpmsRaw, 1, timeout);
int in_len = connection.bulkTransfer(endpoint_in, tpmsRaw, 4, timeout);
//int out_len = connection.controlTransfer(0x42, 0x0, 0x100, 0, tpmsRaw, tpmsRaw.length, timeout);
//int in_len = connection.controlTransfer(0x41, 0x0, 0x100, 0, tpmsRaw, tpmsRaw.length, timeout);

对于我可能做错的事情,我们深表感激。如果你有任何建议,我很乐意尝试一些不同的东西来进一步调试。

谢谢!

以下是基于Chris帮助的解决方案。我将呼叫转换为队列/请求等待:

ByteBuffer buf = ByteBuffer.allocate(4);
buf.put(0, (byte) (0x20 + sensorId));
UsbRequest send = new UsbRequest();
send.initialize(connection, endpoint_out);
Boolean sent = send.queue(buf, 1);
UsbRequest r1 = connection.requestWait();
send.initialize(connection, endpoint_in);
send.queue(buf, 4);
UsbRequest r2 = connection.requestWait();

我需要调整的另一件事是这个调用,并将第二个参数设置为true:

connection.claimInterface(intf, true);

就这样,完成了。谢谢你的帮助!

最新更新