SlideShare uma empresa Scribd logo
1 de 103
Baixar para ler offline
@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

Mais conteúdo relacionado

Mais procurados

RouterBOARD with OpenFlow
RouterBOARD with OpenFlowRouterBOARD with OpenFlow
RouterBOARD with OpenFlowToshiki Tsuboi
 
Interrupt Affinityについて
Interrupt AffinityについてInterrupt Affinityについて
Interrupt AffinityについてTakuya ASADA
 
BMP活用による SDN時代のオーバレイNW監視手法の提案
BMP活用による SDN時代のオーバレイNW監視手法の提案BMP活用による SDN時代のオーバレイNW監視手法の提案
BMP活用による SDN時代のオーバレイNW監視手法の提案Toshiki Tsuboi
 
Zynq VIPを利用したテストベンチ
Zynq VIPを利用したテストベンチZynq VIPを利用したテストベンチ
Zynq VIPを利用したテストベンチMr. Vengineer
 
4章 Linuxカーネル - 割り込み・例外 4
 4章 Linuxカーネル - 割り込み・例外 4 4章 Linuxカーネル - 割り込み・例外 4
4章 Linuxカーネル - 割り込み・例外 4mao999
 
4章 Linuxカーネル - 割り込み・例外 3
4章 Linuxカーネル - 割り込み・例外 34章 Linuxカーネル - 割り込み・例外 3
4章 Linuxカーネル - 割り込み・例外 3mao999
 
FPGAで作るOpenFlow Switch (FPGAエクストリーム・コンピューティング 第6回) FPGAX#6
FPGAで作るOpenFlow Switch (FPGAエクストリーム・コンピューティング 第6回) FPGAX#6FPGAで作るOpenFlow Switch (FPGAエクストリーム・コンピューティング 第6回) FPGAX#6
FPGAで作るOpenFlow Switch (FPGAエクストリーム・コンピューティング 第6回) FPGAX#6Kentaro Ebisawa
 
FPGAX6_hayashi
FPGAX6_hayashiFPGAX6_hayashi
FPGAX6_hayashi愛美 林
 
高位合成友の会@ドワンゴ,2015年12月8日
高位合成友の会@ドワンゴ,2015年12月8日高位合成友の会@ドワンゴ,2015年12月8日
高位合成友の会@ドワンゴ,2015年12月8日貴大 山下
 
/proc/irq/&lt;irq>/smp_affinity
/proc/irq/&lt;irq>/smp_affinity/proc/irq/&lt;irq>/smp_affinity
/proc/irq/&lt;irq>/smp_affinityTakuya ASADA
 
BGP/MPLS-VPNのお勉強資料
BGP/MPLS-VPNのお勉強資料BGP/MPLS-VPNのお勉強資料
BGP/MPLS-VPNのお勉強資料Toshiki Tsuboi
 
発表資料 Fortranを用いた高位合成技術FortRockの開発
発表資料 Fortranを用いた高位合成技術FortRockの開発発表資料 Fortranを用いた高位合成技術FortRockの開発
発表資料 Fortranを用いた高位合成技術FortRockの開発貴大 山下
 
FPGAのトレンドをまとめてみた
FPGAのトレンドをまとめてみたFPGAのトレンドをまとめてみた
FPGAのトレンドをまとめてみたTakefumi MIYOSHI
 
4章 Linuxカーネル - 割り込み・例外 2
4章 Linuxカーネル - 割り込み・例外 24章 Linuxカーネル - 割り込み・例外 2
4章 Linuxカーネル - 割り込み・例外 2mao999
 
Synthesijer.Scala (PROSYM 2015)
Synthesijer.Scala (PROSYM 2015)Synthesijer.Scala (PROSYM 2015)
Synthesijer.Scala (PROSYM 2015)Takefumi MIYOSHI
 

Mais procurados (20)

ICD/CPSY 201412
ICD/CPSY 201412ICD/CPSY 201412
ICD/CPSY 201412
 
RouterBOARD with OpenFlow
RouterBOARD with OpenFlowRouterBOARD with OpenFlow
RouterBOARD with OpenFlow
 
Reconf_201409
Reconf_201409Reconf_201409
Reconf_201409
 
