TMK keyboard firmware collection

User avatar

22 Oct 2013, 01:54


Keycodes are defined as enum(hid_keyboard_keypad_usage) in common/keycodes.h. You don't need to know real value(0x04), just use keycode symbol(KC_A).
EDIT: you can refer descriptoion in keycode.txt to know meaning of keycode symbol.

K00-K5H of KEYMAP macro definition are not related to keycode value at all, just parameters of macro and have no meaning in practice. I just named them like K<row><col>, where row and col is comprised of 0-9A-I; G, H and I mean 16, 17 and 18.

From your Excel file(removed now?) your matrix has Space key on K55(row 5, col 5), so I placed 'SPC' on that palce of keymap. I'm not sure why your space bar doesn't work.

User avatar

08 Dec 2013, 00:02

Since my Phantom case will be here next week I'd like to finalize my firmware for it now.
I set up my keymap and all is fine with that.

What I am struggeling with is the "command" key.
How exactly do I set it correctly?

It should be this part of the config.h, right?

Code: Select all

/* key combination for command */
#define IS_COMMAND() ( \
    keyboard_report->mods == (MOD_BIT(KC_FN0) | MOD_BIT(KC_F12)) \
As you can see, I want to use FN0 + F12 as the "command" key. Is that correct how I did it?
So then FN0 + F12 + Pause would bring the Teensy into the programming mode as the physical button on it, is that right?

Also, is it possible to activate NKRO with "command" + "n", even if I commented out the USB_nkro line in the makefile.pjrc?

Would be cool if someone could clear up my concerns ;)

User avatar

08 Dec 2013, 03:11

That code requires modifiers but FN key and F12 are not. Just use modifiers instaed.

You can place any code to detect command key combination in config.h, so FN0+F12 should be possible. That is my design intention though it is not documented and tested. I'll have to work on this later.

User avatar

08 Dec 2013, 11:42

Ok, I just tried with the standard LSHIFT + RSHIFT and that works as intended.

But I have no idea how #define IS_COMMAND() should look for FN0 + F12 correctly.
Can you give me a hint?

User avatar

08 Dec 2013, 22:41

hmm, to check normal keys it has no useful utility function/macro atm, but you will be able to see FN0 and F12 in keyboard_report->keys array whose size is 6.

It seems this code works for you but not sure.
(keyboard_report->keys[0] == KC_FN0 && keyboard_report->keys[1] == KC_F12) ||
(keyboard_report->keys[1] == KC_FN0 && keybaord_report->keys[0] == KC_F12)

EDIT: ah, you cannot see KC_FN0 in keyboard_report. You need to check matrix to see whether KC_FN0 is pressed. but to see matrix is a bit confusing and it needs dirty code atm.
See this code if you are still interested... ... nfig.h#L59


09 Jan 2014, 03:36

hasu, I finally got back to working on the TrackPoint for my keyboard running your firmware. The TP now works beautifully with the recent changes you made. It even does middle-button scroll. :-D Thanks!!

