Rich Bayliss / AndroidAccessory
Committer:
richbayliss
Date:
Mon Jul 11 20:51:05 2011 +0000
Revision:
0:8a0d4584ca86
Child:
3:ca0516beb781
Initial Version

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