Interrupt Affinityについて
Interrupt AffinityについてInterrupt Affinityについて
Interrupt Affinityについて
 
BMP活用による SDN時代のオーバレイNW監視手法の提案
BMP活用による SDN時代のオーバレイNW監視手法の提案BMP活用による SDN時代のオーバレイNW監視手法の提案
BMP活用による SDN時代のオーバレイNW監視手法の提案
 
Zynq VIPを利用したテストベンチ
Zynq VIPを利用したテストベンチZynq VIPを利用したテストベンチ
Zynq VIPを利用したテストベンチ
 
4章 Linuxカーネル - 割り込み・例外 4
 4章 Linuxカーネル - 割り込み・例外 4 4章 Linuxカーネル - 割り込み・例外 4
4章 Linuxカーネル - 割り込み・例外 4
 
4章 Linuxカーネル - 割り込み・例外 3
4章 Linuxカーネル - 割り込み・例外 34章 Linuxカーネル - 割り込み・例外 3
4章 Linuxカーネル - 割り込み・例外 3
 
FPGAで作るOpenFlow Switch (FPGAエクストリーム・コンピューティング 第6回) FPGAX#6
FPGAで作るOpenFlow Switch (FPGAエクストリーム・コンピューティング 第6回) FPGAX#6FPGAで作るOpenFlow Switch (FPGAエクストリーム・コンピューティング 第6回) FPGAX#6
FPGAで作るOpenFlow Switch (FPGAエクストリーム・コンピューティング 第6回) FPGAX#6
 
FPGAX6_hayashi
FPGAX6_hayashiFPGAX6_hayashi
FPGAX6_hayashi
 
高位合成友の会@ドワンゴ,2015年12月8日
高位合成友の会@ドワンゴ,2015年12月8日高位合成友の会@ドワンゴ,2015年12月8日
高位合成友の会@ドワンゴ,2015年12月8日
 
Interrupts on xv6
Interrupts on xv6Interrupts on xv6
Interrupts on xv6
 
/proc/irq/&lt;irq>/smp_affinity
/proc/irq/&lt;irq>/smp_affinity/proc/irq/&lt;irq>/smp_affinity
/proc/irq/&lt;irq>/smp_affinity
 
Takep lpc1114-190614
Takep lpc1114-190614Takep lpc1114-190614
Takep lpc1114-190614
 
VTI の中身
VTI の中身VTI の中身
VTI の中身
 
BGP/MPLS-VPNのお勉強資料
BGP/MPLS-VPNのお勉強資料BGP/MPLS-VPNのお勉強資料
BGP/MPLS-VPNのお勉強資料
 
発表資料 Fortranを用いた高位合成技術FortRockの開発
発表資料 Fortranを用いた高位合成技術FortRockの開発発表資料 Fortranを用いた高位合成技術FortRockの開発
発表資料 Fortranを用いた高位合成技術FortRockの開発
 
FPGAのトレンドをまとめてみた
FPGAのトレンドをまとめてみたFPGAのトレンドをまとめてみた
FPGAのトレンドをまとめてみた
 
4章 Linuxカーネル - 割り込み・例外 2
4章 Linuxカーネル - 割り込み・例外 24章 Linuxカーネル - 割り込み・例外 2
4章 Linuxカーネル - 割り込み・例外 2
 
Synthesijer.Scala (PROSYM 2015)
Synthesijer.Scala (PROSYM 2015)Synthesijer.Scala (PROSYM 2015)
Synthesijer.Scala (PROSYM 2015)
 

Semelhante a Adk2012

Androidロボットサミットin名古屋
Androidロボットサミットin名古屋Androidロボットサミットin名古屋
Androidロボットサミットin名古屋Kenichi Yoshida
 
Androidロボットサミットin愛媛
Androidロボットサミットin愛媛Androidロボットサミットin愛媛
Androidロボットサミットin愛媛Kenichi Yoshida
 
Androidロボットサミットin京都
Androidロボットサミットin京都Androidロボットサミットin京都
Androidロボットサミットin京都Kenichi Yoshida
 