I am having some timing issues with key presses now (when typing fast, some key presses don't appear to be sent to the host). But I think that can be worked out. Maybe I should adjust the polling frequency for the TP and see if that helps.

Edit: That seemed to have fixed the problem. Polling max once per 10 ms was enough to prevent missed keystrokes while maintaining smoothness in the mouse pointer motion: ... f3501952c8

User avatar

22 Jan 2014, 21:44

I thought I'd post my step-by-step protocol on how to get the TMK firmware onto bpiphany's HID Liberation Device (for Filco Majestouch 2 TKL).
I wrote this down like a year ago or so. Some links could be dead, version numbers could be different.

This is on Win7 64bit.

Code: Select all

Program the HID Liberation Device for Filco Majestouch 2 TKL

Done on Win7 64bit


For hasu's how-to, see:

and on github in the firmware source files:


Installed WinAVR-20100110 from;id=59;
[not in "Program Files" to avoid spaces; don't know if that is important]

Allowed the installer to "Add directory to PATH". Just to make sure, I checked
System Properties -> Advanced -> Environment Variables -> System Variables -> Path
to contain these:

The 'make' command should now be generally available on the system. Checked by opening a command window and issued 'make' (gives error about no target specified; that's OK).

Installed ATMEL's FLIP DFU (Device Firmware Update) (incl. USB drivers for Atmel chips) from

Downloaded the tmk_keyboard firmware source files from:

Extracted tmk_keyboard firmware.

Opened command window in the hid_liber subdirdirectory of the firmware source (Ctrl+Shift+right click in Windows Explorer, select open command window here).
<path to firmware source>\keyboard\hid_liber

make -f Makefile.pjrc
resulting in file hid_liber_pjrc.hex and lots of other files and directories.

Connected Filco Majestouch 2 TKL (with HID Liberation Device installed) to PC -> new keyboard got installed (ignored that)

Reset HID Liberation Device by holding magnet over it and waited a few seconds -> no driver message -> cancel

Installed driver: Control Panel -> Device manager -> Atmel USB Devices -> ATmega32U4 -> update driver (from local file):
selected the following directory:
C:\Program Files (x86)\Atmel\Flip 3.4.7\usb

Started FLIP
Selected target Device (ATmega32U4)
Selected a communication medium (USB -> open)
File -> load HEX file
Kept 'Erase', 'Blank Check', 'Program' and 'Verify' check boxes selected and pressed 'Run'
When done, disconnected and then reconnected the USB plug of the Filco.
(See here for pictures:


This is how to clean the directory (=revert to te original state, removes .hex file and other compiled files and directories):
make -f Makefile.prjc clean


For future keyboard remappings, i.e. once all the software and drivers are installed:

1) "make -f Makefile.pjrc" in the appropriate directory (command window); generates "hid_liber_pjrc.hex"
2) connect keyboard with HID Liberation Device
3) reset HID Liberation Device with magnet (possibly no notification, only a sound played)
4) flash firmware with FLIP (see above)
5) unplug and replug USB connector
6) done

User avatar

23 Jan 2014, 10:37

I find having the Windows device manager open so you can see when the keyboard has connected and when it moves from keyboard mode into "flash" mode was helpful as well. I also found that you have to open FLIP only when the keyboard is in flash mode otherwise the flash will fail, I'm not sure if thats just a strange thing with my computer though.

Thats a nice writeup though, I'm going to keep a copy of that somewhere, it took me a while to figure out some of that stuff and I'm not sure I'd remember how if I had to do it again!

User avatar

30 Jan 2014, 10:52

After a little struggle understanding how to build my phantom layout i must say this firmware is fantastic, i'm enjoying the customizations very much every day.

Now i set my gaze upon a little detail i could use some help with: i'd like to use the Scroll-Lock LED for my numpad FN-toggle layer.. is that possible, and how?

User avatar

12 Feb 2014, 00:29

First day typing with my Apple Extended Keyboard II here, thanks for the ADB converter Hasu! (And Kint and Snoopy for helping me find one in great condition and for getting it over from Germany.) These damped Alps might just be growing on me…

Here's a potentially very silly request. I also have an M0110 (also via Snoopy) that I'd like to convert to USB. For now I'll just breadboard it. I can redefine the appropriate data and clock pins so I can do both with the same Teensy and breadboard; just with two sockets attached. Then upload the appropriate firmware to the Teensy when I switch keyboard.

But! The ADB and M0110 converters are built from similar source. Could I coax you into combining them into one .hex so that I can have an old Apple keyboard version of what I do with my IBMs?


Soarer's converter with a knob! I use three sockets on that box. It gets a lot of use, as I'm on the Mac so no PS/2 ports.

User avatar

12 Feb 2014, 03:29

Nice. almost sure you will want to try orange AEK next :D

Unfortunately tmk doesn't support multiple protocols with one binary, you need to build a dedicated firmware each protocol.
Supporting both protocols at same build is possible in terms of technical meaning but you will want to spend money for another Teensy rather than working on the code :)

User avatar

12 Feb 2014, 04:38

I apologize for not reading all the posts here or all the source before asking my questions, but I figure asking directly is simpler and clearer.

I've been meaning to use this firmware for a long time and see that it has improved a lot since I last looked at it. There are a couple features I'm curious about.

