@magoroku15
    Rev.1.0
  2012/7/13
横浜android PF部
Who am I
 最底辺活動家、下が好き
 オーディオマニア
 iPhoneだと機器認証しないと取りだせない
  PCMが、ADK2で取りだせそうなのでやる気
  満々
 昔こんなの作った
     オレオレ家電
     http://www.slideshare.net/magoroku15/ss-10335135



2012/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 sync




2012/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
 tools



2012/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製 PIC10




2012/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 SENSE



2012/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      ソースコード
     tools

2012/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
  139


2012/7/16                   横浜android PF部                           25
adkInit
   BT UART
     BTモジュールとのインタフェースとしてUARTを使って
        いるのでその初期化
   HCI
     ホスト(MPU)とBTコントローラの間のIF
   SDP
     サービスを通知するためのプロトコル
   RFCOMM
     シリアル通信のエミュレーションプロトコル
   A2DP

2012/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

                          RF


2012/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                                                     615
595      dbgPrintf("¥r%d", num++);
596      cmd = (HCI_Cmd*)script;
597      btTxCmdPacketEx(cmd);
598      script += 3 + cmd->totalParamLen;
599      btRxEventPacket(0);
                                                     BTモジュールの
605 }                                               ファームを書きこむ
606
607 //get buffer size
608 packetState =
   hciCmdPacketStart(HCI_OGF_Informational,




2012/7/16                                       横浜android PF部                                                 29
btInit #2
616     uint16_t aclLen, aclNum, scoNum;
617     uint8_t scoLen;
618
619     aclLen = (((uint16_t)evt->params[5]) << 8) | evt->params[4];
620     scoLen = evt->params[6];
621
622
        aclNum = (((uint16_t)evt->params[8]) << 8) | evt->params[7];
        scoNum = (((uint16_t)evt->params[10]) << 8) | evt->params[9];
                                                                                         •ペアリングの処理
623
628     gAclPacketsCanSend = aclNum;
629
630     //set connectibility/discoverability
631     pageState = 0;
632     btDiscoverableConnectable();
633
634     //enable simple passcodes
635     if(SUPORT_SSP){
636       packetState = hciCmdPacketStart(HCI_OGF_Controller_and_Baseband, HCI_CMD_Write_Simple_Pairing_Mode);
637       packetState = hciCmdPacketAddU8(packetState, 1); //enable it
638       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     }
645
651 }
652




