キーボードLEDの情報を取得する

NumLock,CapsLock,ScrollLockのLEDを制御します。今回一番苦労したところです。「LEDは付けない」という人には不要と思うかもしれませんが、テンキーの切替のためNumLockの情報だけは必要です。今回使用したキーボードはテンキーはありませんが側面に数字が印刷されたキーがあり、NumLockの状態によりキーコードを塗り替える処理を追加します。

LEDの情報はどう扱うのか

HIDの仕様書等参考資料によると、LEDの制御はデバイス側で行うのではなく、あくまでもデバイス側は押されたキーをホスト(PC)に送るだけでキーロックの状態はホストから送られて来る、と記述されています。SetConfigurationというコントロールトランスファで、エンドポイント0に1バイトのデータ(キーロック情報:下位5ビット)が送られて来ます。

SETUPstage:SETUPDAT[0..7]は、
データ位置 内容
SETUPDAT[0] bmRequestType (0x21)
SETUPDAT[1] bmRequest SET_REPORT(0x09)
SETUPDAT[2-3] wValue Report Type (0x02) Report ID(0x00)
SETUPDAT[4-5] wIndex Interface (0x00)
SETUPDAT[6-7] wLength Report Length (0x0004)

DATAstage:EP0BUF[0]は、
ビット位置 Usageコード 対応するLED
0 $01 Num Lock
1 $02 Caps Lock
2 $03 Scroll Lock
3 $04 Compose
4 $05 Kana

のようにホストからデータが送られて来ます。

取得の仕方

まず、dscr.a51にLED情報を得られるようにReportDscr(14行目と15行目の間)に書き加えます。

    db  95h, 05h  ;; REPORT_COUNT (5) LED out
    db  75h, 01h  ;; REPORT_SIZE (1)
    db  05h, 08h  ;; USAGE_PAGE (LEDs)
    db  19h, 01h  ;; USAGE_MINIMUM (Num Lock)
    db  29h, 05h  ;; USAGE_MAXIMUM (Kana)
    db  91h, 02h  ;; OUTPUT (Data,Var,Abs)
    db  95h, 01h  ;; REPORT_COUNT (1)
    db  75h, 03h  ;; REPORT_SIZE (3)
    db  91h, 01h  ;; OUTPUT (Cnst) LED report padding

SetConfigurationは、fw.cのメイン処理で捕捉され、bulkloop.cのDR_SetConfiguration(void)を呼び出しているのでこの中に処理を書きます。

BOOL DR_SetConfiguration(void)   // Called when a Set Configuration command is received
{
   Configuration = SETUPDAT[2];
   if(SETUPDAT[0] == 0x21 && SETUPDAT[3] == 0x02){ //キーロック情報(Num,Scrlk,Capslk)取得
      Test = 1;
      EP0BCH = 0; EP0BCL = 0;
   }
   return(TRUE);            // Handled by user code
}

フラグ(Test)を立てておき、このフラグが立っているときエンドポイント0にデータが来たときはLEDの情報だと判断します。EP0BCをリセットしていますがこうしておかないとデータが来ないようです。

次に、エンドポイント0出力の割込みを有効にします。fw.cの割込みの設定しているところに、

  EA = 1;                  // Enable 8051 interrupts
  EPIE |= 0x02; //Enable EndPoint0 OUT interrupt. ←追加

のように追加します。そしてエンドポイント0出力の割込み処理ISR_Ep0out(void)に処理を書き加えます。

void ISR_Ep0out(void)  interrupt 0
{
   if(Test){ // キーロック情報(Num,Scrlk,Capslk)取得
       lock_led = EP0BUF[0];
       if(lock_led != lock_led_bak){
           //lock_led b0:Num. b1:Caps. b2:Scroll.
           //IOD.b4〜b6:LED出力用.0で点灯.下位4ビットに影響を与えない
           OED = (OED & 0x0F) | ((lock_led << 4) & 0xF0);
           lock_led_bak = lock_led;
       }
       Test = 0;
   }
   EZUSB_IRQ_CLEAR();
   EPIRQ = 0x02; //Ep0out request clear
}

lock_ledにLEDの情報が取得され、Dポート(b4〜b6)に接続したLEDを制御します。

LEDの取り付け


ぎりぎりのサイズでケースを作ってしまってスペースが無いため、超小型のフルカラーLEDを使用しました。判り難いので市販のものには絶対採用されない方法ですがかえって手作りには面白いと思います。

USBキーボードの製作へ戻る

関連リンク

http://mcn.oops.jp/wiki/index.php?USB%2F%BB%C5%CD%CD


お名前: コメント:

トップ メニュー

This web page is described in Japanese, but you can read in English by translation site.

  • このサイトはリンクフリーです。
  • コメント欄は改行せず一行で入れてください。
  • スパム判定ではじかれた場合は、その後に「書込みました」旨のみのコメント等何らかの書き込み成功していただけると早く対応できます。
  • 非日本語対応ブラウザからは書き込みできません。