1. Can I use it to make a combination USB (LUFA) and bluetooth (iWRAP) keyboard so that it will function over bluetooth when the USB cable is disconnected and shutdown bluetooth automatically and switch to USB mode once USB is connected?

2. How is the power consumption when used as a bluetooth keyboard? I plan to put this into a Kinesis which has lots of room for batteries, but having to charge them often or spend lots of money to extend the battery life is not ideal.

3. Is there any unit test framework in place for the code? If the above features are missing, I'm inclined to add them in as needed and would like to avoid breaking as much as possible. I quickly skimmed the code and did not see anything.

3a. If there is no unit testing framework and I were to add some tests, is there a framework you would like me to use? I have some experience with CppUTest.

Thanks for making this great firmware and opening it up to the community. :)

User avatar

12 Feb 2014, 14:48

1. Yes you can. I used VUSB and iWRAP to support both USB and Bluetooth on my HHKB. You can use host_driver API to change host side protocols dynamically.(BTW as said above, keyboard side protocols can not be changeable atm.) protocol/iwrap is my code, it is temporary dirty hack but it worked. I didn't detect cable state due to hardware limitation(I used ATmega168) but I think you can do this with ATmega32U4.

2. In my case HHKB needs 5V and cosumes considerable amp. And Bluegiga module also uses good amount of current and I couldn't make it sleep deeply for some reason. With the latest firmware the sleep problem may be solved but I don't know.
In terms of current consumption mechanical switch is clearly better than HHKB and probably the best option for wireless. So power consumption depends mainly on your BT module.

3a. No preference. I don't have any experience except for a little of JUnit and have never looked into testing frameworks in C yet. CppUTest seems to be nice.

User avatar

12 Feb 2014, 15:08

Thanks for the quick response hasu! Hopefully I'll finally find some time to build my custom board. :D

User avatar

12 Feb 2014, 15:19

Bluegiga Bluetooth is something I'd like to try, too. Any guides or suggestions? I'm talking about adding it to my MX + Teensy custom keyboard, or potentially my SSK and other larger keyboards with plenty of room for batteries.

I get your point about my Teensy-stretching plan for ADB+M0110. I do have the Teensies anyway (ordering more via Jdcarpe) but I just like the craftiness of a single magic box. Still need to even find a cable for my M0110, in any case…

User avatar

26 Mar 2014, 20:08

How would I add new keycodes? Add them in keycode.h? How? :D

I have my stick buttons in the matrix and have to call some new ps2_mouse() functions in action.c. I don't want to use KC_MS_BTNn as this will break MouseKeys.

Where would I define KC_TP_BTN1/2/3 ?

I also need an action ACT_TPKEY which I defined as 0b0111 in action_key.h. Would that be correct?

As this requires several changes in tmk sources: how would I not lose connection to the master branch (and future updates)? I'm currently on a copy of the master branch ("let's try this and that quickly") but I'm getting to the point where it will be some work to transfer to a new master.

User avatar

27 Mar 2014, 02:54

You can define your own keycodes at empty code area; it is 0xBB-BF or 0xE8-EF. But I'm not sure whether I want to merge those extended codes or not at this time. It is no problem to try it in your repository, of course. Same can be applied for action codes.

I think your problem is this. Tmk has no integration between TrackPoint(PS/2 Mouse support) and MouseKey yet, both functions was implemented independently in ad hoc way and they send their own mouse report discretely. But we need that they should be cooperative on seding report.

How about this?
Change *_task() of mousekey.c and ps2_mouse.c not to send report in each and to just return mouse report.

Code: Select all

    mouse_report_t mousekey_task(void) // called repeatedly from main loop; doesn't send report in this task, *just create report*

    mouse_report_t ps2_mouse_task(void) // called repeatedly from main loop; doesn't send report in this task, *just create report*
And send mixed report at once.

Code: Select all

keyboard.c: in keyboard_task() loop

    mouse_report_t mousekey_reprot = mousekey_task();
    mouse_report_t ps2_mouse_report = ps2_mouse_task();

   // send one mouse report with mixing two reports in some way
   host_mouse_send(mousekey_report | ps2_mous_report);