2012/7/16                                                      横浜android PF部                                                    30
btStart() #1
void 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() #2
void 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){ //match
1608                                                       1627
1609 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(":");                                    1630
1612 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
adkBtConnectionRequest
1588 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 ");                                     1604
1591 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
adkBtLinkKeyCreated
1643 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
adkBtPinRequest
1684 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() #2
void 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() #3
void 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
btRfcommReserveDlci
408 #define RFCOMM_DLCI_PREFERENCE_NONE 0x80                          //use this param to the below
409 #define RFCOMM_DLCI_NEED_EVEN                                     0x81
410 #define RFCOMM_DLCI_NEED_ODD                                      0x82
411
412 uint8_t btRfcommReserveDlci(uint8_t preference){
413
414 uint8_t start = 0, end = 64, step = 2;
415
416 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{
420
421      start = preference;
422      end = preference + 1;
423      step = 1;
424 }
425
426 while(start < end && (reserved & (1ULL << ((uint64_t)start)))) start += step;
427
428 if(start >= end) return 0; //we failed
429
430 reserved |= (1ULL << ((uint64_t)start));
431
2012/7/16
432 return start;                                     横浜android PF部                                   39
btStart() #4
void 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 }



              受信ハンドラを設定
              データを受け取るとCallBack



2012/7/16                       横浜android PF部                        41
btAdkPortRx
1527 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
adkProcessCommand
1274 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 sent
1191 #define BT_CMD_DISPLAY_MODE        15 // () -> (u8) OR (u8) -> ()
1192 #define BT_CMD_LOCK                16 // () -> (u8) OR (u8) -> ()




  2012/7/16                              横浜android PF部                                                        44
adkProcessCommand
1471        case BT_CMD_GET_LICENSE:
1472         {
1473           static const uint32_t maxPacket = MAX_PACKET_SZ - 10;              //seems reasonable
1474
1475          if(*licPos >= sizeof(gzippedLicences)){         //send terminator
1476            reply[sendSz++] = 0;
1477            *licPos = 0;
1478          }
1479          else{
1480
1481
1482
                  uint32_t left = sizeof(gzippedLicences) - *licPos;
                  if(left > maxPacket) left = maxPacket;
                                                                                  ライセンス
1483
1484
                  reply[sendSz++] = 1;
                  while(left--) reply[sendSz++] = gzippedLicences[(*licPos)++];   の送信??
1485          }
1486         }
1487         break;



2012/7/16                                          横浜android PF部                                       45
processUSBAccessory
1772 // 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           84000000ULL
73 void audioSetSample(int source, uint32_t samplerate)
74 {
75 sampleRates[source] = samplerate;
77 // if we're not the highest priority audio source, dont set it
78 if (source != highestPriAudio())
79       return;
81 samplerate =                                        DAC(PWMで代用)の初期化
         (BOARD_MCK + samplerate - 1) / samplerate;
        //err on the side of slower audio
83 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 44100
static 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.c
void 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_ACCESSORY
DEVICE_TO_HOST | TYPE_VENDOR,0x33, version
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
HOST_TO_DEVICE | TYPE_VENDOR,0x35, 0


                                         御約束の呪文

2012/7/16                横浜android PF部                        56
L.usbh_init()
 USBH_DEVICE_TRY_ACCESSORY
DEVICE_TO_HOST | TYPE_VENDOR,0x33, version
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
HOST_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_ACCESSORY
2012/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_IDLE

2012/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.c
switch ((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
                                                    もうすぐ5000view


2012/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 -v




2012/7/16         横浜android PF部   77
Device Descriptor
                                               case 0x18d12d00: // accessory
                                               case 0x18d12d01: // accessory + adb
Bus 003 Device 016: ID 18d1:2d04               case 0x18d12d02: // audio
Device 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 Descriptor
Configuration 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 Interface



Endpoint 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 – AudioControl
Interface 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 – AudioStream
Interface 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
    用のライブラリを使ってConfig




2012/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 console
AOA Demo Running
Device Unattached.
Device Attached.
Getting Device Data.                                最初はMPTが見える
Android Device Detected - Non-Accessory mode.
Device Unattached.
Device Attached.
                                                      呪文を唱える
Getting Device Data.
Audio mode disable
Android Device Detected - Accessory mode.
Getting Config Data.
HOST_GETCONFIG_Successful
                                                   別のdeviceが接続されて
156 268467540
                                                   初期化完了
endpoint >> 128
endpoint >> 0
Input 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 Pointer

2012/7/16       横浜android PF部                  92
Endpoint参照の周期
             0
            16
             8
            24
                                                                        32ms毎に参照
             4
            20
            12                                                          4ms毎に参照
                                                                           Interrupt
                                                                           Endpoint
            28                                                             Descriptor
             2
            18
            10                                                          1ms毎に参照
            26
             6
Interrupt   22
Head        14
Pointers    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
        1
2012/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 次のED
2012/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 Format



HCCA 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 HC




2012/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          .wMaxPacketSize




2012/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

Adk2012

  • 1.
    @magoroku15 Rev.1.0 2012/7/13 横浜android PF部
  • 2.
    Who am I 最底辺活動家、下が好き  オーディオマニア  iPhoneだと機器認証しないと取りだせない PCMが、ADK2で取りだせそうなのでやる気 満々  昔こんなの作った  オレオレ家電  http://www.slideshare.net/magoroku15/ss-10335135 2012/7/16 横浜android PF部 2
  • 3.
    今日のお話  ADK2012の解析 ハード編 ADK2012の解析 ソフト編  CLONEの作り方・可能性 2012/7/16 横浜android PF部 3
  • 4.
  • 5.
    Accessory Development Kit2012 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 sync 2012/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  tools 2012/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製 PIC10 2012/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 SENSE 2012/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.
  • 22.
    2012/7/16 横浜android PF部 22
  • 23.
    adk2012/board  MakefileBasedBuild  ATMEL ATMEL SAM3X依存部  App ソースコード  Build  flash  setup  hardware ハード編で説明  library  ADK2 ソースコード  tools 2012/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 120void 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 139 2012/7/16 横浜android PF部 25
  • 26.
    adkInit  BT UART  BTモジュールとのインタフェースとしてUARTを使って いるのでその初期化  HCI  ホスト(MPU)とBTコントローラの間のIF  SDP  サービスを通知するためのプロトコル  RFCOMM  シリアル通信のエミュレーションプロトコル  A2DP 2012/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 RF 2012/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 615 595 dbgPrintf("¥r%d", num++); 596 cmd = (HCI_Cmd*)script; 597 btTxCmdPacketEx(cmd); 598 script += 3 + cmd->totalParamLen; 599 btRxEventPacket(0); BTモジュールの 605 } ファームを書きこむ 606 607 //get buffer size 608 packetState = hciCmdPacketStart(HCI_OGF_Informational, 2012/7/16 横浜android PF部 29
  • 30.
    btInit #2 616 uint16_t aclLen, aclNum, scoNum; 617 uint8_t scoLen; 618 619 aclLen = (((uint16_t)evt->params[5]) << 8) | evt->params[4]; 620 scoLen = evt->params[6]; 621 622 aclNum = (((uint16_t)evt->params[8]) << 8) | evt->params[7]; scoNum = (((uint16_t)evt->params[10]) << 8) | evt->params[9]; •ペアリングの処理 623 628 gAclPacketsCanSend = aclNum; 629 630 //set connectibility/discoverability 631 pageState = 0; 632 btDiscoverableConnectable(); 633 634 //enable simple passcodes 635 if(SUPORT_SSP){ 636 packetState = hciCmdPacketStart(HCI_OGF_Controller_and_Baseband, HCI_CMD_Write_Simple_Pairing_Mode); 637 packetState = hciCmdPacketAddU8(packetState, 1); //enable it 638 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 } 645 651 } 652 2012/7/16 横浜android PF部 30
  • 31.
    btStart() #1 void 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() #2 void 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){ //match 1608 1627 1609 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(":"); 1630 1612 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.
    adkBtConnectionRequest 1588 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 "); 1604 1591 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.
    adkBtLinkKeyCreated 1643 static voidadkBtLinkKeyCreated(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.
    adkBtPinRequest 1684 static charadkBtPinRequest(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() #2 void 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() #3 void 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.
    btRfcommReserveDlci 408 #define RFCOMM_DLCI_PREFERENCE_NONE0x80 //use this param to the below 409 #define RFCOMM_DLCI_NEED_EVEN 0x81 410 #define RFCOMM_DLCI_NEED_ODD 0x82 411 412 uint8_t btRfcommReserveDlci(uint8_t preference){ 413 414 uint8_t start = 0, end = 64, step = 2; 415 416 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{ 420 421 start = preference; 422 end = preference + 1; 423 step = 1; 424 } 425 426 while(start < end && (reserved & (1ULL << ((uint64_t)start)))) start += step; 427 428 if(start >= end) return 0; //we failed 429 430 reserved |= (1ULL << ((uint64_t)start)); 431 2012/7/16 432 return start; 横浜android PF部 39
  • 40.
    btStart() #4 void 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 voidbtRfcommRegisterPort(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 } 受信ハンドラを設定 データを受け取るとCallBack 2012/7/16 横浜android PF部 41
  • 42.
    btAdkPortRx 1527 static voidbtAdkPortRx(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.
    adkProcessCommand 1274 static uint16_tadkProcessCommand(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 sent 1191 #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.
    adkProcessCommand 1471 case BT_CMD_GET_LICENSE: 1472 { 1473 static const uint32_t maxPacket = MAX_PACKET_SZ - 10; //seems reasonable 1474 1475 if(*licPos >= sizeof(gzippedLicences)){ //send terminator 1476 reply[sendSz++] = 0; 1477 *licPos = 0; 1478 } 1479 else{ 1480 1481 1482 uint32_t left = sizeof(gzippedLicences) - *licPos; if(left > maxPacket) left = maxPacket; ライセンス 1483 1484 reply[sendSz++] = 1; while(left--) reply[sendSz++] = gzippedLicences[(*licPos)++]; の送信?? 1485 } 1486 } 1487 break; 2012/7/16 横浜android PF部 45
  • 46.
    processUSBAccessory 1772 // USBaccessory 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 overBluetooth のまとめ  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 84000000ULL 73 void audioSetSample(int source, uint32_t samplerate) 74 { 75 sampleRates[source] = samplerate; 77 // if we're not the highest priority audio source, dont set it 78 if (source != highestPriAudio()) 79 return; 81 samplerate = DAC(PWMで代用)の初期化 (BOARD_MCK + samplerate - 1) / samplerate; //err on the side of slower audio 83 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 44100 staticuint32_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.c void 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_ACCESSORY DEVICE_TO_HOST |TYPE_VENDOR,0x33, version 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 HOST_TO_DEVICE | TYPE_VENDOR,0x35, 0 御約束の呪文 2012/7/16 横浜android PF部 56
  • 57.
    L.usbh_init()  USBH_DEVICE_TRY_ACCESSORY DEVICE_TO_HOST |TYPE_VENDOR,0x33, version 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 HOST_TO_DEVICE | TYPE_VENDOR,0x35, 0 1か所追加これが Audio機能を呼び出す 2012/7/16 横浜android PF部 57
  • 58.
    L.usbh_init()→usbTask() /* for thecoop 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_ACCESSORY 2012/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_IDLE 2012/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.c switch ((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 もうすぐ5000view 2012/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.
    フレームワーク  直叩きでも出来るけど、とりあえず  nxpUSBlibhttp://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.
  • 78.
    Device Descriptor case 0x18d12d00: // accessory case 0x18d12d01: // accessory + adb Bus 003 Device 016: ID 18d1:2d04 case 0x18d12d02: // audio Device 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 Descriptor Configuration 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部分 InterfaceDescriptor: 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 Interface Endpoint 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 – AudioControl InterfaceDescriptor: 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 – AudioStream InterfaceDescriptor: 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 用のライブラリを使ってConfig 2012/7/16 横浜android PF部 83
  • 84.
    現状  Version2のプロトコルでネゴシエーション  AudioDockモードでコンフィグ  Isochronous 転送  USBバス上は転送を確認  API経由でデータが受け取れない 2012/7/16 横浜android PF部 84
  • 85.
    USBのキャプチャ 2012/7/16 横浜android PF部 85
  • 86.
    Debug console AOA DemoRunning Device Unattached. Device Attached. Getting Device Data. 最初はMPTが見える Android Device Detected - Non-Accessory mode. Device Unattached. Device Attached. 呪文を唱える Getting Device Data. Audio mode disable Android Device Detected - Accessory mode. Getting Config Data. HOST_GETCONFIG_Successful 別のdeviceが接続されて 156 268467540 初期化完了 endpoint >> 128 endpoint >> 0 Input 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 Pointer 2012/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 6 Interrupt 22 Head 14 Pointers 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 1 2012/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 次のED 2012/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 TransferDescriptor 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 TransferDescriptor 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: HostController Communications Area Format HCCA 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 HC 2012/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 .wMaxPacketSize 2012/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