Recommended
PDF
PDF
PDF
KEY
PDF
PDF
PDF
PDF
PDF
PDF
PDF
PDF
発表資料 Fortranを用いた高位合成技術FortRockの開発
PDF
PDF
/proc/irq/<irq>/smp_affinity
PDF
PDF
PDF
PDF
PPTX
PDF
FPGAで作るOpenFlow Switch (FPGAエクストリーム・コンピューティング 第6回) FPGAX#6
PDF
PDF
BMP活用による SDN時代のオーバレイNW監視手法の提案
PDF
PDF
PDF
PDF
PDF
RouterBOARD with OpenFlow
PDF
Synthesijer.Scala (PROSYM 2015)
PDF
PDF
io tつくるよ! LT [m5stackの拡張基板をつくったよ!」
More Related Content What's hot
PDF
PDF
PDF
PDF
発表資料 Fortranを用いた高位合成技術FortRockの開発
PDF
PDF
/proc/irq/<irq>/smp_affinity
PDF
PDF
PDF
PDF
PPTX
PDF
FPGAで作るOpenFlow Switch (FPGAエクストリーム・コンピューティング 第6回) FPGAX#6
PDF
PDF
BMP活用による SDN時代のオーバレイNW監視手法の提案
PDF
PDF
PDF
PDF
PDF
RouterBOARD with OpenFlow
PDF
Synthesijer.Scala (PROSYM 2015)
Similar to Adk2012
PDF
PDF
io tつくるよ! LT [m5stackの拡張基板をつくったよ!」
KEY
DE0でラジコンカー作ってみた 関西de0 fpga勉強会20120519
PDF
KEY
PPTX
PPTX
Androidとfpgaを高速fifo通信させちゃう
PDF
KEY
KEY
KEY
PDF
PDF
Android-controlled robot,Original PCB to work as a bridge between Android-pho...
PDF
Android-controlled robot,Original PCB to work as a bridge between Android-pho...
PPTX
PDF
Android端末と組み込み機器が連携する Android Make Days
PDF
20121013 ADK bootcamp in Tokyo
ODP
ODP
PDF
More from magoroku Yamamoto
PDF
PDF
PDF
PPTX
PDF
PDF
PDF
PDF
Android builders summit slide tour
PDF
PDF
Oscar compiler for power reduction
PPTX
PDF
自動並列化コンパイラをAndroidに適用してみた
PDF
PDF
PDF
PDF
KEY
PDF
PDF
PDF
Recently uploaded
PDF
ふみこんで学ぶ世界遺産700<第2版>世界遺産検定準1級公式テキスト(2026年発売)
PPTX
Introduction to Japanese Language Learning.pptx
PDF
横浜国立大学3年生に向けて研究室を紹介するスライド【2026年度研究室配属について】
PDF
プログラミング講座 【小学校高学年向け】Revision 6 2025/11/30
PDF
横浜国立大学3年生に向けて研究室を紹介する資料【2026年度研究室配属について】
PDF
高等専門学校卒業資格における準学士学位 (Associate Degre) の制度的展望 —国際的学位制度との比較から—
Adk2012 1. 2. Who am I
最底辺活動家、下が好き
オーディオマニア
iPhoneだと機器認証しないと取りだせない
PCMが、ADK2で取りだせそうなのでやる気
満々
昔こんなの作った
オレオレ家電
http://www.slideshare.net/magoroku15/ss-10335135
2012/7/16 横浜android PF部 2
3. 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. 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. 10. 11. メインボード回路図 hardware/adk2012_base.pdf
電源
クロック コネクタ Bluetooth
USB
SD-CARD
書き込み
コネクタ
2012/7/16 横浜android PF部 11
12. 13. PIC10の用途
書き込み
Flashのeraseに使っている
2012/7/16 横浜android PF部 13
14. 15. 16. LEDボードの回路図 hardware/adk2012_led.pdf
ARDUINO HEADER AUDIO SENSORS
LED & DRIVERS
CAP SENSE
2012/7/16 横浜android PF部 16
17. AUDIO
TIのデジタル
アンプ
OP AMP
IV変換
MPUのDAC0から
2012/7/16 横浜android PF部 17
18. SENSORS
すべてI2C接続
ADCは使わない
2012/7/16 横浜android PF部 18
19. CAP SENSE
21点の入力スイッチ
GPIOは使わないI2C入力
2012/7/16 横浜android PF部 19
20. LEDS AND DRIVERS
流し込み側が4ch、吸いこみ側が24x2チャンネル
24x2x4 = 192chのLEDを4096階調
この内の3chで1個のRGB LEDを点灯
TLC5947
24チャネル定電流シンク出力
1チャネルあたりの最大定電流値= 30mA
12ビット(4096階調)PWMコントロール
2012/7/16 横浜android PF部 20
21. 22. 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. 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. 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. 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. 74. フレームワーク
直叩きでも出来るけど、とりあえず
nxpUSBlib http://www.lpcware.com/content/project/nxpusblib
HOSTモードサポート
Isochronousをサポート
○ UAC(USB Audio Class)のUSB 出力のサンプルあり
ADK1.0のサンプル添付
2012/7/16 横浜android PF部 74
75. BT モジュール
USBドングル or cc256x
普通のUSBドングルはHCI
BOMにあったLBMA1BGUG2はcc256xをモジュール
に加工?
まずは、cc256xで考える
cc256xの入手性は
PANASONIC製のモジュールを見つけた
DigikeyはJP向けに出てこない(輸出できない)
Mouser はオーダは直後にキャンセルされた
chip one stopなんとか入手
2012/7/16 横浜android PF部 75
76. モジュールだけどBGA
このパッドの内VCC,GND,RST,TX,RX,RTS,CTSの
7本の細線をつけられるか?自信なし。
→評価ボードを追加で発注した
技適は当然ありませんorz
まだ電源は入れてないのでヨロシクね
2012/7/16 横浜android PF部 76
77. 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. 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. 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. 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. 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