マウスのM

グリッチは、発生するプログラム自体よりも興味深い場合があります。 時々彼らは楽しんだり、何か新しいことを学ぶのを助けます。 今回はグリッチのおかげで、マウスの作り方を学びました。



実験セット



木曜日の夜、コントローラー用の小さなプログラムをデバッグしました。アナログジョイスティックのステータスは、デバッグボードからUARTを介してコンピューターに送信されました。 コンピューターにCOMポートが装備されていることはめったにないため、USB-COMアダプターを使用して作業しました。 私の考えがブルーデススクリーンによってほぼ中断されたときに、Comport Toolkitのデータ列がギザギザになっている理由を理解しようとしていました。



ネクタイ



リセット後、マウスカーソルは完全に予期せずワイルドになりました。 前例のない忍耐力で、彼は画面の左下隅にrawいました! 私はこの行動を初めて見ましたが、しばらくの間、何を考えるべきかわかりませんでした。 残念なことに、カーソルを制御せずに、Windowsにログインすることさえできませんでした(ホットキーがわからず、win7のようこそ画面でのタブ移動が機能しないため)。

コンピューターからすべてのデバイスを切り離し、Resetを数回押すと、カーソルが落ち着き、ログインできました。 デバイスを順番に戻すことで、USB-COMアダプターがマウス暴動の原因であることがわかりました(左下隅にあるコントロールするカーソルもクリックされたことがわかりました)。 アダプターを埋めることができると決めたので、私は家に帰りました。



誰が責任があるのか



翌日(金曜日)、同僚に必死のアダプターを見せました。 デモンストレーション中に、次のことが明らかになりました:デバッグボード(この間ずっとジョイスティックからデータを無限ループで正直に送信していました)を切断すると、「マウス効果」が消えました。



そのため、ボードが特定のWindowsで送信したデータ、またはこれらすべてとUSB-COMアダプターを組み合わせたデータのいずれかでした。 アダプターを介してボードを別のコンピューターに接続して(効果が保存された)、ハードウェアCOMポートにアダプターを使用せずに(効果が保存された)これらの仮定を確認しました。 したがって、ボードそのものでした。

ボードを別のコンピューターに接続すると、ポップアップメッセージ「新しいデバイス-Microsoftボールポイントトラックボール」が見つかりました!







しかし、これはどのように可能ですか?!



トラックボールの名前をグーグルで検索すると、古代のDSLモデムやCOMポートを使用する特定のデバイスで同様の問題が発生することがわかりました。 しかし、問題を特定し、それを解決する(デバイスマネージャで「トラックボール」を無効にする)ことは、どういうわけか面白くありませんでした。

より一般的なクエリ「Microsoftシリアルマウスプロトコル」では、まったく驚くべき(私にとって)ことが明らかになりました。デバイスがMicrosoftシリアルマウスとして認識されるためには、DTRピンがCOMポートにあるときに文字「M」(0x4D)を送信するだけで十分であることがわかりました状態を変更します[1]



詳細



マウスプロトコル(Microsoftシリアルマウス用)は次のようになります。 各パケットは3バイトで構成されます(ただし、使用されるデータは7ビットのみです)。

6ビット 5ビット 4ビット 3ビット 2ビット 1ビット 0ビット
バイト1 1 Lb RB Y7 Y6 X7 X6
バイト2 0 X5 X4 X3 X2 X1 X0
バイト3 0 Y5 Y4 Y3 Y2 Y1 X0


ここに:



このようなマウスは1200 bpsの速度で動作し、各バイトで7ビットのデータを使用します(つまり、最上位ビットは無視されます)、1ストップビット。



叙情的な余談



デバッグボードには完全なCOMコネクタがありましたが、RXおよびTXピンのみを使用し、DTR状態を監視しませんでした。 どうやら、ボードからの連続したデータストリームが、ぎくしゃくしたピンでビートになったようです。 さらに、Microsoftシリアルマウスは1200 bps(および9600のI)の速度で動作し、7ビットのデータパケットでも動作します。 どうやら、星はその夜正しい位置を取りました!



もう1つのGoogleセッション(すでに好奇心が強いため)から、「プラグアンドプレイ。 外部COMデバイスの仕様」、1995年2月付け、マウス操作アルゴリズムが見つかりました[2]



  1. 常にハードウェアでDTRをDSRにエコーします。 電源投入時(DTR = 1およびTXD =マークから)
  2. RTS = 0の場合、RTS = 1になるまで(永久に)待機します
  3. RTS = 1の場合、COM IDを送信します(例表3)
  4. マウスになる
  5. RTS = 0の場合、状態2に戻ります


非表示のテキスト
これは、DTRではなくRTSピン上のユニットの期待を示していますが、真実がどこにあるかを理解するために、これらのピンを追跡できなかったため、あまり興味がありませんでした。 しかし今では、プラグアンドプレイの仕組みを理解しています。ポートにある2つのピンは、デバイスが接続されると単に短絡します。 これにより割り込み要求が発生し、デバイスがポーリングされ、オフとオンになります。


残念ながら、そこにはリストにトラックボール識別子がありませんでした。 最初にComPort ToolkitでCOMポートを「開いて」、ボードをそれに接続した場合、「マウス効果」は発生しませんでした。 ボードの送信内容を聞いた後、次のようなものを見ました。

「KkKkKkkkkkkkjFF.ŒÎckkkkkj。」 この混乱の中にトラックボールIDが見つかりませんでした(個々の文字kまたはjは機能しませんでした)。



マウスになる



1200 bpsの速度で200文字Mの行を送信するテストでは、望ましい結果が得られました。ボードはMicrosoftシリアルマウスとして定義されていました。 座標をパックするための関数をすぐに投げたところ、カーソルが素直に目的の角度に忍び込んできました!



static void formPacket(bool leftClick, bool rightClick, int8_t x, int8_t y) { packet[0] = 0; packet[1] = 0; packet[2] = 0; //  packet[0] |= (1<<6) | (leftClick<<5) | (rightClick<<4); // high y packet[0] |= ((y>>6) & 0x3) << 2; // high x packet[0] |= ((x>>6) & 0x3); packet[1] = x & 0x1F; packet[2] = y & 0x1F; }
      
      







「初期化シーケンス」をトラックボールに置き換えると、トラックボールのパッケージがまったく同じであることが示されたため、トラックボールに対する私の関心は完全に薄れました。



欠点と妨害







結果





負の増分の横枠のため、ジョイスティックの傾斜を座標の増分に正直に変換してスチームバスを使用せず、ジョイスティックを各軸で単純に3ポジションにしました。 -1とほぼ一致するように、正方向の増分を選択しました。



私はそのような「マウス」の他のアプリケーションを思い付くことができませんでしたが、誰かが役に立つかもしれません。



All Articles