Android Open Accessory Library化してみました。 バルク転送の使い方が分かっていないため、相変わらず動作は不安定。 I do not understand the usage of the bulk transfer. Please teach someone.

Dependencies:   mbed

Revision:
0:4fcfc05943ff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AndroidAccessory.cpp	Fri Jun 03 17:43:15 2011 +0000
@@ -0,0 +1,308 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "USBHost.h"
+#include "AndroidAccessory.h"
+#include "mbed.h"
+
+AndroidAccessory* _adk;
+
+void AdkreadCallback(int device, int endpoint, int status, u8* buf, int len, void* userData);
+void AdkwriteCallback(int device, int endpoint, int status, u8* buf, int len, void* userData);
+
+
+
+AndroidAccessory::AndroidAccessory(int rbuffsize,int wbuffsize,
+                                   const char* manufacturer,
+                                   const char *model,
+                                   const char *description,
+                                   const char *version,
+                                   const char *uri,
+                                   const char *serial
+                                  ) {
+
+    _adk=this;
+
+    this->manufacturer=manufacturer;
+    this->model=model;
+    this->description=description;
+    this->version=version;
+    this->uri=uri;
+    this->serial=serial;
+
+    u32 len;
+    u8* p=USBGetBuffer(&len);
+    if (len<(rbuffsize+wbuffsize+255)) {
+        error("buff size too big.please resize max=%d. currentSize=%d\r\n",len,(rbuffsize+wbuffsize+255));
+    }
+
+    _readbuff=p;
+    _readbuffsize=rbuffsize;
+    p+=rbuffsize;
+    _writebuff=p;
+    _writebuffsize=wbuffsize;
+    p+=wbuffsize;
+    _strbuff=p;
+    p+=255;
+
+}
+
+
+
+int AndroidAccessory::write(u8 *buff, int len) {
+    log("AndroidAccessory::write ");
+   // __disable_irq();
+    int ret=USBBulkTransfer(_device,output_ep,buff,len/*,AdkwriteCallback,this*/);
+   // __enable_irq();
+    log("--ret=%d \r\n",ret);
+    return ret;
+}
+
+#if 0
+int AndroidAccessory::read(u8 *buff, int len) {
+    if(_initok==false)return 0;
+    
+    log("AndroidAccessory::read ");
+   // __disable_irq();
+    int ret=USBBulkTransfer(_device,input_ep|0x80,buff,len);
+   // __enable_irq();
+    log("--ret=%d \r\n",ret);
+    return ret;
+}
+#endif
+
+void AndroidAccessory::init(int device, int configuration, int interfaceNumber) {
+
+    log("AndroidAccessory::init \r\n");
+
+//    _initok=false;
+    _device = device;
+    _configuration = configuration;
+    _interfaceNumber = interfaceNumber;
+    printf("device = %d configuration = %d interfaceNumber = %d\r\n", device, configuration, interfaceNumber);
+    int err;
+
+    u8* buffer=_strbuff;
+    err = GetDescriptor(_device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,4);
+
+    if (err < 0) {
+        log("Failed to get descriptor\r\n");
+        return;
+    }
+
+
+    int len = buffer[2] | (buffer[3] << 8);
+    if (len > 255) {
+        log("config descriptor too large\n");
+        /* might want to truncate here */
+        return;
+    }
+    err = GetDescriptor(_device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,len);
+    u8* p = buffer;
+    input_ep=0;
+    output_ep=0;
+    EndpointDescriptor *epDesc;
+    while (p<(buffer+len)) {
+        u8 descLen  = p[0];
+        u8 descType = p[1];
+        log("descLen=%d,descType=%d\r\n",descLen,descType);
+        switch (descType) {
+            case DESCRIPTOR_TYPE_CONFIGURATION:
+                log("config desc\r\n");
+                break;
+            case DESCRIPTOR_TYPE_INTERFACE:
+                log("interface desc\r\n");
+                break;
+            case DESCRIPTOR_TYPE_ENDPOINT:
+                epDesc=(EndpointDescriptor*)p;
+                if (!input_ep && (epDesc->bEndpointAddress& 0x80)) {
+                    input_ep=epDesc->bEndpointAddress& 0x7f;
+                    //PacketSize drop
+                    log("input Endpoint address=%d,wMaxPacketSize=%d,bmAttributes=%d\r\n",input_ep,epDesc->wMaxPacketSize,epDesc->bmAttributes);
+
+                } else if (!output_ep) {
+                    output_ep=epDesc->bEndpointAddress& 0x7f;
+                    //PacketSize drop
+                    log("output Endpoint address=%d,wMaxPacketSize=%d,bmAttributes=%d\r\n",input_ep,epDesc->wMaxPacketSize,epDesc->bmAttributes);
+                } else {
+                    //other
+                    log("non input,output Endpoint address=%d,wMaxPacketSize=%d,bmAttributes=%d\r\n",input_ep,epDesc->wMaxPacketSize,epDesc->bmAttributes);
+                }
+                break;
+            default:
+                log("unkown desc type(%d) \r\n",descType);
+        }
+        p+=descLen;
+    }
+
+    if (!(input_ep && output_ep)) {
+        log("can't find accessory endpoints\r\n");
+        return;
+    }
+
+    log("SetConfiguration\r\n");
+    err = SetConfiguration(device,configuration);
+    if (err < 0) {
+        log("SetConfiguration error\r\n");
+        return;
+    }
+
+
+    log("interrupt setup\r\n");
+    //interrupt setup
+    if (_readbuff==NULL || _readbuffsize<=0) {
+        error("_readbuffer error please setup buffer call setReadBuffer function\r\n");
+    }
+
+    if (IO_PENDING!=USBBulkTransfer(_device,input_ep|0x80,_readbuff,_readbuffsize,AdkreadCallback,this))
+        return;
+
+
+    log("setupDevice\r\n");
+    this->setupDevice();
+//    _initok=true;
+}
+
+
+
+bool AndroidAccessory::switchDevice(int device) {
+
+    if (1==getProtocol(device)) {
+        log("device supports protocol 1\r\n");
+
+    } else {
+        log("could not read device protocol version\r\n");
+        return false;
+    }
+
+
+    sendString(device,ACCESSORY_STRING_MANUFACTURER,manufacturer);
+    sendString(device,ACCESSORY_STRING_MODEL,model);
+    sendString(device,ACCESSORY_STRING_DESCRIPTION,description);
+    sendString(device,ACCESSORY_STRING_VERSION,version);
+    sendString(device,ACCESSORY_STRING_URI,uri);
+    sendString(device,ACCESSORY_STRING_SERIAL,serial);
+    USBControlTransfer(device,
+                       HOST_TO_DEVICE |REQUEST_TYPE_VENDOR|RECIPIENT_DEVICE,
+                       ACCESSORY_START,
+                       0,//value
+                       0, //index
+                       0,
+                       0,
+                       0,
+                       0 );
+
+    wait_ms(4);
+    //reset usb host
+    USBInit();
+
+    return true;
+
+}
+
+
+int AndroidAccessory::getProtocol(int device) {
+    s16 data=-1;
+    USBControlTransfer(device,
+                       DEVICE_TO_HOST|REQUEST_TYPE_VENDOR|RECIPIENT_DEVICE,
+                       ACCESSORY_GET_PROTOCOL,
+                       0,//value
+                       0, //index
+                       (u8*)&data,
+                       2,
+                       0,
+                       0 );
+    return data;
+
+}
+
+void AndroidAccessory::sendString(int device, int index, const char *str) {
+
+    LOG("send_string start(%d,%d,%s)  %d \r\n",device,index,str,strlen(str)+1);
+    strcpy((char*)_strbuff,str);
+    //thankyou curryman san
+    USBControlTransfer(device,
+                       HOST_TO_DEVICE|REQUEST_TYPE_VENDOR|RECIPIENT_DEVICE,
+                       ACCESSORY_SEND_STRING,
+                       0,//value
+                       index,
+                       _strbuff,
+                       strlen(str)+1
+                      );
+
+    LOG("send_string end(%d,%d,%s)\r\n",device,index,str);
+
+}
+
+
+/** from USBHost load function. initialize Android device**/
+void OnLoadDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc) {
+    printf("LoadDevice %d %02X:%02X:%02X\r\n",device,interfaceDesc->bInterfaceClass,interfaceDesc->bInterfaceSubClass,interfaceDesc->bInterfaceProtocol);
+    char s[128];
+
+    for (int i = 1; i < 3; i++) {
+        if (GetString(device,i,s,sizeof(s)) < 0)
+            break;
+        printf("%d: %s\r\n",i,s);
+    }
+
+    //for android ADK
+    if ( ( deviceDesc->idVendor != 0x18D1 ||
+            ( deviceDesc->idProduct != 0x2D00 && deviceDesc->idProduct != 0x2D01))
+            &&_adk->switchDevice(device)) {
+
+        printf("  try to change accmode.interfaceDesc->bInterfaceClass=%d\r\n",interfaceDesc->bInterfaceClass);
+        //1th root
+        //accmode_support=true;
+        printf("accessory mode ok.\r\n");
+        return;
+    }
+
+    if (deviceDesc->idVendor == 0x18D1 &&
+            (deviceDesc->idProduct == 0x2D00 || deviceDesc->idProduct == 0x2D01)) {
+        //2th root
+        printf("connecting Android.\r\n");
+        printf("idVender=%x  idProduct=%x  interfaceDesc->bInterfaceClass=%d\r\n",deviceDesc->idVendor,deviceDesc->idProduct,interfaceDesc->bInterfaceClass);
+        _adk->init(device,1,0);
+        //_AdkUSB.loop();
+        return;
+    }
+}
+
+void AdkreadCallback(int device, int endpoint, int status, u8* buf, int len, void* userData) {
+    log("AdkreadCallback(int device=%d, int endpoint=%x, int status=%d, u8* buf=%p, int len=%d, void* userData=%p)\r\n",
+        device,endpoint,status,buf,len,userData);
+//    __disable_irq();
+    AndroidAccessory* t = (AndroidAccessory*)userData;
+    if (status!=0) {
+        log("adk end.\r\n");
+        t->adkEnd();
+//        __enable_irq();
+        USBInit();
+        return;
+    }
+
+
+    //virtual method run
+    t->callbackRead(buf,len);
+
+    USBBulkTransfer(device, endpoint , buf, len, AdkreadCallback, userData);
+
+//    wait_ms(4);
+//    __enable_irq();
+}
+
+
+
+#if 0
+void AdkwriteCallback(int device, int endpoint, int status, u8* buf, int len, void* userData) {
+
+    log("AdkwriteCallback(int device=%d, int endpoint=%x, int status=%d, u8* buf=%p, int len=%d, void* userData=%p)\r\n",
+        device,endpoint,status,buf,len,userData);
+
+    //AndroidAccessory* t = (AndroidAccessory*)userData;
+    //wait_ms(4);
+
+}
+#endif