Odyssey MAX 10 FPGA入門セミナーテキスト
Odyssey MAX 10 FPGA入門セミナーテキストOdyssey MAX 10 FPGA入門セミナーテキスト
Odyssey MAX 10 FPGA入門セミナーテキストTsuyoshi Horigome
 
20221027_Toyota_Gadget_Labo_vol1_kitazaki_v1.pdf
20221027_Toyota_Gadget_Labo_vol1_kitazaki_v1.pdf20221027_Toyota_Gadget_Labo_vol1_kitazaki_v1.pdf
20221027_Toyota_Gadget_Labo_vol1_kitazaki_v1.pdfAyachika Kitazaki
 
「前回の COMSTAR ネタに刺激されてしまったので、オレも COMSTAR を使ってみた。」(仮)
「前回の COMSTAR ネタに刺激されてしまったので、オレも COMSTAR を使ってみた。」(仮)「前回の COMSTAR ネタに刺激されてしまったので、オレも COMSTAR を使ってみた。」(仮)
「前回の COMSTAR ネタに刺激されてしまったので、オレも COMSTAR を使ってみた。」(仮)Kazuyuki Sato
 
.NET Micro Framework (プラレールと電子工作)
.NET Micro Framework (プラレールと電子工作).NET Micro Framework (プラレールと電子工作)
.NET Micro Framework (プラレールと電子工作)Akira Hatsune
 
オリジナルMIDIシーケンサ 開発ノート
オリジナルMIDIシーケンサ 開発ノートオリジナルMIDIシーケンサ 開発ノート
オリジナルMIDIシーケンサ 開発ノートyou_ucchy
 
第 1 回 Jetson ユーザー勉強会
第 1 回 Jetson ユーザー勉強会第 1 回 Jetson ユーザー勉強会
第 1 回 Jetson ユーザー勉強会NVIDIA Japan
 
多数の小容量FPGAを用いた スケーラブルなステンシル計算機の開発
多数の小容量FPGAを用いた スケーラブルなステンシル計算機の開発多数の小容量FPGAを用いた スケーラブルなステンシル計算機の開発
多数の小容量FPGAを用いた スケーラブルなステンシル計算機の開発Ryohei Kobayashi
 
20221018_IoTLT_vol92_kitazaki_v1.pdf
20221018_IoTLT_vol92_kitazaki_v1.pdf20221018_IoTLT_vol92_kitazaki_v1.pdf
20221018_IoTLT_vol92_kitazaki_v1.pdfAyachika Kitazaki
 
M5Stackのシールドを作った話
M5Stackのシールドを作った話M5Stackのシールドを作った話
M5Stackのシールドを作った話Masawo Yamazaki
 
Adk互換モジュールのbt対応改造
Adk互換モジュールのbt対応改造Adk互換モジュールのbt対応改造
Adk互換モジュールのbt対応改造Reiko Yamashita
 
ルーティングチュートリアル - AS間経路制御
ルーティングチュートリアル - AS間経路制御ルーティングチュートリアル - AS間経路制御
ルーティングチュートリアル - AS間経路制御Shintaro Kojima
 
