Official USBHost library and Android Accessory process to connect/write

05 Mar 2014

Hello,

I'm trying to develop a library to work with an Android accessory per the AOA protocol. So far I've encountered two issues:

1) I can connect to the Android device and get the VID/PID from it and check to see if it's the correct value. If not, I can also successfully issue the control messages to get it into the correct VID/PID and enter accessory mode. However, it only seems to get into that mode if I reset the mbed (process is connect android, reset mbed, android reports connected as media device, reset mbed, android reports as connected as an accessory). Based on the USB debug messages it seems like the USB device is disconnecting when the android device receives the command to switch to accessory mode. Is there a specific process needed to restore communication?

The code I use to set communication follows:

connect method

int ADK::Connect(){
    uint32_t VID, PID;
   
    if (dev_connected) {
        return true;
    }
    printf("host: %X\r\n", &host);
//    for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { //only one device connected
        printf("getDevice(0): %X\r\n",  host->getDevice(0));
        if ((dev = host->getDevice(0)) != NULL) {
            host->enumerate(dev, this);
            VID = dev->getVid();
            PID = dev->getPid();
            printf("First VID query: VID:%04X\r\n", dev->getVid());
            printf("First PID query: PID:%04X\r\n", dev->getPid());
            
            //Check VID + PID
            if((VID != 0x18D1) || (PID != 0x2D00)){
                printf("PVID no match");
                switch_mode();
                Thread::wait(500);
                dev = host->getDevice(0);
                host->enumerate(dev, this);               
                VID = dev->getVid();
                PID = dev->getPid();
                printf("Second VID query: VID:%04x\r\n", dev->getVid());
                printf("Second PID query: PID:%04x\r\n", dev->getPid());

            }
            //check if VID + PID match AOA format
            if((VID == 0x18D1) && (PID == 0x2D00)){
                bulk_in = dev->getEndpoint(ADK_intf, BULK_ENDPOINT, IN);
                bulk_out = dev->getEndpoint(ADK_intf, BULK_ENDPOINT, OUT);
                printf("New Serial device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, ADK_intf);
                dev->setName("ADK", ADK_intf);
                size_bulk_in = bulk_in->getSize();
                size_bulk_out = bulk_out->getSize();
                printf("Size BI: %X\r\n", size_bulk_in);
                printf("Size BO: %X\r\n", size_bulk_out);
                bulk_in->attach(this, &ADK::read_callback);
                bulk_out->attach(this, &ADK::write_callback);// &myClass::myMemberFunction
                dev_connected = true;
                return true;
            }
    }
    return false;
}

void ADK::switch_mode(){
    uint8_t cont_buf[64];
    host->controlRead(dev, USB_DIR_IN | USB_TYPE_VENDOR, 51, 0, 0, cont_buf, 2);
    printf("buf[0]: %X    buf[1]: %X\r\n", cont_buf[0], cont_buf[1]);
    //check protocol          
    if(cont_buf[0] >=1){
        //send ID strings
        host->controlWrite(dev, USB_DIR_OUT | USB_TYPE_VENDOR, 52, 0, 0, manufacturer, 8);                    
        host->controlWrite(dev, USB_DIR_OUT | USB_TYPE_VENDOR, 52, 0, 1, model, 5);                    
        host->controlWrite(dev, USB_DIR_OUT | USB_TYPE_VENDOR, 52, 0, 2, description, 8);                    
        host->controlWrite(dev, USB_DIR_OUT | USB_TYPE_VENDOR, 52, 0, 3, version, 4);                    
        host->controlWrite(dev, USB_DIR_OUT | USB_TYPE_VENDOR, 52, 0, 4, uri, 16);                    
        host->controlWrite(dev, USB_DIR_OUT | USB_TYPE_VENDOR, 52, 0, 5, serial, 11);                    
        host->controlWrite(dev, USB_DIR_OUT | USB_TYPE_VENDOR, 53, 0, 0, 0, 0);
    }
}

2) The second issue I have is that bulkWrite messages don't seem to work. bulkread successfully gets data from the android tablet however. When I check the bulkWrite messages it seems like it gets stuck on the "Processing" mode. Any suggestions on where to look to see why it's getting stuck there?

The way I issue the command is just:

host->bulkWrite(dev, bulk_out, wbuff, bulk_out->getSize(), false);