USBキーボードをエミュレートするゲームコントローラーの製作 2022.9.27

    1.はじめに

     こちらのページ「ゲーム三昧の毎日はいかがですか」で紹介しましたゲームコントローラーですが、今となっては随分と古い物ばかりです。

     ジョイスティックの「AVENGER PRO」を除いて他の物は、オークションで売却したり、部品取りで分解したりで、もう手元にはありません。

     その中の「RockFire」については、見た目がゲームパッドなのにPS2キーボードのキーをエミュレーションする面白いツールでした。今回、これと同じような物を、セガ・サターンのゲームコントローラを使って製作しましたので紹介します。

     その完成写真が次です。

    お手本のROCKFIRE
    ケーブルを交換しています。
    中にマイコン回路を組み込んでいます。

     使ったサターンのコントローラは「HSS-0101」です。ハードオフにてジャンクで購入したものです。

     ケーブルは、USB-AケーブルとPS2のメスコネクタの付いたケーブルの2本に交換しています。コントローラ内部には、マイコン回路を仕組んでいます。STARTボタンのすぐ上にLEDを取り付けています。

     PS2メスコネクタにPS2キーボードを繋ぎ、USBケーブルをパソコンのUSBポートに差し込むと、パソコンではUSBキーボードとして認識されます。

     つまり、このコントローラは、基本機能として、PS2キーボードをUSBキーボードに変換する機能を有しています。

     
    2.使い方

     PS2キーボードを繋ぎ、USBケーブルをパソコンのUSBポートに差し込みます。パソコンのUSBポートから電源供給され、正常に起動するとSTARTボタンの上にあるLEDが点灯します。

     この状態でPS2キーボードを操作すると、USBキーボードとしてパソコンにキーが入力されます。コントローラのボタンを押しても初期状態では、ボタンにキーボードのキーが割り付けられていないので何も入力されません。

    2-1 コントローラのボタンへのキーの割り付け

     コントローラのSTARTボタンを短く押します。するとLEDが、点灯から0.1秒の点滅に切り替わります。

     コントローラのボタンに割り付けたいキーボードのキーを押します。この後、割り付けたいコントローラのボタンを押すとそのボタンにキーが割り付けられます。LEDが点灯に変わり割り付け完了です。

     コントローラのボタンを押すまでは、キーボードのキー入力操作を行うことが出来ます。この場合には、ボタンを押す直前のキーが割り付けられます。

     一回の操作で割り付け出来るのは一つのボタンだけです。割り付けたいボタンの数だけSTARTボタンを押して操作を繰り返します。STARTボタンを除く12個のボタンに割り付け出来ます。

     割り付けが終わったボタンは、押すとその割り付けたキーがパソコンに入力されます。

    2-2 パターンの切替

     キーの割り付けの組み合わせは、4パターンまで登録出来ます。遊ぶゲーム毎に割り付けを行うことができます。

     割り付けパターンの切替は、STARTボタンを1秒以上押し続けます。するとLEDが点灯から0.3秒の点滅に変わります。

     STARTボタンを押したまま、コントローラの左の十字ボタンを操作します。UPで1番、RIGHTで2番、DOWNで3番、LEFTで4番のパターンを選択できます。十字ボタンが押されたことを認識すると0.5秒間LEDが素早く点滅します。

     STARTボタンを離すまでは、パターン選択の操作が可能です。STARTボタンを離すと最後に選択した番号のパターンになります。LEDが点灯に変わり切替操作を終了します。

     十字ボタンを操作せずにSTARTボタンを離すとパターンは切り替わりません。

     パターン毎のキーの割り付け情報は、マイコンのフラッシュメモリに書き込んでいますので、電源を切っても消えることはありません。


    3.製 作

     全体の構成としては、次のように考えました。

    ・コントローラは、ジャンクで購入したセガ・サターンのコントローラを使う。

     マイコンで簡単にボタンの押下が読み取れそうな回路であったことと、内部にマイコン回路を組み込むスペースが確保できそうだったことから採用しました。

    ・パソコンへの接続はUSBとするが、接続するキーボードはPS2キーボードとする。

     今時、PS2ではなくUSBが当たり前なので、接続するキーボードもUSBキーボードにしたかったのですが、マイコンに内蔵のUSBモジュールは、ホスト機能とデバイス機能を同時に動かすことは出来ないということから、USBキーボードは諦めました。

     なお、PS2キーボードは、clock と data の2本の信号で簡単に制御できますし、ちょっと古い有線式のUSBキーボードは、USB-PS2の変換コネクタを通せばPS2キーボードとして動く物が多いのでPS2キーボードが無くても困らないだろうと思った次第です。

    3-1.コントローラの清掃と制御信号の調査

     ジャンク品なので汚れもあります。まずは分解して清掃です。コントローラ本体は、日焼けして茶色くなっています。まずは、これの焼け抜き作業を行います。

     ABS樹脂製品の経年による焼けを元に戻すには、洗濯用の漂白剤に浸けて日干しすると少し時間がかかりますが綺麗に元に戻ってくれます。

    経年焼けしたコントローラ
    分解して清掃する。
    端子の信号調査は後で。
    基板表。1995年製(古い!)
    SEGAの専用チップ 315-5789A
    この漂白剤を使います
    バケツの中で漂白剤に浸けておきます。直射日光(紫外線)に晒すと早く戻る。
    24時間でほぼ元に戻る。
    SEGAのロゴが薄くなってしまった。

     コントローラのボタンの押下をマイコンで判定するプログラムを作るのに必要な情報をネットで検索しました。結果です。
    HSS-0101 Cable
    1GND
    2D0
    3D1
    4+5V(IN)
    5+5V(OUT)
    6D2
    7D3
    8S0
    9S1
    HSS-0101 Signal
    S1S0D3D2D1D0
    00RXYZ
    01SACB
    10RtLtDnUp
    11L100
    *S0=1,S1=1の時:
    D2-D0の 100はHSS-0101のIDと思われる

     ケーブルの5番(茶)には、基板内で4番の+5Vが折り返し出力されています。サターン本体がコントローラの接続の有無を調べる為のものだと思います。
     S0,S1はキーを読み取る選択信号です。D0からD3に各ボタンの信号が現れます。押していない時は1、押していると0です。

    3-2. 回 路

     コントローラの他に必要なものは、USBケーブルとPS2ケーブルです。いつも使っているPIC32MX220F032Bを中心に製作した回路が次です。

    回路図(クリックで拡大)

     回路の+5V電源は、パソコンから供給されるUSB電源から取り出しています。3.3Vのレギュレータを経てPICに供給しています。

     サターンのコントローラとの接続は、事前の調査結果に基づき、選択信号(S0,S1)はRB5,RB7に、キー信号(D0-D3)はRB0-RB3に接続しています。RB5,RB7はデジタル出力ピン、RB0-RB3はデジタル入力ピンとなります。S0,S1は2,7KΩで+5Vにプルアップしています。

     PS2キーボードとの接続は、ClockラインとDataラインの2本だけです。「The PS/2 Mouse/Keyboard Protocol」に記載の次の回路では、Clock、Dataともにマイコンのデジタルポートを2つ使うように書かれていますが、少し工夫すればそれぞれ1ポートで済ますことが出来ます。

    PS/2インタフェース回路

    3-3.ファームウエアの作成

     PICマイコンのプログラムは、MPLAB IDEにて、C32コンパイラを使って作成しました。

    ■ コントローラHSS-0101のキーの読み取り

     次のようにコーディングしています。ボタンの信号は押した時に1になるように論理反転を行っています。

    
        int HS0101_read(void)
        {
            int   n;
            int   btn;
    
            btn = 0;
            for(n=0; n<4; n++){
                S0 = (n & 1);
                S1 = ((n & 2) >> 1);
                delay_1us();
                btn |= ((~PORTB & 0b1111) << (n*4));  // 信号は反転しておく
            }
    
            return btn & 0b1000111111111111;   // delete ID part
        }
    
     S0,S1の選択信号によって読み取れる4bitのボタンの4組の情報を、16bitの1つのデータとして取得しています。
     これにより、ボタンが押されたか離されたかの判定が次のように簡単に行うことが出来ます。
    
       static int prev_btn; // 前回読み取った値
    
       btn=HS0101_read();   // 今回の読み取り
    
       if((prev_btn ^ btn)==0){ // 前回値と XOR する
          // ボタンに変化無し
       }else{
          // いずれかのボタンに変化有り
       }
    
       prev_btn = btn;   // 今回値を前回値に設定
    
    

    ■ PS/2キーボードの処理

     PS2キーボードとの通信については 基本的には、「The PS/2 Mouse/Keyboard Protocol」に記載のプロトコルを処理するだけです。

     clockとdataの制御には、入力と出力の2つのポートが必要なのですが、次のようにして1ポートで済ませます。

    今回は、RB9 を clock としています。clock ラインを High にするには、TRISBbits.TRISB9=1; として RB9をデジタル入力にします。プルアップ抵抗により clock ラインは 1 になります。キーボード側が制御する clock ラインの変化は、そのままデジタル入力として取得できます。

     clock ラインを Low にするには、TRISBbits.TRISB9=0; LATBbits.LATB9=0;としてRB9をデジタル出力にして0を出力します。マイコン側が clock ラインを Low にしている時は、キーボード側からの clock ラインの制御は禁止状態となります。(ps2_keyboard.c)

    ■ USBキーボードの処理

     USBドライバー部分については、マイクロチップから提供されている「Microchip Libraries for Applications v2013-06-15」の中の"USB/Device-HID-Keyboard"サンプルデモを使いました。

     これにより、面倒なUSB部分の処理を作る必要もなく、PS2キーボードやコントローラから送られてくるキーのコードをUSBのキーコードに変換する処理を作成するだけで済みます。

     コードの変換もテーブル参照で行うようにしましたのでプログラムはそう難しいものではありません。

     なお、Microchipのサンプルコードのusb_descriptors.c の中にある Report Descriptor の hid_rpt01 については、英語圏での使用が想定されていて、このままでは、'\' や '_'、 'カナ' を入力できませんので一部修正しています。

    ■ コントローラへのキーの割り付け処理とメモリへの書き込み

     「2.使い方」で説明しました内容に従ってプログラムしています。詳細は、(main.c)を参照ください。

     割り付けたキーの情報は、使用の都度、再度設定しなくても良いようにマイコンに記憶させる訳ですが、PIC32MXでは、プログラムメモリ(Flash Memory)に書き込むことになります。

     Flash Memoryへデータを書き込む際には、書き込む前にメモリの消去処理が必要です。この消去は、ページ単位(4096バイト)で行われますので、メモリには、最低4096バイトの領域を確保しておく必要があります。

     そこで、次のようにFlash Memoryのページ境界に4096バイトのデータ領域を確保し、配列の先頭アドレス &flash[0] から メモリ書き込みやメモリ読み取りを行うようにしました。(flash.c)

    
         const unsigned int __attribute__ ((aligned (4096))) flash[1024]={   // ページ境界に確保
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         };
    

    ■ Project File 一式は、こちら(USB_Keyboard_Emulator.zip)になります。


    4.動作確認と回路の組込

      開発と動作確認
      ブレッドボード部拡大
      コントローラ内部に回路を組み込む

     プログラムの開発や動作確認は、ブレッドボードで行いました。コントローラケーブル、USBケーブル、PS2ケーブルは、心線にピンを半田付けしてボードに差し込んでいます。

     コントローラへの組込では、3.3Vレギュレータ回路は基板の切れ端を使っていますがその他は空中配線としています。マイコンはICソケットに差し込んで裏向けに取り付けています。

     PICKit3やUARTの接続用のピンヘッダは完成後には不要ですが、今後の改良に備えて設けています。