io tつくるよ! LT [m5stackの拡張基板をつくったよ!」
io tつくるよ! LT [m5stackの拡張基板をつくったよ!」io tつくるよ! LT [m5stackの拡張基板をつくったよ!」
io tつくるよ! LT [m5stackの拡張基板をつくったよ!」Masawo Yamazaki
 
Bluetooth通信の 仕組みと活用法紹介
Bluetooth通信の仕組みと活用法紹介Bluetooth通信の仕組みと活用法紹介
Bluetooth通信の 仕組みと活用法紹介Takehiko YOSHIDA
 
Arduino 習作工坊 - Lesson 5 機械之夜
Arduino 習作工坊 - Lesson 5 機械之夜Arduino 習作工坊 - Lesson 5 機械之夜
Arduino 習作工坊 - Lesson 5 機械之夜CAVEDU Education
 

Semelhante a Adk2012 (20)

Androidロボットサミットin名古屋
Androidロボットサミットin名古屋Androidロボットサミットin名古屋
Androidロボットサミットin名古屋
 
Androidロボットサミットin愛媛
Androidロボットサミットin愛媛Androidロボットサミットin愛媛
Androidロボットサミットin愛媛
 
Androidロボットサミットin京都
Androidロボットサミットin京都Androidロボットサミットin京都
Androidロボットサミットin京都
 
Odyssey MAX 10 FPGA入門セミナーテキスト
Odyssey MAX 10 FPGA入門セミナーテキストOdyssey MAX 10 FPGA入門セミナーテキスト
Odyssey MAX 10 FPGA入門セミナーテキスト
 
20221027_Toyota_Gadget_Labo_vol1_kitazaki_v1.pdf
20221027_Toyota_Gadget_Labo_vol1_kitazaki_v1.pdf20221027_Toyota_Gadget_Labo_vol1_kitazaki_v1.pdf
20221027_Toyota_Gadget_Labo_vol1_kitazaki_v1.pdf
 
「前回の COMSTAR ネタに刺激されてしまったので、オレも COMSTAR を使ってみた。」(仮)
「前回の COMSTAR ネタに刺激されてしまったので、オレも COMSTAR を使ってみた。」(仮)「前回の COMSTAR ネタに刺激されてしまったので、オレも COMSTAR を使ってみた。」(仮)
「前回の COMSTAR ネタに刺激されてしまったので、オレも COMSTAR を使ってみた。」(仮)
 
.NET Micro Framework (プラレールと電子工作)
.NET Micro Framework (プラレールと電子工作).NET Micro Framework (プラレールと電子工作)
.NET Micro Framework (プラレールと電子工作)
 
Pdp11 on-fpga
Pdp11 on-fpgaPdp11 on-fpga
Pdp11 on-fpga
 
オリジナルMIDIシーケンサ 開発ノート
オリジナルMIDIシーケンサ 開発ノートオリジナルMIDIシーケンサ 開発ノート
オリジナルMIDIシーケンサ 開発ノート
 
第 1 回 Jetson ユーザー勉強会
第 1 回 Jetson ユーザー勉強会第 1 回 Jetson ユーザー勉強会
第 1 回 Jetson ユーザー勉強会
 
多数の小容量FPGAを用いた スケーラブルなステンシル計算機の開発
多数の小容量FPGAを用いた スケーラブルなステンシル計算機の開発多数の小容量FPGAを用いた スケーラブルなステンシル計算機の開発
多数の小容量FPGAを用いた スケーラブルなステンシル計算機の開発
 
Imaocande LT
Imaocande LTImaocande LT
Imaocande LT
 
20221018_IoTLT_vol92_kitazaki_v1.pdf
20221018_IoTLT_vol92_kitazaki_v1.pdf20221018_IoTLT_vol92_kitazaki_v1.pdf
20221018_IoTLT_vol92_kitazaki_v1.pdf
 
M5Stackのシールドを作った話
M5Stackのシールドを作った話M5Stackのシールドを作った話
M5Stackのシールドを作った話
 
Adk互換モジュールのbt対応改造
Adk互換モジュールのbt対応改造Adk互換モジュールのbt対応改造
Adk互換モジュールのbt対応改造
 
ルーティングチュートリアル - AS間経路制御
ルーティングチュートリアル - AS間経路制御ルーティングチュートリアル - AS間経路制御
ルーティングチュートリアル - AS間経路制御
 
io tつくるよ! LT [m5stackの拡張基板をつくったよ!」
io tつくるよ! LT [m5stackの拡張基板をつくったよ!」io tつくるよ! LT [m5stackの拡張基板をつくったよ!」
io tつくるよ! LT [m5stackの拡張基板をつくったよ!」
 
Bluetooth通信の 仕組みと活用法紹介
Bluetooth通信の仕組みと活用法紹介Bluetooth通信の仕組みと活用法紹介
Bluetooth通信の 仕組みと活用法紹介
 
Arduino 習作工坊 - Lesson 5 機械之夜
Arduino 習作工坊 - Lesson 5 機械之夜Arduino 習作工坊 - Lesson 5 機械之夜
Arduino 習作工坊 - Lesson 5 機械之夜
 
Delayの等価回路モデル
Delayの等価回路モデルDelayの等価回路モデル
Delayの等価回路モデル
 

Mais de magoroku Yamamoto

Mais de magoroku Yamamoto (20)

Deep learning入門
Deep learning入門Deep learning入門
Deep learning入門
 
波形で見るBig.little
波形で見るBig.little波形で見るBig.little
波形で見るBig.little
 
自動並列化コンパイラをAndroidに適用してみた
自動並列化コンパイラをAndroidに適用してみた自動並列化コンパイラをAndroidに適用してみた
自動並列化コンパイラをAndroidに適用してみた
 
Oscar compiler for power reduction
Oscar compiler for power reduction Oscar compiler for power reduction
Oscar compiler for power reduction
 
Unix v6 セミナー vol. 5
Unix v6 セミナー vol. 5Unix v6 セミナー vol. 5
Unix v6 セミナー vol. 5
 
仮想記憶入門 BSD-4.3を例題に
仮想記憶入門 BSD-4.3を例題に仮想記憶入門 BSD-4.3を例題に
仮想記憶入門 BSD-4.3を例題に
 
Android binder-ipc
Android binder-ipcAndroid binder-ipc
Android binder-ipc
 
V6 unix in okinawa
V6 unix in okinawaV6 unix in okinawa
V6 unix in okinawa
 
ぐだ生って何
ぐだ生って何ぐだ生って何
ぐだ生って何
 
Android builders summit slide tour
Android builders summit slide tourAndroid builders summit slide tour
Android builders summit slide tour
 
Poorman’s adk トレーナ
Poorman’s adk トレーナPoorman’s adk トレーナ
Poorman’s adk トレーナ
 
20分でわかった事にするパワーマネジメント
20分でわかった事にするパワーマネジメント20分でわかった事にするパワーマネジメント
20分でわかった事にするパワーマネジメント
 
Poormans sdk
Poormans sdkPoormans sdk
Poormans sdk
 
Ngk2011 b
Ngk2011 bNgk2011 b
Ngk2011 b
 
オレオレ家電
オレオレ家電オレオレ家電
オレオレ家電
 
V6read#4
V6read#4V6read#4
V6read#4
 
V6read#3
V6read#3V6read#3
V6read#3
 
Unixファイルシステムの歴史
Unixファイルシステムの歴史Unixファイルシステムの歴史
Unixファイルシステムの歴史
 
V6read#2
V6read#2V6read#2
V6read#2
 
Androidの入力システム
Androidの入力システムAndroidの入力システム
Androidの入力システム
 

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. http://developer.android.com/tools/adk/index.html 2012/7/16 横浜android PF部 4
  • 5. Accessory Development Kit 2012 Guideの内容  ADK2.0の使い方  Alarm Clock  Playing Audio  Developing Accessories with ADK 2012 $> mkdir android-accessories $> cd android-accessories $> repo init -u https://android.googlesource.com/accessories/manifest $> repo 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. スイッチとLEDの配置 2012/7/16 横浜android PF部 21
  • 22. 2012/7/16 横浜android PF部 22
  • 23. adk2012/board  MakefileBasedBuild  ATMEL ATMEL SAM3X依存部  App ソースコード  Build  flash  setup  hardware ハード編で説明  library  ADK2 ソースコード  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 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
  • 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 void adkBtLinkKeyCreated(const uint8_t* mac, const 1664 Serial.print(" "); uint8_t* buf){ //link key was just created, save it if you 1665 Serial.print(buf[j], HEX); want it later 1666 } 1644 1667 Serial.print(" }"); 1645 uint8_t j; 1668 1646 1669 if(numPairedDevices < maxPairedDevices){ 1647 Serial.print("Key created for "); 1670 1648 Serial.print(mac[5], HEX); 1671 for(j = 0; j < Bluetooth_LINK_KEY_SIZE; j++) 1649 Serial.print(":"); savedKey[numPairedDevices][j] = buf[j]; 1650 Serial.print(mac[4], HEX); 1672 for(j = 0; j < Bluetooth_MAC_SIZE; j++) 1651 Serial.print(":"); savedMac[numPairedDevices][j] = mac[j]; 1652 Serial.print(mac[3], HEX); 1673 numPairedDevices++; 1653 Serial.print(":"); 1674 Serial.print("saved to slot "); 1654 Serial.print(mac[2], HEX); 1675 Serial.print(numPairedDevices); 1655 Serial.print(":"); 1676 Serial.print("/"); 1656 Serial.print(mac[1], HEX); 1677 Serial.println(maxPairedDevices); 1657 Serial.print(":"); 1678 } 1658 Serial.print(mac[0], HEX); 1679 else{ 1659 Serial.print(" <- "); 1680 Serial.println("out of slots...discaring¥n"); 1660 1681 } 1661 Serial.print("{"); 1682 } 1662 for(j = 0; j < Bluetooth_LINK_KEY_SIZE; j++){ 1663 2012/7/16 横浜android PF部 35
  • 36. 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
  • 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_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
  • 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 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
  • 42. 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
  • 43. 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
  • 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 // USB accessory 1773 static void processUSBAccessory() 1774 { 1781 int res = L.accessoryReceive(receiveBuf, sizeof(receiveBuf)); 1782 if (res >= 4) { 1783 uint8_t cmd = receiveBuf[0]; 1784 uint8_t seq = receiveBuf[1]; 1785 uint16_t size = receiveBuf[2] | receiveBuf[3] << 8; 1786 1792 uint16_t replylen = adkProcessCommand(cmd, receiveBuf + 4, size, 0, reply + 4, MAX_PACKET_SZ - 4); 1793 if (replylen > 0) { 1794 reply[0] = cmd | CMD_MASK_REPLY; 1795 reply[1] = seq; 1796 reply[2] = replylen; 1797 reply[3] = replylen >> 8; 1798 replylen += 4; 1799 1800 dbgPrintf("ADK: USB: sending %d bytes¥n", replylen); USBの接続も、ア 1801 1802 } L.accessorySend(reply, replylen); プリ層のコマンド 処理は同じ関数で 1803 } 1804 } 1805 2012/7/16 横浜android PF部 46
  • 47. ADK Connection over Bluetooth のまとめ  BTモジュールとの接続は5ピン  TX,RX,CTS,RTS,RST  HCIレベルで操作  ペアリング、PINの処理ほか  BTモジュールはcc256xを前提  cc256xのROMコードを抱き込み  HCIレベルの互換性は不明  アプリ層のコマンドはBTとUSBと共通 2012/7/16 横浜android PF部 47
  • 48. http://developer.android.com/tools/adk/adk2.html#adk-conn ADK Connection over USB ADK L; void setup() { L.adkInit(); L.usbSetAccessoryStringVendor(...); L.usbSetAccessoryStringName(...); L.usbSetAccessoryStringLongname(...); L.usbSetAccessoryStringVersion(...); L.usbSetAccessoryStringUrl(...); L.usbSetAccessoryStringSerial(...); L.usbStart(); } ADK1.0と同じ 2012/7/16 横浜android PF部 48
  • 49. http://developer.android.com/tools/adk/adk2.html#audio-dock USB Audio Dock Implementation ADK L; void setup() { L.audioInit(); L.usbh_init() L.usbStart(); } void loop(void) { ... L.adkEventProcess(); //let the adk framework do its thing ... } 2012/7/16 横浜android PF部 49
  • 50. L.audioInit()を読んでみる ADK L; void setup() { L.audioInit(); // オーディオの初期化 L.usbh_init() // USBの初期化 L.usbStart(); // USBの起動 } void loop(void) { ... L.adkEventProcess(); // アプリケーション定義の ... // コマンド処理 } 2012/7/16 横浜android PF部 50
  • 51. L.audioInit()→audioInit() PMC: Power Management Controller  libraries/ADK/Audio.c PWMC: Plus Width Modulation Controller DACC: Digital Audio Converter Controller 36 void audioInit(void) 37 { 38 PMC_EnablePeripheral(ID_PWM); // PWMCをPON 39 PWMC_ConfigureClocks(0, 0, BOARD_MCK); 40 PWMC_ConfigureChannel(PWM, 0, PWM_CMR_CPRE_MCK, 0, 0); 41 PWMC_ConfigureEventLineMode(PWM, 0, 1); 43 audioSetSample(AUDIO_NULL, DEFAULT_AUDIO_SAMPLERATE); 45 PWMC_EnableChannel(PWM, 0); 46 PMC_EnablePeripheral(ID_DACC); // DACCをPON 47 DACC_Initialize(DACC, ID_DACC, 1, 4, 0, 0, BOARD_MCK, 8, DACC_CHANNEL_0, 0, 16 ); 48 DACC_EnableChannel(DACC, DACC_CHANNEL_0); 49 } 2012/7/16 横浜android PF部 51
  • 52. L.audioInit() →audioSetSample() #define BOARD_MCK 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 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
  • 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 the coop threading system */ static void usbhTask(void* ptr) { for (;;) { coopYield(); usbh_work(); accessory_work(); } } 2012/7/16 横浜android PF部 58
  • 59. usbh_work()  755 void usbh_work(void) USBH_INIT USBH_DEVICE_ATTACHED_QUERY 0x18d12d00: // accessory USBH_DEVICE_UNATTACHED 0x18d12d01: // accessory + adb 0x18d12d02: // audio USBH_WAIT_FOR_DEVICE 0x18d12d03: // audio + adb 0x18d12d04: // accessory + audio USBH_DEVICE_ATTACHED 0x18d12d05: // accessory + audio + adb USBH_DEVICE_ATTACHED_SOF_WAIT FALSE TRUE USBH_DEVICE_ATTACHED_RESET USBH_DEVICE_ATTACHED_RESET_WAIT USBH_DEVICE_TRY_ACCESSORY USBH_DEVICE_ATTACHED_POST_RESET_WAIT この時点でVendorと Productがみえるので次で 確認 2012/7/16 横浜android PF部 59
  • 60. usbh_work() USBH_DEVICE_TRY_ACCESSORY  DEVICE_TO_HOST | TYPE_VENDOR,0x33, versionの取得 versionが1又は2以外ならstateをUSBH_DEVICE_IDLEへ  HOST_TO_DEVICE | TYPE_VENDOR,0x34, 1, “Google, Inc.”を送る  HOST_TO_DEVICE | TYPE_VENDOR,0x34, 2, “DemoKit”送る  HOST_TO_DEVICE | TYPE_VENDOR,0x34, 3, “DemoKit ADK2012”送る  HOST_TO_DEVICE | TYPE_VENDOR,0x34, 4, “2.0”送る  HOST_TO_DEVICE | TYPE_VENDOR,0x34, 5, http://www.android.com送る  HOST_TO_DEVICE | TYPE_VENDOR,0x34, 5, “0000000012345678“送る  HOST_TO_DEVICE | TYPE_VENDOR,0x3a, 1 Auidoモードを要求 1:mono, 2:stereo  HOST_TO_DEVICE | TYPE_VENDOR,0x35, 0 AccessoryをON これ曲者  stateをUSBH_DEVICE_IDLEへ •以上の処理で、Android側が別のVendor,ProductのUSB ディバイスに 変化して、新たなUSBデイバイスの検出処理が開始される •コード0x3aがADK2.0で追加された 2012/7/16 横浜android PF部 60
  • 61. usbh_work()  755 void usbh_work(void) USBH_INIT USBH_DEVICE_ATTACHED_QUERY 0x18d12d00: // accessory USBH_DEVICE_UNATTACHED 0x18d12d01: // accessory + adb 0x18d12d02: // audio USBH_WAIT_FOR_DEVICE 0x18d12d03: // audio + adb 0x18d12d04: // accessory + audio USBH_DEVICE_ATTACHED 0x18d12d05: // accessory + audio + adb USBH_DEVICE_ATTACHED_SOF_WAIT FALSE TRUE USBH_DEVICE_ATTACHED_RESET USBH_DEVICE_ATTACHED_RESET_WAIT USBH_DEVICE_TRY_ACCESSORY USBH_DEVICE_ATTACHED_POST_RESET_WAIT この時点でVendorと Productがみえるので次で 確認 2012/7/16 横浜android PF部 61
  • 62. usbh_work() USBH_DEVICE_ACCESSORY_INIT  755 void usbh_work(void) USBH_INIT USBH_DEVICE_ATTACHED_QUERY 0x18d12d00: // accessory USBH_DEVICE_UNATTACHED 0x18d12d01: // accessory + adb 0x18d12d02: // audio USBH_WAIT_FOR_DEVICE 0x18d12d03: // audio + adb 0x18d12d04: // accessory + audio USBH_DEVICE_ATTACHED 0x18d12d05: // accessory + audio + adb USBH_DEVICE_ATTACHED_SOF_WAIT FALSE TRUE USBH_DEVICE_ATTACHED_RESET USBH_DEVICE_ATTACHED_RESET_WAIT USBH_DEVICE_ACCESSORY_INIT USBH_DEVICE_ATTACHED_POST_RESET_WAIT Accessoryの この時点でVendorと 初期化 Productがみえる USBH_DEVICE_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. フレームワーク  直叩きでも出来るけど、とりあえず  nxpUSBlib http://www.lpcware.com/content/project/nxpusblib  HOSTモードサポート  Isochronousをサポート ○ UAC(USB Audio Class)のUSB 出力のサンプルあり  ADK1.0のサンプル添付 2012/7/16 横浜android PF部 74
  • 75. BT モジュール  USBドングル or cc256x  普通のUSBドングルはHCI  BOMにあったLBMA1BGUG2はcc256xをモジュール に加工?  まずは、cc256xで考える  cc256xの入手性は  PANASONIC製のモジュールを見つけた  DigikeyはJP向けに出てこない(輸出できない)  Mouser はオーダは直後にキャンセルされた  chip one stopなんとか入手 2012/7/16 横浜android PF部 75
  • 76. モジュールだけどBGA このパッドの内VCC,GND,RST,TX,RX,RTS,CTSの 7本の細線をつけられるか?自信なし。 →評価ボードを追加で発注した 技適は当然ありませんorz まだ電源は入れてないのでヨロシクね 2012/7/16 横浜android PF部 76
  • 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部分 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
  • 81. 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
  • 82. 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
  • 83. USBで繋ぐには  最初のInterfaceはADK1.0と同じ手順で  VID,PID他,classなど,細かな変更が必要  2,3番目のInterfaceはnxpUSBlibのAudioConfig 用のライブラリを使ってConfig 2012/7/16 横浜android PF部 83
  • 84. 現状  Version2のプロトコルでネゴシエーション  Audio Dockモードでコンフィグ  Isochronous 転送  USBバス上は転送を確認  API経由でデータが受け取れない 2012/7/16 横浜android PF部 84
  • 85. USBのキャプチャ 2012/7/16 横浜android PF部 85
  • 86. Debug 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
  • 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 Transfer Descriptor 3 2 2 2 2 2 2 2 2 1 1 0 0 1 8 7 6 5 4 3 1 0 9 8 3 0 Dword 0 CC EC T DI DP R — Dword 1 Current Buffer Pointer (CBP) Dword 2 Next TD (NextTD) 0 Dword 3 Buffer End (BE) • R DataUnderrunを無視 • NextTD 次のTD • DP 方向とPIDを指定 • BE バッファの末尾アドレス • DI 割り込みタイミング • T DataToggle • EC エラーカウント • CC 完了コード • CBP バッファ領域 2012/7/16 横浜android PF部 97
  • 98. ITD Isochronous Transfer Descriptor 3 2 2 2 2 2 2 2 1 1 1 1 0 0 0 1 8 7 6 4 3 1 0 6 5 2 1 5 4 0 Dword 0 CC – FC DI — SF Dword 1 Buffer Page 0 (BP0) — Dword 2 NextTD 0 Dword 3 Buffer End (BE) Dword 4 Offset1/PSW1 Offset0/PSW0 Dword 5 Offset3/PSW3 Offset2/PSW2 Dword 6 Offset5/PSW5 Offset4/PSW4 Dword 7 Offset7/PSW7 Offset6/PSW6 • SF 転送開始フレーム • OffsetN • DI 割り込みを待たせる時間 • 下位12ビットがオフセット • FC 転送フレームすう0-7 • 12ビット目で上位20ビット • CC 完了コード を決める 0 BufferPage0の上位20ビット • BP0 バッファの先頭アドレス 1 BufferEndの上位20ビット • NextTD 次のITD • OSWN • BE バッファの終端 • サイズとCC • CCがNotAccessedで OfffsetNとして扱う 2012/7/16 横浜android PF部 98
  • 99. Figure 4-5: Host Controller Communications Area 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