User avatar

27 Mar 2014, 09:58

This is perfect, will do, thank you. I can just use MouseKeys then, no redundant button definitions and no inter-module communication required.

User avatar

28 Mar 2014, 12:56

Well, in the end it was easier to finish my 'dirty' solution (now that I knew how to add keycodes). No matter how good I would have done it, it will be obsolete when the master gets updated. I have to learn Github, I think.

Edit: I actually prefer using separate stick button definitions (KC_TP_BTN1/2/3) now because it gives me the choice to activate MouseKeys in the makefile or not.

User avatar

14 Apr 2014, 16:16

Hi: Will all keycodes work in Windows 7/8? I guess the answer is no, but I'm just asking

I'm basically insterested in

It would be great to have an OS compatibility table.
Many thanks!

User avatar

14 Apr 2014, 16:27

Both of those work in OS X, for what it's worth. The first brings up the Sleep/Restart/Shutdown dialog and the latter sends the Mac straight to sleep.

User avatar

14 Apr 2014, 17:30

Muirium wrote:Both of those work in OS X, for what it's worth. The first brings up the Sleep/Restart/Shutdown dialog and the latter sends the Mac straight to sleep.
Only OS X?

User avatar

14 Apr 2014, 21:04

No, they should also work w/ Windows.

User avatar

14 Apr 2014, 21:33

Yeah, should do. But I haven't tried. No Windows here.

User avatar

15 Apr 2014, 00:28

KC_SYSTEM_* keys can be used in Windows but they are 'special extra' keys(GNERIC DESKTOP page), not normal keyboard keys(Keyboard page). You need to define EXTRAKEY_ENABLE in makefile to use them in TMK.

Code: Select all

EXTRAKEY_ENABLE = yes          # Audio control and System control
See page 27 of HID Usage Table.

See this document to know keys you can use in Windowns. As you can see, KC_POWER and KC__VOLUP, KC__VOLDOWN, KC__MUTE(Keyboard page) are not suported in Windows. You should use KC_SYSTEM_*() and KC_AUDIO_*(Consumer page) keys instead in Windows. ... nslate.pdf

While OSX and Linux can recognize all kind of keys so you can use normal 'keyboard page' keyKC_POWER, KC__VOL* and KC__MUTE to control system and audio without EXTRAKEY_ENABLE.

User avatar

15 Apr 2014, 23:05

Many thanks, I'll let you know after my first build

User avatar

12 May 2014, 19:02

Is there an easy list for what the FN00-FN31 keys can be used? I know there is a list at the end of action_code.h but it doesn't tell me if all these elements are really to be used with FN keys and which are useful from an user point of view.

Right now on my test keyboard I use one for the Cursor layer and one for a Macro and that's it.

I'm trying to figure out how to distribute the function keys among
- layer switching momentary
- layer switching toggle
- macros (as many as possible)
- what else?

Like 7 for momentary layer switching (for a total of 8 momentary layers), 3 for layer toggling (total 4 toggle layers), 16 for macros and 6 left for... something.

Currently doing the designs for the host software and this came up.

User avatar

13 May 2014, 02:33

lowpoly wrote:Is there an easy list for what the FN00-FN31 keys can be used? I know there is a list at the end of action_code.h but it doesn't tell me if all these elements are really to be used with FN keys and which are useful from an user point of view.
Did you see this yet? This is the only document for those at this time. Not complete but better than nothing. ... /

User avatar

13 May 2014, 14:25

I read through it some time ago, but not with fn in mind. Thanks for reminding me. Looks like I can continue like planned then.

User avatar

20 Jun 2014, 03:37

I've finally found some time to work on my keyboard. I have got the two Kinesis keywells hooked up and working, but the two backslash keys don't seem to be working. I also noticed that if I press and hold "down", it looks like I have just tapped the "down" key.

I am wondering if perhaps there is some place where these keys are being set to function keys or something that I did not notice. I have based my project on the gh60 one and commented out the fn_actions[] array. I'm not sure if there is somewhere else I should be looking.

My code can be found here: ... berkinesis

Post Reply

Return to “Workshop”