Domanda

Sto costruendo un'applicazione per comunicare con una tavola su misura (PIC16F1454) tramite USB.Ho testato la comunicazione del consiglio utilizzando applicazioni terminali sul telefono e sul laptop e funziona perfettamente.

Ho costruito un'applicazione per inviare e ricevere dati dalla scheda ma nulla sembra funzionare.Di seguito è riportata la mia classe responsabile della comunicazione:

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() + " >==<");
    }
}
.

Verrò restituito valori di 0 e 7 per i trasferimenti di controllo e 1 per il trasferimento di massa durante l'invio e nulla è ricevuto.

Sebbene il trasferimento BULK indica che il valore viene inviato, nulla cambia sul lato ricevente (un LED lampeggiante sulla scheda).

La mia speculazione è che ci deve essere qualcosa di sbagliato nel trasferimento di controllo:

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

Il dispositivo USB è configurato come dispositivo CDC.

Qualsiasi aiuto?

È stato utile?

Soluzione

Grazie al commento da Chris Stratton, sono stato in grado di trovare il problema nel mio codice.

    .
  1. Stavo inviando 0x04 (Ctrl-D) anziché 0x34 (4)
  2. Il controltransfer sembra essere inutile, sto usando PIC16F1454 con funzionalità USB integrate
  3. Il buffer ricevente era più piccolo della risposta della foto che ha causato anche problemi
  4. Il codice modificato è sotto:

    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() + " >==<");
        }
    }
    
    .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top