Weitere ähnliche Inhalte Mehr von magoroku Yamamoto (20) Adk20122. Who am I
最底辺活動家、下が好き
オーディオマニア
iPhoneだと機器認証しないと取りだせない
PCMが、ADK2で取りだせそうなのでやる気
満々
昔こんなの作った
オレオレ家電
http://www.slideshare.net/magoroku15/ss-10335135
2012/7/16 横浜android PF部 2
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
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
11. メインボード回路図 hardware/adk2012_base.pdf
電源
クロック コネクタ Bluetooth
USB
SD-CARD
書き込み
コネクタ
2012/7/16 横浜android PF部 11
13. PIC10の用途
書き込み
Flashのeraseに使っている
2012/7/16 横浜android PF部 13
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
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
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
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
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
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
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
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
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