Your SlideShare is downloading. ×
0
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Adk2012
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Adk2012

7,507

Published on

Published in: Education, Technology, Business
1 Comment
17 Likes
Statistics
Notes
No Downloads
Views
Total Views
7,507
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
75
Comments
1
Likes
17
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. @magoroku15 Rev.1.0 2012/7/13横浜android PF部
  • 2. Who am I 最底辺活動家、下が好き オーディオマニア iPhoneだと機器認証しないと取りだせない PCMが、ADK2で取りだせそうなのでやる気 満々 昔こんなの作った  オレオレ家電  http://www.slideshare.net/magoroku15/ss-103351352012/7/16 横浜android PF部 2
  • 3. 今日のお話 ADK2012の解析 ハード編 ADK2012の解析 ソフト編 CLONEの作り方・可能性2012/7/16 横浜android PF部 3
  • 4. http://developer.android.com/tools/adk/index.html 2012/7/16 横浜android PF部 4
  • 5. Accessory Development Kit 2012 Guideの内容 ADK2.0の使い方  Alarm Clock  Playing Audio Developing Accessories with ADK 2012 $> mkdir android-accessories $> cd android-accessories $> repo init -u https://android.googlesource.com/accessories/manifest $> repo sync2012/7/16 横浜android PF部 5
  • 6. Developing Accessories with ADK 2012の内容 adk1  旧バージョン adk2012 前半はここを中心に  board  ハード設計情報、回路図、BOM  回路図、レイアウトはEagleで記述  App  Androidアプリのソースコード External  Ide  IDE用のコードなど  Toolchain  クロスコンパイラ2012/7/16 横浜android PF部 6
  • 7. 2012/7/16 横浜android PF部 7
  • 8. adk2012/board MakefileBasedBuild hardware  adk2012 BOM.rtf メインボードの部品表  adk2012_base_eng.zip メインボードの回路  adk2012_base_fab.zip メインボードのガーバー  adk2012_LED BOM.rtf IOボードの部品表  adk2012_led_eng.zip IOボードの回路  adk2012_led_fab.zip IOボードのガーバー  adk2_led_layout.pdf IOの外装図  adk2012_flex_eng.zip フレキ回路図  adk2012_flex_fab.zip フレキの指示書 library tools2012/7/16 横浜android PF部 8
  • 9. 2012/7/16 横浜android PF部 9
  • 10. メインボードの主要部品hardware/adk2012 BOM.rtf ATSAM3X8EA-AU  ATMEL製 Coretex-M3 LBMA1BGUG2  村田製作所製 Bluetooth HCI Module PIC10F200T-I/OT  MicroChip製 PIC102012/7/16 横浜android PF部 10
  • 11. メインボード回路図 hardware/adk2012_base.pdf 電源 クロック コネクタ Bluetooth USB SD-CARD 書き込み コネクタ2012/7/16 横浜android PF部 11
  • 12. メインボード回路図 Bluetooth BTモジュールは,TX,RX, RTS,CTS,RESET,CLKの 6本のみ使用。2012/7/16 横浜android PF部 12
  • 13. PIC10の用途 書き込み Flashのeraseに使っている2012/7/16 横浜android PF部 13
  • 14. 2012/7/16 横浜android PF部 14
  • 15. IOボードの主要部品hardware/adk2012_LED BOM.rtf SHT21  SENSIRION製 湿度センサ MAX44005GDT+  MAXIM製 カラーセンサー AT42QT2120-HHM  ATMEL製 タッチセンサ BMP180  BOSCH製 圧力センサ2012/7/16 横浜android PF部 15
  • 16. LEDボードの回路図 hardware/adk2012_led.pdf ARDUINO HEADER AUDIO SENSORS LED & DRIVERS CAP SENSE2012/7/16 横浜android PF部 16
  • 17. AUDIO TIのデジタル アンプ OP AMP IV変換 MPUのDAC0から2012/7/16 横浜android PF部 17
  • 18. SENSORS すべてI2C接続 ADCは使わない2012/7/16 横浜android PF部 18
  • 19. CAP SENSE 21点の入力スイッチ GPIOは使わないI2C入力2012/7/16 横浜android PF部 19
  • 20. LEDS AND DRIVERS 流し込み側が4ch、吸いこみ側が24x2チャンネル 24x2x4 = 192chのLEDを4096階調 この内の3chで1個のRGB LEDを点灯 TLC5947 24チャネル定電流シンク出力 1チャネルあたりの最大定電流値= 30mA 12ビット(4096階調)PWMコントロール2012/7/16 横浜android PF部 20
  • 21. スイッチとLEDの配置2012/7/16 横浜android PF部 21
  • 22. 2012/7/16 横浜android PF部 22
  • 23. adk2012/board MakefileBasedBuild  ATMEL ATMEL SAM3X依存部  App ソースコード  Build  flash  setup hardware ハード編で説明 library  ADK2 ソースコード tools2012/7/16 横浜android PF部 23
  • 24. http://developer.android.com/tools/adk/adk2.html#adk-conn ADK Connection over Bluetooth ADK L; void setup() { L.adkInit(); L.btStart(); } The ADK 2012 app and hardware accessory use a Bluetooth Serial Port Profile (SPP) connection to communicate. This connection allows two way communication between the ADK accessory and Android devices. 2012/7/16 横浜android PF部 24
  • 25. adkInit 120 void ADK::adkInit(void){ 121 131 132 //bt init 133 static const BtFuncs myBtFuncs = {this, btVerboseScanCbkF, btConnReqF, btConnStartF, btConnEndF, btPinRequestF,btLinkKeyRequest, btLinkKeyCreated, btAclDataRxF, btSspShowF}; 134 btInit(&myBtFuncs); //BT UART & HCI driver 135 btSdpRegisterL2capService(); //SDP daemon 136 btRfcommRegisterL2capService(); //RFCOMM framework 137 eliza(); //easter egg 138 btA2dpRegister(); //A2DP profile 1392012/7/16 横浜android PF部 25
  • 26. adkInit BT UART  BTモジュールとのインタフェースとしてUARTを使って いるのでその初期化 HCI  ホスト(MPU)とBTコントローラの間のIF SDP  サービスを通知するためのプロトコル RFCOMM  シリアル通信のエミュレーションプロトコル A2DP2012/7/16 横浜android PF部 26
  • 27. adkInit Bluetoothの復習 BT UART  BTモジュールとのインタフェースとしてUARTを使っているのでそ の初期化 HCI  ホスト(MPU)とBTコントローラの間のIF SDP  サービスを通知するためのプロトコル RFCOMM  シリアル通信のエミュレーションプロトコル L2CAP  複数接続を管理するプロトコル A2DP  AVプロファイル、音声通話用のHSPより高音質2012/7/16 横浜android PF部 27
  • 28. adkInit BlurToothの復習 SDP RFCOMM A2DP Control L2CAP ホスト側 HCI HCI LMP MCU BTモジュール Baseband RF2012/7/16 横浜android PF部 28
  • 29. •UARTを初期化btInit #1 •GPIO経由でBTモ ジュールをリセット559 char btInit(const BtFuncs* btf){ HCI_CMD_Read_Buffer_Size);564 const uint8_t* script = cc256x_init_script; 609 hciCmdPacketFinish(packetState);572 initBtUart(1); 610 btTxCmdPacket();578 packetState = hciCmdPacketStart(0x3f, 0x336); 611 do{579 packetState = hciCmdPacketAddU32(packetState, 612 BT_BAUDRATE); btRxEventPacket(HCI_EVT_Command_Complete_Event);580 hciCmdPacketFinish(packetState); 613 }while(evt->params[1] !=581 btTxCmdPacket(); (HCI_OPCODE(HCI_OGF_Informational,582 btRxPacket(); //it responds at old speed HCI_CMD_Read_Buffer_Size) & 0xFF) ||592 //init script 614 evt->params[2] != (HCI_OPCODE(HCI_OGF_Informational,593 while(*script++){ HCI_CMD_Read_Buffer_Size) >> 8));594 615595 dbgPrintf("¥r%d", num++);596 cmd = (HCI_Cmd*)script;597 btTxCmdPacketEx(cmd);598 script += 3 + cmd->totalParamLen;599 btRxEventPacket(0); BTモジュールの605 } ファームを書きこむ606607 //get buffer size608 packetState = hciCmdPacketStart(HCI_OGF_Informational,2012/7/16 横浜android PF部 29
  • 30. btInit #2616 uint16_t aclLen, aclNum, scoNum;617 uint8_t scoLen;618619 aclLen = (((uint16_t)evt->params[5]) << 8) | evt->params[4];620 scoLen = evt->params[6];621622 aclNum = (((uint16_t)evt->params[8]) << 8) | evt->params[7]; scoNum = (((uint16_t)evt->params[10]) << 8) | evt->params[9]; •ペアリングの処理623628 gAclPacketsCanSend = aclNum;629630 //set connectibility/discoverability631 pageState = 0;632 btDiscoverableConnectable();633634 //enable simple passcodes635 if(SUPORT_SSP){636 packetState = hciCmdPacketStart(HCI_OGF_Controller_and_Baseband, HCI_CMD_Write_Simple_Pairing_Mode);637 packetState = hciCmdPacketAddU8(packetState, 1); //enable it638 hciCmdPacketFinish(packetState);639 btTxCmdPacket();640 do{641 btRxEventPacket(HCI_EVT_Command_Complete_Event);642 }while(evt->params[1] != (HCI_OPCODE(HCI_OGF_Controller_and_Baseband, HCI_CMD_Write_Simple_Pairing_Mode) & 0xFF) ||643 evt->params[2] != (HCI_OPCODE(HCI_OGF_Controller_and_Baseband, HCI_CMD_Write_Simple_Pairing_Mode) >> 8));644 }645651 }6522012/7/16 横浜android PF部 30
  • 31. btStart() #1void btStart(){ L.btEnable(adkBtConnectionRequest, adkBtLinkKeyRequest, adkBtLinkKeyCreated,adkBtPinRequest, NULL); L.btRfcommReserveDlci(RFCOMM_DLCI_NEED_EVEN); for(i = 0, f = -1; i < sizeof(sdpDescrADK); i++){ if(sdpDescrADK[i] == MAGIX){ if(f == -1) f = i; else break; } } sdpDescrADK[f] = dlci >> 1; L.btRfcommRegisterPort(dlci, btAdkPortOpen, btAdkPortClose, btAdkPortRx); L.btSdpServiceDescriptorAdd(sdpDescrADK, sizeof(sdpDescrADK));} 2012/7/16 横浜android PF部 31
  • 32. btStart() #2void btStart(){ L.btEnable(adkBtConnectionRequest, adkBtLinkKeyRequest, adkBtLinkKeyCreated,adkBtPinRequest, NULL); L.btRfcommReserveDlci(RFCOMM_DLCI_NEED_EVEN); for(i = 0, f = -1; i < sizeof(sdpDescrADK); i++){ •ADK固有のハンドシェークパラメ if(sdpDescrADK[i] == MAGIX){ タを設定 if(f == -1) f = i; • static BtFuncs cbks;に登録してハ else break; ンドシェークの過程でCallbackされ } る } sdpDescrADK[f] = dlci >> 1; L.btRfcommRegisterPort(dlci, btAdkPortOpen, btAdkPortClose, btAdkPortRx); L.btSdpServiceDescriptorAdd(sdpDescrADK, sizeof(sdpDescrADK));} 2012/7/16 横浜android PF部 32
  • 33. adkBtLinkKeyReques 1623 for(i = 0; i < numPairedDevices; i++){1605 static char adkBtLinkKeyRequest(const uint8_t* mac, 1624 uint8_t* buf){ //link key create 1625 for(j = 0; j < Bluetooth_MAC_SIZE &&1606 savedMac[i][j] == mac[j]; j++);1607 uint8_t i, j; 1626 if(j == Bluetooth_MAC_SIZE){ //match1608 16271609 Serial.print("Key request from "); 1628 Serial.print("{");1610 Serial.print(mac[5], HEX); 1629 for(j = 0; j < Bluetooth_LINK_KEY_SIZE; j++){1611 Serial.print(":"); 16301612 Serial.print(mac[4], HEX); 1631 Serial.print(" ");1613 Serial.print(":"); 1632 Serial.print(savedKey[i][j], HEX);1614 Serial.print(mac[3], HEX); 1633 buf[j] = savedKey[i][j];1615 Serial.print(":"); 1634 }1616 Serial.print(mac[2], HEX); 1635 Serial.println(" }");1617 Serial.print(":"); 1636 return 1;1618 Serial.print(mac[1], HEX); 1637 }1619 Serial.print(":"); 1638 }1620 Serial.print(mac[0], HEX); 1639 Serial.println("FAIL");1621 Serial.print(" -> "); 1640 return 0;1622 1641 }2012/7/16 横浜android PF部 33
  • 34. adkBtConnectionRequest1588 static char 1599 Serial.print(mac[1], HEX); adkBtConnectionRequest(const uint8_t* 1600 Serial.print(":"); mac, uint32_t devClass, uint8_t linkType){ 1601 Serial.println(mac[0], HEX); //return 1 to accept 1602 return 1;1589 1603 }1590 Serial.print("Accepting connection from "); 16041591 Serial.print(mac[5], HEX);1592 Serial.print(":");1593 Serial.print(mac[4], HEX);1594 Serial.print(":");1595 Serial.print(mac[3], HEX);1596 Serial.print(":");1597 Serial.print(mac[2], HEX);1598 Serial.print(":");2012/7/16 横浜android PF部 34
  • 35. adkBtLinkKeyCreated1643 static void adkBtLinkKeyCreated(const uint8_t* mac, const 1664 Serial.print(" "); uint8_t* buf){ //link key was just created, save it if you 1665 Serial.print(buf[j], HEX); want it later 1666 } 1644 1667 Serial.print(" }"); 1645 uint8_t j; 1668 1646 1669 if(numPairedDevices < maxPairedDevices){ 1647 Serial.print("Key created for "); 1670 1648 Serial.print(mac[5], HEX); 1671 for(j = 0; j < Bluetooth_LINK_KEY_SIZE; j++) 1649 Serial.print(":"); savedKey[numPairedDevices][j] = buf[j]; 1650 Serial.print(mac[4], HEX); 1672 for(j = 0; j < Bluetooth_MAC_SIZE; j++) 1651 Serial.print(":"); savedMac[numPairedDevices][j] = mac[j]; 1652 Serial.print(mac[3], HEX); 1673 numPairedDevices++; 1653 Serial.print(":"); 1674 Serial.print("saved to slot "); 1654 Serial.print(mac[2], HEX); 1675 Serial.print(numPairedDevices); 1655 Serial.print(":"); 1676 Serial.print("/"); 1656 Serial.print(mac[1], HEX); 1677 Serial.println(maxPairedDevices); 1657 Serial.print(":"); 1678 } 1658 Serial.print(mac[0], HEX); 1679 else{ 1659 Serial.print(" <- "); 1680 Serial.println("out of slots...discaring¥n"); 1660 1681 } 1661 Serial.print("{"); 1682 } 1662 for(j = 0; j < Bluetooth_LINK_KEY_SIZE; j++){ 1663 2012/7/16 横浜android PF部 35
  • 36. adkBtPinRequest1684 static char adkBtPinRequest(const 1698 Serial.print(":"); uint8_t* mac, uint8_t* buf){ 1699 Serial.print(mac[0], HEX); //fill buff with PIN code, return num 1700 bytes used (16 max) return 0 to decline 1685 1701 if(btPIN){ 1686 uint8_t v, i = 0; 1702 Serial.print(" -> using pin "); 1687 1703 Serial.print((char*)btPIN); 1688 Serial.print("PIN request from "); 1704 Serial.println(""); 1689 Serial.print(mac[5], HEX); 1705 for(i = 0; btPIN[i]; i++) buf[i] = btPIN[i]; 1690 Serial.print(":"); 1706 return i; 1691 Serial.print(mac[4], HEX); 1707 } 1692 Serial.print(":"); 1708 else Serial.println(" no PIN set. 1693 Serial.print(mac[3], HEX); rejecting"); 1694 Serial.print(":"); 1709 return 0; 1695 Serial.print(mac[2], HEX); 1710 } 1696 Serial.print(":"); 1697 Serial.print(mac[1], HEX); 2012/7/16 横浜android PF部 36
  • 37. btStart() #2void btStart(){ L.btEnable(adkBtConnectionRequest, adkBtLinkKeyRequest, adkBtLinkKeyCreated,adkBtPinRequest, NULL); L.btRfcommReserveDlci(RFCOMM_DLCI_NEED_EVEN); for(i = 0, f = -1; i < sizeof(sdpDescrADK); i++){ if(sdpDescrADK[i] == MAGIX){ if(f == -1) f = i; else break; } "Key request from” +MAC +KEY } “Accepting connection from“ +MAC "Key created for “ +MAC +SLOT sdpDescrADK[f] = dlci >> 1; "PIN request from “ +MAC +PIN L.btRfcommRegisterPort(dlci, btAdkPortOpen, btAdkPortClose, btAdkPortRx); L.btSdpServiceDescriptorAdd(sdpDescrADK, sizeof(sdpDescrADK));} 2012/7/16 横浜android PF部 37
  • 38. btStart() #3void btStart(){ L.btEnable(adkBtConnectionRequest, adkBtLinkKeyRequest, adkBtLinkKeyCreated,adkBtPinRequest, NULL); L.btRfcommReserveDlci(RFCOMM_DLCI_NEED_EVEN); for(i = 0, f = -1; i < sizeof(sdpDescrADK); i++){ if(sdpDescrADK[i] == MAGIX){ if(f == -1) f = i; else break; } } sdpDescrADK[f] = dlci >> 1; L.btRfcommRegisterPort(dlci, btAdkPortOpen, btAdkPortClose, btAdkPortRx); L.btSdpServiceDescriptorAdd(sdpDescrADK, sizeof(sdpDescrADK));} 2012/7/16 横浜android PF部 38
  • 39. btRfcommReserveDlci408 #define RFCOMM_DLCI_PREFERENCE_NONE 0x80 //use this param to the below409 #define RFCOMM_DLCI_NEED_EVEN 0x81410 #define RFCOMM_DLCI_NEED_ODD 0x82411412 uint8_t btRfcommReserveDlci(uint8_t preference){413414 uint8_t start = 0, end = 64, step = 2;415416 if(preference == RFCOMM_DLCI_PREFERENCE_NONE) step = 1;417 else if(preference == RFCOMM_DLCI_NEED_EVEN);418 else if(preference == RFCOMM_DLCI_NEED_ODD) start++;419 else{420421 start = preference;422 end = preference + 1;423 step = 1;424 }425426 while(start < end && (reserved & (1ULL << ((uint64_t)start)))) start += step;427428 if(start >= end) return 0; //we failed429430 reserved |= (1ULL << ((uint64_t)start));4312012/7/16432 return start; 横浜android PF部 39
  • 40. btStart() #4void btStart(){ L.btEnable(adkBtConnectionRequest, adkBtLinkKeyRequest, adkBtLinkKeyCreated,adkBtPinRequest, NULL); L.btRfcommReserveDlci(RFCOMM_DLCI_NEED_EVEN); for(i = 0, f = -1; i < sizeof(sdpDescrADK); i++){ if(sdpDescrADK[i] == MAGIX){ if(f == -1) f = i; else break; } } sdpDescrADK[f] = dlci >> 1; L.btRfcommRegisterPort(dlci, btAdkPortOpen, btAdkPortClose, btAdkPortRx); L.btSdpServiceDescriptorAdd(sdpDescrADK, sizeof(sdpDescrADK));} 2012/7/16 横浜android PF部 40
  • 41. btRfcommRegisterPort 366 void btRfcommRegisterPort(uint8_t dlci, BtRfcommPortOpenF oF, BtRfcommPortCloseF cF, BtRfcommPortRxF rF){ 367 368 if(dlci >= NUM_DLCIs) return; //no such DLCI; 369 370 gPortHandlers[dlci].oF = oF; // OPENハンドラ 371 gPortHandlers[dlci].cF = cF; // CLOSE ハンドラ 372 gPortHandlers[dlci].rF = rF; // 受信ハンドラ 373 } 受信ハンドラを設定 データを受け取るとCallBack2012/7/16 横浜android PF部 41
  • 42. btAdkPortRx1527 static void btAdkPortRx(void* port, uint8_t dlci, const uint8_t* 1551 cmdSz += cmdBuf[2]; data, uint16_t sz){ 1552 1528 1553 if(bufPos - 4 < cmdSz) return; //not entire command 1529 uint8_t reply[MAX_PACKET_SZ]; received yet 1530 uint32_t i; 1554 1531 uint8_t seq, cmd; 1555 sendSz = adkProcessCommand(cmd, cmdBuf + 4, 1532 uint16_t cmdSz; cmdSz, 1, reply + 4, MAX_PACKET_SZ - 4); 1533 uint8_t* ptr; 1556 if(sendSz){ 1534 1557 1535 while(sz || bufPos){ 1558 reply[0] = cmd | CMD_MASK_REPLY; 1536 1559 reply[1] = seq; 1537 uint16_t sendSz = 0; 1560 reply[2] = sendSz; 1538 1561 reply[3] = sendSz >> 8; 1539 //copy to buffer as much as we can 1562 sendSz += 4; 1540 while(bufPos < MAX_PACKET_SZ && sz){ 1563 1541 cmdBuf[bufPos++] = *data++; 1564 L.btRfcommPortTx(port, dlci, reply, sendSz); 1542 sz--; 1565 } 1543 } 1566 1544 受け取ったデータを 1567 1568 //adjust buffer as needed for(i = 0; i < bufPos - cmdSz - 4; i++){ 1545 //see if a packet exists 1546 adkProcessCommandに渡す if(bufPos < 4) return; // too small to be a packet -> discard 1569 1570 } cmdBuf[i] = cmdBuf[i + cmdSz + 4]; 1547 cmd = cmdBuf[0]; 1571 bufPos = i; 1548 seq = cmdBuf[1]; 1572 } 1549 cmdSz = cmdBuf[3]; 1573 } 1550 2012/7/16cmdSz <<= 8; 横浜android PF部 42
  • 43. adkProcessCommand1274 static uint16_t adkProcessCommand(uint8_t cmd, const 1307 putLE16(reply, &sendSz, prox[5]); uint8_t* dataIn, uint16_t sz, char fromBT, uint8_t* reply, 1308 putLE16(reply, &sendSz, prox[2]); uint16_t maxReplySz){ //returns num bytes to reply with 1309 putLE16(reply, &sendSz, prox[6]); (or 0 for no reply) 1310 putLE16(reply, &sendSz, accel[0]); 1288 //process packet 1311 putLE16(reply, &sendSz, accel[1]); 1289 switch(cmd){ 1312 putLE16(reply, &sendSz, accel[2]); 1290 1313 putLE16(reply, &sendSz, mag[0]); 1291 case BT_CMD_GET_PROTO_VERSION: 1314 putLE16(reply, &sendSz, mag[1]); 1292 { 1315 putLE16(reply, &sendSz, mag[2]); 1293 reply[sendSz++] = 1316 } BT_PROTO_VERSION_CURRENT; 1317 break; 1294 } 1318 1295 break; 1319 case BT_CMD_FILE_LIST: 1296 1320 { 1297 case BT_CMD_GET_SENSORS: 1321 1298 { 1322 if(sz){ //reset 1299 putLE32(reply, &sendSz, hTemp); 1323 1300 putLE32(reply, &sendSz, hHum); 1324 if(*dirP) L.fatfsCloseDir(*dirP); 1301 putLE32(reply, &sendSz, bPress); 1325 if(L.fatfsOpenDir(dirP, (char*)dataIn)) *dirP = 0; 1302 putLE32(reply, &sendSz, bTemp); 1326 } 1303 putLE16(reply, &sendSz, prox[0]); 1327 if(*dirP){ 1304 1305 putLE16(reply, &sendSz, prox[1]); putLE16(reply, &sendSz, prox[3]); アプリ層のコマンドを処理 1328 1306 putLE16(reply, &sendSz, prox[4]); センサの値をAndroidに送信 2012/7/16 横浜android PF部 43
  • 44. adkProcessCommand コマンド一覧1177 #define BT_CMD_GET_PROTO_VERSION 1 // () -> (u8 protocolVersion)1178 #define BT_CMD_GET_SENSORS 2 // () -> (sensors: i32,i32,i32,i32,u16,u16,u16,u16,u16,u16,u16,i16,i16,i16,i16,i16,i16)1179 #define BT_CMD_FILE_LIST 3 // FIRST: (char name[]) -> (fileinfo or single zero byte) OR NONLATER: () -> (fileinfo or empty or single zero byte)1180 #define BT_CMD_FILE_DELETE 4 // (char name[0-255)) -> (char success)1181 #define BT_CMD_FILE_OPEN 5 // (char name[0-255]) -> (char success)1182 #define BT_CMD_FILE_WRITE 6 // (u8 data[]) -> (char success)1183 #define BT_CMD_FILE_CLOSE 7 // () -> (char success)1184 #define BT_CMD_GET_UNIQ_ID 8 // () -> (u8 uniq[16])1185 #define BT_CMD_BT_NAME 9 // (char name[]) -> () OR () -> (char name[])1186 #define BT_CMD_BT_PIN 10 // (char PIN[]) -> () OR () -> (char PIN[])1187 #define BT_CMD_TIME 11 // (timespec) -> (char success)) OR () > (timespec)1188 #define BT_CMD_SETTINGS 12 // () -> (alarm:u8,u8,u8,brightness:u8,color:u8,u8,u8:volume:u8) or (alarm:u8,u8,u8,brightness:u8,color:u8,u8,u8:volume:u8) > (char success)1189 #define BT_CMD_ALARM_FILE 13 // () -> (char file[0-255]) OR (char file[0-255]) > (char success)1190 #define BT_CMD_GET_LICENSE 14 // () -> (u8 licensechunk[]) OR () if last sent1191 #define BT_CMD_DISPLAY_MODE 15 // () -> (u8) OR (u8) -> ()1192 #define BT_CMD_LOCK 16 // () -> (u8) OR (u8) -> () 2012/7/16 横浜android PF部 44
  • 45. adkProcessCommand1471 case BT_CMD_GET_LICENSE:1472 {1473 static const uint32_t maxPacket = MAX_PACKET_SZ - 10; //seems reasonable14741475 if(*licPos >= sizeof(gzippedLicences)){ //send terminator1476 reply[sendSz++] = 0;1477 *licPos = 0;1478 }1479 else{148014811482 uint32_t left = sizeof(gzippedLicences) - *licPos; if(left > maxPacket) left = maxPacket; ライセンス14831484 reply[sendSz++] = 1; while(left--) reply[sendSz++] = gzippedLicences[(*licPos)++]; の送信??1485 }1486 }1487 break;2012/7/16 横浜android PF部 45
  • 46. processUSBAccessory1772 // USB accessory 1773 static void processUSBAccessory() 1774 { 1781 int res = L.accessoryReceive(receiveBuf, sizeof(receiveBuf)); 1782 if (res >= 4) { 1783 uint8_t cmd = receiveBuf[0]; 1784 uint8_t seq = receiveBuf[1]; 1785 uint16_t size = receiveBuf[2] | receiveBuf[3] << 8; 1786 1792 uint16_t replylen = adkProcessCommand(cmd, receiveBuf + 4, size, 0, reply + 4, MAX_PACKET_SZ - 4); 1793 if (replylen > 0) { 1794 reply[0] = cmd | CMD_MASK_REPLY; 1795 reply[1] = seq; 1796 reply[2] = replylen; 1797 reply[3] = replylen >> 8; 1798 replylen += 4; 1799 1800 dbgPrintf("ADK: USB: sending %d bytes¥n", replylen); USBの接続も、ア 1801 1802 } L.accessorySend(reply, replylen); プリ層のコマンド 処理は同じ関数で 1803 } 1804 } 1805 2012/7/16 横浜android PF部 46
  • 47. ADK Connection over Bluetooth のまとめ BTモジュールとの接続は5ピン  TX,RX,CTS,RTS,RST HCIレベルで操作  ペアリング、PINの処理ほか BTモジュールはcc256xを前提  cc256xのROMコードを抱き込み  HCIレベルの互換性は不明 アプリ層のコマンドはBTとUSBと共通2012/7/16 横浜android PF部 47
  • 48. http://developer.android.com/tools/adk/adk2.html#adk-conn ADK Connection over USB ADK L; void setup() { L.adkInit(); L.usbSetAccessoryStringVendor(...); L.usbSetAccessoryStringName(...); L.usbSetAccessoryStringLongname(...); L.usbSetAccessoryStringVersion(...); L.usbSetAccessoryStringUrl(...); L.usbSetAccessoryStringSerial(...); L.usbStart(); } ADK1.0と同じ 2012/7/16 横浜android PF部 48
  • 49. http://developer.android.com/tools/adk/adk2.html#audio-dock USB Audio Dock Implementation ADK L; void setup() { L.audioInit(); L.usbh_init() L.usbStart(); } void loop(void) { ... L.adkEventProcess(); //let the adk framework do its thing ... } 2012/7/16 横浜android PF部 49
  • 50. L.audioInit()を読んでみるADK L;void setup() { L.audioInit(); // オーディオの初期化 L.usbh_init() // USBの初期化 L.usbStart(); // USBの起動}void loop(void){ ... L.adkEventProcess(); // アプリケーション定義の ... // コマンド処理} 2012/7/16 横浜android PF部 50
  • 51. L.audioInit()→audioInit() PMC: Power Management Controller libraries/ADK/Audio.c PWMC: Plus Width Modulation Controller DACC: Digital Audio Converter Controller 36 void audioInit(void) 37 { 38 PMC_EnablePeripheral(ID_PWM); // PWMCをPON 39 PWMC_ConfigureClocks(0, 0, BOARD_MCK); 40 PWMC_ConfigureChannel(PWM, 0, PWM_CMR_CPRE_MCK, 0, 0); 41 PWMC_ConfigureEventLineMode(PWM, 0, 1); 43 audioSetSample(AUDIO_NULL, DEFAULT_AUDIO_SAMPLERATE); 45 PWMC_EnableChannel(PWM, 0); 46 PMC_EnablePeripheral(ID_DACC); // DACCをPON 47 DACC_Initialize(DACC, ID_DACC, 1, 4, 0, 0, BOARD_MCK, 8, DACC_CHANNEL_0, 0, 16 ); 48 DACC_EnableChannel(DACC, DACC_CHANNEL_0); 49 }2012/7/16 横浜android PF部 51
  • 52. L.audioInit() →audioSetSample()#define BOARD_MCK 84000000ULL73 void audioSetSample(int source, uint32_t samplerate)74 {75 sampleRates[source] = samplerate;77 // if were not the highest priority audio source, dont set it78 if (source != highestPriAudio())79 return;81 samplerate = DAC(PWMで代用)の初期化 (BOARD_MCK + samplerate - 1) / samplerate; //err on the side of slower audio83 PWMC_SetPeriod(PWM, 0, samplerate);84 PWMC_ConfigureComparisonUnit(PWM, 0, (samplerate + 1) >> 1, 1);85 } 2012/7/16 横浜android PF部 52
  • 53. L.audioInit()#define DEFAULT_AUDIO_SAMPLERATE 44100static uint32_t sampleRates[AUDIO_MAX_SOURCE];static uint32_t audioActive; // bitmap of active audio sources#define AUDIO_NULL 0#define AUDIO_USB 1#define AUDIO_BT 2#define AUDIO_ALARM 3#define AUDIO_MAX_SOURCE 4 2012/7/16 横浜android PF部 53
  • 54. L.usbh_init()を読んでみるADK L;void setup() { L.audioInit(); L.usbh_init() L.usbStart();}void loop(void){ ... L.adkEventProcess(); //let the adk framework do its thing ...} 2012/7/16 横浜android PF部 54
  • 55. L.usbh_init()libraries/ADK/Usbh.cvoid usbh_init(void){ USBの電源とクロックを設定 usbh.state = USBH_DISABLED; pmc_enable_periph_clk(ID_UOTGHS); /* Enable UPLL 480 MHz */ /* Wait that UPLL is considered locked by the PMC */ /* USB clock register: USB Clock Input is UTMI PLL */ PMC->PMC_USB = PMC_USB_USBS | PMC_USB_USBDIV(0); PMC->PMC_SCER = PMC_SCER_UOTGCLK; NVIC_SetPriority(UOTGHS_IRQn, (1<<__NVIC_PRIO_BITS) - 1); NVIC_EnableIRQ(UOTGHS_IRQn); coopSpawn(&usbhTask, NULL, 2048); Usb_freeze_clock();} 2012/7/16 横浜android PF部 55
  • 56. L.usbh_init() USBH_DEVICE_TRY_ACCESSORYDEVICE_TO_HOST | TYPE_VENDOR,0x33, versionHOST_TO_DEVICE | TYPE_VENDOR,0x34, 1, "Google, Inc.“HOST_TO_DEVICE | TYPE_VENDOR,0x34, 2, "DemoKit“HOST_TO_DEVICE | TYPE_VENDOR,0x34, 3, "DemoKit ADK2012“HOST_TO_DEVICE | TYPE_VENDOR,0x34, 4, "2.0“HOST_TO_DEVICE | TYPE_VENDOR,0x34, 5,http://www.android.comHOST_TO_DEVICE | TYPE_VENDOR,0x34, 5, "0000000012345678“HOST_TO_DEVICE | TYPE_VENDOR,0x3a, 1HOST_TO_DEVICE | TYPE_VENDOR,0x35, 0 御約束の呪文2012/7/16 横浜android PF部 56
  • 57. L.usbh_init() USBH_DEVICE_TRY_ACCESSORYDEVICE_TO_HOST | TYPE_VENDOR,0x33, versionHOST_TO_DEVICE | TYPE_VENDOR,0x34, 1, "Google, Inc.“HOST_TO_DEVICE | TYPE_VENDOR,0x34, 2, "DemoKit“HOST_TO_DEVICE | TYPE_VENDOR,0x34, 3, "DemoKit ADK2012“HOST_TO_DEVICE | TYPE_VENDOR,0x34, 4, "2.0“HOST_TO_DEVICE | TYPE_VENDOR,0x34, 5,http://www.android.comHOST_TO_DEVICE | TYPE_VENDOR,0x34, 5, "0000000012345678“HOST_TO_DEVICE | TYPE_VENDOR,0x3a, 1HOST_TO_DEVICE | TYPE_VENDOR,0x35, 0 1か所追加これが Audio機能を呼び出す2012/7/16 横浜android PF部 57
  • 58. L.usbh_init()→usbTask()/* for the coop threading system */static void usbhTask(void* ptr){ for (;;) { coopYield(); usbh_work(); accessory_work(); }} 2012/7/16 横浜android PF部 58
  • 59. usbh_work() 755 void usbh_work(void) USBH_INIT USBH_DEVICE_ATTACHED_QUERY 0x18d12d00: // accessory USBH_DEVICE_UNATTACHED 0x18d12d01: // accessory + adb 0x18d12d02: // audio USBH_WAIT_FOR_DEVICE 0x18d12d03: // audio + adb 0x18d12d04: // accessory + audio USBH_DEVICE_ATTACHED 0x18d12d05: // accessory + audio + adb USBH_DEVICE_ATTACHED_SOF_WAIT FALSE TRUE USBH_DEVICE_ATTACHED_RESET USBH_DEVICE_ATTACHED_RESET_WAIT USBH_DEVICE_TRY_ACCESSORY USBH_DEVICE_ATTACHED_POST_RESET_WAIT この時点でVendorと Productがみえるので次で 確認2012/7/16 横浜android PF部 59
  • 60. usbh_work() USBH_DEVICE_TRY_ACCESSORY DEVICE_TO_HOST | TYPE_VENDOR,0x33, versionの取得 versionが1又は2以外ならstateをUSBH_DEVICE_IDLEへ HOST_TO_DEVICE | TYPE_VENDOR,0x34, 1, “Google, Inc.”を送る HOST_TO_DEVICE | TYPE_VENDOR,0x34, 2, “DemoKit”送る HOST_TO_DEVICE | TYPE_VENDOR,0x34, 3, “DemoKit ADK2012”送る HOST_TO_DEVICE | TYPE_VENDOR,0x34, 4, “2.0”送る HOST_TO_DEVICE | TYPE_VENDOR,0x34, 5, http://www.android.com送る HOST_TO_DEVICE | TYPE_VENDOR,0x34, 5, “0000000012345678“送る HOST_TO_DEVICE | TYPE_VENDOR,0x3a, 1 Auidoモードを要求 1:mono, 2:stereo HOST_TO_DEVICE | TYPE_VENDOR,0x35, 0 AccessoryをON これ曲者 stateをUSBH_DEVICE_IDLEへ •以上の処理で、Android側が別のVendor,ProductのUSB ディバイスに 変化して、新たなUSBデイバイスの検出処理が開始される •コード0x3aがADK2.0で追加された 2012/7/16 横浜android PF部 60
  • 61. usbh_work() 755 void usbh_work(void) USBH_INIT USBH_DEVICE_ATTACHED_QUERY 0x18d12d00: // accessory USBH_DEVICE_UNATTACHED 0x18d12d01: // accessory + adb 0x18d12d02: // audio USBH_WAIT_FOR_DEVICE 0x18d12d03: // audio + adb 0x18d12d04: // accessory + audio USBH_DEVICE_ATTACHED 0x18d12d05: // accessory + audio + adb USBH_DEVICE_ATTACHED_SOF_WAIT FALSE TRUE USBH_DEVICE_ATTACHED_RESET USBH_DEVICE_ATTACHED_RESET_WAIT USBH_DEVICE_TRY_ACCESSORY USBH_DEVICE_ATTACHED_POST_RESET_WAIT この時点でVendorと Productがみえるので次で 確認2012/7/16 横浜android PF部 61
  • 62. usbh_work() USBH_DEVICE_ACCESSORY_INIT 755 void usbh_work(void) USBH_INIT USBH_DEVICE_ATTACHED_QUERY 0x18d12d00: // accessory USBH_DEVICE_UNATTACHED 0x18d12d01: // accessory + adb 0x18d12d02: // audio USBH_WAIT_FOR_DEVICE 0x18d12d03: // audio + adb 0x18d12d04: // accessory + audio USBH_DEVICE_ATTACHED 0x18d12d05: // accessory + audio + adb USBH_DEVICE_ATTACHED_SOF_WAIT FALSE TRUE USBH_DEVICE_ATTACHED_RESET USBH_DEVICE_ATTACHED_RESET_WAIT USBH_DEVICE_ACCESSORY_INIT USBH_DEVICE_ATTACHED_POST_RESET_WAIT Accessoryの この時点でVendorと 初期化 Productがみえる USBH_DEVICE_ACCESSORY2012/7/16 横浜android PF部 62
  • 63. usbh_work() USBH_DEVICE_ACCESSORY_INIT  set configuration 1 ○ HOST_TO_DEVICE,SETUP_SET_CONFIGURATION,  accessory_init(&usbh.dev)を呼んで ○ USBH_DEVICE_ACCESSORYへ2012/7/16 横浜android PF部 63
  • 64. L.usbh_init()→accessory_init() accessory_init() デイバイスのコンフィギュレーションディスクリプタを読み If typeが DESCRIPTOR_INTERFACE なら If num_ep == 2 && class == 0xff && sub_class == 0xff &&(inendp <= 0 || outendp <= 0) なら →accessory interface if class == 0x1(Audio) &&sub_class == 0x2(Streaming) && num_ep > 0 なら →interface is audio If type がDESCRIPTOR_ENDPOINT なら acc_interfaceのinendp, outendpを設定 audio_interfaceのaudioendpを設定2012/7/16 横浜android PF部 64
  • 65. usbh_work() USBH_DEVICE_TRY_ACCESSORY 755 void usbh_work(void) USBH_INIT USBH_DEVICE_ATTACHED_QUERY 0x18d12d00: // accessory USBH_DEVICE_UNATTACHED 0x18d12d01: // accessory + adb 0x18d12d02: // audio USBH_WAIT_FOR_DEVICE 0x18d12d03: // audio + adb 0x18d12d04: // accessory + audio USBH_DEVICE_ATTACHED 0x18d12d05: // accessory + audio + adb USBH_DEVICE_ATTACHED_SOF_WAIT FALSE TRUE USBH_DEVICE_ATTACHED_RESET USBH_DEVICE_TRY_ACCESSORY USBH_DEVICE_ATTACHED_RESET_WAIT USBH_DEVICE_ACCESSORY_INIT USBH_DEVICE_ATTACHED_POST_RESET_WAIT Accessoryに 変更を試みる Accessoryの この時点でVendorと 初期化 Productがみえる USBH_DEVICE_IDLE USBH_DEVICE_IDLE2012/7/16 横浜android PF部 65
  • 66. L.usbh_init()→accessory_init() 設定されるendpoint  inendp, outendp, audioendp 呼び出す処理  audioOn(AUDIO_USB, audsamplerate);  pmc_enable_periph_clk(ID_SMC);  SETUP_SET_INTERFACEを送信 struct usb_setup_packet setup = (struct usb_setup_packet){ USB_SETUP_DIR_HOST_TO_DEVICE | USB_SETUP_RECIPIENT_INTERFACE, SETUP_SET_INTERFACE, audio_alternate_setting, audiointerface, 0 ISO転送の起動、受信データ }; のコールバックを設定 usbh_send_setup(&setup, NULL, false);  usbh_queue_iso_transfer(audiopipe, audrecvbuf, sizeof(audrecvbuf), &audio_iso_callback, NULL);2012/7/16 横浜android PF部 66
  • 67. audio_iso_callback() Iso転送の完了割り込みで呼ばれる Underrun,overrunの調整 process_audio(audbuf + curraudbuf * AUDBUFSIZE + audbufpos, buf, pos);  /* take 16 bit stereo signed samples and downconvert in place to mono 12 bit unsigned */  size_t process_audio(uint16_t *outbuf, uint16_t *inbuf, size_t len) 16ビットStereoで受け取った データを12ビットmonoに変更2012/7/16 横浜android PF部 67
  • 68. ADK2/usbh.cswitch ((usbh.dev.vid << 16) | usbh.dev.pid) { case 0x18d12d00: // accessory case 0x18d12d01: // accessory + adb case 0x18d12d02: // audio case 0x18d12d03: // audio + adb case 0x18d12d04: // accessory + audio case 0x18d12d05: // accessory + audio + adb IDが増えてます 2012/7/16 横浜android PF部 68
  • 69. 2012/7/16 横浜android PF部 69
  • 70. こんなやつ これはADK1.0互換 Audioがいらなければこれでもできると思う http://www.slideshare.net/magoroku15/poormans-adk-11350123 もうすぐ5000view2012/7/16 横浜android PF部 70
  • 71. 仕様案 センサ、LEDは載せない  必要になった時点で載せればよい  ADK2012の本質はBT,Audio,HID Bluetooth  欲しい USBオーディオ  PCM 16bit 44.1KHz stereoで出せれば立派なトランスポート  iPhoneは機器認証部品が1社独占のライセンス  HOST + isochronous のサポート できるだけ安く  できればブレッドボードで2012/7/16 横浜android PF部 71
  • 72. MCU NXP のLPC1769  Coretex M3 120MHz Flash 512Kb SRAM 64Kb  Programmer 付き  安価に秋月で入手可能 2500円  I2SでオーディオDACを繋ぎたい2012/7/16 横浜android PF部 72
  • 73. プログラミング環境 Eclipse ベースの LPCXpresso ROMサイズで128Kbまで無償2012/7/16 横浜android PF部 73
  • 74. フレームワーク 直叩きでも出来るけど、とりあえず nxpUSBlib http://www.lpcware.com/content/project/nxpusblib  HOSTモードサポート  Isochronousをサポート ○ UAC(USB Audio Class)のUSB 出力のサンプルあり  ADK1.0のサンプル添付 2012/7/16 横浜android PF部 74
  • 75. BT モジュール USBドングル or cc256x  普通のUSBドングルはHCI  BOMにあったLBMA1BGUG2はcc256xをモジュール に加工?  まずは、cc256xで考える cc256xの入手性は  PANASONIC製のモジュールを見つけた  DigikeyはJP向けに出てこない(輸出できない)  Mouser はオーダは直後にキャンセルされた  chip one stopなんとか入手2012/7/16 横浜android PF部 75
  • 76. モジュールだけどBGA このパッドの内VCC,GND,RST,TX,RX,RTS,CTSの 7本の細線をつけられるか?自信なし。 →評価ボードを追加で発注した 技適は当然ありませんorz まだ電源は入れてないのでヨロシクね2012/7/16 横浜android PF部 76
  • 77. BTは後回しにしてUSBで作業開始 nxpUSBlibに付属のADK1.0ソースをベースに Linux上のlibUSBでコントロール通信  ACCESSORY + AUDIO に切り替えて  Lsusb -v2012/7/16 横浜android PF部 77
  • 78. Device Descriptor case 0x18d12d00: // accessory case 0x18d12d01: // accessory + adbBus 003 Device 016: ID 18d1:2d04 case 0x18d12d02: // audioDevice Descriptor: case 0x18d12d03: // audio + adb case 0x18d12d04: // accessory + audio bLength 18 case 0x18d12d05: // accessory + audio + adb bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x18d1 idProduct 0x2d04 bcdDevice 2.16 iManufacturer 2 samsung iProduct 3 Galaxy Nexus iSerial 4 014994750801300D bNumConfigurations 1
  • 79. Configuration DescriptorConfiguration Descriptor: これが曲者、Audioモードで STREOを指定するとAUDIOが bLength 9 見えず、この値が32?で、 bDescriptorType 2 Interfaceも1に wTotalLength 133 bNumInterfaces 3 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 500mA
  • 80. Interface#1 – 従来のADK部分Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 255 Vendor Specific Subclass bInterfaceProtocol 0 iInterface 6 Android Accessory InterfaceEndpoint Descriptor: Endpoint Descriptor: bLength 7 bLength 7 bDescriptorType 5 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 bmAttributes 2 Transfer Type Bulk Transfer Type Bulk Synch Type None Synch Type None Usage Type Data Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 bInterval 0
  • 81. Interface#2 – AudioControlInterface Descriptor: bNrChannels 2 bLength 9 wChannelConfig 0x0003 bDescriptorType 4 Left Front (L) bInterfaceNumber 1 Right Front (R) bAlternateSetting 0 iChannelNames 0 bNumEndpoints 0 iTerminal 0 bInterfaceClass 1 Audio AudioControl Interface Descriptor: bInterfaceSubClass 1 Control Device bLength 9 bInterfaceProtocol 0 bDescriptorType 36 iInterface 0 bDescriptorSubtype 3 (OUTPUT_TERMINAL)AudioControl Interface Descriptor: bTerminalID 3 bLength 10 wTerminalType 0x0101 USB Streaming bDescriptorType 36 bAssocTerminal 2 bDescriptorSubtype 1 (HEADER) bSourceID 2 bcdADC 1.00 iTerminal 0 wTotalLength 40 AudioControl Interface Descriptor: bInCollection 2 bLength 9 baInterfaceNr( 0) 0 bDescriptorType 36 baInterfaceNr( 1) 1 bDescriptorSubtype 6 (FEATURE_UNIT) AudioControl Interface Descriptor: bUnitID 2 bLength 12 bSourceID 1 bDescriptorType 36 bControlSize 2 bDescriptorSubtype 2 (INPUT_TERMINAL) bmaControls( 0) 0x00 bTerminalID 1 bmaControls( 0) 0x00 wTerminalType 0x0201 Microphone iFeature 0 bAssocTerminal 0
  • 82. Interface#3 – AudioStreamInterface Descriptor: bBitResolution 16 bLength 9 bSamFreqType 1 Discrete bDescriptorType 4 tSamFreq[ 0] 44100 bInterfaceNumber 2 Endpoint Descriptor: bAlternateSetting 1 bLength 9 bNumEndpoints 1 bDescriptorType 5 bInterfaceClass 1 Audio bEndpointAddress 0x82 EP 2 IN bInterfaceSubClass 2 Streaming bmAttributes 13 bInterfaceProtocol 0 Transfer Type Isochronous iInterface 0 Synch Type Synchronous AudioStreaming Interface Descriptor: Usage Type Data bLength 7 wMaxPacketSize 0x0100 1x 256 bytes bDescriptorType 36 bInterval 4 bDescriptorSubtype 1 (AS_GENERAL) bRefresh 0 bTerminalLink 1 bSynchAddress 0 bDelay 1 frames AudioControl Endpoint Descriptor: wFormatTag 1 PCM bLength 7 AudioStreaming Interface Descriptor: bDescriptorType 37 bLength 11 bDescriptorSubtype 1 (EP_GENERAL) bDescriptorType 36 bmAttributes 0x01 bDescriptorSubtype 2 (FORMAT_TYPE) Sampling Frequency bFormatType 1 (FORMAT_TYPE_I) bLockDelayUnits 1 Milliseconds bNrChannels 2 wLockDelay 1 Milliseconds bSubframeSize 2
  • 83. USBで繋ぐには 最初のInterfaceはADK1.0と同じ手順で  VID,PID他,classなど,細かな変更が必要 2,3番目のInterfaceはnxpUSBlibのAudioConfig 用のライブラリを使ってConfig2012/7/16 横浜android PF部 83
  • 84. 現状 Version2のプロトコルでネゴシエーション Audio Dockモードでコンフィグ Isochronous 転送  USBバス上は転送を確認  API経由でデータが受け取れない2012/7/16 横浜android PF部 84
  • 85. USBのキャプチャ2012/7/16 横浜android PF部 85
  • 86. Debug consoleAOA Demo RunningDevice Unattached.Device Attached.Getting Device Data. 最初はMPTが見えるAndroid Device Detected - Non-Accessory mode.Device Unattached.Device Attached. 呪文を唱えるGetting Device Data.Audio mode disableAndroid Device Detected - Accessory mode.Getting Config Data.HOST_GETCONFIG_Successful 別のdeviceが接続されて156 268467540 初期化完了endpoint >> 128endpoint >> 0Input Audio Interface is initialized 2012/7/16 横浜android PF部 86
  • 87. 今後 Audio Dockを作る  Isochronousを何とか受け取れるようにする  I2SでオーディオDACに繋ぐ BTで繋ぐ  USB,CCの両面で  CCの場合はファームを流し込む形では技適取れないよなぁ、  Bomコスト3000円でCCにファーム流しこみ済で技適取得モ ジュール作ったら買う人いる?  @10,000円で海外含めて10,000台出るなら……….. 無理ね。 HIDを試す  Audioと同様に呪文を唱えるとHIDとしてアクセサリを接続で きるみたい  キーボードとか、タブレットとか軽く作れるんじゃないかな2012/7/16 横浜android PF部 87
  • 88. 付録2012/7/16 横浜android PF部 88
  • 89. USBの転送 4 種類の転送方式 Interrupt転送  Periodic 転送  少量のデータを一定の間隔で転送  転送の間隔は、対象となるデバイス毎に決める Isochronous転送  一定のレート・周期で転送  Periodic 転送 Control転送  Configuration情報、コマンド情報、Status情報を転送する方式 Bulk転送  大量のデータを転送する方式2012/7/16 横浜android PF部 89
  • 90. EDとTD ED EndpointDescriptor  転送の対象となるEndpointを管理  デバイスのアドレス、Endpoint の番号、デバイスのSpeed、MaxPacketSize などを 含む TD TransferDescriptor  Endpoint に転送するデータパケットについての情報を管理  PID、データトグル情報、メモリのアドレス、転送完了時のステータス情報を含む HCD Host Controller Driver  ED、TD 群を転送タイプ毎にList という形に纏めて、  List の先頭アドレスをHC に渡します。  List の先頭アドレスの受けわたし方 ○ HC の内部レジスタを介する方法、 ○ メモリ HostControllerCommunicationArea(HCCA)を介する方法 HC Host Controller  転送処理を完了したTD をDoneQueueにリスト化  DoneQueueの先頭アドレスをHCDに通知2012/7/16 横浜android PF部 90
  • 91. Non-Periodic 転送用List Bulk転送、Control転送用のListの形式 Bulk転送用HeadPointer HcBulkHeadED Control転送用HeadPointer HcControlHeadED E E E Head Pointer D D D TD TD TD TD TD TD 2012/7/16 横浜android PF部 91
  • 92. Periodic 転送用List 32個のHeadPointer 32msで一周 Head Pointer Head Pointer 全てのHeadPointerに Head Pointer EDをつないでおくと、 Head Pointer 1回/1msで参照 Head Pointer Head Pointer Head Pointer Head Pointer Head Pointer Head Pointer Head Pointer2012/7/16 横浜android PF部 92
  • 93. Endpoint参照の周期 0 16 8 24  32ms毎に参照 4 20 12  4ms毎に参照 Interrupt Endpoint 28 Descriptor 2 18 10  1ms毎に参照 26 6Interrupt 22Head 14Pointers 30 1 17 9 25 5 21 13 29 3 19 11 27 7 23 15 31 32 16 8 4 2 1 Endpoint Poll Interval (ms)2012/7/16 横浜android PF部 93
  • 94. HcBulkHeadED bulk転送 HcControlHeadED control転送 InterruptHeadED#0 32個全てから参照 InterruptHeadED#1 する事で1ms毎に参 InterruptHeadED#2 照 InterruptHeadED#3 InterruptHeadED#4 InterruptHeadED#5 InterruptHeadED#6 Interrupt転送 Isochronous転送 InterruptHeadED#1 0 InterruptHeadED#3 12012/7/16 横浜android PF部 94
  • 95. ED:Endpoint Descripter 3 2 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 6 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 Dword 0 — MPS F K S D EN FA Dword 1 TD Queue Tail Pointer (TailP) — Dword 2 TD Queue Head Pointer (HeadP) 0 C H Dword 3 Next Endpoint Descriptor (NextED) —• FA USBディバイスのアドレス • MPS パケットサイズ• EN endpoint番号 • TailP 終端EDのアドレス• D 転送方向 • H 停止。HCがセット• S 速度(0:full 1:low) • C ToggleCarry• K Skip • HeapP 先頭EDのアドレス• F TDタイプ(0:GTD 1:ITD) • NextED 次のED2012/7/16 横浜android PF部 95
  • 96. TD:Transfer Descriptor GTDとITDの2種類  GTD General Transfer Descriptor  ITD Isochronous Transfer Descriptor 0~8192byteのバッファをもつ EDにリンクされる HCが処理して処理後にDoneQueueに繋がる2012/7/16 横浜android PF部 96
  • 97. GTD General Transfer Descriptor 3 2 2 2 2 2 2 2 2 1 1 0 0 1 8 7 6 5 4 3 1 0 9 8 3 0 Dword 0 CC EC T DI DP R — Dword 1 Current Buffer Pointer (CBP) Dword 2 Next TD (NextTD) 0 Dword 3 Buffer End (BE)• R DataUnderrunを無視 • NextTD 次のTD• DP 方向とPIDを指定 • BE バッファの末尾アドレス• DI 割り込みタイミング• T DataToggle• EC エラーカウント• CC 完了コード• CBP バッファ領域2012/7/16 横浜android PF部 97
  • 98. ITD Isochronous Transfer Descriptor 3 2 2 2 2 2 2 2 1 1 1 1 0 0 0 1 8 7 6 4 3 1 0 6 5 2 1 5 4 0 Dword 0 CC – FC DI — SF Dword 1 Buffer Page 0 (BP0) — Dword 2 NextTD 0 Dword 3 Buffer End (BE) Dword 4 Offset1/PSW1 Offset0/PSW0 Dword 5 Offset3/PSW3 Offset2/PSW2 Dword 6 Offset5/PSW5 Offset4/PSW4 Dword 7 Offset7/PSW7 Offset6/PSW6• SF 転送開始フレーム • OffsetN• DI 割り込みを待たせる時間 • 下位12ビットがオフセット• FC 転送フレームすう0-7 • 12ビット目で上位20ビット• CC 完了コード を決める 0 BufferPage0の上位20ビット• BP0 バッファの先頭アドレス 1 BufferEndの上位20ビット• NextTD 次のITD • OSWN• BE バッファの終端 • サイズとCC • CCがNotAccessedで OfffsetNとして扱う2012/7/16 横浜android PF部 98
  • 99. Figure 4-5: Host Controller Communications Area FormatHCCA Host Controller Communication Area Size Offset (bytes) Name R/W Description 0 128 HccaInterrruptTable R 32 個のInterrupt ED へのポインタ 0x80 2 HccaFrameNumber W 現在のフレーム番号。このフィールドは、 各フレームのED 処理開始 前にHC が更新 0x82 2 HccaPad1 W HC がHccaFrameNumber をアップデー トした際に、0 がセットされ ます。 0x84 4 HccaDoneHead W フレームの終了時、WriteBackDoneHead 割り込みが有効になっていた場合、HC はこのフィールドにHcDoneHead 値を書 き込みむ。 HC が書き込むと、Software がこの フィールドをクリアして、 HcInterruptStatus のWD ビットをクリア しない限り、HC はこのフィ ールドに書き込みません。 0x88 116 reserved R/W Reserved for use by HC2012/7/16 横浜android PF部 99
  • 100. 付録2012/7/16 横浜android PF部 100
  • 101. android-omap-tuna-3.0-jb-pre1/drivers/usb/gadget 806 static struct android_usb_function *supported_functions[] = { 807 &adb_function, 808 &acm_function, 809 &mtp_function, 810 &ptp_function, 811 &rndis_function, 812 &mass_storage_function, 813 &accessory_function, 814 &audio_source_function, 815 NULL 816 };2012/7/16 横浜android PF部 101
  • 102. android-omap-tuna-3.0-jb-pre1/drivers/usb/gadget 125 static struct usb_interface_descriptor acc_interface_desc = { 126 .bLength = USB_DT_INTERFACE_SIZE, 127 .bDescriptorType = USB_DT_INTERFACE, 128 .bInterfaceNumber = 0, 129 .bNumEndpoints = 2, 130 .bInterfaceClass = USB_CLASS_VENDOR_SPEC, 131 .bInterfaceSubClass = USB_SUBCLASS_VENDOR_SPEC, 132 .bInterfaceProtocol = 0, 133 }; 134 135 static struct usb_endpoint_descriptor acc_highspeed_in_desc = { 136 .bLength = USB_DT_ENDPOINT_SIZE, 137 .bDescriptorType = USB_DT_ENDPOINT, 138 .bEndpointAddress = USB_DIR_IN, 139 .bmAttributes = USB_ENDPOINT_XFER_BULK, 140 .wMaxPacketSize2012/7/16 横浜android PF部 102
  • 103. android-omap-tuna-3.0-jb-pre1/drivers/usb/gadget 213 static struct snd_pcm_hardware audio_hw_info = { 214 .info = SNDRV_PCM_INFO_MMAP | 215 SNDRV_PCM_INFO_MMAP_VALID | 216 SNDRV_PCM_INFO_BATCH | 217 SNDRV_PCM_INFO_INTERLEAVED | 218 SNDRV_PCM_INFO_BLOCK_TRANSFER, 219 220 .formats = SNDRV_PCM_FMTBIT_S16_LE, 221 .channels_min = 2, 222 .channels_max = 2, 223 .rate_min = SAMPLE_RATE, 224 .rate_max = SAMPLE_RATE, 225 226 .buffer_bytes_max =1024 * 1024, 227 .period_bytes_min =64, 228 .period_bytes_max =512 * 1024, 229 .periods_min =2, 230 .periods_max =1024, 231 };2012/7/16 横浜android PF部 103

×