Adk2012
Upcoming SlideShare
Loading in...5
×
 

Adk2012

on

  • 7,241 views

 

Statistics

Views

Total Views
7,241
Views on SlideShare
7,070
Embed Views
171

Actions

Likes
17
Downloads
74
Comments
1

11 Embeds 171

https://twitter.com 100
http://picgames.tumblr.com 30
https://si0.twimg.com 13
http://us-w1.rockmelt.com 10
http://shimamoo.tumblr.com 6
http://twitter.com 3
http://pinterest.com 2
https://twimg0-a.akamaihd.net 2
http://shimamoo.jeekoid.com 2
http://safe.tumblr.com 2
http://www.tumblr.com 1
More...

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Adk2012 Adk2012 Presentation Transcript

  • @magoroku15 Rev.1.0 2012/7/13横浜android PF部
  • Who am I 最底辺活動家、下が好き オーディオマニア iPhoneだと機器認証しないと取りだせない PCMが、ADK2で取りだせそうなのでやる気 満々 昔こんなの作った  オレオレ家電  http://www.slideshare.net/magoroku15/ss-103351352012/7/16 横浜android PF部 2
  • 今日のお話 ADK2012の解析 ハード編 ADK2012の解析 ソフト編 CLONEの作り方・可能性2012/7/16 横浜android PF部 3
  • http://developer.android.com/tools/adk/index.html 2012/7/16 横浜android PF部 4
  • 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
  • Developing Accessories with ADK 2012の内容 adk1  旧バージョン adk2012 前半はここを中心に  board  ハード設計情報、回路図、BOM  回路図、レイアウトはEagleで記述  App  Androidアプリのソースコード External  Ide  IDE用のコードなど  Toolchain  クロスコンパイラ2012/7/16 横浜android PF部 6
  • 2012/7/16 横浜android PF部 7
  • 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
  • 2012/7/16 横浜android PF部 9
  • メインボードの主要部品hardware/adk2012 BOM.rtf ATSAM3X8EA-AU  ATMEL製 Coretex-M3 LBMA1BGUG2  村田製作所製 Bluetooth HCI Module PIC10F200T-I/OT  MicroChip製 PIC102012/7/16 横浜android PF部 10
  • メインボード回路図 hardware/adk2012_base.pdf 電源 クロック コネクタ Bluetooth USB SD-CARD 書き込み コネクタ2012/7/16 横浜android PF部 11
  • メインボード回路図 Bluetooth BTモジュールは,TX,RX, RTS,CTS,RESET,CLKの 6本のみ使用。2012/7/16 横浜android PF部 12
  • PIC10の用途 書き込み Flashのeraseに使っている2012/7/16 横浜android PF部 13
  • 2012/7/16 横浜android PF部 14
  • IOボードの主要部品hardware/adk2012_LED BOM.rtf SHT21  SENSIRION製 湿度センサ MAX44005GDT+  MAXIM製 カラーセンサー AT42QT2120-HHM  ATMEL製 タッチセンサ BMP180  BOSCH製 圧力センサ2012/7/16 横浜android PF部 15
  • LEDボードの回路図 hardware/adk2012_led.pdf ARDUINO HEADER AUDIO SENSORS LED & DRIVERS CAP SENSE2012/7/16 横浜android PF部 16
  • AUDIO TIのデジタル アンプ OP AMP IV変換 MPUのDAC0から2012/7/16 横浜android PF部 17
  • SENSORS すべてI2C接続 ADCは使わない2012/7/16 横浜android PF部 18
  • CAP SENSE 21点の入力スイッチ GPIOは使わないI2C入力2012/7/16 横浜android PF部 19
  • 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
  • スイッチとLEDの配置2012/7/16 横浜android PF部 21
  • 2012/7/16 横浜android PF部 22
  • adk2012/board MakefileBasedBuild  ATMEL ATMEL SAM3X依存部  App ソースコード  Build  flash  setup hardware ハード編で説明 library  ADK2 ソースコード tools2012/7/16 横浜android PF部 23
  • 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
  • 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
  • adkInit BT UART  BTモジュールとのインタフェースとしてUARTを使って いるのでその初期化 HCI  ホスト(MPU)とBTコントローラの間のIF SDP  サービスを通知するためのプロトコル RFCOMM  シリアル通信のエミュレーションプロトコル A2DP2012/7/16 横浜android PF部 26
  • adkInit Bluetoothの復習 BT UART  BTモジュールとのインタフェースとしてUARTを使っているのでそ の初期化 HCI  ホスト(MPU)とBTコントローラの間のIF SDP  サービスを通知するためのプロトコル RFCOMM  シリアル通信のエミュレーションプロトコル L2CAP  複数接続を管理するプロトコル A2DP  AVプロファイル、音声通話用のHSPより高音質2012/7/16 横浜android PF部 27
  • adkInit BlurToothの復習 SDP RFCOMM A2DP Control L2CAP ホスト側 HCI HCI LMP MCU BTモジュール Baseband RF2012/7/16 横浜android PF部 28
  • •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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 2012/7/16 横浜android PF部 69
  • こんなやつ これはADK1.0互換 Audioがいらなければこれでもできると思う http://www.slideshare.net/magoroku15/poormans-adk-11350123 もうすぐ5000view2012/7/16 横浜android PF部 70
  • 仕様案 センサ、LEDは載せない  必要になった時点で載せればよい  ADK2012の本質はBT,Audio,HID Bluetooth  欲しい USBオーディオ  PCM 16bit 44.1KHz stereoで出せれば立派なトランスポート  iPhoneは機器認証部品が1社独占のライセンス  HOST + isochronous のサポート できるだけ安く  できればブレッドボードで2012/7/16 横浜android PF部 71
  • MCU NXP のLPC1769  Coretex M3 120MHz Flash 512Kb SRAM 64Kb  Programmer 付き  安価に秋月で入手可能 2500円  I2SでオーディオDACを繋ぎたい2012/7/16 横浜android PF部 72
  • プログラミング環境 Eclipse ベースの LPCXpresso ROMサイズで128Kbまで無償2012/7/16 横浜android PF部 73
  • フレームワーク 直叩きでも出来るけど、とりあえず nxpUSBlib http://www.lpcware.com/content/project/nxpusblib  HOSTモードサポート  Isochronousをサポート ○ UAC(USB Audio Class)のUSB 出力のサンプルあり  ADK1.0のサンプル添付 2012/7/16 横浜android PF部 74
  • BT モジュール USBドングル or cc256x  普通のUSBドングルはHCI  BOMにあったLBMA1BGUG2はcc256xをモジュール に加工?  まずは、cc256xで考える cc256xの入手性は  PANASONIC製のモジュールを見つけた  DigikeyはJP向けに出てこない(輸出できない)  Mouser はオーダは直後にキャンセルされた  chip one stopなんとか入手2012/7/16 横浜android PF部 75
  • モジュールだけどBGA このパッドの内VCC,GND,RST,TX,RX,RTS,CTSの 7本の細線をつけられるか?自信なし。 →評価ボードを追加で発注した 技適は当然ありませんorz まだ電源は入れてないのでヨロシクね2012/7/16 横浜android PF部 76
  • BTは後回しにしてUSBで作業開始 nxpUSBlibに付属のADK1.0ソースをベースに Linux上のlibUSBでコントロール通信  ACCESSORY + AUDIO に切り替えて  Lsusb -v2012/7/16 横浜android PF部 77
  • 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
  • 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
  • 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
  • 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
  • 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
  • USBで繋ぐには 最初のInterfaceはADK1.0と同じ手順で  VID,PID他,classなど,細かな変更が必要 2,3番目のInterfaceはnxpUSBlibのAudioConfig 用のライブラリを使ってConfig2012/7/16 横浜android PF部 83
  • 現状 Version2のプロトコルでネゴシエーション Audio Dockモードでコンフィグ Isochronous 転送  USBバス上は転送を確認  API経由でデータが受け取れない2012/7/16 横浜android PF部 84
  • USBのキャプチャ2012/7/16 横浜android PF部 85
  • 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
  • 今後 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
  • 付録2012/7/16 横浜android PF部 88
  • USBの転送 4 種類の転送方式 Interrupt転送  Periodic 転送  少量のデータを一定の間隔で転送  転送の間隔は、対象となるデバイス毎に決める Isochronous転送  一定のレート・周期で転送  Periodic 転送 Control転送  Configuration情報、コマンド情報、Status情報を転送する方式 Bulk転送  大量のデータを転送する方式2012/7/16 横浜android PF部 89
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 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
  • 付録2012/7/16 横浜android PF部 100
  • 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
  • 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
  • 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