The modified AndroidAccessory Library

Dependents:   ADKTerm droidcycle uva_nc androidservo ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AndroidAccessory.cpp Source File

AndroidAccessory.cpp

00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 
00005 #include "USBHost.h"
00006 #include "AndroidAccessory.h"
00007 #include "mbed.h"
00008 
00009 AndroidAccessory* _adk;
00010 
00011 void AdkreadCallback(int device, int endpoint, int status, u8* buf, int len, void* userData);
00012 void AdkwriteCallback(int device, int endpoint, int status, u8* buf, int len, void* userData);
00013 
00014 
00015 
00016 AndroidAccessory::AndroidAccessory(int rbuffsize,int wbuffsize,
00017                                    const char* manufacturer,
00018                                    const char *model,
00019                                    const char *description,
00020                                    const char *version,
00021                                    const char *uri,
00022                                    const char *serial
00023                                   ) {
00024 
00025     _adk=this;
00026 
00027     this->manufacturer=manufacturer;
00028     this->model=model;
00029     this->description=description;
00030     this->version=version;
00031     this->uri=uri;
00032     this->serial=serial;
00033 
00034     u32 len;
00035     u8* p=USBGetBuffer(&len);
00036     if (len<(rbuffsize+wbuffsize+255)) {
00037         error("buff size too big.please resize max=%d. currentSize=%d\r\n",len,(rbuffsize+wbuffsize+255));
00038     }
00039 
00040     _readbuff=p;
00041     _readbuffsize=rbuffsize;
00042     p+=rbuffsize;
00043     _writebuff=p;
00044     _writebuffsize=wbuffsize;
00045     p+=wbuffsize;
00046     _strbuff=p;
00047     p+=255;
00048 
00049 }
00050 
00051 
00052 
00053 int AndroidAccessory::write(u8 *buff, int len) {
00054     log("AndroidAccessory::write ");
00055    // __disable_irq();
00056     int ret=USBBulkTransfer(_device,output_ep,buff,len,AdkwriteCallback,this);
00057    // __enable_irq();
00058     log("--ret=%d \r\n",ret);
00059     return ret;
00060 }
00061 int AndroidAccessory::writeNC(u8 *buff, int len) {
00062     log("AndroidAccessory::write ");
00063    // __disable_irq();
00064     int ret=USBBulkTransfer(_device,output_ep,buff,len);
00065    // __enable_irq();
00066     log("--ret=%d \r\n",ret);
00067     return ret;
00068 }
00069 
00070 
00071 
00072 int AndroidAccessory::read(u8 *buff, int len) {
00073    // if(_initok==false)return 0;
00074     
00075     log("AndroidAccessory::read ");
00076    // __disable_irq();
00077     int ret=USBBulkTransfer(_device,input_ep|0x80,buff,len);
00078    // __enable_irq();
00079     log("--ret=%d \r\n",ret);
00080     return ret;
00081 }
00082 
00083 
00084 void AndroidAccessory::init(int device, int configuration, int interfaceNumber) {
00085 
00086     log("AndroidAccessory::init \r\n");
00087 
00088 //    _initok=false;
00089     _device = device;
00090     _configuration = configuration;
00091     _interfaceNumber = interfaceNumber;
00092     printf("device = %d configuration = %d interfaceNumber = %d\r\n", device, configuration, interfaceNumber);
00093     int err;
00094 
00095     u8* buffer=_strbuff;
00096     err = GetDescriptor(_device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,4);
00097 
00098     if (err < 0) {
00099         log("Failed to get descriptor\r\n");
00100         return;
00101     }
00102 
00103 
00104     int len = buffer[2] | (buffer[3] << 8);
00105     if (len > 255) {
00106         log("config descriptor too large\n");
00107         /* might want to truncate here */
00108         return;
00109     }
00110     err = GetDescriptor(_device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,len);
00111     u8* p = buffer;
00112     input_ep=0;
00113     output_ep=0;
00114     EndpointDescriptor *epDesc;
00115     while (p<(buffer+len)) {
00116         u8 descLen  = p[0];
00117         u8 descType = p[1];
00118         log("descLen=%d,descType=%d\r\n",descLen,descType);
00119         switch (descType) {
00120             case DESCRIPTOR_TYPE_CONFIGURATION:
00121                 log("config desc\r\n");
00122                 break;
00123             case DESCRIPTOR_TYPE_INTERFACE:
00124                 log("interface desc\r\n");
00125                 break;
00126             case DESCRIPTOR_TYPE_ENDPOINT:
00127                 epDesc=(EndpointDescriptor*)p;
00128                 if (!input_ep && (epDesc->bEndpointAddress& 0x80)) {
00129                     input_ep=epDesc->bEndpointAddress& 0x7f;
00130                     //PacketSize drop
00131                     log("input Endpoint address=%d,wMaxPacketSize=%d,bmAttributes=%d\r\n",input_ep,epDesc->wMaxPacketSize,epDesc->bmAttributes);
00132 
00133                 } else if (!output_ep) {
00134                     output_ep=epDesc->bEndpointAddress& 0x7f;
00135                     //PacketSize drop
00136                     log("output Endpoint address=%d,wMaxPacketSize=%d,bmAttributes=%d\r\n",input_ep,epDesc->wMaxPacketSize,epDesc->bmAttributes);
00137                 } else {
00138                     //other
00139                     log("non input,output Endpoint address=%d,wMaxPacketSize=%d,bmAttributes=%d\r\n",input_ep,epDesc->wMaxPacketSize,epDesc->bmAttributes);
00140                 }
00141                 break;
00142             default:
00143                 log("unkown desc type(%d) \r\n",descType);
00144         }
00145         p+=descLen;
00146     }
00147 
00148     if (!(input_ep && output_ep)) {
00149         log("can't find accessory endpoints\r\n");
00150         return;
00151     }
00152 
00153     log("SetConfiguration\r\n");
00154     err = SetConfiguration(device,configuration);
00155     if (err < 0) {
00156         log("SetConfiguration error\r\n");
00157         return;
00158     }
00159 
00160 
00161     log("interrupt setup\r\n");
00162     //interrupt setup
00163     if (_readbuff==NULL || _readbuffsize<=0) {
00164         error("_readbuffer error please setup buffer call setReadBuffer function\r\n");
00165     }
00166 
00167     if (IO_PENDING!=USBBulkTransfer(_device,input_ep|0x80,_readbuff,_readbuffsize,AdkreadCallback,this))
00168         return;
00169 
00170 
00171     log("setupDevice\r\n");
00172     this->setupDevice();
00173 //    _initok=true;
00174 }
00175 
00176 
00177 
00178 bool AndroidAccessory::switchDevice(int device) {
00179 
00180     if (1==getProtocol(device)) {
00181         log("device supports protocol 1\r\n");
00182 
00183     } else {
00184         log("could not read device protocol version\r\n");
00185         return false;
00186     }
00187 
00188 
00189     sendString(device,ACCESSORY_STRING_MANUFACTURER,manufacturer);
00190     sendString(device,ACCESSORY_STRING_MODEL,model);
00191     sendString(device,ACCESSORY_STRING_DESCRIPTION,description);
00192     sendString(device,ACCESSORY_STRING_VERSION,version);
00193     sendString(device,ACCESSORY_STRING_URI,uri);
00194     sendString(device,ACCESSORY_STRING_SERIAL,serial);
00195     USBControlTransfer(device,
00196                        HOST_TO_DEVICE |REQUEST_TYPE_VENDOR|RECIPIENT_DEVICE,
00197                        ACCESSORY_START,
00198                        0,//value
00199                        0, //index
00200                        0,
00201                        0,
00202                        0,
00203                        0 );
00204 
00205     wait_ms(4);
00206     //reset usb host
00207     USBInit();
00208 
00209     return true;
00210 
00211 }
00212 
00213 
00214 int AndroidAccessory::getProtocol(int device) {
00215     s16 data=-1;
00216     USBControlTransfer(device,
00217                        DEVICE_TO_HOST|REQUEST_TYPE_VENDOR|RECIPIENT_DEVICE,
00218                        ACCESSORY_GET_PROTOCOL,
00219                        0,//value
00220                        0, //index
00221                        (u8*)&data,
00222                        2,
00223                        0,
00224                        0 );
00225     return data;
00226 
00227 }
00228 
00229 void AndroidAccessory::sendString(const char *str) {
00230     sendString(_device,1,str);
00231 
00232 }
00233 
00234 void AndroidAccessory::sendString(int device, int index, const char *str) {
00235 
00236     LOG("send_string start(%d,%d,%s)  %d \r\n",device,index,str,strlen(str)+1);
00237     strcpy((char*)_strbuff,str);
00238     //thankyou curryman san
00239     USBControlTransfer(device,
00240                        HOST_TO_DEVICE|REQUEST_TYPE_VENDOR|RECIPIENT_DEVICE,
00241                        ACCESSORY_SEND_STRING,
00242                        0,//value
00243                        index,
00244                        _strbuff,
00245                        strlen(str)+1
00246                       );
00247 
00248     LOG("send_string end(%d,%d,%s)\r\n",device,index,str);
00249 
00250 }
00251 
00252 
00253 /** from USBHost load function. initialize Android device**/
00254 void OnLoadDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc) {
00255     printf("LoadDevice %d %02X:%02X:%02X\r\n",device,interfaceDesc->bInterfaceClass,interfaceDesc->bInterfaceSubClass,interfaceDesc->bInterfaceProtocol);
00256     char s[128];
00257 
00258     for (int i = 1; i < 3; i++) {
00259         if (GetString(device,i,s,sizeof(s)) < 0)
00260             break;
00261         printf("%d: %s\r\n",i,s);
00262     }
00263 
00264     //for android ADK
00265     if ( ( deviceDesc->idVendor != 0x18D1 ||
00266             ( deviceDesc->idProduct != 0x2D00 && deviceDesc->idProduct != 0x2D01))
00267             &&_adk->switchDevice(device)) {
00268 
00269         printf("  try to change accmode.interfaceDesc->bInterfaceClass=%d\r\n",interfaceDesc->bInterfaceClass);
00270         //1th root
00271         //accmode_support=true;
00272         printf("accessory mode ok.\r\n");
00273         return;
00274     }
00275 
00276     if (deviceDesc->idVendor == 0x18D1 &&
00277             (deviceDesc->idProduct == 0x2D00 || deviceDesc->idProduct == 0x2D01)) {
00278         //2th root
00279         printf("connecting Android.\r\n");
00280         printf("idVender=%x  idProduct=%x  interfaceDesc->bInterfaceClass=%d\r\n",deviceDesc->idVendor,deviceDesc->idProduct,interfaceDesc->bInterfaceClass);
00281         _adk->init(device,1,0);
00282         //_AdkUSB.loop();
00283         return;
00284     }
00285 }
00286 
00287 void AdkreadCallback(int device, int endpoint, int status, u8* buf, int len, void* userData) {
00288     log("AdkreadCallback(int device=%d, int endpoint=%x, int status=%d, u8* buf=%p, int len=%d, void* userData=%p)\r\n",
00289         device,endpoint,status,buf,len,userData);
00290 //    __disable_irq();
00291     AndroidAccessory* t = (AndroidAccessory*)userData;
00292     if (status!=0 && status!=8) {
00293         log("adk end.\r\n");
00294         t->adkEnd();
00295 //        __enable_irq();
00296         USBInit();
00297         return;
00298     }
00299 
00300 
00301     //virtual method run
00302     t->callbackRead(buf,len);
00303 
00304     USBBulkTransfer(device, endpoint , buf, len, AdkreadCallback, userData);
00305 
00306 //    wait_ms(4);
00307 //    __enable_irq();
00308 }
00309 
00310 
00311 
00312 
00313 void AdkwriteCallback(int device, int endpoint, int status, u8* buf, int len, void* userData) {
00314 
00315     log("AdkwriteCallback(int device=%d, int endpoint=%x, int status=%d, u8* buf=%p, int len=%d, void* userData=%p)\r\n",
00316         device,endpoint,status,buf,len,userData);
00317     
00318     AndroidAccessory* t = (AndroidAccessory*)userData;
00319     t->callbackWrite();
00320     //wait_ms(4);
00321     //USBBulkTransfer(device, endpoint , buf, len, AdkwriteCallback, userData);
00322 }
00323