TODO test on remote site tmk.github.io/tmk_editor/hhkb/? github pages https://help.github.com/articles/user-organization-and-project-pages save file button https://developer.mozilla.org/en-US/docs/Web/API/Blob var typedArray = GetTheTypedArraySomehow(); var blob = new Blob([typedArray], {type: "application/octet-binary"}); // pass a useful mime type here "application/octet-stream" var url = URL.createObjectURL(blob); TrueErgonomic var a = document.getElementById("download-link"); a.href = window.URL.createObjectURL(blob); a.download = 'TrulyErgonomic_v3_3.hex'; // a.textContent = 'Download file.'; a.className = 'TE_link'; a.click() keyboard key text css align of wrapped text edit action for FN key load/save JSON load/save hex(binary) binary file format meta info: date/time keyboard id keymap/actionmap firmware load binary Mass Storage or HID comm fixed address for keymaps action map support Hex file format http://en.wikipedia.org/wiki/Intel_HEX 1.Start code: ':' 2.Byte Count: 2 hex(0-255) 3.Address: 4 hex(0-2^16) 4.Record Type: 2 hex(00-05) 00: Data record. which contains 16bit address and data. 01: End of File record. It must appear in the last line.(usually :00000001FF) 02: Extended Segment Address Record. 03: Start Segment Address Record. 04: Extended Linear Address Record. Upper two bytes of 32 bit address. 05: Start Linear Address Record. 5.Data: byte_count * hex(a sequence of bytes) 6.Checksum: 2 hex LSB of 2's complement of the sum of fields: 'Byte Count', 'Address', 'Record Type' and 'Data'. checksum = ~(the sum of bytes)&0xff + 1 = (the sum)&0xff^0xff + 1 TMK keymapping mode keymap 8bit code Special 8bit code Fn0-32 can be assigned for action code. actions[] -> --------------- | action x 32 | keymaps[] -> --------------- | keymap 0 | --------------- | keymap 1 | --------------- | keymap 2 | --------------- | keymap 3 | --------------- Interface: uint8_t keymap_key_to_keycode(uint8_t layer, key_t key) in keymap.h action_t keymap_fn_to_action(uint8_t keycode) in keymap.h static const uint16_t PROGMEM fn_actions[] = { [0] = ACTION_LAYER_MOMENTARY(0), [1] = ACTION_LAYER_MOMENTARY(1), [2] = ACTION_LAYER_MOMENTARY(2), [3] = ACTION_LAYER_MOMENTARY(3), [4] = ACTION_LAYER_TOGGLE(0), [5] = ACTION_LAYER_TOGGLE(1), [6] = ACTION_LAYER_TOGGLE(2), [7] = ACTION_LAYER_TOGGLE(3), [8] = ACTION_LAYER_TAP_TOGGLE(0), [9] = ACTION_LAYER_TAP_TOGGLE(1), [10] = ACTION_LAYER_TAP_TOGGLE(2), [11] = ACTION_LAYER_TAP_TOGGLE(3), }; actionmap 16bit code All key action can be defined in 16bit code. Memory usage will be about doubled size compared to keymap 8bit code. Map Structure: actionmaps[] -> --------------- | actionmap 0 | --------------- | actionmap 1 | --------------- | actionmap 2 | --------------- | actionmap 3 | --------------- Interface: action_t action_for_key(uint8_t layer, key_t key) in action.h Flash usage cosidaration ATmega32U4 32KB Firmware -24KB(with full option) Keymapping 4KB- Bootloader 4KB(Atmel stock) or 512B(Teensy) ATmega16U4 16KB Firmware -10KB Keymapping 2KB- Bootloader 4KB(Atmel stock) or 512B(Teensy) PS/2 and ADB have 256 keys in map, so use 512B each layer. 8layers will be available for ATMega32U4 and 4layers for 16U4. This seems like enough in most case. HTML Keyboard key element ID a) ID indicates place of look. needs Converter Table. b) ID indicates matrix position. x c) ID indicates defalut key name like: q, w, ... lshift... Not good. no consistency of name length. Javascript Keymap Array includes matrix postions of the key. keymap[LAYER][8][8] = { { { }, { } } Keycode table keyname => keycode(16bit) keycode => keyname Keymap 16bit keymap at first 8bit keymap support depends on future request Fn key configure Macro editor Where it converts key postion into matrix position at? Convert table? UI can use position of elemen placing. UI uses matrix posiotn for ID of element. HHKB key matrix COL 0 1 2 3 4 5 6 7 ROW --------------------------------------------------------------- 0| 2 q w s a z x c 1| 3 4 r e d f v b 2| 5 6 y t g h n _NONE_ 3| 1 Esc Tab Control LShift LAlt LMeta Space 4| 7 8 u i k j m _NONE_ 5| \ ` Delete Return Fn RShift RAlt RMeta 6| 9 0 o p ; l , _NONE_ 7| - + ] [ ' / . _NONE_ Key to matrix Table /* Qwerty * ,-----------------------------------------------------------. * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| `| * |-----------------------------------------------------------| * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]|Backs| * |-----------------------------------------------------------| * |Contro| A| S| D| F| G| H| J| K| L| ;| '|Enter | * |-----------------------------------------------------------| * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Fn | * `-----------------------------------------------------------' * |Gui|Alt | Space |Alt |Gui| * `-------------------------------------------' */ [ 0x31, 0x30, 0x00, 0x10, 0x11, 0x20, 0x21, 0x40, 0x41, 0x60, 0x61, 0x70, 0x71, 0x50, 0x51, 0x32, 0x01, 0x02, 0x13, 0x12, 0x23, 0x22, 0x42, 0x43, 0x62, 0x63, 0x73, 0x72, 0x52, 0x33, 0x04, 0x03, 0x14, 0x15, 0x24, 0x25, 0x45, 0x44, 0x65, 0x64, 0x66, 0x53, 0x34, 0x05, 0x06, 0x07, 0x16, 0x17, 0x26, 0x46, 0x66, 0x76, 0x75, 0x55, 0x54, 0x35, 0x36, 0x37, 0x57, 0x56, ] KC_NO = 0x00, KC_ROLL_OVER, KC_POST_FAIL, KC_UNDEFINED, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, /* 0x10 */ KC_N, KC_O, KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, KC_X, KC_Y, KC_Z, KC_1, KC_2, KC_3, /* 0x20 */ KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_ENTER, KC_ESCAPE, KC_BSPACE, KC_TAB, KC_SPACE, KC_MINUS, KC_EQUAL, KC_LBRACKET, KC_RBRACKET, /* 0x30 */ KC_BSLASH, /* \ (and |) */ KC_NONUS_HASH, /* Non-US # and ~ */ KC_SCOLON, /* ; (and :) */ KC_QUOTE, /* ' and " */ KC_GRAVE, /* Grave accent and tilde */ KC_COMMA, /* , and < */ KC_DOT, /* . and > */ KC_SLASH, /* / and ? */ KC_CAPSLOCK, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, /* 0x40 */ KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCREEN, KC_SCROLLLOCK, KC_PAUSE, KC_INSERT, KC_HOME, KC_PGUP, KC_DELETE, KC_END, KC_PGDOWN, KC_RIGHT, KC_LEFT, /* 0x50 */ KC_DOWN, KC_UP, KC_NUMLOCK, KC_KP_SLASH, KC_KP_ASTERISK, KC_KP_MINUS, KC_KP_PLUS, KC_KP_ENTER, KC_KP_1, KC_KP_2, KC_KP_3, KC_KP_4, KC_KP_5, KC_KP_6, KC_KP_7, KC_KP_8, /* 0x60 */ KC_KP_9, KC_KP_0, KC_KP_DOT, KC_NONUS_BSLASH, /* Non-US \ and | */ KC_APPLICATION, KC_POWER, KC_KP_EQUAL, KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, KC_F21, /* 0x70 */ KC_F22, KC_F23, KC_F24, KC_EXECUTE, KC_HELP, KC_MENU, KC_SELECT, KC_STOP, KC_AGAIN, KC_UNDO, KC_CUT, KC_COPY, KC_PASTE, KC_FIND, KC__MUTE, KC__VOLUP, /* 0x80 */ KC__VOLDOWN, KC_LOCKING_CAPS, /* locking Caps Lock */ KC_LOCKING_NUM, /* locking Num Lock */ KC_LOCKING_SCROLL, /* locking Scroll Lock */ KC_KP_COMMA, KC_KP_EQUAL_AS400, /* equal sign on AS/400 */ KC_INT1, KC_INT2, KC_INT3, KC_INT4, KC_INT5, KC_INT6, KC_INT7, KC_INT8, KC_INT9, KC_LANG1, /* 0x90 */ KC_LANG2, KC_LANG3, KC_LANG4, KC_LANG5, KC_LANG6, KC_LANG7, KC_LANG8, KC_LANG9, KC_ALT_ERASE, KC_SYSREQ, KC_CANCEL, KC_CLEAR, KC_PRIOR, KC_RETURN, KC_SEPARATOR, KC_OUT, /* 0xA0 */ KC_OPER, KC_CLEAR_AGAIN, KC_CRSEL, KC_EXSEL, /* 0xA4 */ /* NOTE: Following codes(0xB0-DD) are not used. Leave them for reference. */ KC_KP_00 = 0xB0, KC_KP_000, KC_THOUSANDS_SEPARATOR, KC_DECIMAL_SEPARATOR, KC_CURRENCY_UNIT, KC_CURRENCY_SUB_UNIT, KC_KP_LPAREN, KC_KP_RPAREN, KC_KP_LCBRACKET, /* { */ KC_KP_RCBRACKET, /* } */ KC_KP_TAB, KC_KP_BSPACE, KC_KP_A, KC_KP_B, KC_KP_C, KC_KP_D, KC_KP_E, /* 0xC0 */ KC_KP_F, KC_KP_XOR, KC_KP_HAT, KC_KP_PERC, KC_KP_LT, KC_KP_GT, KC_KP_AND, KC_KP_LAZYAND, KC_KP_OR, KC_KP_LAZYOR, KC_KP_COLON, KC_KP_HASH, KC_KP_SPACE, KC_KP_ATMARK, KC_KP_EXCLAMATION, KC_KP_MEM_STORE, /* 0xD0 */ KC_KP_MEM_RECALL, KC_KP_MEM_CLEAR, KC_KP_MEM_ADD, KC_KP_MEM_SUB, KC_KP_MEM_MUL, KC_KP_MEM_DIV, KC_KP_PLUS_MINUS, KC_KP_CLEAR, KC_KP_CLEAR_ENTRY, KC_KP_BINARY, KC_KP_OCTAL, KC_KP_DECIMAL, KC_KP_HEXADECIMAL, /* 0xDD */ /* Modifiers */ KC_LCTRL = 0xE0, KC_LSHIFT, KC_LALT, KC_LGUI, KC_RCTRL, KC_RSHIFT, KC_RALT, KC_RGUI,