ぶていのログでぶログ

思い出したが吉日

自作キーボードHelixにトラックポイントを付ける その2

前回の記事では、トラックポイント基板の準備まで書いた。 今回は、Helix/QMKにトラックポイントを接続するところまでを書く。

PS/2の接続モード

トラックポイント基板から出るPS/2信号をQMKが取り込む方法として、ドキュメントには以下の3つのパターンが示されている。 このうちの1つを使って、トラックポイント基板と接続する必要がある。

  1. Busywaitモード
  2. Interruptモード
  3. USARTモード

1のBusywaitモードについては、ドキュメントにnot recommendedと書いてあるので、この方法はよっぽどのことが無い限り使わない方が良い*1。 ベストな方法として書かれているのは、3のUSARTモードである。 この方法を使いたいのだが、クロック用としてD5ピンをデータ用としてD2ピンを使用する必要がある。 ProMicroではD5ピンをオンボードのLEDとして使っているためUSARTモードを使うことが出来ない。。 したがって、必然的に2のInterruptモードを利用することになる。

Interruptモードで使用するピンは、D2をクロック、D5をデータとして使う例がドキュメントに載っているが、クロック側はINTまたはPCINTが使えるピン、データ側はどこのピンを選択しても良いようだ。 先述した通りドキュメントの例の通りにピンを選択することはできないので、別のピンを選択する必要がある。

接続ピンの選択

まず、空いているピンを探すのだが、これについてはおまけに書いた。 その結果、(ProMicroに書いてある)ピン9(B5)と10(B6)が使われておらず、また、両方ともPCINTが使えるので、ピン9と10を使うことにした!(下図の青丸部分) また、ピン9をクロック、ピン10をデータ用のピンにした。

f:id:buty4649:20180417005613p:plain

Helixソースの修正

Helixのデフォルトファームのままでは、もちろん扱えない。 ドキュメントに書いてある通り、rules.mkとconfig.hに設定を追加する必要がある。

設定を変更する前に、右手用と左手用でkeymapsディレクトリを分ける必要がある。 これは、なぜかというとトラックポイント基板がついていない左手側でPS/2 Mouse機能を有効化してしまうと、正しくキー入力ができなくなってしまうためである*2。 とはいえ、右手と左手で差分があるのはrules.mkだけであるため、私はrules.mkのみ両方のディレクトリに作成し、それ以外のファイルは右手側をマスターとして左手側はシンボリックリンクにしている。

$ cd keyboards/helix/rev2/keymaps/
$ ls -l right/
total 28
-rw-r--r-- 1 *** *** 2387  3 28 14:52 config.h
-rw-r--r-- 1 *** *** 8033  3 28 14:53 keymap.c
-rw-r--r-- 1 *** ***  430  3 13 20:53 readme.md
-rw-r--r-- 1 *** *** 1296  3 13 21:40 rules.mk
$ ls -l left/
total 4
lrwxr-xr-x 1 *** ***   17  3 13 20:53 config.h -> ../right/config.h
lrwxr-xr-x 1 *** ***   17  3 13 20:53 keymap.c -> ../right/keymap.c
lrwxr-xr-x 1 *** ***   18  3 13 20:53 readme.md -> ../right/readme.md
-rw-r--r-- 1 *** *** 1298  3 13 20:53 rules.mk

rules.mkの変更

以下の設定を右手側の rules.mkに追加する。なお、この設定を行うとそこそこファームウェアサイズが増えるので、OLEDやバックライトLEDを有効にしていた場合はファームウェアサイズに注意した方が良い。

PS2_MOUSE_ENABLE = yes
PS2_USE_INT = yes

config.hの変更

次にconfig.hを変更する。この変更は両手に書いても問題ない。 以下では、ピン9(B5)をクロック、ピン10(B6)をデータ用のピンとしている。

/* Select hand configuration */

//#define MASTER_LEFT          // ①MASTER_LEFTをコメントアウトして
#define MASTER_RIGHT           //   MASTER_RIGHTのコメントをはずす
// #define EE_HANDS

-- -- (省略) -- --

#ifdef PS2_USE_INT
#define PS2_CLOCK_PORT  PORTB  // ②クロックピンの設定
#define PS2_CLOCK_PIN   PINB   //         〃
#define PS2_CLOCK_DDR   DDRB   //         〃
#define PS2_CLOCK_BIT   5      //         〃
#define PS2_DATA_PORT   PORTB  // ③データピンの設定
#define PS2_DATA_PIN    PINB   //         〃
#define PS2_DATA_DDR    DDRB   //         〃
#define PS2_DATA_BIT    6      //         〃

#define PS2_INT_INIT()  do {    \  // ④割り込みの設定
    PCICR |= (1<<PCIE0);        \  //       〃
} while (0)                        //       〃
#define PS2_INT_ON()  do {      \  //       〃
    PCMSK0 |= (1<<PCINT5);      \  //       〃
} while (0)                        //       〃
#define PS2_INT_OFF() do {      \  //       〃
    PCMSK0 &= ~(1<<PCINT5);     \  //       〃
} while (0)                        //       〃
#define PS2_INT_VECT   PCINT0_vect // ⑤利用する割り込みベクタの設定
#endif

各設定について解説する。なお、すべてを正しく理解しているわけではない!ので間違っているかもしれない…*3

①Helixにどちら側にUSBケーブルを刺すのかを決定する。 ここでは、必ずMASTER_RIGHTに変更しなくてはならない。 この変更を行ってもキーマップが反転することはないが、OLEDを使用している場合、右手側に情報が出て、左側にHelixロゴがでるようになる。

