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