BlueUSBの続編です。
BlueUSBのUSB通信のところは難解なので、必要な部分はブラックボックスのままで引き抜く方針で、その結果をインターバル割込みで読みます。
+アウトライン+
①BlueUSB+Wiiリモコンの動きを確認します。
②必要な部分だけを見つけます。
③割り込みでデータを見ます。
④自分用にまとめてみる。
①いつもの手法で行きます。
プログラムのいろんなところにprintfをばらまいて動きを見ます。
深さ優先探索です。
BlueUSBの中にmain.cppがあり、
main関数は
TestShell();で終わっています。
なので、その先に行きます。
TestShell.cppの中にTestShell();があります。
その中には
USBInit();
gApp.Run();
があります。
でまず、
USBInit();
printf("A\n");
gApp.Run();
printf("B\n");
見たいにすると、Bが出力されないことが分かります。
なのでgApp.Run();に肝があると思います。
で、TestShell.cppの中に
void Run()があって、
ForとかIfとかがあるので↓の様にします。
void Run() { printf("C\n"); for(;;) { printf("D\n"); const char* cmd = ReadLine(); if (strcmp(cmd,"scan") == 0 || strcmp(cmd,"inquiry") == 0) { printf("E\n"); Inquiry();} else if (strcmp(cmd,"ls") == 0) { printf("F\n"); ・・・・・・こうすると、Dまで出力されることが分かります。
なので、肝はReadLine();の中にあると思います。
同様にReadLine();は↓のようにします。
const char* ReadLine() { printf("L\n"); int i; for (i = 0; i < 255; ) { printf("M%2d\n",i); USBLoop(); printf("O\n"); int c = GetConsoleChar(); if (c == -1) continue; if (c == '\n' || c == 13) break; _line[i++] = c; } _line[i] = 0; return _line; }USBLoopが怪しいです。しかもMに続く数字はずっと'0'でした。
つまりUSBLoopになんどもなんども入っています。
で、USBHost.cppの中にVoid Loop()があります。
同様に下のようにします。
void Loop() { printf("P\n"); u16 elapsed = CommunicationArea.FrameNumber - (u16)_frameNumber; // extend to 32 bits _frameNumber += elapsed; // Do callbacks, if any while (_callbacksPending) { printf("Q\n"); for (int i = 0; i < MAX_ENDPOINTS_TOTAL; i++) { printf("R”); Endpoint* endpoint = Endpoints + i; if (endpoint->CurrentState == Endpoint::CallbackPending)・・・・・してみると、初期設定的なWiiリモコンとペアリングっぽいことをやっている間はPとQとRが出てきます。
なんか知りませんがPの次がRだったりして良くわかりません。(すべてをTeraterm出来ているわけではない?)
で、Wiiとの通信が確立するとRがいっぱいとQになります。
たぶんwhileから抜け出していません。
②以上のことを踏まえると、
USBInit();のあとに、いろいろすっとばして
USBLoop();が回っていればいいと思います。
ですので、
void TestShell(){ USBInit(); while(1){ printf("AA\n"); USBLoop(); printf("AB\n"); }・・・・・としてみました。
いまのところ問題は見つかっていません。
③割り込みと同時にいろいろ起きて大丈夫か?にチャレンジします。
main.cppに書き加えます
Lチカと割り込み時に時間をカウントしてみましょう。
void TestShell();/***/Ticker intvTimer; // インターバルタイマDigitalOut Led2(LED2); // LED2extern int32_t TimeMs=0;void isrInterval(void) { Led2=(TimeMs/50)%2; TimeMs+=5; }/***/int main(){ // インターバルタイマ 割込み設定、タイマスタート intvTimer.attach_us(isrInterval, 5000); // 500ms pc.baud(9600); printf("BlueUSB\nNow get a bunch of usb or bluetooth things and plug them in\n"); TestShell();}で、それに加えLoop内で時間を確認します。
void Loop() { printf("P\n"); u16 elapsed = CommunicationArea.FrameNumber - (u16)_frameNumber; // extend to 32 bits _frameNumber += elapsed; // Do callbacks, if any while (_callbacksPending) { printf("Q\n"); for (int i = 0; i < MAX_ENDPOINTS_TOTAL; i++) { printf("R%d\n",TimeMs); Endpoint* endpoint = Endpoints + i; if (endpoint->CurrentState == Endpoint::CallbackPending) {注意)extern int32_t TimeMs;をUSBHost.cppの上の方に書き加えてます。
複数のファイルにまたがるので、(あまりexternの使い方わかってない)
で出力は以下の用になりました。
BlueUSBNow get a bunch of usb or bluetooth things and plug them inUSB INIT (Controller is 1396 bytes)AAPHubStatusChange Hub:0 Port:1 00010101ResetPort Hub:0 Port:1ABAAPABAAPHubStatusChange Hub:0 Port:1 00100103ABAAPABがはじめのほう。
で通信がはじまると
================wii====================PP0000 A1 30 00 03 .0..R16110R16120R16125R16135R16140R16150R16155R16165R16170R16175R16185R16190QR16200R16210R16215R16225OnHidControl0000 00 .R16300R16310R16315R16325R16330R16340R16345R16350R16360R16365R16375R16380QR16390R16400R16405R16415OnHidControl0000 00 .R16490R16500R16505R16515R16520R16525R16535R16540R16550R16555R16565R16570QR16580R16590R16595R16605WII 0300 529 546 650R16630R16640R16645R16655R16660R16670R16675R16685R16690R16695R16705R16710QR16720R16730R16735R16745WII 0300 529 546 650という感じになります。
通信が始まるのに16秒ぐらいかかってますね。
Teratermにはいてる時間が一番ながいんでしょうけど。
④自分用にまとめるとは?
この後サーボ動かしたり、加速度を読んだりしたいのでBluetoothの通信は簡素にしてしまいたいし、通信と同じループ内でサーボを動かしたりしたいので、汎用ループを作ってしまいたい所存です。
Try1.
割り込み内で、通信以外を全部やる。
→結果無理。
無理だった作戦。
・Wiiリモコン値をグローバル変数に格納
・インターバル割り込みでprintfしてteratermする。
結果:
teratermするとBluetoothとの通信が終わっちゃう。
割り込みはしてもいいけどシリアル通信は無理っぽい。
時間的になのか、リソースの使い方的なものなのかは不明。(今回はどうでもいい)
もしかすると確率的に、軽い割り込みであったとしても、Bluetoothが止まるかも知れない。
(遊びなのでどうでもいい。)
Try2.
USBLoopから抜けているので、汎用ループ内にUSBLoopを置く。
結果:
今のところOk。
USBHost.cppは何もしない
TestShell.cppは↓
case 0x37: // Accelerometer http://wiki.wiimoteproject.com/Reports { int pad = (d[2] & 0x9F) | ((d[3] & 0x9F) << 8); int x = (d[2] & 0x60) >> 5 | d[4] << 2; int y = (d[3] & 0x20) >> 4 | d[5] << 2; int z = (d[3] & 0x40) >> 5 | d[6] << 2; //printf("WII %04X %d %d %d\n",pad,x,y,z); m_pad=pad; m_x = x; m_y = y; m_z = z; wii_f=1; } break;各値をグローバルに入れる&Wiiリモコンとの通信出来てますフラグを立てる。
main.cppは↓
int main(){ // インターバルタイマ 割込み設定、タイマスタート intvTimer.attach_us(isrInterval, 5000); // 500ms pc.baud(9600); printf("BlueUSB\nNow get a bunch of usb or bluetooth things and plug them in\n"); //TestShell(); USBInit(); while(1){ USBLoop(); if(wii_f) { printf("main %04X %d %d %d %d\n",m_pad,m_x,m_y,m_z,TimeMs); } }}で出力は、
BlueUSBNow get a bunch of usb or bluetooth things and plug them inUSB INIT (Controller is 1396 bytes)HubStatusChange Hub:0 Port:1 00010101ResetPort Hub:0 Port:1HubStatusChange Hub:0 Port:1 00100103Connect Hub:0 Port:1 fullと始まって、
Wiiリモコンと通信すると
================wii====================0000 A1 30 00 03 .0..OnHidControl0000 00 .OnHidControl0000 00 .main 0300 529 546 650 14760main 0300 528 546 650 14785main 0300 528 546 650 14815main 0300 528 546 650 14845こんな感じになります。
さしあてってWii_fのif内でいろいろはできるんじゃないでしょうか。
終わり。
[0回]
PR