00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <Max3421e.h>
00019 #include <Usb.h>
00020 #include <AndroidAccessory.h>
00021
00022 #define USB_ACCESSORY_VENDOR_ID 0x18D1
00023 #define USB_ACCESSORY_PRODUCT_ID 0x2D00
00024
00025 #define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01
00026 #define ACCESSORY_STRING_MANUFACTURER 0
00027 #define ACCESSORY_STRING_MODEL 1
00028 #define ACCESSORY_STRING_DESCRIPTION 2
00029 #define ACCESSORY_STRING_VERSION 3
00030 #define ACCESSORY_STRING_URI 4
00031 #define ACCESSORY_STRING_SERIAL 5
00032
00033 #define ACCESSORY_GET_PROTOCOL 51
00034 #define ACCESSORY_SEND_STRING 52
00035 #define ACCESSORY_START 53
00036
00037
00038 AndroidAccessory::AndroidAccessory(const char *manufacturer,
00039 const char *model,
00040 const char *description,
00041 const char *version,
00042 const char *uri,
00043 const char *serial) : manufacturer(manufacturer),
00044 model(model),
00045 description(description),
00046 version(version),
00047 uri(uri),
00048 serial(serial),
00049 connected(false)
00050 {
00051
00052 }
00053
00054 void AndroidAccessory::powerOn(void)
00055 {
00056 max.powerOn();
00057 delay(200);
00058 }
00059
00060 int AndroidAccessory::getProtocol(byte addr)
00061 {
00062 uint16_t protocol = -1;
00063 usb.ctrlReq(addr, 0,
00064 USB_SETUP_DEVICE_TO_HOST |
00065 USB_SETUP_TYPE_VENDOR |
00066 USB_SETUP_RECIPIENT_DEVICE,
00067 ACCESSORY_GET_PROTOCOL, 0, 0, 0, 2, (char *)&protocol);
00068 return protocol;
00069 }
00070
00071 void AndroidAccessory::sendString(byte addr, int index, const char *str)
00072 {
00073 usb.ctrlReq(addr, 0,
00074 USB_SETUP_HOST_TO_DEVICE |
00075 USB_SETUP_TYPE_VENDOR |
00076 USB_SETUP_RECIPIENT_DEVICE,
00077 ACCESSORY_SEND_STRING, 0, 0, index,
00078 strlen(str) + 1, (char *)str);
00079 }
00080
00081
00082 bool AndroidAccessory::switchDevice(byte addr)
00083 {
00084 int protocol = getProtocol(addr);
00085
00086 if (protocol == 1) {
00087 Serial.print("device supports protcol 1\n");
00088 } else {
00089 Serial.print("could not read device protocol version\n");
00090 return false;
00091 }
00092
00093 sendString(addr, ACCESSORY_STRING_MANUFACTURER, manufacturer);
00094 sendString(addr, ACCESSORY_STRING_MODEL, model);
00095 sendString(addr, ACCESSORY_STRING_DESCRIPTION, description);
00096 sendString(addr, ACCESSORY_STRING_VERSION, version);
00097 sendString(addr, ACCESSORY_STRING_URI, uri);
00098 sendString(addr, ACCESSORY_STRING_SERIAL, serial);
00099
00100 usb.ctrlReq(addr, 0,
00101 USB_SETUP_HOST_TO_DEVICE |
00102 USB_SETUP_TYPE_VENDOR |
00103 USB_SETUP_RECIPIENT_DEVICE,
00104 ACCESSORY_START, 0, 0, 0, 0, NULL);
00105
00106 while (usb.getUsbTaskState() != USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE) {
00107 max.Task();
00108 usb.Task();
00109 }
00110
00111 return true;
00112 }
00113
00114
00115 bool AndroidAccessory::findEndpoints(byte addr, EP_RECORD *inEp, EP_RECORD *outEp)
00116 {
00117 int len;
00118 byte err;
00119 uint8_t *p;
00120
00121 err = usb.getConfDescr(addr, 0, 4, 0, (char *)descBuff);
00122 if (err) {
00123 Serial.print("Can't get config descriptor length\n");
00124 return false;
00125 }
00126
00127
00128 len = descBuff[2] | ((int)descBuff[3] << 8);
00129 if (len > sizeof(descBuff)) {
00130 Serial.print("config descriptor too large\n");
00131
00132 return false;
00133 }
00134
00135 err = usb.getConfDescr(addr, 0, len, 0, (char *)descBuff);
00136 if (err) {
00137 Serial.print("Can't get config descriptor\n");
00138 return false;
00139 }
00140
00141 p = descBuff;
00142 inEp->epAddr = 0;
00143 outEp->epAddr = 0;
00144 while (p < (descBuff + len)){
00145 uint8_t descLen = p[0];
00146 uint8_t descType = p[1];
00147 USB_ENDPOINT_DESCRIPTOR *epDesc;
00148 EP_RECORD *ep;
00149
00150 switch (descType) {
00151 case USB_DESCRIPTOR_CONFIGURATION:
00152 Serial.print("config desc\n");
00153 break;
00154
00155 case USB_DESCRIPTOR_INTERFACE:
00156 Serial.print("interface desc\n");
00157 break;
00158
00159 case USB_DESCRIPTOR_ENDPOINT:
00160 epDesc = (USB_ENDPOINT_DESCRIPTOR *)p;
00161 if (!inEp->epAddr && (epDesc->bEndpointAddress & 0x80))
00162 ep = inEp;
00163 else if (!outEp->epAddr)
00164 ep = outEp;
00165 else
00166 ep = NULL;
00167
00168 if (ep) {
00169 ep->epAddr = epDesc->bEndpointAddress & 0x7f;
00170 ep->Attr = epDesc->bmAttributes;
00171 ep->MaxPktSize = epDesc->wMaxPacketSize;
00172 ep->sndToggle = bmSNDTOG0;
00173 ep->rcvToggle = bmRCVTOG0;
00174 }
00175 break;
00176
00177 default:
00178 Serial.print("unkown desc type ");
00179 Serial.println( descType, HEX);
00180 break;
00181 }
00182
00183 p += descLen;
00184 }
00185
00186 if (!(inEp->epAddr && outEp->epAddr))
00187 Serial.println("can't find accessory endpoints");
00188
00189 return inEp->epAddr && outEp->epAddr;
00190 }
00191
00192 bool AndroidAccessory::configureAndroid(void)
00193 {
00194 byte err;
00195 EP_RECORD inEp, outEp;
00196
00197 if (!findEndpoints(1, &inEp, &outEp))
00198 return false;
00199
00200 memset(&epRecord, 0x0, sizeof(epRecord));
00201
00202 epRecord[inEp.epAddr] = inEp;
00203 if (outEp.epAddr != inEp.epAddr)
00204 epRecord[outEp.epAddr] = outEp;
00205
00206 in = inEp.epAddr;
00207 out = outEp.epAddr;
00208
00209 Serial.println(inEp.epAddr, HEX);
00210 Serial.println(outEp.epAddr, HEX);
00211
00212 epRecord[0] = *(usb.getDevTableEntry(0,0));
00213 usb.setDevTableEntry(1, epRecord);
00214
00215 err = usb.setConf( 1, 0, 1 );
00216 if (err) {
00217 Serial.print("Can't set config to 1\n");
00218 return false;
00219 }
00220
00221 usb.setUsbTaskState( USB_STATE_RUNNING );
00222
00223 return true;
00224 }
00225
00226 bool AndroidAccessory::isConnected(void)
00227 {
00228 USB_DEVICE_DESCRIPTOR *devDesc = (USB_DEVICE_DESCRIPTOR *) descBuff;
00229 byte err;
00230
00231 max.Task();
00232 usb.Task();
00233
00234 if (!connected &&
00235 usb.getUsbTaskState() >= USB_STATE_CONFIGURING &&
00236 usb.getUsbTaskState() != USB_STATE_RUNNING) {
00237 Serial.print("\nDevice addressed... ");
00238 Serial.print("Requesting device descriptor.\n");
00239
00240 err = usb.getDevDescr(1, 0, 0x12, (char *) devDesc);
00241 if (err) {
00242 Serial.print("\nDevice descriptor cannot be retrieved. Trying again\n");
00243 return false;
00244 }
00245
00246 if (isAccessoryDevice(devDesc)) {
00247 Serial.print("found android acessory device\n");
00248
00249 connected = configureAndroid();
00250 } else {
00251 Serial.print("found possible device. swithcing to serial mode\n");
00252 switchDevice(1);
00253 }
00254 } else if (usb.getUsbTaskState() == USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE) {
00255 if (connected)
00256 Serial.println("disconnect\n");
00257 connected = false;
00258 }
00259
00260 return connected;
00261 }
00262
00263 int AndroidAccessory::read(void *buff, int len, unsigned int nakLimit)
00264 {
00265 return usb.newInTransfer(1, in, len, (char *)buff, nakLimit);
00266 }
00267
00268 int AndroidAccessory::write(void *buff, int len)
00269 {
00270 usb.outTransfer(1, out, len, (char *)buff);
00271 return len;
00272 }
00273