Library to allow your mbed device to communicate with the Android ADK.

Committer:
richbayliss
Date:
Tue Jul 12 17:36:58 2011 +0000
Revision:
3:ca0516beb781
Parent:
0:8a0d4584ca86

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
richbayliss 0:8a0d4584ca86 1 #include <stdio.h>
richbayliss 0:8a0d4584ca86 2 #include <stdlib.h>
richbayliss 0:8a0d4584ca86 3 #include <string.h>
richbayliss 0:8a0d4584ca86 4
richbayliss 0:8a0d4584ca86 5 #include "USBHost.h"
richbayliss 0:8a0d4584ca86 6 #include "AndroidAccessory.h"
richbayliss 0:8a0d4584ca86 7 #include "mbed.h"
richbayliss 0:8a0d4584ca86 8
richbayliss 0:8a0d4584ca86 9 AndroidAccessory* _adk;
richbayliss 0:8a0d4584ca86 10
richbayliss 0:8a0d4584ca86 11 void AdkreadCallback(int device, int endpoint, int status, u8* buf, int len, void* userData);
richbayliss 0:8a0d4584ca86 12 void AdkwriteCallback(int device, int endpoint, int status, u8* buf, int len, void* userData);
richbayliss 0:8a0d4584ca86 13
richbayliss 0:8a0d4584ca86 14
richbayliss 0:8a0d4584ca86 15
richbayliss 0:8a0d4584ca86 16 AndroidAccessory::AndroidAccessory(int rbuffsize,int wbuffsize,
richbayliss 0:8a0d4584ca86 17 const char* manufacturer,
richbayliss 0:8a0d4584ca86 18 const char *model,
richbayliss 0:8a0d4584ca86 19 const char *description,
richbayliss 0:8a0d4584ca86 20 const char *version,
richbayliss 0:8a0d4584ca86 21 const char *uri,
richbayliss 0:8a0d4584ca86 22 const char *serial
richbayliss 0:8a0d4584ca86 23 ) {
richbayliss 0:8a0d4584ca86 24
richbayliss 0:8a0d4584ca86 25 _adk=this;
richbayliss 0:8a0d4584ca86 26
richbayliss 0:8a0d4584ca86 27 this->manufacturer=manufacturer;
richbayliss 0:8a0d4584ca86 28 this->model=model;
richbayliss 0:8a0d4584ca86 29 this->description=description;
richbayliss 0:8a0d4584ca86 30 this->version=version;
richbayliss 0:8a0d4584ca86 31 this->uri=uri;
richbayliss 0:8a0d4584ca86 32 this->serial=serial;
richbayliss 0:8a0d4584ca86 33
richbayliss 0:8a0d4584ca86 34 u32 len;
richbayliss 0:8a0d4584ca86 35 u8* p=USBGetBuffer(&len);
richbayliss 0:8a0d4584ca86 36 if (len<(rbuffsize+wbuffsize+255)) {
richbayliss 0:8a0d4584ca86 37 error("buff size too big.please resize max=%d. currentSize=%d\r\n",len,(rbuffsize+wbuffsize+255));
richbayliss 0:8a0d4584ca86 38 }
richbayliss 0:8a0d4584ca86 39
richbayliss 0:8a0d4584ca86 40 _readbuff=p;
richbayliss 0:8a0d4584ca86 41 _readbuffsize=rbuffsize;
richbayliss 0:8a0d4584ca86 42 p+=rbuffsize;
richbayliss 0:8a0d4584ca86 43 _writebuff=p;
richbayliss 0:8a0d4584ca86 44 _writebuffsize=wbuffsize;
richbayliss 0:8a0d4584ca86 45 p+=wbuffsize;
richbayliss 0:8a0d4584ca86 46 _strbuff=p;
richbayliss 0:8a0d4584ca86 47 p+=255;
richbayliss 0:8a0d4584ca86 48
richbayliss 0:8a0d4584ca86 49 }
richbayliss 0:8a0d4584ca86 50
richbayliss 0:8a0d4584ca86 51
richbayliss 0:8a0d4584ca86 52
richbayliss 0:8a0d4584ca86 53 int AndroidAccessory::write(u8 *buff, int len) {
richbayliss 0:8a0d4584ca86 54 log("AndroidAccessory::write ");
richbayliss 0:8a0d4584ca86 55 // __disable_irq();
richbayliss 0:8a0d4584ca86 56 int ret=USBBulkTransfer(_device,output_ep,buff,len/*,AdkwriteCallback,this*/);
richbayliss 0:8a0d4584ca86 57 // __enable_irq();
richbayliss 0:8a0d4584ca86 58 log("--ret=%d \r\n",ret);
richbayliss 0:8a0d4584ca86 59 return ret;
richbayliss 0:8a0d4584ca86 60 }
richbayliss 0:8a0d4584ca86 61
richbayliss 0:8a0d4584ca86 62 #if 0
richbayliss 0:8a0d4584ca86 63 int AndroidAccessory::read(u8 *buff, int len) {
richbayliss 0:8a0d4584ca86 64 if(_initok==false)return 0;
richbayliss 0:8a0d4584ca86 65
richbayliss 0:8a0d4584ca86 66 log("AndroidAccessory::read ");
richbayliss 0:8a0d4584ca86 67 // __disable_irq();
richbayliss 0:8a0d4584ca86 68 int ret=USBBulkTransfer(_device,input_ep|0x80,buff,len);
richbayliss 0:8a0d4584ca86 69 // __enable_irq();
richbayliss 0:8a0d4584ca86 70 log("--ret=%d \r\n",ret);
richbayliss 0:8a0d4584ca86 71 return ret;
richbayliss 0:8a0d4584ca86 72 }
richbayliss 0:8a0d4584ca86 73 #endif
richbayliss 0:8a0d4584ca86 74
richbayliss 0:8a0d4584ca86 75 void AndroidAccessory::init(int device, int configuration, int interfaceNumber) {
richbayliss 0:8a0d4584ca86 76
richbayliss 0:8a0d4584ca86 77 log("AndroidAccessory::init \r\n");
richbayliss 0:8a0d4584ca86 78
richbayliss 3:ca0516beb781 79 USBInit();
richbayliss 0:8a0d4584ca86 80 // _initok=false;
richbayliss 0:8a0d4584ca86 81 _device = device;
richbayliss 0:8a0d4584ca86 82 _configuration = configuration;
richbayliss 0:8a0d4584ca86 83 _interfaceNumber = interfaceNumber;
richbayliss 0:8a0d4584ca86 84 printf("device = %d configuration = %d interfaceNumber = %d\r\n", device, configuration, interfaceNumber);
richbayliss 0:8a0d4584ca86 85 int err;
richbayliss 0:8a0d4584ca86 86
richbayliss 0:8a0d4584ca86 87 u8* buffer=_strbuff;
richbayliss 0:8a0d4584ca86 88 err = GetDescriptor(_device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,4);
richbayliss 0:8a0d4584ca86 89
richbayliss 0:8a0d4584ca86 90 if (err < 0) {
richbayliss 0:8a0d4584ca86 91 log("Failed to get descriptor\r\n");
richbayliss 0:8a0d4584ca86 92 return;
richbayliss 0:8a0d4584ca86 93 }
richbayliss 0:8a0d4584ca86 94
richbayliss 0:8a0d4584ca86 95
richbayliss 0:8a0d4584ca86 96 int len = buffer[2] | (buffer[3] << 8);
richbayliss 0:8a0d4584ca86 97 if (len > 255) {
richbayliss 0:8a0d4584ca86 98 log("config descriptor too large\n");
richbayliss 0:8a0d4584ca86 99 /* might want to truncate here */
richbayliss 0:8a0d4584ca86 100 return;
richbayliss 0:8a0d4584ca86 101 }
richbayliss 0:8a0d4584ca86 102 err = GetDescriptor(_device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,len);
richbayliss 0:8a0d4584ca86 103 u8* p = buffer;
richbayliss 0:8a0d4584ca86 104 input_ep=0;
richbayliss 0:8a0d4584ca86 105 output_ep=0;
richbayliss 0:8a0d4584ca86 106 EndpointDescriptor *epDesc;
richbayliss 0:8a0d4584ca86 107 while (p<(buffer+len)) {
richbayliss 0:8a0d4584ca86 108 u8 descLen = p[0];
richbayliss 0:8a0d4584ca86 109 u8 descType = p[1];
richbayliss 0:8a0d4584ca86 110 log("descLen=%d,descType=%d\r\n",descLen,descType);
richbayliss 0:8a0d4584ca86 111 switch (descType) {
richbayliss 0:8a0d4584ca86 112 case DESCRIPTOR_TYPE_CONFIGURATION:
richbayliss 0:8a0d4584ca86 113 log("config desc\r\n");
richbayliss 0:8a0d4584ca86 114 break;
richbayliss 0:8a0d4584ca86 115 case DESCRIPTOR_TYPE_INTERFACE:
richbayliss 0:8a0d4584ca86 116 log("interface desc\r\n");
richbayliss 0:8a0d4584ca86 117 break;
richbayliss 0:8a0d4584ca86 118 case DESCRIPTOR_TYPE_ENDPOINT:
richbayliss 0:8a0d4584ca86 119 epDesc=(EndpointDescriptor*)p;
richbayliss 0:8a0d4584ca86 120 if (!input_ep && (epDesc->bEndpointAddress& 0x80)) {
richbayliss 0:8a0d4584ca86 121 input_ep=epDesc->bEndpointAddress& 0x7f;
richbayliss 0:8a0d4584ca86 122 //PacketSize drop
richbayliss 0:8a0d4584ca86 123 log("input Endpoint address=%d,wMaxPacketSize=%d,bmAttributes=%d\r\n",input_ep,epDesc->wMaxPacketSize,epDesc->bmAttributes);
richbayliss 0:8a0d4584ca86 124
richbayliss 0:8a0d4584ca86 125 } else if (!output_ep) {
richbayliss 0:8a0d4584ca86 126 output_ep=epDesc->bEndpointAddress& 0x7f;
richbayliss 0:8a0d4584ca86 127 //PacketSize drop
richbayliss 0:8a0d4584ca86 128 log("output Endpoint address=%d,wMaxPacketSize=%d,bmAttributes=%d\r\n",input_ep,epDesc->wMaxPacketSize,epDesc->bmAttributes);
richbayliss 0:8a0d4584ca86 129 } else {
richbayliss 0:8a0d4584ca86 130 //other
richbayliss 0:8a0d4584ca86 131 log("non input,output Endpoint address=%d,wMaxPacketSize=%d,bmAttributes=%d\r\n",input_ep,epDesc->wMaxPacketSize,epDesc->bmAttributes);
richbayliss 0:8a0d4584ca86 132 }
richbayliss 0:8a0d4584ca86 133 break;
richbayliss 0:8a0d4584ca86 134 default:
richbayliss 0:8a0d4584ca86 135 log("unkown desc type(%d) \r\n",descType);
richbayliss 0:8a0d4584ca86 136 }
richbayliss 0:8a0d4584ca86 137 p+=descLen;
richbayliss 0:8a0d4584ca86 138 }
richbayliss 0:8a0d4584ca86 139
richbayliss 0:8a0d4584ca86 140 if (!(input_ep && output_ep)) {
richbayliss 0:8a0d4584ca86 141 log("can't find accessory endpoints\r\n");
richbayliss 0:8a0d4584ca86 142 return;
richbayliss 0:8a0d4584ca86 143 }
richbayliss 0:8a0d4584ca86 144
richbayliss 0:8a0d4584ca86 145 log("SetConfiguration\r\n");
richbayliss 0:8a0d4584ca86 146 err = SetConfiguration(device,configuration);
richbayliss 0:8a0d4584ca86 147 if (err < 0) {
richbayliss 0:8a0d4584ca86 148 log("SetConfiguration error\r\n");
richbayliss 0:8a0d4584ca86 149 return;
richbayliss 0:8a0d4584ca86 150 }
richbayliss 0:8a0d4584ca86 151
richbayliss 0:8a0d4584ca86 152
richbayliss 0:8a0d4584ca86 153 log("interrupt setup\r\n");
richbayliss 0:8a0d4584ca86 154 //interrupt setup
richbayliss 0:8a0d4584ca86 155 if (_readbuff==NULL || _readbuffsize<=0) {
richbayliss 0:8a0d4584ca86 156 error("_readbuffer error please setup buffer call setReadBuffer function\r\n");
richbayliss 0:8a0d4584ca86 157 }
richbayliss 0:8a0d4584ca86 158
richbayliss 0:8a0d4584ca86 159 if (IO_PENDING!=USBBulkTransfer(_device,input_ep|0x80,_readbuff,_readbuffsize,AdkreadCallback,this))
richbayliss 0:8a0d4584ca86 160 return;
richbayliss 0:8a0d4584ca86 161
richbayliss 0:8a0d4584ca86 162
richbayliss 0:8a0d4584ca86 163 log("setupDevice\r\n");
richbayliss 0:8a0d4584ca86 164 this->setupDevice();
richbayliss 0:8a0d4584ca86 165 // _initok=true;
richbayliss 0:8a0d4584ca86 166 }
richbayliss 0:8a0d4584ca86 167
richbayliss 0:8a0d4584ca86 168
richbayliss 0:8a0d4584ca86 169
richbayliss 0:8a0d4584ca86 170 bool AndroidAccessory::switchDevice(int device) {
richbayliss 0:8a0d4584ca86 171
richbayliss 0:8a0d4584ca86 172 if (1==getProtocol(device)) {
richbayliss 0:8a0d4584ca86 173 log("device supports protocol 1\r\n");
richbayliss 0:8a0d4584ca86 174
richbayliss 0:8a0d4584ca86 175 } else {
richbayliss 0:8a0d4584ca86 176 log("could not read device protocol version\r\n");
richbayliss 0:8a0d4584ca86 177 return false;
richbayliss 0:8a0d4584ca86 178 }
richbayliss 0:8a0d4584ca86 179
richbayliss 0:8a0d4584ca86 180
richbayliss 0:8a0d4584ca86 181 sendString(device,ACCESSORY_STRING_MANUFACTURER,manufacturer);
richbayliss 0:8a0d4584ca86 182 sendString(device,ACCESSORY_STRING_MODEL,model);
richbayliss 0:8a0d4584ca86 183 sendString(device,ACCESSORY_STRING_DESCRIPTION,description);
richbayliss 0:8a0d4584ca86 184 sendString(device,ACCESSORY_STRING_VERSION,version);
richbayliss 0:8a0d4584ca86 185 sendString(device,ACCESSORY_STRING_URI,uri);
richbayliss 0:8a0d4584ca86 186 sendString(device,ACCESSORY_STRING_SERIAL,serial);
richbayliss 0:8a0d4584ca86 187 USBControlTransfer(device,
richbayliss 0:8a0d4584ca86 188 HOST_TO_DEVICE |REQUEST_TYPE_VENDOR|RECIPIENT_DEVICE,
richbayliss 0:8a0d4584ca86 189 ACCESSORY_START,
richbayliss 0:8a0d4584ca86 190 0,//value
richbayliss 0:8a0d4584ca86 191 0, //index
richbayliss 0:8a0d4584ca86 192 0,
richbayliss 0:8a0d4584ca86 193 0,
richbayliss 0:8a0d4584ca86 194 0,
richbayliss 0:8a0d4584ca86 195 0 );
richbayliss 0:8a0d4584ca86 196
richbayliss 0:8a0d4584ca86 197 wait_ms(4);
richbayliss 0:8a0d4584ca86 198 //reset usb host
richbayliss 0:8a0d4584ca86 199 USBInit();
richbayliss 0:8a0d4584ca86 200
richbayliss 0:8a0d4584ca86 201 return true;
richbayliss 0:8a0d4584ca86 202
richbayliss 0:8a0d4584ca86 203 }
richbayliss 0:8a0d4584ca86 204
richbayliss 0:8a0d4584ca86 205
richbayliss 0:8a0d4584ca86 206 int AndroidAccessory::getProtocol(int device) {
richbayliss 0:8a0d4584ca86 207 s16 data=-1;
richbayliss 0:8a0d4584ca86 208 USBControlTransfer(device,
richbayliss 0:8a0d4584ca86 209 DEVICE_TO_HOST|REQUEST_TYPE_VENDOR|RECIPIENT_DEVICE,
richbayliss 0:8a0d4584ca86 210 ACCESSORY_GET_PROTOCOL,
richbayliss 0:8a0d4584ca86 211 0,//value
richbayliss 0:8a0d4584ca86 212 0, //index
richbayliss 0:8a0d4584ca86 213 (u8*)&data,
richbayliss 0:8a0d4584ca86 214 2,
richbayliss 0:8a0d4584ca86 215 0,
richbayliss 0:8a0d4584ca86 216 0 );
richbayliss 0:8a0d4584ca86 217 return data;
richbayliss 0:8a0d4584ca86 218
richbayliss 0:8a0d4584ca86 219 }
richbayliss 0:8a0d4584ca86 220
richbayliss 0:8a0d4584ca86 221 void AndroidAccessory::sendString(int device, int index, const char *str) {
richbayliss 0:8a0d4584ca86 222
richbayliss 0:8a0d4584ca86 223 LOG("send_string start(%d,%d,%s) %d \r\n",device,index,str,strlen(str)+1);
richbayliss 0:8a0d4584ca86 224 strcpy((char*)_strbuff,str);
richbayliss 0:8a0d4584ca86 225 //thankyou curryman san
richbayliss 0:8a0d4584ca86 226 USBControlTransfer(device,
richbayliss 0:8a0d4584ca86 227 HOST_TO_DEVICE|REQUEST_TYPE_VENDOR|RECIPIENT_DEVICE,
richbayliss 0:8a0d4584ca86 228 ACCESSORY_SEND_STRING,
richbayliss 0:8a0d4584ca86 229 0,//value
richbayliss 0:8a0d4584ca86 230 index,
richbayliss 0:8a0d4584ca86 231 _strbuff,
richbayliss 0:8a0d4584ca86 232 strlen(str)+1
richbayliss 0:8a0d4584ca86 233 );
richbayliss 0:8a0d4584ca86 234
richbayliss 0:8a0d4584ca86 235 LOG("send_string end(%d,%d,%s)\r\n",device,index,str);
richbayliss 0:8a0d4584ca86 236
richbayliss 0:8a0d4584ca86 237 }
richbayliss 0:8a0d4584ca86 238
richbayliss 0:8a0d4584ca86 239
richbayliss 0:8a0d4584ca86 240 /** from USBHost load function. initialize Android device**/
richbayliss 0:8a0d4584ca86 241 void OnLoadDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc) {
richbayliss 0:8a0d4584ca86 242 printf("LoadDevice %d %02X:%02X:%02X\r\n",device,interfaceDesc->bInterfaceClass,interfaceDesc->bInterfaceSubClass,interfaceDesc->bInterfaceProtocol);
richbayliss 0:8a0d4584ca86 243 char s[128];
richbayliss 0:8a0d4584ca86 244
richbayliss 0:8a0d4584ca86 245 for (int i = 1; i < 3; i++) {
richbayliss 0:8a0d4584ca86 246 if (GetString(device,i,s,sizeof(s)) < 0)
richbayliss 0:8a0d4584ca86 247 break;
richbayliss 0:8a0d4584ca86 248 printf("%d: %s\r\n",i,s);
richbayliss 0:8a0d4584ca86 249 }
richbayliss 0:8a0d4584ca86 250
richbayliss 0:8a0d4584ca86 251 //for android ADK
richbayliss 0:8a0d4584ca86 252 if ( ( deviceDesc->idVendor != 0x18D1 ||
richbayliss 0:8a0d4584ca86 253 ( deviceDesc->idProduct != 0x2D00 && deviceDesc->idProduct != 0x2D01))
richbayliss 0:8a0d4584ca86 254 &&_adk->switchDevice(device)) {
richbayliss 0:8a0d4584ca86 255
richbayliss 0:8a0d4584ca86 256 printf(" try to change accmode.interfaceDesc->bInterfaceClass=%d\r\n",interfaceDesc->bInterfaceClass);
richbayliss 0:8a0d4584ca86 257 //1th root
richbayliss 0:8a0d4584ca86 258 //accmode_support=true;
richbayliss 0:8a0d4584ca86 259 printf("accessory mode ok.\r\n");
richbayliss 0:8a0d4584ca86 260 return;
richbayliss 0:8a0d4584ca86 261 }
richbayliss 0:8a0d4584ca86 262
richbayliss 0:8a0d4584ca86 263 if (deviceDesc->idVendor == 0x18D1 &&
richbayliss 0:8a0d4584ca86 264 (deviceDesc->idProduct == 0x2D00 || deviceDesc->idProduct == 0x2D01)) {
richbayliss 0:8a0d4584ca86 265 //2th root
richbayliss 0:8a0d4584ca86 266 printf("connecting Android.\r\n");
richbayliss 0:8a0d4584ca86 267 printf("idVender=%x idProduct=%x interfaceDesc->bInterfaceClass=%d\r\n",deviceDesc->idVendor,deviceDesc->idProduct,interfaceDesc->bInterfaceClass);
richbayliss 0:8a0d4584ca86 268 _adk->init(device,1,0);
richbayliss 0:8a0d4584ca86 269 //_AdkUSB.loop();
richbayliss 0:8a0d4584ca86 270 return;
richbayliss 0:8a0d4584ca86 271 }
richbayliss 0:8a0d4584ca86 272 }
richbayliss 0:8a0d4584ca86 273
richbayliss 0:8a0d4584ca86 274 void AdkreadCallback(int device, int endpoint, int status, u8* buf, int len, void* userData) {
richbayliss 0:8a0d4584ca86 275 log("AdkreadCallback(int device=%d, int endpoint=%x, int status=%d, u8* buf=%p, int len=%d, void* userData=%p)\r\n",
richbayliss 0:8a0d4584ca86 276 device,endpoint,status,buf,len,userData);
richbayliss 0:8a0d4584ca86 277 // __disable_irq();
richbayliss 0:8a0d4584ca86 278 AndroidAccessory* t = (AndroidAccessory*)userData;
richbayliss 0:8a0d4584ca86 279 if (status!=0) {
richbayliss 0:8a0d4584ca86 280 log("adk end.\r\n");
richbayliss 0:8a0d4584ca86 281 t->adkEnd();
richbayliss 0:8a0d4584ca86 282 // __enable_irq();
richbayliss 0:8a0d4584ca86 283 USBInit();
richbayliss 0:8a0d4584ca86 284 return;
richbayliss 0:8a0d4584ca86 285 }
richbayliss 0:8a0d4584ca86 286
richbayliss 0:8a0d4584ca86 287
richbayliss 0:8a0d4584ca86 288 //virtual method run
richbayliss 0:8a0d4584ca86 289 t->callbackRead(buf,len);
richbayliss 0:8a0d4584ca86 290
richbayliss 0:8a0d4584ca86 291 USBBulkTransfer(device, endpoint , buf, len, AdkreadCallback, userData);
richbayliss 0:8a0d4584ca86 292
richbayliss 0:8a0d4584ca86 293 // wait_ms(4);
richbayliss 0:8a0d4584ca86 294 // __enable_irq();
richbayliss 0:8a0d4584ca86 295 }
richbayliss 0:8a0d4584ca86 296
richbayliss 0:8a0d4584ca86 297
richbayliss 0:8a0d4584ca86 298
richbayliss 0:8a0d4584ca86 299 #if 0
richbayliss 0:8a0d4584ca86 300 void AdkwriteCallback(int device, int endpoint, int status, u8* buf, int len, void* userData) {
richbayliss 0:8a0d4584ca86 301
richbayliss 0:8a0d4584ca86 302 log("AdkwriteCallback(int device=%d, int endpoint=%x, int status=%d, u8* buf=%p, int len=%d, void* userData=%p)\r\n",
richbayliss 0:8a0d4584ca86 303 device,endpoint,status,buf,len,userData);
richbayliss 0:8a0d4584ca86 304
richbayliss 0:8a0d4584ca86 305 //AndroidAccessory* t = (AndroidAccessory*)userData;
richbayliss 0:8a0d4584ca86 306 //wait_ms(4);
richbayliss 0:8a0d4584ca86 307
richbayliss 0:8a0d4584ca86 308 }
richbayliss 0:8a0d4584ca86 309 #endif