Autor: matt3o
Artigo original: https://deskthority.net/viewtopic.php?f=7&t=7177&start=#p141386
Bem-vindo à parte 2 de “Como fazer o firmware para seu teclado”! Leia a parte 1 primeiro se ainda não tiver feito isso.
Isso pode parecer difícil num primeiro momento mas se você seguir estas instruções passo a passo perceberá que é mais difícil explicar do que fazer.
Nós ainda estamos no diretório keyboard/gh60
. Tudo o que precisamos está aqui. Agora nós iremos personalizar a matriz do teclado propriamente falando e suas camadas de função (FN).
Definindo a matriz
Antes de mais nada nós precisamos mapear a matriz no arquivo keymap_common.h
.
A parte que precisamos é esta:
#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 } \ }
Lembre-se que aqui estamos vendo um exemplo (de um teclado 60%, para ser mais específico). O esquema do seu arquivo deve refletir a matriz do seu teclado, ou seja, a forma como os botões estão conectados.
Vejamos a primeira linha:
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D,
Isto significa que todos os botões da primeira linha estão todos conectados em conjunto. Se você precisar de mais teclas você pode continuar adicionando mais posições, por exemplo:
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K0F,
Aqui eu adicionei duas novas teclas na primeira linha (K0E
e K0F
). Lembre-se de adicionar , \
(vírgula + barra invertida) no fim de cada linha.
Você tem que repetir esta mesma configuração de teclas no bloco de código seguinte.
{ 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 }, \
Como você pode ver é a mesma coisa que fizemos mais acima, porém com uma sintaxe um pouco diferente.
Agora olhemos para a última linha:
K40, K41, K42, K45, K49, K4A, K4B, K4C, K4D \
Desta vez nós temos um salto de K42
para K45
. A linha inferior de um teclado normalmente possui menos teclas que as demais e há um buraco entre a tecla ALT e a barra de espaço. Tome cuidado ao checar em qual coluna cada botão está respectivamente conectado.
{ 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 } \
No segundo bloco de código nós temos que identificar os espaços vazios com o código KC_NO
. Então, enquanto que no primeiro bloco nós simplesmente pulávamos de uma coluna para outra se não há conexão física presente, no segundo bloco nós precisamos preencher o vazio com KC_NO
.
Como exemplo, veja a matriz do HHFox (talvez seja melhor você copiar o código abaixo e colar num editor de texto).
#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 } \ }
Isso reflete exatamente a matriz feita à mão. É um pouco chato escrever isso tudo mas não é nada complexo. Apenas tenha cuidado na hora de anotar as letras e números para não cometer nenhum erro.
Você pode ignorar completamente a parte que tem o código KEYMAP_ANSI
.
Mapa de teclas
E finalmente a parte divertida! Por padrão o arquivo Makefile
está compilando o mapa de teclas do teclado Poker então, no intuito de simplificar as coisas, iremos modificar este arquivo. Abra o arquivo keymap_poker.c
.
Apague tudo e substitua com isto:
#include "keymap_common.h" const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { }; const uint16_t PROGMEM fn_actions[] = { };
Primeiro temos de fazer a lista do mapa de teclas. O primeiro elemento da lista será o nosso mapa de teclas principal (QWERTY ou outro que você queira). Você pode copiar/colar um mapa de teclas já pronto ou começar do zero. Em nosso exemplo, o mapa de teclas básico será o seguinte:
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),
Note que esta é apenas uma lista de caracteres da esquerda para a direita assim como você as vê no teclado. Você não precisa adicionar espaços, barras invertidas ou códigos especiais, mas nós os colocamos apenas para tornar o código mais legível. Tecnicamente, entretanto, tudo isso poderia estar em apenas uma linha.
Basicamente apenas leia os caracteres de seu teclado da esquerda para a direita, de cima para baixo.
O mapa de teclas para o HHFox se pareceria com algo assim:
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), };
Se você quiser ser capaz de reprogramar o firmware sem precisar acessar o botão de reset do Teensy, é melhor você incluir a tecla PAUS
, e ela deve estar na primeira camada (e não numa camada FN).
Camadas de Função
Teclas de Função são definidas com a sintaxe FNx
, onde x é um número de 0 a 5.
Para adicionar uma camada de função você precisa apenas acrescentar um novo mapa de teclas à lista. O código a seguir é a primeira camada FN do HHFox.
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), };
Mesma coisa que falei antes, a única diferença é que nós usamos a palavra-chave TRNS
(transparente) para todas as teclas que não mudam de comportamento quando a tecla de função é pressionada.
Até agora nós apenas definimos a camada de função, para realmente ativá-la nós precisamos acrescentar algo à lista fn_action
const uint16_t PROGMEM fn_actions[] = { [0] = ACTION_LAYER_MOMENTARY(1), };
Isso significa que a tecla FN[0]
irá acionar a camada (1)
com uma ação ACTION_LAYER_MOMENTARY
. Você pode definir muitas ações, as mais comuns/úteis são:
-
ACTION_LAYER_MOMENTARY(camada)
, aciona a camada enquanto a tecla FN estiver pressionada
-
ACTION_LAYER_TOGGLE(camada)
, ativa a camada no primeiro pressionamento, desativa no segundo
ACTION_LAYER_TAP_KEY(camada, tecla)
, funciona comoACTION_LAYER_MOMENTARY
enquanto você a pressiona, mas executa a tecla especificada quando faz apenas um tap (pressionamento/soltura rápidos)
Vamos acrescentar uma ação tap ao HHFox.
const uint16_t PROGMEM fn_actions[] = { [0] = ACTION_LAYER_MOMENTARY(1), [1] = ACTION_LAYER_TAP_KEY(1, KC_ESC), };
Pressionando a tecla FN1
nós ativamos a primeira camada de função (assim como FN0
), mas ao fazer um tap na mesma tecla nós temos como resultado a tecla ESC. Maneiro, não é? Obrigado por isto, Hasu.
O restante seria o último mapa de teclas para o HHFox (este é apenas um exemplo, não a minha configuração atual de teclas). Eu tomei a liberdade de adicionar uma segunda camada de função que é ativada ao pressionar a tecla 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) };
Que bonito, que beleza, que alegria! Nós acabamos!
Preparar; Apontar; Compilar!
Feche o arquivo. Abra o terminal, vá para o diretório gh60
e execute:
make -f Makefile
Se você tiver feito tudo certo, ao final da compilação terá um arquivo chamado gh60_lufa.hex
.
Conecte seu teclado à porta USB. No Linux você não precisa fazer mais nada, tudo já deverá estar funcionando. No Mac e no Windows você provavelmente terá de fazer uma rápida instalação.
Quando tudo estiver pronto, execute o Teensy Loader, acione o botão “Auto”, carregue o firmware (o arquivo hex) e aperte o botão reset no Teensy. O firmware será carregado e o teclado começará a funcionar em seguida!
Correção de problemas
Agora um dos seguintes cenários pode acontecer:
Tudo está bem e seu teclado está funcionando de cara
Legal! Você é um mestre dos teclados!
O teclado começa a disparar caracteres aleatórios na tela e o computador começa a bipar
Desconecte o teclado, rápido! Isso provavelmente é um problema de software. Confira novamente seu código. Quando estiver pronto para recarregar, abra o seu novo firmware no Teensy Loader, reconecte o teclado e rapidamente aperte o botão de reset.
O teclado funciona mas algumas teclas estão com defeito
Isso é muito provavelmente um problema de hardware. Confira sua fiação e veja se não há curtos-circuitos.
Eu montei meu teclado e não tenho acesso ao botão de reset de hardware
Assumindo que seu teclado esteja funcionando corretamente, você pode fazer um reset de software pressionando LSHIFT + RSHIFT + PAUSE.
Tudo parece funcionar mas algumas teclas modificadoras retornam a tecla errada
Desconecte o teclado e reconecte-o segurando a tecla BACKSPACE.
Isso é tudo, pessoal. Obrigado por lerem este guia. Se tiverem qualquer problema não tenha medo de perguntar no fórum.