2014-02-18 1 views
1

У меня есть адаптер для управления давлением в шинах (TPMS), который подключается к USB (http://store.mp3car.com/USB_TPMS_Version_2_20_4_Sensor_Kit_p/com-090.htm). У меня есть работа с исходным программным обеспечением Windows, а также с кодом Linux C для чтения давления и температуры в шинах. Теперь я пытаюсь использовать этот адаптер на Android, и мне сложно. Я могу обнаружить устройство в порядке, но мои чтения все возвращают -1 байты, как бы ни старались. Вот код C Я пытаюсь преобразовать:Как конвертировать Linux C USB для чтения на Android?

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; 

Значение УЛМ 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); 

Любые мысли о том, что я могу делать неправильно, очень ценятся. Я рад попробовать несколько разных вещей для дальнейшего отладки, если у вас есть предложения.

Спасибо!

+0

Ваш код libusb подразумевает, что вам необходимо использовать ** прерывание передачи **, а не синхронные методы передачи или контроля передачи, которые вы пытались использовать. Пожалуйста, прочитайте документацию по адресу http://developer.android.com/reference/android/hardware/usb/UsbRequest.html, в частности: «Запросы на массовые конечные точки могут отправляться синхронно через bulkTransfer (UsbEndpoint, byte [], int, int) или асинхронно через очередь (ByteBuffer, int) и requestWait(). ** Запросы на конечных точках прерывания отправляются и принимаются асинхронно **. " Я вижу, что код ракеты-носителя может быть подходящим примером. –

+0

звучит как классный проект. – danny117

+0

Крис, большое спасибо за ответ. С несколькими хитростями я просто получил его на работу. Я отправлю записку с кодом ниже. –

ответ

1

Вот решение, основанное на помощи Криса. Я преобразовал звонки в очередь/requestWait:

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(); 

Другое дело, что мне нужно, чтобы настроить был этот вызов и установить второй параметр верно:

connection.claimInterface(intf, true); 

Вот и все. Готово. Спасибо за помощь!

Смежные вопросы