根據tmk製作自己的機械鍵盤固件(二)
Welcome to part 2 of "Build your own keyboard firmware" tutorial.
歡迎來到「構建自己的鍵盤框架」的第二部分。
It may seem hard at first but if you follow all the steps of this tutorial youll see that its harder to explain than to do.
第一眼看上去好像挺難,但是如果你跟著本文的步驟走的話,你會發現,實際上解釋起來可能比實際做起來更困難。
We are still on keyboard/gh60 directory. All we need resides there. This time we are going to customize the actual keyboard matrix and FN layers.
我們的工作目錄還在keyboard/gh60文件夾。我們所做的都在這個文件夾內。這次我們修改真是的鍵盤矩陣和FN層。
Defining the matrix
First of all we need to map the matrix in the keymap_common.h file.
首先我們需要在keymap_common.h文件中的映射鍵盤矩陣。
The bit we need is:
#define KEYMAP( K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K40, K41, K42, K45, K49, K4A, K4B, K4C, K4D ) { { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07, KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K0D }, { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17, KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D }, { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27, KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D }, { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37, KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D }, { KC_##K40, KC_##K41, KC_##K42, KC_NO, KC_NO, KC_##K45, KC_NO, KC_NO, KC_NO, KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D } }
The above schema should reflect your keyboard matrix, or how you wired the switches together.
Take the first row:
上面的這個排列應該符合你真是的鍵盤矩陣,或者是符合你將開關連接在一起的樣子。先看看第一行吧。
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D,
It means that all switches in the first row are straight connected together. If you need more keys you can keep adding them like so:
這意味著,第一行的所有的開關被直接的連接在一塊了。如果你需要更多的按鍵,你應該自行添加,就像下面這個代碼一樣:
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K0F,
Here Ive added two new keys in the first row (K0E and K0F). Remember to add ", " (coma+backslash) at the end of each line.
這裡我又在第一行中多加了兩個按鍵(K0E 和K0F)。記住,別忘了在最後加「,」(都好+反斜杠)
You have to repeat the same key configuration in block of code below.
還有,你還需要在下面那一塊中重複設置一下按鍵。
{ KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07, KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K0D },
As you can see its the same thing we did above with a slightly different syntax.
就像你看到這個和前面的內容是一樣的,但是語法上稍微有點變化。
Now look at the last row:
現在我們來看最後一行吧
K40, K41, K42, K45, K49, K4A, K4B, K4C, K4D
This time we have a jump from K42 to K45. In fact the lower row usually has fewer keys and theres a gap between the ALT key and the SPACEBAR switches. Be careful checking which column each switch is connected to.
這次我們需要從K42直接跳到K45。實際上,最後一行確實按鍵比較少,在ALT鍵和SPACEBAR的開關之間有著間隔。注意一下哪一行和開關連接到了一塊。
{ KC_##K40, KC_##K41, KC_##K42, KC_NO, KC_NO, KC_##K45, KC_NO, KC_NO, KC_NO, KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D }
In the second block we have to identify empty spaces with the KC_NOcode. So while in the first block we just jump from one column to another if no physical connection is present, in the second block we need to fill the void with KC_NO.
在第二部分中我們需要使用KC_NO來表示空鍵。所以在第一塊程序部分中我們從某一列跳到另外一列,中間部分並沒有物理上的連接。在第二部分中我們就需要使用KC_NO填充那些沒有被連接的列。
Have a look at the matrix of the HHFox (you better copy the code below and paste into a text editor).
我們來看看HHFox鍵盤的矩陣排列吧(最好能自行複製到編輯器中查看,因為可能在這裡看可能比較亂)
#define KEYMAP( K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K10, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, K20, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2E, K30, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, K41, K43, K48, K4B, K4C ) { { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07, KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K0D, KC_##K0E }, { KC_##K10, KC_NO , KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17, KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_##K1E }, { KC_##K20, KC_NO , KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27, KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_NO , KC_##K2E }, { KC_##K30, KC_NO , KC_NO , KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37, KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E }, { KC_NO , KC_##K41, KC_NO , KC_##K43, KC_NO , KC_NO , KC_NO , KC_NO , KC_##K48, KC_NO, KC_NO , KC_##K4B, KC_##K4C, KC_NO , KC_NO } }
That exactly resembles the hand wired matrix. Its a bit boring to write up but nothing too complex. Just be careful at writing down the letters and numbers correctly.
這就是矩陣的連接。這一點都不複雜反而有點無聊。但是在這裡還需要強調,你千萬要把字元和數字寫對啊!
You can safely ignore the KEYMAP_ANSI thing.
那啥,你現在可以忽略KEYMAP_ANSI這個宏。
Keymap
And finally the fun part! By default the makefile is building the keymap for the Poker keyboard, so for the sake of simplicity we are going to modify that file. Open the keymap_poker.c
最後是最有趣的部分!默認情況下makefile是用來構建Poker鍵盤的(譯者註:IKBC的一款60的鍵盤),所以我們需要修改這個文件。
Clean everything up and replace it with:
清除所有的內容並用下面的代碼替換:
#include "keymap_common.h"const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {};const uint16_t PROGMEM fn_actions[] = {};
The first is the array of keymaps. The first element in the array will be our main qwerty (or whatever) keymap. You can copy/paste an already made keymap or start over. The base Poker keymap is as follow:
第一個是keymaps的數組。數組中的第一個元素使我們最主要qwerty(或者其他的)keymap。你可以可以複製已經只做好的keymap或者從頭做起。下面這個是根據poker的keymap的修改得到的:
KEYMAP(ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, GRV, BSLS, TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSPC, LCTL, A, S, D, F, G, H, J, K, L, SCLN,QUOT,ENT, LSFT, Z, X, C, V, B, N, M, COMM,DOT, SLSH,RSFT, FN0, LALT, FN1, SPC, PAUS,RALT),
Please note that this is just the list of characters from left to right as you see them on the keyboard. You dont need to add spaces or special codes. Here we are adding some spaces and new lines just to make it more readable, but technically this could be all in one line.
請注意這只是你看鍵盤上從左到右的按鍵上代表的按鍵功能的排列。你並不需要增加額外的空格或者其他特別的代碼。我們這裡之所有還有些縮進和空格,只是為了看上去更好看一點,從編程的角度來看,這些個縮進啥的根本沒用。
Basically just read the characters on your keyboard from left to right, from top to bottom.
基本上我們只是從鍵盤上獲得了了從左到右從上到下的按鍵字元而已。
The keymap for the HHFox would look like so:
所以HHFox的keymap應該是是這樣的「
const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* 0: qwerty */ KEYMAP(ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, GRV, BSLS, TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSPC, LCTL, A, S, D, F, G, H, J, K, L, SCLN,QUOT,ENT, LSFT, Z, X, C, V, B, N, M, COMM,DOT, SLSH,RSFT,FN0, LALT, FN1, SPC, PAUS,RALT),};
If you want to be able to burn your firmware without accessing the teensy reset switch you better add the PAUS key, and it must be on the first layer (not an FN layer).
如果你想要不通過teensy的重置開關就能燒錄你的程序框架,你最好增加一個PAUS按鍵,並且這個按鍵還得再第一層(不是FN層)。(譯者註:不明白是啥意思)
Function layers 功能層? 函數層?
Function keys are defined with the FNx syntax, where x is a number from 0 to 5.
功能按鍵被定義為FNx語法,其中x是0到5。
To add a function layer we just add a new keymap to the array. The following is the first FN layer of the HHFox.
為了增加功能層,我們僅僅需要想數組中增加新的keymap。下面就是HHFox的第一FN層。
const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* 0: qwerty */ KEYMAP(ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, GRV, BSLS, TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSPC, LCTL, A, S, D, F, G, H, J, K, L, SCLN,QUOT,ENT, LSFT, Z, X, C, V, B, N, M, COMM,DOT, SLSH,RSFT,FN0, LALT, FN1, SPC, PAUS,FN2), /* 1: FN 1 */ KEYMAP(MUTE, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, VOLU, VOLD, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, PGUP, UP, TRNS, DEL, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, MYCM, TRNS, TRNS, PGDN, LEFT, RGHT, TRNS, TRNS, TRNS, TRNS, CALC, TRNS, TRNS, TRNS, TRNS, HOME, END, DOWN, TRNS, TRNS, LGUI, TRNS, TRNS, PSCR, RCTL),};
Same shit as above, the only difference is that we use the keyword TRNS (transparent) for all the keys that do not change in behavior when the function key is pressed.
下面那一坨和上面那一坨的區別僅僅在於當我們功能按鍵被按下的時候我們使用了TRNS(transparent)表示我們不改變那些我們不需要改變的按鍵。
So far we just defined the function layer, to actually activate it we need to add something in the fn_action array
現在我們定義了功能層,為了真實的激活這個層,我們需要在fn_action數組中添加一些東西。
const uint16_t PROGMEM fn_actions[] = { [0] = ACTION_LAYER_MOMENTARY(1),};
This means that the FN[0] key will trigger the layer (1) with a ACTION_LAYER_MOMENTARY action. You can define many actions, the most common/useful of which are:
這就意味著FN[0]鍵將會使用行為ACTION_LAYER_MOMENTARY觸發layer(1)(第一層)。你可以定義很多的行為,最常用、最有用的有:
ACTION_LAYER_MOMENTARY(layer), activate layer when holding down the FN keyACTION_LAYER_MOMENTARY(layer),只有當按下並保持按下FN鍵時才觸發這一層
ACTION_LAYER_TOGGLE(layer), activate on first press, deactivate on second pressACTION_LAYER_TOGGLE(layer),第一次按下的時候激活,第二次按下時候恢復
ACTION_LAYER_TAP_KEY(layer, key), works like ACTION_LAYER_MOMENTARY when holding but executes the specified key on tap (quick press/release phase) ACTION_LAYER_TAP_KEY(layer, key),當此按鍵被按下並保持按下的時候和ACTION_LAYER_MOMENTARY的行為一樣,只是當我們使用某種節奏(周期的快按下快鬆開)(譯者註:這都在說什麼啊!)
Lets add a tap action to the HHFox.
來來來,咱們來為HHFox添加 tap action。
const uint16_t PROGMEM fn_actions[] = { [0] = ACTION_LAYER_MOMENTARY(1), [1] = ACTION_LAYER_TAP_KEY(1, KC_ESC),};
Holding the FN1 key we activate the first function layer (same as FN0), but by quickly tapping the same key we get the ESC key instead. Pretty cool, huh? Thank Hasu for that.
按下FN1鍵將會激活第一層功能層(和FN0一樣),但是當我們快速的按下同一個按鍵,我們將得到ESC按鍵而不是其他的。很有意思,對吧?感謝Hasu的努力。
The following would be the final keymap for the HHFox (please note this is not my actual key config). Ive taken the liberty of adding a second function layer that is toggled by pressing the FN2 key.
接下來是HHFox的最後一部分的keymap(譯者註:翻譯成按鍵映射?)(請注意,這不是我真實的按鍵配置)。我已經自行添加了通過按下FN2觸發的第二層功能層。
#include "keymap_common.h"const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { /* 0: qwerty */ KEYMAP(ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, GRV, BSLS, TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSPC, LCTL, A, S, D, F, G, H, J, K, L, SCLN,QUOT,ENT, LSFT, Z, X, C, V, B, N, M, COMM,DOT, SLSH,RSFT, FN0, LALT, FN1, SPC, PAUS,RALT), /* 1: FN 1 */ KEYMAP(MUTE, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, VOLU, VOLD, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, PGUP, UP, TRNS, DEL, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, MYCM, TRNS, TRNS, PGDN, LEFT, RGHT, TRNS, TRNS, TRNS, TRNS, CALC, TRNS, TRNS, TRNS, TRNS, HOME, END, DOWN, TRNS, TRNS, LGUI, TRNS, TRNS, PSCR, RCTL), /* 2: FN 2 */ KEYMAP(MUTE, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, VOLU, VOLD, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, PGUP, UP, TRNS, DEL, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, MYCM, TRNS, TRNS, PGDN, LEFT, RGHT, TRNS, TRNS, TRNS, TRNS, CALC, TRNS, TRNS, TRNS, TRNS, HOME, END, DOWN, TRNS, TRNS, LGUI, TRNS, TRNS, PSCR, SLEP),};const uint16_t PROGMEM fn_actions[] = { [0] = ACTION_LAYER_MOMENTARY(1), [1] = ACTION_LAYER_TAP_KEY(1, KC_ESC), [2] = ACTION_LAYER_TOGGLE(2)};
Oh the joy! We are done!
To the compile! 開始編譯吧!
Exit. Open the terminal go to the gh60 directory and run:
打開終端,cd到gh60的文件夾內,運行一下命令:
make -f Makefile
If you did everything fine youll end up with a file called gh60_lufa.hex.
如果你別的地方都寫的沒啥問題了,你會得到一個名為gh60_lufa.hex的文件。
Connect your keyboard to the USB. On linux you need to do nothing, everything is already working. On Mac and Windows youll probably have to follow a quick installation.
將你的鍵盤通過USB連接到電腦。在linux下,你什麼都不用做。在Mac和Windows下,你需要看一下快速安裝教程。
When done, run the teensy loader, activate the "Auto" button, load the firmware (the hex file) and press the reset button on the teensy. The firmware will be uploaded and the keyboard will start working right away!
好了,運行teensy loader,點擊」Auto「按鈕,載入固件(就是那個hex文件)並按下teensy的複位按鍵。固件就會燒入鍵盤,鍵盤就會正確的運行。
Troubleshooting
Now one of the following scenarios might happen:
現在,一下某個情節或許會發生:
Everythings fine and your keyboard will be working right away
所有的事情都很正常,包括你的鍵盤。
Cool! Youre a keyboard master!
好!你已經成為鍵盤大師了!
The keyboard starts firing random characters on screen and the computer starts beeping
鍵盤開始不停的在屏幕上輸出隨機按鍵,電腦開始發出嗶嗶的聲音。
Disconnect the keyboard, fast! This is most likely a software problem. Double check your code. When you are ready to re-flash, load the new firmware in the teensy loader, reconnect the keyboard and quickly press the reset button.
趕快斷開你的鍵盤!這很有可能是軟體的問題。仔細檢查你的代碼。當你準備好了去重新刷入,使用teensy loader載入你新的固件,重新連接鍵盤並且快速的按下重置按鈕。
The keyboard works but some keys are faulty
鍵盤已經正確工作了,但是有一些按鍵錯了
This is likely a hardware problem. Check your wiring and double check for shorts.
這應該是硬體問題了。檢查你的線路並重點檢查錯誤的地方。
I closed my keyboard and I dont have access to the hardware reset button
**我關閉了我的鍵盤並且我沒有辦法接觸到硬體上的重置按鈕」
Assuming your keyboard is correctly working, software reset is it accomplished with LSHIFT + RSHIFT + PAUSE.
假設你的鍵盤是完全正確的,軟重置可以使用 左shift+右shift+PAUSE按鍵激活。
Everything seems to work but some mods return the wrong key
**所有的好像都正常工作了,但是某些模式下會出現錯誤的按鍵「
Disconnect the keyboard and reconnect holding down the BACKSPACE.
斷開鍵盤連接之後,按住BACKSPACE的同時重新連接。
Thats all for now. Thanks for watching. If you have any trouble dont hesitate to ask.
這就是所有的內容了。感謝你還能看到這裡。如果你有任何的問題,不要猶豫直接問吧!
譯者註:原文鏈接:https://deskthority.net/workshop-f7/how-to-build-your-very-own-keyboard-firmware-t7177.html,此為二部分的翻譯。就這樣吧
推薦閱讀:
※UEFI到操作系統的虛擬地址轉換
※根據tmk製作自己的機械鍵盤固件(一)
※UEFI快速上手:如何用VS調試NT32模擬環境