1 page.title=Accessory Development Kit 2011 Guide 2 @jd:body 3 4 <div id="qv-wrapper"> 5 <div id="qv"> 6 <h2>In this document</h2> 7 8 <ol> 9 <li><a href="#components">ADK Components</a></li> 10 <li> 11 12 <a href="#getting-started">Getting Started with the ADK</a> 13 14 <ol> 15 <li><a href="#installing">Installing the Arduino software and necessary 16 libraries</a></li> 17 18 <li><a href="#installing-firmware">Installing the firmware to the ADK board</a></li> 19 20 <li><a href="#running-demokit">Running the DemoKit Android application</a></li> 21 22 <li><a href="#monitoring">Monitoring the ADK board</a></li> 23 </ol> 24 </li> 25 26 <li> 27 <a href="#firmware">How the ADK board implements the Android Accessory Protocol</a> 28 29 <ol> 30 <li><a href="#wait-adk">Wait for and detect connected devices</a></li> 31 32 <li><a href="#determine-adk">Determine the connected device's accessory mode 33 support</a></li> 34 35 <li><a href="#start-adk">Attempt to start the device in accessory mode</a></li> 36 37 <li><a href="#establish-adk">Establish communication with the device</a></li> 38 </ol> 39 </li> 40 </ol> 41 42 <h2>Download</h2> 43 <ol> 44 <li><a href="https://dl-ssl.google.com/android/adk/adk_release_20120606.zip">ADK package</a></li> 45 </ol> 46 47 <h2>See also</h2> 48 49 <ol> 50 <li><a href="http://www.youtube.com/watch?v=s7szcpXf2rE">Google I/O Session Video</a></li> 51 <li><a href="{@docRoot}guide/topics/connectivity/usb/accessory.html">USB Accessory Dev Guide</a></li> 52 </ol> 53 54 </div> 55 </div> 56 57 <p>The Android Open Accessory Development Kit (ADK) is a reference implementation of an Android 58 Open Accessory, based on the <a href="http://www.arduino.cc/">Arduino open source electronics 59 prototyping platform</a>. The accessory's hardware design files, code that implements the 60 accessory's firmware, and the Android application that interacts with the accessory are provided 61 as part of the kit to help hardware builders and software developers get started building their 62 own accessories. The hardware design files and firmware code are contained in the <a href= 63 "https://dl-ssl.google.com/android/adk/adk_release_20120606.zip">ADK package download</a>.</p> 64 65 <p>A limited number of kits were produced and distributed at the Google I/O 2011 developer 66 conference. However, many hardware builders have reproduced and enhanced the original design and 67 these boards are available for purchase. The following list of distributors are currently 68 producing Android Open Accessory compatible development boards:</p> 69 70 <ul> 71 <li>The <a href="http://store.arduino.cc/">Arduino Store</a> provides the <a 72 href="http://arduino.cc/en/Main/ArduinoBoardADK">Arduino Mega ADK</a> (for EU nations or non- 73 EU nations) that is based on the ATmega2560 and supports the ADK firmware.</li> 74 75 <li><a href="https://store.diydrones.com/ProductDetails.asp?ProductCode=BR-PhoneDrone">DIY 76 Drones</a> provides an Arduino-compatible board geared towards RC (radio controlled) and UAV 77 (unmanned aerial vehicle) enthusiasts.</li> 78 79 <li><a href="http://mbed.org/order/">mbed</a> provides a microcontroller and a library 80 to develop accessories that support the Android accessory protocol. For more information, see 81 <a href="http://mbed.org/cookbook/mbed-with-Android-ADK">mbed with the Android ADK</a>. 82 </li> 83 84 <li><a href="http://www.microchip.com/android">Microchip</a> provides a PIC based USB 85 microcontroller board.</li> 86 87 <li><a href="http://shop.moderndevice.com/products/freeduino-usb-host-board">Modern 88 Device</a> provides an Arduino-compatible board that supports the ADK firmware.</li> 89 90 <li><a href="http://www.rt-net.jp/shop/index.php?main_page=product_info&cPath=3_4&products_id=1"> 91 RT Corp</a> provides an Arduino-compatible board based on the Android ADK board design.</li> 92 93 <li><a href="http://www.seeedstudio.com/depot/seeeduino-adk-main-board-p-846.html"> 94 Seeed Studio</a> provides an Arduino-compatible board that supports the ADK firmware.</li> 95 96 <li><a href="http://www.sparkfun.com/products/10748"> 97 SparkFun</a>'s IOIO board now has beta support for the ADK firmware.</li> 98 99 <li><a href="http://troido.de/de/shoplsmallgbuy-android-stufflsmallg">Troido</a> has produced an 100 Arduino-compatible version of the ADK hardware.</li> 101 102 </ul> 103 104 <p>We expect more hardware distributers to create a variety of kits, so please stay tuned for 105 further developments.</p> 106 107 <h2 id="components">ADK Components</h2> 108 109 <p>The main hardware and software components of the ADK include:</p> 110 111 <ul> 112 <li>A USB micro-controller board that is based on the Arduino Mega2560 and Circuits@Home USB 113 Host Shield designs (now referred to as the ADK board), which you will later implement as an 114 Android USB accessory. The ADK board provides input and output pins that you can implement 115 through the use of attachments called "shields." Custom firmware, written in C++, is installed 116 on the board to define the board's functionality and interaction with the attached shield and 117 Android-powered device. The hardware design files for the board are located in 118 <code>hardware/</code> directory.</li> 119 120 <li>An Android Demo Shield (ADK shield) that affixes atop the ADK board implements the input 121 and output points on the board. These implementations include a joystick, LED outputs, and 122 temperature and light sensors. You can create or buy your own shields or wire your own features 123 to the ADK board to implement custom functionality. The hardware design files for the shield 124 are located in <code>hardware/</code>.</li> 125 126 <li>A library based on the <a href= 127 "http://www.circuitsathome.com/arduino_usb_host_shield_projects">Arduino USB Host Shield</a> 128 library provides the logic for the USB micro-controller board to act as a USB Host. This allows 129 the board to initiate transactions with USB devices. Describing how to use this entire library 130 is beyond the scope of this document. Where needed, this document points out important 131 interactions with the library. For more information, see the source code for the Arduino USB 132 Host Shield library in the <code>arduino_libs/USB_Host_Shield</code> directory.</li> 133 134 <li>An Arduino sketch, <code>arduino_libs/AndroidAccessory/examples/demokit/demokit.pde</code>, 135 defines the firmware that 136 runs on the ADK board and is written in C++. The sketch calls the Android accessory protocol 137 library to interact with the Android-powered device. It also sends data from the ADK board and 138 shield to the Android application and receives data from the Android application and outputs it 139 to the ADK board and shield.</li> 140 141 <li>The Android accessory protocol library, which is located in the 142 <code>arduino_libs/AndroidAccessory</code> directory. This library defines how to 143 enumerate the bus, find a connected Android-powered device that supports accessory mode, and 144 how to setup communication with the device.</li> 145 146 <li>Other third party libraries to support the ADK board's functionality: 147 <ul> 148 <li><a href="http://www.arduino.cc/playground/Main/CapSense">CapSense library</a></li> 149 150 <li><a href="http://www.arduino.cc/playground/Learning/I2C">I2C / TWI (Two-Wire Interface) 151 library</a></li> 152 153 <li><a href="http://www.arduino.cc/playground/ComponentLib/Servo">Servo library</a></li> 154 155 <li><a href="http://www.arduino.cc/playground/Code/Spi">Spi library</a></li> 156 157 <li><a href="http://www.arduino.cc/en/Reference/Wire">Wire library</a></li> 158 159 <li>An Android application, DemoKit, that communicates with the ADK board and shield. The 160 source for this project is in the <code>app/</code> directory.</li> 161 </ul> 162 </li> 163 164 </ul> 165 166 <h2 id="getting-started">Getting Started with the ADK</h2> 167 168 <p>The following sections describe how to install the Arduino software on your computer, use the 169 Arduino IDE to install the ADK board's firmware, and install and run the accompanying 170 Android application for the ADK board. Before you begin, download the following items to set up 171 your development environment:</p> 172 173 <ul> 174 <li><a href="http://arduino.cc/en/Main/Software">Arduino 1.0 or higher</a>: contains 175 libraries and an IDE for coding and installing firmware to the ADK board.</li> 176 177 <li><a href="http://www.arduino.cc/playground/Main/CapSense">CapSense library v.04</a>: 178 contains the libraries to sense human capacitance. This library is needed for the capacitive 179 button that is located on the ADK shield.</li> 180 181 <li><a href="https://dl-ssl.google.com/android/adk/adk_release_20120606.zip">ADK software 182 package</a>: contains the firmware for the ADK board and hardware design files for the ADK 183 board and shield.</li> 184 </ul> 185 186 <h3 id="installing">Installing the Arduino software and necessary libraries</h3> 187 188 <p>To install the Arduino software:</p> 189 190 <ol> 191 <li> 192 <a href="http://arduino.cc/en/Main/Software">Download and install</a> the Arduino 1.0 or 193 higher as described on the Arduino website. 194 195 <p class="note"><strong>Note:</strong> If you are on a Mac, install the FTDI USB Serial 196 Driver that is included in the Arduino package, even though the installation instructions say 197 otherwise.</p> 198 </li> 199 200 <li><a href="https://dl-ssl.google.com/android/adk/adk_release_20120606.zip">Download</a> and 201 extract the ADK package to a directory of your choice. You should have an <code>app</code>, 202 <code>arduino_libs</code>, and <code>hardware</code> directories.</li> 203 204 <li><a href="http://www.arduino.cc/playground/Main/CapSense">Download</a> and extract 205 the CapSense package to a directory of your choice.</li> 206 207 <li>Install the necessary libraries: 208 209 <p>On Windows:</p> 210 211 <ol type="a"> 212 <li>Copy the <code>arduino_libs/AndroidAccessory</code> and 213 <code>arduino_libs/USB_Host_Shield</code> directories (the complete directories, 214 not just the files within) to the <code><arduino_installation_root>/libraries/</code> 215 directory.</li> 216 217 <li>Copy the extracted <code>CapSense/</code> library directory and its contents to the 218 <code><arduino_installation_root>/libraries/</code> directory.</li> 219 </ol> 220 221 <p>On Mac:</p> 222 223 <ol type="a"> 224 <li>Create, if it does not already exist, an <code>Arduino</code> 225 directory inside your user account's <code>Documents</code> directory, and within 226 that, a <code>libraries</code> directory.</li> 227 228 <li>Copy the <code>arduino_libs/AndroidAccessory</code> and 229 <code>arduino_libs/USB_Host_Shield</code> directories (the 230 complete directories, not just the files within) to your 231 <code>Documents/Arduino/libraries/</code> directory.</li> 232 233 <li>Copy the extracted <code>CapSense/</code> library directory and its contents to the 234 <code>Documents/Arduino/libraries/</code> directory. 235 </ol> 236 237 <p>On Linux (Ubuntu):</p> 238 239 <ol type="a"> 240 <li>Copy the <code>firmware/arduino_libs/AndroidAccessory</code> and 241 <code>firmware/arduino_libs/USB_Host_Shield</code> directories (the complete directories, 242 not just the files within) to the <code><arduino_installation_root>/libraries/</code> 243 directory.</li> 244 245 <li>Copy the extracted <code>CapSense/</code> library directory and its contents to the 246 <code><arduino_installation_root>/libraries/</code> directory.</li> 247 248 <li>Install the avr-libc library by entering <code>sudo apt-get install avr-libc</code> 249 from a shell prompt.</li> 250 </ol> 251 </li> 252 </ol> 253 254 <p>You should now have three new directories in the Arduino <code>libraries/</code> directory: 255 <code>AndroidAccessory</code>, <code>USB_Host_Shield</code>, and <code>CapSense</code>.</p> 256 257 <h3 id="installing-firmware">Installing the firmware to the ADK board</h3> 258 259 <p>To install the firmware to the ADK board:</p> 260 261 <ol> 262 <li>Connect the ADK board to your computer using the micro-USB port, which allows two-way 263 communication and provides power to the ADK board.</li> 264 265 <li>Launch the Arduino IDE.</li> 266 267 <li>Click <strong>Tools > Board > Arduino Mega 2560</strong> to specify the ADK board's 268 type.</li> 269 270 <li>Select the appropriate USB port: 271 272 <ul> 273 <li>On Windows: click <strong>Tools > Serial Port > COM#</strong> to specify the port 274 of communication. The COM port number varies depending on your computer. COM1 is usually 275 reserved for serial port connections. You most likely want COM2 or COM3.</li> 276 277 <li>On Mac: Click <strong>Tools > Serial Port > dev/tty.usbserial-###</strong> to 278 specify the port of communication.</li> 279 280 <li>On Linux (Ubuntu): Click <strong>Tools > Serial Port > dev/ttyUSB#</strong> to 281 specify the port of communication.</li> 282 </ul> 283 </li> 284 285 <li>To open the Demokit sketch (firmware code), click <strong>File > Examples > 286 AndroidAccessory > demokit</strong>.</li> 287 288 <li>Click <strong>Sketch > Verify/Compile</strong> to ensure that the sketch has no 289 errors.</li> 290 291 <li>Select <strong>File > Upload</strong>. When Arduino outputs <strong>Done 292 uploading.</strong>, the board is ready to communicate with your Android-powered device.</li> 293 </ol> 294 295 <h3 id="running-demokit">Running the DemoKit Android application</h3> 296 297 <p>The DemoKit Android application runs on your Android-powered device and communicates with the 298 ADK board. The ADK board receives commands such as lighting up the board's LEDs or sends data 299 from the board such as joystick movement and temperature readings.</p> 300 301 <p>To install and run the application in Eclipse:</p> 302 303 <ol> 304 <li><a href="http://code.google.com/android/add-ons/google-apis/installing.html">Install the 305 Google APIs API Level 10 add-on library</a>, which includes the Open Accessory library for 306 2.3.4 devices that support accessory mode. This library is also forward compatible with Android 307 3.1 or newer devices that support accessory mode. If you only care about Android 3.1 or newer 308 devices, all you need is API Level 12. For more information on deciding which API level to use, 309 see the <a href="{@docRoot}guide/topics/connectivity/usb/accessory.html#choosing">USB Accessory</a> 310 documentation.</li> 311 312 <li>Click <strong>File > New > Project...</strong>, then select <strong>Android > 313 Android Project</strong></li> 314 315 <li>In the <strong>Project name:</strong> field, type DemoKit.</li> 316 317 <li>Choose <strong>Create project from existing source</strong>, click <strong>Browse</strong>, 318 select the <code>app</code> directory, click <strong>Open</strong> to close that dialog and then 319 click <strong>Finish</strong>.</li> 320 321 <li>For Build Target, select <strong>Google APIs</strong> (Platform 2.3.3, API Level 10). 322 323 <p class="note"><strong>Note:</strong> Even though the add-on is labeled as 324 <strong>2.3.3</strong>, the newest Google API add-on library for API level 10 adds USB Open 325 Accessory API support for 2.3.4 devices.</p> 326 </li> 327 328 <li>Click <strong>Finish</strong>.</li> 329 330 <li>Install the application to your device.</li> 331 332 <li>Connect the ADK board (USB-A) to your Android-powered device (micro-USB). Ensure that the 333 power cable to the accessory is plugged in or that the micro-USB port on the accesory is 334 connected to your computer for power (this also allows you to <a href="#monitoring">monitor the 335 ADK board</a>). When connected, accept the prompt that asks for whether or not to open the 336 DemoKit application to connect to the accessory. If the prompt does not show up, connect and 337 reconnect the accessory.</li> 338 </ol> 339 340 <p>You can now interact with the ADK board by moving the color LED or servo sliders (make sure 341 the servos are connected) or by pressing the relay buttons in the application. On the ADK shield, 342 you can press the buttons and move the joystick to see their outputs displayed in the 343 application.</p> 344 345 <h3 id="monitoring">Monitoring the ADK Board</h3> 346 347 <p>The ADK firmware consists of a few files that you should be looking at if you want to build 348 your own accessory. The files in the <code>arduino_libs/AndroidAccessory</code> 349 directory are the most important files and have the logic to detect and connect to 350 Android-powered devices that support accessory mode. Feel free to add debug statements (Arduino 351 <code>Serial.println()</code> statements) to the code located in the 352 <code><arduino_installation_root>/libraries/AndroidAccessory</code> directory and 353 <code>demokit.pde</code> sketch and re-upload the sketch to the ADK board to 354 discover more about how the firmware works.</p> 355 356 <p>You can view the debug statements in the Arduino Serial Monitor by clicking <strong>Tools > 357 Serial Monitor</strong> and setting the baud to 115200. The following sections about how 358 accessories communicate with Android-powered devices describe much of what you should be doing in 359 your own accessory.</p> 360 361 <h2 id="firmware">How the ADK board implements the Android Accessory protocol</h2> 362 363 <p>If you have access to the ADK board and shield, the following sections describe the firmware 364 code that you installed onto the ADK board. The firmware demonstrates a practical example of how 365 to implement the Android Accessory protocol. Even if you do not have the ADK board and shield, 366 reading through how the hardware detects and interacts with devices in accessory mode is still 367 useful if you want to port the code over for your own accessories.</p> 368 369 <p>The important pieces of the firmware are the 370 <code>arduino_libs/AndroidAccessory/examples/demokit/demokit/demokit.pde</code> sketch, which is 371 the code that receives and sends data to the DemoKit application running on the Android-powered 372 device. The code to detect and set up communication with the Android-powered device is contained 373 in the <code>arduino_libs/AndroidAccessory/AndroidAccessory.h</code> and 374 <code>arduino_libs/AndroidAccessory/AndroidAccessory.cpp</code> files. This code 375 includes most of the logic that will help you implement your own accessory's firmware. It might 376 be useful to have all three of these files open in a text editor as you read through these next 377 sections.</p> 378 379 <p>The following sections describe the firmware code in the context of the algorithm described in 380 <a href="#accessory-protocol">Implementing the Android Accessory Protocol</a>.</p> 381 382 <h3 id="wait-adk">Wait for and detect connected devices</h3> 383 384 <p>In the firmware code (<code>demokit.pde</code>), the <code>loop()</code> function runs 385 repeatedly and calls <code>AndroidAccessory::isConnected()</code> to check for any connected 386 devices. If there is a connected device, it continuously updates the input and output streams 387 going to and from the board and application. If nothing is connected, it continuously checks for 388 a device to be connected:</p> 389 <pre> 390 ... 391 392 AndroidAccessory acc("Google, Inc.", 393 "DemoKit", 394 "DemoKit Arduino Board", 395 "1.0", 396 "http://www.android.com", 397 "0000000012345678"); 398 399 ... 400 void loop() 401 { 402 ... 403 if (acc.isConnected()) { 404 //communicate with Android application 405 } 406 else{ 407 //set the accessory to its default state 408 } 409 ... 410 } 411 </pre> 412 413 <h3 id="determine-adk">Determine the connected device's accessory mode support</h3> 414 415 <p>When a device is connected to the ADK board, it can already be in accessory mode, support 416 accessory mode and is not in that mode, or does not support accessory mode. The 417 <code>AndroidAccessory::isConnected()</code> method checks for these cases and responds 418 accordingly when the <code>loop()</code> function calls it. This function first checks to see if 419 the device that is connected hasn't already been handled. If not, it gets the connected device's 420 device descriptor to figure out if the device is already in accessory mode by calling 421 <code>AndroidAccessory::isAccessoryDevice()</code>. This method checks the vendor and product ID 422 of the device descriptor. A device in accessory mode has a vendor ID of 0x18D1 and a product ID 423 of 0x2D00 or 0x2D01. If the device is in accessory mode, then the ADK board can <a href= 424 "#establish">establish communication with the device</a>. If not, the board <a href= 425 "#start">attempts to start the device in accessory mode</a>.</p> 426 <pre> 427 bool AndroidAccessory::isConnected(void) 428 { 429 USB_DEVICE_DESCRIPTOR *devDesc = (USB_DEVICE_DESCRIPTOR *) descBuff; 430 byte err; 431 432 max.Task(); 433 usb.Task(); 434 435 if (!connected && 436 usb.getUsbTaskState() >= USB_STATE_CONFIGURING && 437 usb.getUsbTaskState() != USB_STATE_RUNNING) { 438 Serial.print("\nDevice addressed... "); 439 Serial.print("Requesting device descriptor."); 440 441 err = usb.getDevDescr(1, 0, 0x12, (char *) devDesc); 442 if (err) { 443 Serial.print("\nDevice descriptor cannot be retrieved. Program Halted\n"); 444 while(1); 445 } 446 447 if (isAccessoryDevice(devDesc)) { 448 Serial.print("found android accessory device\n"); 449 450 connected = configureAndroid(); 451 } else { 452 Serial.print("found possible device. switching to serial mode\n"); 453 switchDevice(1); 454 } 455 } else if (usb.getUsbTaskState() == USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE) { 456 connected = false; 457 } 458 459 return connected; 460 } 461 </pre> 462 463 <h3 id="start-adk">Attempt to start the device in accessory mode</h3> 464 465 <p>If the device is not already in accessory mode, then the ADK board must determine whether or 466 not it supports it by sending control request 51 to check the version of the USB accessory 467 protocol that the device supports (see <code>AndroidAccessory::getProtocol()</code>). Protocol 468 version 1 is supported by Android 2.3.4 (API Level 10) and higher. Protocol version 2 is 469 supported by Android 4.1 (API Level 16) and higher. Versions greater than 2 may supported in 470 the future. 471 If the appropriate protocol version is returned, the board sends control request 52 (one 472 for each string with <code>AndroidAcessory:sendString()</code>) to send it's identifying 473 information, and tries to start the device in accessory mode with control request 53. The 474 <code>AndroidAccessory::switchDevice()</code> method takes care of this:</p> 475 <pre> 476 bool AndroidAccessory::switchDevice(byte addr) 477 { 478 int protocol = getProtocol(addr); 479 if (protocol >= 1) { 480 Serial.print("device supports protocol 1\n"); 481 } else { 482 Serial.print("could not read device protocol version\n"); 483 return false; 484 } 485 486 sendString(addr, ACCESSORY_STRING_MANUFACTURER, manufacturer); 487 sendString(addr, ACCESSORY_STRING_MODEL, model); 488 sendString(addr, ACCESSORY_STRING_DESCRIPTION, description); 489 sendString(addr, ACCESSORY_STRING_VERSION, version); 490 sendString(addr, ACCESSORY_STRING_URI, uri); 491 sendString(addr, ACCESSORY_STRING_SERIAL, serial); 492 493 usb.ctrlReq(addr, 0, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE, 494 ACCESSORY_START, 0, 0, 0, 0, NULL); 495 return true; 496 } 497 </pre>If this method returns false, the board waits until a new device is connected. If it is 498 successful, the device displays itself on the USB bus as being in accessory mode when the ADK board 499 re-enumerates the bus. When the device is in accessory mode, the accessory then <a href= 500 "#establish-adk">establishes communication with the device</a>. 501 502 <h3 id="establish-adk">Establish communication with the device</h3> 503 504 <p>If a device is detected as being in accessory mode, the accessory must find the proper bulk 505 endpoints and set up communication with the device. When the ADK board detects an Android-powered 506 device in accessory mode, it calls the <code>AndroidAccessory::configureAndroid()</code> 507 function:</p> 508 <pre> 509 ... 510 if (isAccessoryDevice(devDesc)) { 511 Serial.print("found android acessory device\n"); 512 513 connected = configureAndroid(); 514 } 515 ... 516 </pre> 517 518 <p>which in turn calls the <code>findEndpoints()</code> function:</p> 519 <pre> 520 ... 521 bool AndroidAccessory::configureAndroid(void) 522 { 523 byte err; 524 EP_RECORD inEp, outEp; 525 526 if (!findEndpoints(1, &inEp, &outEp)) 527 return false; 528 ... 529 </pre> 530 531 <p>The <code>AndroidAccessory::findEndpoints()</code> function queries the Android-powered 532 device's configuration descriptor and finds the bulk data endpoints in which to communicate with 533 the USB device. To do this, it first gets the device's first four bytes of the configuration 534 descriptor (only need descBuff[2] and descBuff[3]), which contains the information about the 535 total length of data returned by getting the descriptor. This data is used to determine whether 536 or not the descriptor can fit in the descriptor buffer. This descriptor also contains information 537 about all the interfaces and endpoint descriptors. If the descriptor is of appropriate size, the 538 method reads the entire configuration descriptor and fills the entire descriptor buffer with this 539 device's configuration descriptor. If for some reason the descriptor is no longer attainable, an 540 error is returned.</p> 541 <pre> 542 ... 543 544 bool AndroidAccessory::findEndpoints(byte addr, EP_RECORD *inEp, EP_RECORD *outEp) 545 { 546 int len; 547 byte err; 548 uint8_t *p; 549 550 err = usb.getConfDescr(addr, 0, 4, 0, (char *)descBuff); 551 if (err) { 552 Serial.print("Can't get config descriptor length\n"); 553 return false; 554 } 555 556 557 len = descBuff[2] | ((int)descBuff[3] << 8); 558 if (len > sizeof(descBuff)) { 559 Serial.print("config descriptor too large\n"); 560 /* might want to truncate here */ 561 return false; 562 } 563 564 err = usb.getConfDescr(addr, 0, len, 0, (char *)descBuff); 565 if (err) { 566 Serial.print("Can't get config descriptor\n"); 567 return false; 568 } 569 570 ... 571 </pre> 572 573 <p>Once the descriptor is in memory, a pointer is assigned to the first position of the buffer 574 and is used to index the buffer for reading. There are two endpoint pointers (input and output) 575 that are passed into <code>AndroidAccessory::findEndpoints()</code> and their addresses are set 576 to 0, because the code hasn't found any suitable bulk endpoints yet. A loop reads the buffer, 577 parsing each configuration, interface, or endpoint descriptor. For each descriptor, Position 0 578 always contains the size of the descriptor in bytes and position 1 always contains the descriptor 579 type. Using these two values, the loop skips any configuration and interface descriptors and 580 increments the buffer with the <code>descLen</code> variable to get to the next descriptor.</p> 581 582 <p class="note"><strong>Note:</strong> An Android-powered device in accessory mode can 583 potentially have two interfaces, one for the default communication to the device and the other 584 for ADB communication. The default communication interface is always indexed first, so finding 585 the first input and output bulk endpoints will return the default communication endpoints, which 586 is what the <code>demokit.pde</code> sketch does. If you are writing your own firmware, the logic 587 to find the appropriate endpoints for your accessory might be different.</p> 588 589 <p>When it finds the first input and output endpoint descriptors, it sets the endpoint pointers 590 to those addresses. If the findEndpoints() function finds both an input and output endpoint, it 591 returns true. It ignores any other endpoints that it finds (the endpoints for the ADB interface, 592 if present).</p> 593 <pre> 594 ... 595 p = descBuff; 596 inEp->epAddr = 0; 597 outEp->epAddr = 0; 598 while (p < (descBuff + len)){ 599 uint8_t descLen = p[0]; 600 uint8_t descType = p[1]; 601 USB_ENDPOINT_DESCRIPTOR *epDesc; 602 EP_RECORD *ep; 603 604 switch (descType) { 605 case USB_DESCRIPTOR_CONFIGURATION: 606 Serial.print("config desc\n"); 607 break; 608 609 case USB_DESCRIPTOR_INTERFACE: 610 Serial.print("interface desc\n"); 611 break; 612 613 case USB_DESCRIPTOR_ENDPOINT: 614 epDesc = (USB_ENDPOINT_DESCRIPTOR *)p; 615 if (!inEp->epAddr && (epDesc->bEndpointAddress & 0x80)) 616 ep = inEp; 617 else if (!outEp->epAddr) 618 ep = outEp; 619 else 620 ep = NULL; 621 622 if (ep) { 623 ep->epAddr = epDesc->bEndpointAddress & 0x7f; 624 ep->Attr = epDesc->bmAttributes; 625 ep->MaxPktSize = epDesc->wMaxPacketSize; 626 ep->sndToggle = bmSNDTOG0; 627 ep->rcvToggle = bmRCVTOG0; 628 } 629 break; 630 631 default: 632 Serial.print("unkown desc type "); 633 Serial.println( descType, HEX); 634 break; 635 } 636 637 p += descLen; 638 } 639 640 if (!(inEp->epAddr && outEp->epAddr)) 641 Serial.println("can't find accessory endpoints"); 642 643 return inEp->epAddr && outEp->epAddr; 644 } 645 646 ... 647 </pre> 648 649 <p>Back in the <code>configureAndroid()</code> function, if there were endpoints found, they are 650 appropriately set up for communication. The device's configuration is set to 1 and the state of 651 the device is set to "running", which signifies that the device is properly set up to communicate 652 with your USB accessory. Setting this status prevents the device from being re-detected and 653 re-configured in the <code>AndroidAccessory::isConnected()</code> function.</p> 654 <pre> 655 bool AndroidAccessory::configureAndroid(void) 656 { 657 byte err; 658 EP_RECORD inEp, outEp; 659 660 if (!findEndpoints(1, &inEp, &outEp)) 661 return false; 662 663 memset(&epRecord, 0x0, sizeof(epRecord)); 664 665 epRecord[inEp.epAddr] = inEp; 666 if (outEp.epAddr != inEp.epAddr) 667 epRecord[outEp.epAddr] = outEp; 668 669 in = inEp.epAddr; 670 out = outEp.epAddr; 671 672 Serial.print("inEp: "); 673 Serial.println(inEp.epAddr, HEX); 674 Serial.print("outEp: "); 675 Serial.println(outEp.epAddr, HEX); 676 677 epRecord[0] = *(usb.getDevTableEntry(0,0)); 678 usb.setDevTableEntry(1, epRecord); 679 680 err = usb.setConf( 1, 0, 1 ); 681 if (err) { 682 Serial.print("Can't set config to 1\n"); 683 return false; 684 } 685 686 usb.setUsbTaskState( USB_STATE_RUNNING ); 687 688 return true; 689 } 690 </pre> 691 692 <p>Lastly, methods to read and write to the appropriate endpoints are needed. The 693 <code>demokit.pde</code> sketch calls these methods depending on the data that is read from the 694 Android-powered device or sent by the ADK board. For instance, moving the joystick on the ADK 695 shield writes data that is read by the DemoKit application running on the Android-powered device. 696 Moving sliders on the DemoKit application is read by the <code>demokit.pde</code> sketch and 697 changes the state of the accessory, such as lighting up or changing the color of the LED 698 lights.</p> 699 <pre> 700 int AndroidAccessory::read(void *buff, int len, unsigned int nakLimit) { 701 return usb.newInTransfer(1, in, len, (char *)buff, nakLimit); } 702 703 int AndroidAccessory::write(void *buff, int len) { 704 usb.outTransfer(1, out, len, (char *)buff); 705 return len; } 706 </pre> 707 708 <p>See the <code>demokit.pde</code> sketch for information about how the ADK board 709 reads and writes data.</p> 710