How to build your very own keyboard firmware
- redesigndavid
- DT Pro Member: -
I can confirm it was the bootmagic build option that cost my firmware to fail on my keyboard. does enabling that require some special sauce? like certain keys should be available or something?
- vivalarevolución
- formerly prdlm2009
- Location: USA
- Main keyboard: IBM Beam spring
- Main mouse: Kangaroo
- Favorite switch: beam spring
- DT Pro Member: 0097
Hey guys, I could use a little help with creating a new keymap for my keyboard. I'm using Terminal in Mac OS, by the way. My keyboard already has the firmware built and loaded and I have been typing on the current keymap for months. I followed the guide and created a new keymap, but I receive an error message when I try compile the hex file. Anybody know what is going on? The error message says this:
keymap_common.c:21:46: error: unknown type name 'key_t'
uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
^
make: *** [obj_gh60_lufa/keymap_common.o] Error 1
Also, here is the keymap that I am attempting to load onto the keyboard:
keymap_common.c:21:46: error: unknown type name 'key_t'
uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
^
make: *** [obj_gh60_lufa/keymap_common.o] Error 1
Also, here is the keymap that I am attempting to load onto the keyboard:
Code: Select all
#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, BSLS, GRV, DEL, \
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC, RBRC, BSPC, PGUP, \
LCTL, A, S, D, F, G, H, J, K, L, SCLN, QUOT, ENT, PGDN, \
LSFT, Z, X, C, V, B, N, M, COMM, DOT, SLSH, RSFT, UP, FN1, \
CAPS, LALT, LGUI, FN0, RGUI, RALT, LEFT, DOWN, RGHT),
/* 1: FN1 */
KEYMAP (
TRNS,F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, TRNS,TRNS, INS, \
TRNS, HOME ,UP, END,PGUP,TRNS,PGUP,HOME,UP,END,PSCR,SLCK, PAUS,DEL, HOME, \
TRNS, LEFT,DOWN,RGHT,PGDN,TRNS,PGDN,LEFT,DOWN,RIGHT,TRNS,TRNS, TRNS,END, \
TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PGUP,TRNS, \
TRNS, TRNS, TRNS, TRNS, TRNS,TRNS,HOME,PGDN,END),
/* 2: alt layout */
KEYMAP (
ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS, EQL, BSLS, GRV, DEL, \
TAB, Q, P, I, Y, B, V, M, U, L, SCLN, LBRC, RBRC, BSPC, PGUP, \
LCTL, A, N, E, S, F, D, T, H, O, R, QUOT, ENT, PGDN, \
LSFT, COMM, DOT, C, G, SLSH, J, W, K, Z, X, RSFT, UP, FN1, \
CAPS, LALT, LGUI, FN0, RGUI, RALT, LEFT, DOWN, RGHT),
};
const uint16_t PROGMEM fn_actions[] = {
/* Poker Layout */
[0] = ACTION_LAYER_TAP_KEY(1, KC_SPC), // to Fn overlay
[1] = ACTION_LAYER_TOGGLE(2),
};
-
- DT Pro Member: -
What would be involved in getting TMK loaded on the Teensy-LC which uses the MKL26Z64VFT4 processor with the Cortex-M0+ core?hasu wrote: ↑TMK also has Cortex-M support now, in fact it works on Infinity(Freescale Kinetis) and I could port PS2-USB converter to NXP LPC11U35. But I didn't try Teensy3.1 yet. TMK uses CMSIS and HAL layer of mbed.org to support the MCU, this means, you are on the shoulders of the giants. Theoretically you can use any MCU mbed.org supports freely like chips from NXP, Freescale, STMicro, Nordic, Renesas. Also you will be able to make use of mbed libraries, code samples and tools.
Meanwhile HaaTa's Kiibohd uses its own concise libraries and PJRC USB stack. You'll be able to grasp its outline and hack it yourself.
The sticking points I'm wondering about so far are as follows:
1) In matt3o's tutorial, you use winavr (at least on Windows). What compiler would you use to generate the .hex file for the Teensy-LC? What modifications do you need to make? Only change the 'MCU =...' line in the makefile?
2)The teensy-lc documentation seems based on using Arduino/Teensyduino. This uses a simplified pin naming and accessing scheme, 0-26. I'm new to Arduino but it seems to limit you to accessing only 1 pin at a time, vs accessing entire Ports and masking out the bits you want. I can't find any documentation for the Teensy-LC showing how to access it's pins through C. I think you would need the mapping from Pin[0-26] -> Port[A-F] Pin ## (assuming the ARM still uses pins such as these).
Anybody have any thoughts about the above points, or other issues I'm likely missing?
Thanks!
- hasu
- Location: Japan
- Main keyboard: HHKB
- Main mouse: HHKB
- Favorite switch: Topre
- DT Pro Member: -
See Infinity project(keyboard/infinity/) to know how TMK works with mbed SDK.
First, you will need to change HAL implementation for the MCU, for example startup codes and linker script.
In mbed.org KL26Z is not supported yet while KL25Z is, I don't know how different the two controllers are but probably they are very similar and most of code can be shared.
See keyboard/infinity/mbed-infinity/ to know how this project changed mbed SDK to support Infinity keyboard.
Then, edit makefile to build TMK with mbed SDK and you files. You will be able to know it from Infinity's makefiles.
See keyboard/infinity/mbed-infinity.mk and tmk_core/tool/mbed/{mbed|common|gcc}.mk.
EDIT: FYI, Infinity is keyboard which uses Freescale MK20DX128VLF5 as controller. https://www.massdrop.com/buy/infinity-keyboard-kit
First, you will need to change HAL implementation for the MCU, for example startup codes and linker script.
In mbed.org KL26Z is not supported yet while KL25Z is, I don't know how different the two controllers are but probably they are very similar and most of code can be shared.
See keyboard/infinity/mbed-infinity/ to know how this project changed mbed SDK to support Infinity keyboard.
Then, edit makefile to build TMK with mbed SDK and you files. You will be able to know it from Infinity's makefiles.
See keyboard/infinity/mbed-infinity.mk and tmk_core/tool/mbed/{mbed|common|gcc}.mk.
EDIT: FYI, Infinity is keyboard which uses Freescale MK20DX128VLF5 as controller. https://www.massdrop.com/buy/infinity-keyboard-kit
- Ray
- Location: Germany
- Main mouse: touchpad
- DT Pro Member: -
Well, I did delve quite into this firmware, but still don't grasp the big theme of it. Maybe it is because I try to avoid looking into USB-stack or other protocols.
If I want to check once after connecting if numlock is set on the computer - and if it isn't, sent a numlock press - where should I do that?
On another note, I want a command to be executed on every keypress except on modifiers (if I could exclude more keys, that's fine too). Where is a nice place to do this? I tried in action.c where it says /* Key and Mods */ after the if(mods) I tried an else, but this gets executed on any keypress still...
On yet another note, I tried to implement something similar to the shift-parantheses in the hhkb/keymap_hasu.c "example". But that code doesn't work for me, it always produces shift, on hold or tap, doesn't matter.
EDIT: okay, this one was simply stupid by me. ACTION_FUNCTION_TAP is correct here, when I tried ACTION_FUNCTION...
If I want to check once after connecting if numlock is set on the computer - and if it isn't, sent a numlock press - where should I do that?
On another note, I want a command to be executed on every keypress except on modifiers (if I could exclude more keys, that's fine too). Where is a nice place to do this? I tried in action.c where it says /* Key and Mods */ after the if(mods) I tried an else, but this gets executed on any keypress still...
On yet another note, I tried to implement something similar to the shift-parantheses in the hhkb/keymap_hasu.c "example". But that code doesn't work for me, it always produces shift, on hold or tap, doesn't matter.
EDIT: okay, this one was simply stupid by me. ACTION_FUNCTION_TAP is correct here, when I tried ACTION_FUNCTION...
-
- Location: Croatia
- Main keyboard: Siemens NIXDORF (MX Blacks)
- Main mouse: Microsoft Intellimouse
- Favorite switch: MX Blues
- DT Pro Member: -
Would this work with Pro Micro board?
Thinking about getting this one
http://www.ebay.com/itm/Leonardo-Pro-Mi ... 4853468c6a
Thinking about getting this one
http://www.ebay.com/itm/Leonardo-Pro-Mi ... 4853468c6a
- Ray
- Location: Germany
- Main mouse: touchpad
- DT Pro Member: -
Yes, the Pro Micro has the same MCU as the Teensy, so from the software-side it is no concern.
You have less pins available though, probably not enough for connecting a keyboard-matrix. But if you want to make a converter that's not an issue. And you have to figure out the AVR-pinnames for the Leonardo-pinnames, but you can find that with google.
You have less pins available though, probably not enough for connecting a keyboard-matrix. But if you want to make a converter that's not an issue. And you have to figure out the AVR-pinnames for the Leonardo-pinnames, but you can find that with google.
-
- Location: Croatia
- Main keyboard: Siemens NIXDORF (MX Blacks)
- Main mouse: Microsoft Intellimouse
- Favorite switch: MX Blues
- DT Pro Member: -
Would i have enough pins for this layout?
http://www.keyboard-layout-editor.com/# ... e025b72844
And what converter are you talking about?
http://www.keyboard-layout-editor.com/# ... e025b72844
And what converter are you talking about?
- Ray
- Location: Germany
- Main mouse: touchpad
- DT Pro Member: -
with that layout (62 Keys?) your matrix alone will need 16 pins at least and about 19 if you don't want to be too crazy with the matrix layout
the leonardo pro micro board has 18 pins available for you. So it depends on what features you want to have and how hard you want to wrap your brain while wiring the matrix.
E.g. if you only put Enter and Delete on the bottom row of your matrix and the rest quite intuitively, that's 18 pins. You wouldn't have LEDS for Capslock or anything (which is fine if you don't want).
You are also lacking the luxury of a reset pushbutton for flashing. But you could add one even accessable when the keyboard is closed. This does not take an I/O pin.
But I am not sure if you can flash this firmware with the Arduino Bootloader. You probably can, not sure. Maybe someone else can clarify this.
I would advise the Teensy, because a lot of info here is directed for the teensy. And what is 10 bucks when it saves you time. But if you don't mind spending 110hours instead of 100hours (well, depending on the features again), then you can probably save 10 bucks, yes.
My custom built needs only 12 pins for the matrix (+2 for my trackpoint +another optional 2 for LEDS), but I don't regret that I bought the teensy for it.
I did mention the converter, because you didn't exactly specify your project. Hasu's firmware can also be used for converters from some older keyboard protocols to USB. Those generally don't need many pins.
the leonardo pro micro board has 18 pins available for you. So it depends on what features you want to have and how hard you want to wrap your brain while wiring the matrix.
E.g. if you only put Enter and Delete on the bottom row of your matrix and the rest quite intuitively, that's 18 pins. You wouldn't have LEDS for Capslock or anything (which is fine if you don't want).
You are also lacking the luxury of a reset pushbutton for flashing. But you could add one even accessable when the keyboard is closed. This does not take an I/O pin.
But I am not sure if you can flash this firmware with the Arduino Bootloader. You probably can, not sure. Maybe someone else can clarify this.
I would advise the Teensy, because a lot of info here is directed for the teensy. And what is 10 bucks when it saves you time. But if you don't mind spending 110hours instead of 100hours (well, depending on the features again), then you can probably save 10 bucks, yes.
My custom built needs only 12 pins for the matrix (+2 for my trackpoint +another optional 2 for LEDS), but I don't regret that I bought the teensy for it.
I did mention the converter, because you didn't exactly specify your project. Hasu's firmware can also be used for converters from some older keyboard protocols to USB. Those generally don't need many pins.
-
- Location: Croatia
- Main keyboard: Siemens NIXDORF (MX Blacks)
- Main mouse: Microsoft Intellimouse
- Favorite switch: MX Blues
- DT Pro Member: -
Thanks for help!
First time building so I am a bit noob.
First time building so I am a bit noob.
-
- Main keyboard: Dactyl (ErgoDoxMod)
- Main mouse: Zelotes C-18
- Favorite switch: Cherry MX Black (vintage)
- DT Pro Member: -
I just wanted to say thank you for this amazing guide. A few things would make it easier for noobs like myself. Add the ((matrix_row_t) information for defining keyboards with more than 16 columns and the binary notation for more than 16 keys KC_##K010. The LED portion appears to be incorrect. I used the following to get mine to work.
void led_set(uint8_t usb_led)
{
if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
// Output High
DDRD |= (1<<4);
PORTD |= (1<<4);
} else {
// Output Low
DDRD &= ~(1<<4);
PORTD &= ~(1<<4);
}
void led_set(uint8_t usb_led)
{
if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
// Output High
DDRD |= (1<<4);
PORTD |= (1<<4);
} else {
// Output Low
DDRD &= ~(1<<4);
PORTD &= ~(1<<4);
}
-
- DT Pro Member: -
Hello. I am currently working on a keyboard for a school project. I have gotten to the compile step, but when I try and do the "make -f Makefile" it tells me that it is an unknown command.
My Question is is there anyway to get "gh60_lufa.hex" as the computer is right now or do I need to download a program?
My Question is is there anyway to get "gh60_lufa.hex" as the computer is right now or do I need to download a program?
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
Yes there is. Use this:
http://www.pjrc.com/teensy/loader.html
I've no idea about your other question. I only ever use pre-rolled firmwares built by other people because whenever I code, things catch fire.
http://www.pjrc.com/teensy/loader.html
I've no idea about your other question. I only ever use pre-rolled firmwares built by other people because whenever I code, things catch fire.
-
- DT Pro Member: -
Hey Muirium,
Thanks for the response. Sorry if my question was unclear.
The problem I am having is I am not sure how to get the gh60_lufa.hex file.
In the in instructions it says to "Open the terminal go to the gh60 directory and run: make -f Makefile, If you did everything fine you'll end up with a file called gh60_lufa.hex.".
I get an message saying it does not recognize the command when I do make -f Makefile.
Is this because I made an error in my code. My teacher said it was because the computers do not have the ability to do that command.
Again, thanks for your help!
Thanks for the response. Sorry if my question was unclear.
The problem I am having is I am not sure how to get the gh60_lufa.hex file.
In the in instructions it says to "Open the terminal go to the gh60 directory and run: make -f Makefile, If you did everything fine you'll end up with a file called gh60_lufa.hex.".
I get an message saying it does not recognize the command when I do make -f Makefile.
Is this because I made an error in my code. My teacher said it was because the computers do not have the ability to do that command.
Again, thanks for your help!
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
Your teacher hasn't heard of makefiles. I'm no coder, absolutely seriously! So you really need someone else to chime in here. But when things are set up right you do indeed build things with the make command.
Building from source: not for everyone!
Building from source: not for everyone!
- HzFaq
- Location: Windsor, UK
- Main keyboard: Phantom
- Main mouse: CST L-Trac
- Favorite switch: MX Clears
- DT Pro Member: -
Are you on Windows? If so, you need to download winavr to get the make command. Then you just open a command window, do your "make -f makefile" bit and it should compile.
Not sure if you're not on Windows, I'm sure one of the other Linux/Mac guys can help.
Not sure if you're not on Windows, I'm sure one of the other Linux/Mac guys can help.
- HunterH
- Main keyboard: WASD V2
- Main mouse: E-3LUE Mazer
- Favorite switch: MX Brown
- DT Pro Member: -
Good day.
As do a large number of people posting on this thread, I have a problem with my firmware.
Currently running on Windows 7, 64bit.
I am able to create the HEX file from the freshly unzipped source.
When I try to run my changed version, however, I encounter problems.
Here is the output of the console:
I was unable to find someone else with this error, or a solution!
Here are the files that I have edited as per the instructional segment at the beginning of this thread.
--
Makefile:
--
config.h
--
matrix.c
--
keymap_common.h
--
keymap_poker.c
Hopefully this is a simple error to fix!
Thanks to the keyboard community for getting me this far already!
-Hunter
As do a large number of people posting on this thread, I have a problem with my firmware.
Currently running on Windows 7, 64bit.
I am able to create the HEX file from the freshly unzipped source.
When I try to run my changed version, however, I encounter problems.
Here is the output of the console:
Spoiler:
Here are the files that I have edited as per the instructional segment at the beginning of this thread.
--
Makefile:
Spoiler:
config.h
Spoiler:
matrix.c
Spoiler:
keymap_common.h
Spoiler:
keymap_poker.c
Spoiler:
Hopefully this is a simple error to fix!
Thanks to the keyboard community for getting me this far already!
-Hunter
- Halvar
- Location: Baden, DE
- Main keyboard: IBM Model M SSK / Filco MT 2
- Favorite switch: Beam & buckling spring, Monterey, MX Brown
- DT Pro Member: 0051
Hi HunterH,
go to the first actual error message and look for where it comes from. When you have found and corrected one error, recompile, because with C, many error messages are just following from errors that were found earlier.
First one is:
keymap_common.h:38:5: error: macro parameters must be comma-separated
which comes from missing commas at the end of the lines in the macro definition for the keymap macro. So in keymap_common.h, try correcting it like this:
The rest of the errors (or most of them) might go away if you correct that.
go to the first actual error message and look for where it comes from. When you have found and corrected one error, recompile, because with C, many error messages are just following from errors that were found earlier.
First one is:
keymap_common.h:38:5: error: macro parameters must be comma-separated
which comes from missing commas at the end of the lines in the macro definition for the keymap macro. So in keymap_common.h, try correcting it like this:
Code: Select all
#define KEYMAP( \
K00, K01, K02, K03, K04, K05, K06, K07, \
K10, K12, K13, K14, K15, K16, K17, \
K22, K23, K24, K25, K26, K27, \
K30, K32, K33, K36, K37, \
K40, K42, K43, K45, K47 \
) { \
{ KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \
{ KC_##K10, KC_NO, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17 }, \
{ KC_NO, KC_NO, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27 }, \
{ KC_##K30, KC_NO, KC_##K32, KC_##K33, KC_NO, KC_NO, KC_##K36, KC_##K37 }, \
{ KC_##K40, KC_NO, KC_##K42, KC_##K43, KC_NO, KC_##K45, KC_NO, KC_##K47 } \
}
- HunterH
- Main keyboard: WASD V2
- Main mouse: E-3LUE Mazer
- Favorite switch: MX Brown
- DT Pro Member: -
Success!!!
I fixed the commas, then one other little error and it compiled!
I have learned to tackle errors chronologically as opposed to trying to attack the biggest chunk.
Thank you two for you help; I really appreciate it!
I fixed the commas, then one other little error and it compiled!
I have learned to tackle errors chronologically as opposed to trying to attack the biggest chunk.
Thank you two for you help; I really appreciate it!
- LeandreN
- Location: ISO Nordic
- Main keyboard: Skidata 60%
- Main mouse: MX Master
- Favorite switch: i like tactile, and linear, and clicky
- DT Pro Member: -
Hey Matt3o. I am a completely noob to software and tried the best i could to follow your tutotial. Some basic things, like the binary step, i could simply not understand, even how clear you were trying to make it. Well, after a long time, i made it through the tutorial, but it won't make the Hex file. Some assistance would be very appericated.
keymap_poker
Matrix
config
Thanks for all help i can get.
keymap_poker
Code: Select all
#include "keymap_common.h"
const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/*0: qwerty*/
KEYMAP(1, 2, 3, 4, \
LEFT, RGHT, \
FN1, ENT \
5, 6, 7, 8, \
9, 0, COMM, DOT),
/*1: FN1*/
KEYMAP(F1, F2, F3, F4 \
EQL, MINS,\
TRNS, ENT,\
F5, F6, F7, F8, \
F9, F10, F11, F12),
)
};
const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_LAYER_MOMENTARY(1),
};
Code: Select all
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* scan matrix
*/
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include <util/delay.h>
#include "print.h"
#include "debug.h"
#include "util.h"
#include "matrix.h"
#ifndef DEBOUNCE
# define DEBOUNCE 5
#endif
static uint8_t debouncing = DEBOUNCE;
/* matrix state(1:on, 0:off) */
static matrix_row_t matrix[MATRIX_ROWS];
static matrix_row_t matrix_debouncing[MATRIX_ROWS];
static matrix_row_t read_cols(void);
static void init_cols(void);
static void unselect_rows(void);
static void select_row(uint8_t row);
inline
uint8_t matrix_rows(void)
{
return MATRIX_ROWS;
}
inline
uint8_t matrix_cols(void)
{
return MATRIX_COLS;
}
void matrix_init(void)
{
// initialize row and col
unselect_rows();
init_cols();
// initialize matrix state: all keys off
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
matrix[i] = 0;
matrix_debouncing[i] = 0;
}
}
uint8_t matrix_scan(void)
{
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
select_row(i);
_delay_us(30); // without this wait read unstable value.
matrix_row_t cols = read_cols();
if (matrix_debouncing[i] != cols) {
matrix_debouncing[i] = cols;
if (debouncing) {
debug("bounce!: "); debug_hex(debouncing); debug("\n");
}
debouncing = DEBOUNCE;
}
unselect_rows();
}
if (debouncing) {
if (--debouncing) {
_delay_ms(1);
} else {
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
matrix[i] = matrix_debouncing[i];
}
}
}
return 1;
}
bool matrix_is_modified(void)
{
if (debouncing) return false;
return true;
}
inline
bool matrix_is_on(uint8_t row, uint8_t col)
{
return (matrix[row] & ((matrix_row_t)1<<col));
}
inline
matrix_row_t matrix_get_row(uint8_t row)
{
return matrix[row];
}
void matrix_print(void)
{
print("\nr/c 0123456789ABCDEF\n");
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
phex(row); print(": ");
pbin_reverse16(matrix_get_row(row));
print("\n");
}
}
uint8_t matrix_key_count(void)
{
uint8_t count = 0;
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
count += bitpop16(matrix[i]);
}
return count;
}
/* Column pin configuration
* col: 0 1 2 3 4 5 6 7 8 9 10 11 12 13
* pin: F5 F4 F1 F0 C6 B6 D4 B1 B0 B5 B4 D7 D6 B3 (Rev.A)
* pin: B7 (Rev.B)
*/
static void init_cols(void)
{
// Input with pull-up(DDR:0, PORT:1)
DDRF &= ~(1<<5 | 1<<4 | 1<<1 | 1<<0);
PORTF |= (1<<5 | 1<<4 | 1<<1 | 1<<0);
}
static matrix_row_t read_cols(void)
{
return (PINF&(1<<5) ? 0 : (1<<0)) |
(PINF&(1<<4) ? 0 : (1<<1)) |
(PINE&(1<<1) ? 0 : (1<<2)) |
(PINC&(1<<0) ? 0 : (1<<3)) |
(PINC&(1<<6) ? 0 : (1<<4)) |
(PINB&(1<<6) ? 0 : (1<<5)) |
(PIND&(1<<4) ? 0 : (1<<6)) |
(PINB&(1<<1) ? 0 : (1<<7)) |
((PINB&(1<<0) && PINB&(1<<7)) ? 0 : (1<<8)) | // Rev.A and B
(PINB&(1<<5) ? 0 : (1<<9)) |
(PINB&(1<<4) ? 0 : (1<<10)) |
(PIND&(1<<7) ? 0 : (1<<11)) |
(PIND&(1<<6) ? 0 : (1<<12)) |
(PINB&(1<<3) ? 0 : (1<<13));
}
/* Row pin configuration
* row: 0 1 2 3 4
* pin: D0 D1 D2 D3 D5
*/
static void unselect_rows(void)
{
// Hi-Z(DDR:0, PORT:0) to unselect
DDRD &= ~0b00101111;
PORTD &= ~0b00101111;
}
static void select_row(uint8_t row)
{
// Output low(DDR:1, PORT:0) to select
switch (row) {
case 0:
DDRC |= (1<<6);
PORTC &= ~(1<<6);
break;
case 1:
DDRD |= (1<<3);
PORTD &= ~(1<<3);
break;
case 2:
DDRD |= (1<<2);
PORTD &= ~(1<<2);
break;
case 3:
DDRD |= (1<<1);
PORTD &= ~(1<<1);
break;
case 4:
DDRD |= (1<<0);
PORTD &= ~(1<<0);
break;
}
}
Code: Select all
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6060
#define DEVICE_VER 0x0001
#define MANUFACTURER geekhack
#define PRODUCT GH60
#define DESCRIPTION t.m.k. keyboard firmware for GH60
/* key matrix size */
#define MATRIX_ROWS 5
#define MATRIX_COLS 4
/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST
/* Set 0 if debouncing isn't needed */
#define DEBOUNCE 5
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/* key combination for command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#endif
- flabbergast
- Location: Southampton, UK
- DT Pro Member: 0120
- Contact:
The problem is not with TMK source code (at least not according to the error message you're getting), but (probably) with your avr-gcc installation and/or memory and/or limit on the number of opened files or something like that. Very weird error - not related to the source code, but with the compiler trying to fork and not being able to (that's something that it normally does quite a lot). You can read more about forking here: https://en.wikipedia.org/wiki/Fork_(system_call) - but it's actually probably irrelevant to your problem...
What I would try to do is some "standard" stuff, like rebooting the machine, etc...
If you feel OK with virtual machines, it might save you some headaches in the long run to have a linux running on one - but on the other hand, people succeed with compiling on windows as well.
EDIT: Forgot to say - it's probably best, as a first step, to compile "clean" TMK (for any keyboard/layout), i.e. to compile something _before_ you edit anything in the sources. That should work. If it doesn't, it's likely there's a problem with the compiler itself.
What I would try to do is some "standard" stuff, like rebooting the machine, etc...
If you feel OK with virtual machines, it might save you some headaches in the long run to have a linux running on one - but on the other hand, people succeed with compiling on windows as well.
EDIT: Forgot to say - it's probably best, as a first step, to compile "clean" TMK (for any keyboard/layout), i.e. to compile something _before_ you edit anything in the sources. That should work. If it doesn't, it's likely there's a problem with the compiler itself.
- LeandreN
- Location: ISO Nordic
- Main keyboard: Skidata 60%
- Main mouse: MX Master
- Favorite switch: i like tactile, and linear, and clicky
- DT Pro Member: -
Hmm, I have tried two different computers and I still get the same message. Also, do the binary stuff in the matrix file look strange to you, I couldn't understand what I should do.
Thanks for your response though. I hope I can fix this together with you.
Thanks for your response though. I hope I can fix this together with you.
- scottc
- ☃
- Location: Remote locations in Europe
- Main keyboard: GH60-HASRO 62g Nixies, HHKB Pro1 HS, Novatouch
- Main mouse: Steelseries Rival 300
- Favorite switch: Nixdorf 'Soft Touch' MX Black
- DT Pro Member: -
To me it sounds like you might've set up something that caused an infinite loop. Did you include your keymap within your keymap definition or something like that? Maybe copy a fresh version of the source code and apply your changes bit by bit to see what causes that error.
- flabbergast
- Location: Southampton, UK
- DT Pro Member: 0120
- Contact:
I would think that compilers can deal with this kind of problems. Also - the first complaint about fork is actually _before_ the compiler runs (before ---begin---). But you may be right.scottc wrote: ↑To me it sounds like you might've set up something that caused an infinite loop. Did you include your keymap within your keymap definition or something like that? Maybe copy a fresh version of the source code and apply your changes bit by bit to see what causes that error.
LeandreN - you should definitely try compiling first without any modification to sources.
- flabbergast
- Location: Southampton, UK
- DT Pro Member: 0120
- Contact:
I had a look at your matrix.c as well - I can't be more specific since I don't know your keyboard matrix. If send me the wiring (which cols are connected to which pins) I can check it.
The way it's now, you only have 4 columns (that are set up in init_cols), but then read_cols doesn't match that, since it's testing for a bunch of other pins as well. init_cols sets up which pins are connected to columns, and read_cols is used periodically to check the status. The same pins should appear in both functions.
The same goes for unselect_rows and select_row. This is also not so in your source - unselect_rows uses PD0, PD1, PD2, PD3, PD5 (PORTD, bits 0,1,2,3,5), while select_row deals with PD0, PD1, PD2, PD3 (PORTD, bits 0,1,2,3) and PC6 (PORTC, bit 6).
So for instance, assuming select_row does the bits that you actually want, unselect_rows should contain
The way it's now, you only have 4 columns (that are set up in init_cols), but then read_cols doesn't match that, since it's testing for a bunch of other pins as well. init_cols sets up which pins are connected to columns, and read_cols is used periodically to check the status. The same pins should appear in both functions.
The same goes for unselect_rows and select_row. This is also not so in your source - unselect_rows uses PD0, PD1, PD2, PD3, PD5 (PORTD, bits 0,1,2,3,5), while select_row deals with PD0, PD1, PD2, PD3 (PORTD, bits 0,1,2,3) and PC6 (PORTC, bit 6).
So for instance, assuming select_row does the bits that you actually want, unselect_rows should contain
Code: Select all
// Hi-Z(DDR:0, PORT:0) to unselect
DDRD &= ~0b00001111;
PORTD &= ~0b00001111;
DDRC &= ~0b01000000;
PORTC &= ~0b01000000;
- scottc
- ☃
- Location: Remote locations in Europe
- Main keyboard: GH60-HASRO 62g Nixies, HHKB Pro1 HS, Novatouch
- Main mouse: Steelseries Rival 300
- Favorite switch: Nixdorf 'Soft Touch' MX Black
- DT Pro Member: -
Oh, good point. I didn't read the output very carefully but it does indeed look like the error is from Make, not the compiler. So I agree - try to compile the firmware without any changes first.flabbergast wrote: ↑I would think that compilers can deal with this kind of problems. Also - the first complaint about fork is actually _before_ the compiler runs (before ---begin---). But you may be right.scottc wrote: ↑To me it sounds like you might've set up something that caused an infinite loop. Did you include your keymap within your keymap definition or something like that? Maybe copy a fresh version of the source code and apply your changes bit by bit to see what causes that error.
LeandreN - you should definitely try compiling first without any modification to sources.
I searched around a bit for this error and it was hinted that it might be a dodgy GCC-AVR install.
- Bhuyakasha
- Main keyboard: QFR
- Main mouse: Logitech G5
- Favorite switch: Cherry MX Blue
- DT Pro Member: -
Hey, any tips for debugging?
My keyboard spams 6 keys, of which 5 are on the same row. I have tried resoldering the row to a different pin but that didn't help. I'd think that it's a hardware problem of shorts, but I checked everything with a multimeter and there don't seem to be any. Can this be a software problem instead?
Link to my code:
https://www.dropbox.com/sh/uw07aa3kiej9 ... VlP3a?dl=0
Regards <3
Edit: Never mind guys, I am typing on it right now! There was a syntax error in the declaration of the pins as well as a mixup between two pins. I'm so giddy!
My keyboard spams 6 keys, of which 5 are on the same row. I have tried resoldering the row to a different pin but that didn't help. I'd think that it's a hardware problem of shorts, but I checked everything with a multimeter and there don't seem to be any. Can this be a software problem instead?
Link to my code:
https://www.dropbox.com/sh/uw07aa3kiej9 ... VlP3a?dl=0
Regards <3
Edit: Never mind guys, I am typing on it right now! There was a syntax error in the declaration of the pins as well as a mixup between two pins. I'm so giddy!
-
- DT Pro Member: -
Hello Gurus - I'm having an issue with this firmware and I am hoping someone can point me in the right direction.
For one of my columns, when I press the top key, the rest of the keys in that column also fire.
eg, Press F5: F5/6/y/g/b all fire
I am also having a similar problem another column, but where all the keys in the row after fire.
eg. Press Right Arrow: Right Arrow/0/./Enter all fire
Do these sound like programming problems or electrical problems?
Any guidance is greatly appreciated!
EDIT: For those who might find this in the future, the first issue appears to have been caused by a short. The second issue: Apparently if you have more than 14 columns, all columns past 14 must us 1UL in read_cols function.
eg
static matrix_row_t read_cols(void)
{
return (PINE&(1<<1) ? 0 : (1<<0)) |
(PINC&(1<<2) ? 0 : (1<<1)) |
(PINC&(1<<1) ? 0 : (1<<2)) |
(PINB&(1<<0) ? 0 : (1<<3)) |
(PINE&(1<<7) ? 0 : (1<<4)) |
(PINE&(1<<6) ? 0 : (1<<5)) |
(PINF&(1<<0) ? 0 : (1<<6)) |
(PINF&(1<<1) ? 0 : (1<<7)) |
(PINF&(1<<2) ? 0 : (1<<8)) |
(PINF&(1<<3) ? 0 : (1<<9)) |
(PINF&(1<<4) ? 0 : (1<<10)) |
(PINF&(1<<5) ? 0 : (1<<11)) |
(PINF&(1<<6) ? 0 : (1<<12)) |
(PINF&(1<<7) ? 0 : (1<<13)) |
(PINE&(1<<0) ? 0 : (1<<14)) |
(PINC&(1<<3) ? 0 : (1UL<<15)) |
(PINB&(1<<6) ? 0 : (1UL<<16)) |
(PINB&(1<<5) ? 0 : (1UL<<17)) |
(PINB&(1<<4) ? 0 : (1UL<<18)) |
(PINB&(1<<3) ? 0 : (1UL<<19));
}
I incorrectly assumed that only 16 and above needed 1UL.
For one of my columns, when I press the top key, the rest of the keys in that column also fire.
eg, Press F5: F5/6/y/g/b all fire
I am also having a similar problem another column, but where all the keys in the row after fire.
eg. Press Right Arrow: Right Arrow/0/./Enter all fire
Do these sound like programming problems or electrical problems?
Any guidance is greatly appreciated!
EDIT: For those who might find this in the future, the first issue appears to have been caused by a short. The second issue: Apparently if you have more than 14 columns, all columns past 14 must us 1UL in read_cols function.
eg
static matrix_row_t read_cols(void)
{
return (PINE&(1<<1) ? 0 : (1<<0)) |
(PINC&(1<<2) ? 0 : (1<<1)) |
(PINC&(1<<1) ? 0 : (1<<2)) |
(PINB&(1<<0) ? 0 : (1<<3)) |
(PINE&(1<<7) ? 0 : (1<<4)) |
(PINE&(1<<6) ? 0 : (1<<5)) |
(PINF&(1<<0) ? 0 : (1<<6)) |
(PINF&(1<<1) ? 0 : (1<<7)) |
(PINF&(1<<2) ? 0 : (1<<8)) |
(PINF&(1<<3) ? 0 : (1<<9)) |
(PINF&(1<<4) ? 0 : (1<<10)) |
(PINF&(1<<5) ? 0 : (1<<11)) |
(PINF&(1<<6) ? 0 : (1<<12)) |
(PINF&(1<<7) ? 0 : (1<<13)) |
(PINE&(1<<0) ? 0 : (1<<14)) |
(PINC&(1<<3) ? 0 : (1UL<<15)) |
(PINB&(1<<6) ? 0 : (1UL<<16)) |
(PINB&(1<<5) ? 0 : (1UL<<17)) |
(PINB&(1<<4) ? 0 : (1UL<<18)) |
(PINB&(1<<3) ? 0 : (1UL<<19));
}
I incorrectly assumed that only 16 and above needed 1UL.
Last edited by gangolfus on 27 Jun 2015, 06:45, edited 2 times in total.