안드로이드에 맞춤형 USB 장치와 통신합니다
문제
USB를 통해 맞춤형 이사회 (PIC16F1454)와 통신하기 위해 응용 프로그램을 작성하고 있습니다.전화 및 노트북의 터미널 응용 프로그램을 사용하여 보드 커뮤니케이션을 테스트했으며 완벽하게 작동합니다.
보드에서 데이터를 보내고받는 응용 프로그램을 만들었지만 아무 것도 작동하지 않는 것 같습니다.다음은 커뮤니케이션에 대한 책임이 있습니다 :
package com.fyp.eece502androidusb;
import java.util.HashMap;
import java.util.Iterator;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.util.Log;
public class UsbController {
private final Context mApplicationContext;
private final UsbManager mUsbManager;
private final IUsbConnectionHandler mConnectionHandler;
private final int VID;
private final int PID;
protected static final String ACTION_USB_PERMISSION = "com.fyp.eece502androidusb.USB";
/**
* Activity is needed for onResult
*
* @param parentActivity
*/
public UsbController(Activity parentActivity,
IUsbConnectionHandler connectionHandler, int vid, int pid) {
mApplicationContext = parentActivity.getApplicationContext();
mConnectionHandler = connectionHandler;
mUsbManager = (UsbManager) mApplicationContext
.getSystemService(Context.USB_SERVICE);
VID = vid;
PID = pid;
init();
}
private void init() {
enumerate(new IPermissionListener() {
@Override
public void onPermissionDenied(UsbDevice d) {
UsbManager usbman = (UsbManager) mApplicationContext
.getSystemService(Context.USB_SERVICE);
PendingIntent pi = PendingIntent.getBroadcast(
mApplicationContext, 0, new Intent(
ACTION_USB_PERMISSION), 0);
mApplicationContext.registerReceiver(mPermissionReceiver,
new IntentFilter(ACTION_USB_PERMISSION));
usbman.requestPermission(d, pi);
}
});
}
public void stop() {
mStop = true;
synchronized (sSendLock) {
sSendLock.notify();
}
try {
if (mUsbThread != null)
mUsbThread.join();
} catch (InterruptedException e) {
e(e);
}
mStop = false;
mLoop = null;
mUsbThread = null;
try {
mApplicationContext.unregisterReceiver(mPermissionReceiver);
} catch (IllegalArgumentException e) {
}
;// bravo
}
private UsbRunnable mLoop;
private Thread mUsbThread;
private void startHandler(UsbDevice d) {
if (mLoop != null) {
mConnectionHandler.onErrorLooperRunningAlready();
return;
}
mLoop = new UsbRunnable(d);
mUsbThread = new Thread(mLoop);
mUsbThread.start();
}
public void send(byte data) {
mData = data;
synchronized (sSendLock) {
sSendLock.notify();
}
}
private void enumerate(IPermissionListener listener) {
l("enumerating");
HashMap<String, UsbDevice> devlist = mUsbManager.getDeviceList();
Iterator<UsbDevice> deviter = devlist.values().iterator();
while (deviter.hasNext()) {
UsbDevice d = deviter.next();
l("Found device: "
+ String.format("%04X:%04X", d.getVendorId(),
d.getProductId()));
if (d.getVendorId() == VID && d.getProductId() == PID) {
l("Device under: " + d.getDeviceName());
if (!mUsbManager.hasPermission(d))
listener.onPermissionDenied(d);
else {
startHandler(d);
return;
}
break;
}
}
l("no more devices found");
mConnectionHandler.onDeviceNotFound();
}
private class PermissionReceiver extends BroadcastReceiver {
private final IPermissionListener mPermissionListener;
public PermissionReceiver(IPermissionListener permissionListener) {
mPermissionListener = permissionListener;
}
@Override
public void onReceive(Context context, Intent intent) {
mApplicationContext.unregisterReceiver(this);
if (intent.getAction().equals(ACTION_USB_PERMISSION)) {
if (!intent.getBooleanExtra(
UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
mPermissionListener.onPermissionDenied((UsbDevice) intent
.getParcelableExtra(UsbManager.EXTRA_DEVICE));
} else {
l("Permission granted");
UsbDevice dev = (UsbDevice) intent
.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (dev != null) {
if (dev.getVendorId() == VID
&& dev.getProductId() == PID) {
startHandler(dev);// has new thread
}
} else {
e("device not present!");
}
}
}
}
}
// MAIN LOOP
private static final Object[] sSendLock = new Object[] {};
private boolean mStop = false;
private byte mData = 0x00;
private class UsbRunnable implements Runnable {
private final UsbDevice mDevice;
UsbRunnable(UsbDevice dev) {
mDevice = dev;
}
@Override
public void run() {// here the main USB functionality is implemented
UsbDeviceConnection conn = mUsbManager.openDevice(mDevice);
if (!conn.claimInterface(mDevice.getInterface(1), true)) {
return;
}
// controlTransfer
int baudRate = 115200;
int stopBits = 1;
int parity = 0;
int dataBits = 8;
byte[] msg = { (byte) (baudRate & 0xff),
(byte) ((baudRate >> 8) & 0xff),
(byte) ((baudRate >> 16) & 0xff),
(byte) ((baudRate >> 24) & 0xff),
(byte) stopBits, (byte) parity, (byte) dataBits };
int USB_RT_ACM = UsbConstants.USB_TYPE_CLASS | 1;
UsbControllerActivity.conn1Reply = conn.controlTransfer(USB_RT_ACM,
34, 0x03, 0, null, 0, 0);
UsbControllerActivity.conn2Reply = conn.controlTransfer(USB_RT_ACM,
32, 0, 0, msg, msg != null ? msg.length : 0, 0);
//
UsbEndpoint epIN = null;
UsbEndpoint epOUT = null;
UsbInterface usbIf = mDevice.getInterface(1);
for (int i = 0; i < usbIf.getEndpointCount(); i++) {
if (usbIf.getEndpoint(i).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (usbIf.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN) {
epIN = usbIf.getEndpoint(i);
UsbControllerActivity.epINExists = true;
} else {
epOUT = usbIf.getEndpoint(i);
UsbControllerActivity.epOUTExists = true;
}
}
}
for (;;) {// this is the main loop for transferring
synchronized (sSendLock) {
try {
sSendLock.wait();
} catch (InterruptedException e) {
if (mStop) {
mConnectionHandler.onUSBStopped();
return;
}
e.printStackTrace();
}
}
UsbControllerActivity.mDataSent = new byte[] { (byte) (0x04) };
UsbControllerActivity.bulkXFEROutReply = conn.bulkTransfer(
epOUT, UsbControllerActivity.mDataSent, 1, 0);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
UsbControllerActivity.bulkXFERInReply = conn.bulkTransfer(epIN,
UsbControllerActivity.mDataReceived, 10, 0);
if (mStop) {
mConnectionHandler.onUSBStopped();
return;
}
}
}
}
// END MAIN LOOP
private BroadcastReceiver mPermissionReceiver = new PermissionReceiver(
new IPermissionListener() {
@Override
public void onPermissionDenied(UsbDevice d) {
l("Permission denied on " + d.getDeviceId());
}
});
private static interface IPermissionListener {
void onPermissionDenied(UsbDevice d);
}
public final static String TAG = "USBController";
private void l(Object msg) {
Log.d(TAG, ">==< " + msg.toString() + " >==<");
}
private void e(Object msg) {
Log.e(TAG, ">==< " + msg.toString() + " >==<");
}
}
.
제어 전송에 대해 0과 7의 값이 0 및 7이고, 전송할 때 대량 이송을위한 1은 일괄 전송을 받고 있습니다.
벌크 전송이 값이 전송되었음을 나타내지 만 수신 측 (보드의 깜박임 LED)의 변경 사항은 아무것도 변경하지 않습니다.
내 추측은 제어 전송에 문제가 있어야한다는 것입니다.
int baudRate = 115200;
int stopBits = 1;
int parity = 0;
int dataBits = 8;
byte[] msg = { (byte) (baudRate & 0xff),
(byte) ((baudRate >> 8) & 0xff),
(byte) ((baudRate >> 16) & 0xff),
(byte) ((baudRate >> 24) & 0xff),
(byte) stopBits, (byte) parity, (byte) dataBits };
int USB_RT_ACM = UsbConstants.USB_TYPE_CLASS | 1;
UsbControllerActivity.conn1Reply = conn.controlTransfer(USB_RT_ACM,
34, 0x03, 0, null, 0, 0);
UsbControllerActivity.conn2Reply = conn.controlTransfer(USB_RT_ACM,
32, 0, 0, msg, msg != null ? msg.length : 0, 0);
.
USB 장치는 CDC 장치로 구성됩니다.
도움말
해결책
Chris Stratton의 의견 덕분에 내 코드에서 문제를 찾을 수있었습니다.
- 0x34 (4) 대신 0x04 (Ctrl-D)를 보내고 있었다.
- ControlTransfer는 불필요한 것 같습니다. USB 기능이 내장 된 PIC16F1454를 사용하고 있습니다
- 수신 버퍼는 PIC의 응답보다 작았 다
수정 된 코드는 다음과 같습니다.
package com.fyp.eece502androidusb;
import java.util.HashMap;
import java.util.Iterator;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.util.Log;
public class UsbController {
private final Context mApplicationContext;
private final UsbManager mUsbManager;
private final IUsbConnectionHandler mConnectionHandler;
private final int VID;
private final int PID;
protected static final String ACTION_USB_PERMISSION = "com.fyp.eece502androidusb.USB";
/**
* Activity is needed for onResult
*
* @param parentActivity
*/
public UsbController(Activity parentActivity,
IUsbConnectionHandler connectionHandler, int vid, int pid) {
mApplicationContext = parentActivity.getApplicationContext();
mConnectionHandler = connectionHandler;
mUsbManager = (UsbManager) mApplicationContext
.getSystemService(Context.USB_SERVICE);
VID = vid;
PID = pid;
init();
}
private void init() {
enumerate(new IPermissionListener() {
@Override
public void onPermissionDenied(UsbDevice d) {
UsbManager usbman = (UsbManager) mApplicationContext
.getSystemService(Context.USB_SERVICE);
PendingIntent pi = PendingIntent.getBroadcast(
mApplicationContext, 0, new Intent(
ACTION_USB_PERMISSION), 0);
mApplicationContext.registerReceiver(mPermissionReceiver,
new IntentFilter(ACTION_USB_PERMISSION));
usbman.requestPermission(d, pi);
}
});
}
public void stop() {
mStop = true;
synchronized (sSendLock) {
sSendLock.notify();
}
try {
if (mUsbThread != null)
mUsbThread.join();
} catch (InterruptedException e) {
e(e);
}
mStop = false;
mLoop = null;
mUsbThread = null;
try {
mApplicationContext.unregisterReceiver(mPermissionReceiver);
} catch (IllegalArgumentException e) {
}
}
private UsbRunnable mLoop;
private Thread mUsbThread;
private void startHandler(UsbDevice d) {
if (mLoop != null) {
mConnectionHandler.onErrorLooperRunningAlready();
return;
}
mLoop = new UsbRunnable(d);
mUsbThread = new Thread(mLoop);
mUsbThread.start();
}
public void send(byte data) {
mData = data;
synchronized (sSendLock) {
sSendLock.notify();
}
}
private void enumerate(IPermissionListener listener) {
l("enumerating");
HashMap<String, UsbDevice> devlist = mUsbManager.getDeviceList();
Iterator<UsbDevice> deviter = devlist.values().iterator();
while (deviter.hasNext()) {
UsbDevice d = deviter.next();
l("Found device: "
+ String.format("%04X:%04X", d.getVendorId(),
d.getProductId()));
if (d.getVendorId() == VID && d.getProductId() == PID) {
l("Device under: " + d.getDeviceName());
if (!mUsbManager.hasPermission(d))
listener.onPermissionDenied(d);
else {
startHandler(d);
return;
}
break;
}
}
l("no more devices found");
mConnectionHandler.onDeviceNotFound();
}
private class PermissionReceiver extends BroadcastReceiver {
private final IPermissionListener mPermissionListener;
public PermissionReceiver(IPermissionListener permissionListener) {
mPermissionListener = permissionListener;
}
@Override
public void onReceive(Context context, Intent intent) {
mApplicationContext.unregisterReceiver(this);
if (intent.getAction().equals(ACTION_USB_PERMISSION)) {
if (!intent.getBooleanExtra(
UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
mPermissionListener.onPermissionDenied((UsbDevice) intent
.getParcelableExtra(UsbManager.EXTRA_DEVICE));
} else {
l("Permission granted");
UsbDevice dev = (UsbDevice) intent
.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (dev != null) {
if (dev.getVendorId() == VID
&& dev.getProductId() == PID) {
startHandler(dev);// has new thread
}
} else {
e("device not present!");
}
}
}
}
}
// MAIN LOOP
private static final Object[] sSendLock = new Object[] {};
private boolean mStop = false;
private byte mData = 0x00;
private class UsbRunnable implements Runnable {
private final UsbDevice mDevice;
UsbRunnable(UsbDevice dev) {
mDevice = dev;
}
@Override
public void run() {// here the main USB functionality is implemented
UsbDeviceConnection conn = mUsbManager.openDevice(mDevice);
if (!conn.claimInterface(mDevice.getInterface(1), true)) {
return;
}
UsbEndpoint epIN = null;
UsbEndpoint epOUT = null;
UsbInterface usbIf = mDevice.getInterface(1);
for (int i = 0; i < usbIf.getEndpointCount(); i++) {
if (usbIf.getEndpoint(i).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (usbIf.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN) {
epIN = usbIf.getEndpoint(i);
UsbControllerActivity.epINExists = true;
} else {
epOUT = usbIf.getEndpoint(i);
UsbControllerActivity.epOUTExists = true;
}
}
}
for (;;) {// this is the main loop for transferring
synchronized (sSendLock) {
try {
sSendLock.wait();
} catch (InterruptedException e) {
if (mStop) {
mConnectionHandler.onUSBStopped();
return;
}
e.printStackTrace();
}
}
UsbControllerActivity.mDataSent = new byte[] { (byte) (0x34) };
UsbControllerActivity.bulkXFEROutReply = conn.bulkTransfer(
epOUT, UsbControllerActivity.mDataSent, 1, 0);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
UsbControllerActivity.bulkXFERInReply = conn.bulkTransfer(epIN,
UsbControllerActivity.mDataReceived, 20, 0);
if (mStop) {
mConnectionHandler.onUSBStopped();
return;
}
}
}
}
// END MAIN LOOP
private BroadcastReceiver mPermissionReceiver = new PermissionReceiver(
new IPermissionListener() {
@Override
public void onPermissionDenied(UsbDevice d) {
l("Permission denied on " + d.getDeviceId());
}
});
private static interface IPermissionListener {
void onPermissionDenied(UsbDevice d);
}
public final static String TAG = "USBController";
private void l(Object msg) {
Log.d(TAG, ">==< " + msg.toString() + " >==<");
}
private void e(Object msg) {
Log.e(TAG, ">==< " + msg.toString() + " >==<");
}
}
.제휴하지 않습니다 StackOverflow