②、③ではクロックとデータピンを設定する。 PORTB/PINB、DDRBが何を示しているのかは正しく理解していないが(!)、おそらくArduinoにおけるピンの定義だろうという雰囲気を感じている。 ピン9,10はそれぞれB5、B6としてArdruinoにマッピングされているのでそんな感じに設定する(ふんわり)。

④割り込みを初期化/有効化/無効化するマクロを設定する。 ドキュメントではINTを使うようになっているが、私はPCINTを使うので有効にするレジスタを変更している*4。 なお、私はここが一番工夫したところだと思っている!

⑤利用する割り込みベクタを設定する。

動作確認

rules.mkとconfig.hの設定を変更し、無事にビルドができたらPro Microにファームウェアを書き込む。 Pro Microにファームウェアを書き込んだら、一旦Helix基板から取り外し、ブレッドボードにPro Microと前回作成したリセット回路付きトラックポイント基板を接続して動作確認すると良いと思う。 接続は以下の通り行う。

Pro Micro リセット回路付きトラックポイント基板
RAW or VCC <--> VCC
ピン9 <--> CLK
ピン10 <--> DATA
GND <--> GND

USBケーブルをPro Microに刺し、トラックポイントを動かすとマウスカーソルが動く!!!!!!!!!!・・・・はず。 動かない場合はリセット回路を見直すのがよい。

ここまでのまとめ

QMKの設定を変更して、トラックポイント基板と接続することができた。 次回は、Helixに組み込む方法について書きたい。

おまけ: どうやって空いているピンを調査したか

まずはじめに、ProMicroの回路図とにらめっこした。 Pro Microの回路図(PDF)

基板のピンアウトは下図のとおり。 ここにある、D2~D10、A0~A3、SCK、MISO、MOSIが回路図右側のATMEGA32U4の各ピンにつながっていることがわかる*5

f:id:buty4649:20180417021456p:plain

ATMEGA32U4の各ピンにはPD2だったり本記事でも出てきたPB5、PB6などと書いてある。 これは何かというと、答えはデータシート(PDF)に書いてある。 各ピンごとに機能が違い、使用できるピンごとにA~Fまでグループに分かれているのである。 詳しくはデータシートの2.2 Pin Descriptionを参照。

物理的なピン配置がわかったので、次はソフトウェア部分を見ていく。 キーマトリクスに使われいるピンはそれぞれ、MATRIX_COL_PINSMATRIX_ROW_PINSで定義されている。 5行版だとそれぞれ以下のように定義されている。

#define MATRIX_ROW_PINS { D4, C6, D7, E6, B4 }
#define MATRIX_COL_PINS { F4, F5, F6, F7, B1, B3, B2 }

このD4だったりC6というのが、Atmega32u4上の各ピンに該当している。 これで各々がどうつながっているかがわかったので、表にまとめた。 それぞれHelixでの用途、Pro Micro上のシルクプリントとATmega32u4上のピンになる。

Helix Pro Micro ATmega32u4 ATmega32u4 Pro Micro Helix
RGB? TXO PD3 - RAW Vcc
Serial? RXI PD2 - GND GND
GND GND - - RST RST
GND GND - - Vcc Vcc
SDA(I2c) 2 PD1 PF7 A3 COL4
SCL(I2c) 3 PD0 PF6 A2 COL3
ROW1 4 PD4 PF5 A1 COL2
ROW2 5 PC6 PF4 A0 COL1
ROW3 6 PD7 PB1 15 COL5
ROW4 7 PE6 PB3 14 COL6
ROW5 8 PB4 PB2 16 COL7
- 9 PB5 PB6 10 -

おまけで、5行版のデフォルトのキーマップとピン番号の対応表も書いておく。

        PF4    PF5    PF6    PF7    PB1    PB3   PB2    PB2    PB3    PB1    PF7     PF6    PF5   PF4
     ,-----------------------------------------.             ,-----------------------------------------.
PD4  |   `  |   1  |   2  |   3  |   4  |   5  |             |   6  |   7  |   8  |   9  |   0  | Del  |  PD4
     |------+------+------+------+------+------|             |------+------+------+------+------+------|
PC6  | Tab  |   Q  |   W  |   E  |   R  |   T  |             |   Y  |   U  |   I  |   O  |   P  | Bksp |  PC6
     |------+------+------+------+------+------|             |------+------+------+------+------+------|
PD7  | Ctrl |   A  |   S  |   D  |   F  |   G  |             |   H  |   J  |   K  |   L  |   ;  |  '   |  PD7
     |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
PE6  | Shift|   Z  |   X  |   C  |   V  |   B  |   [  |   ]  |   N  |   M  |   ,  |   .  |   /  |Enter |  PE6
     |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
PB4  |Adjust| Esc  | Alt  | GUI  | EISU |Lower |Space |Space |Raise | KANA | Left | Down |  Up  |Right |  PB4
     `-------------------------------------------------------------------------------------------------'

*1:名前から察するに、入力の待ち受けにsleepを使うのだろうか。それによって、システム全体が止まるので、キー入力に影響があると思われる。

*2:9,10ピンが浮いているので変にノイズが入って、それが割り込み処理をひきおこしているせいなのだろうかという憶測

*3:雰囲気でQMKをいじっている

*4:INTはLレベル、論理変化、立ち下がり、立ち上がりで割り込めるがポートが少ない。PCINTは論理変化のみだがポートが多いという違いであると知った

*5:改めてみるとPro Microはその小ささゆえに未使用なピンが多いことに気がつく