1
0

Add hex download button

This commit is contained in:
tmk 2013-09-05 11:11:34 +09:00
parent 48b6c5baae
commit b37cadd0af
4 changed files with 1617 additions and 334 deletions

View File

@ -1,10 +1,11 @@
TODO TODO
test on remote site ----
X test on remote site
tmk.github.io/tmk_editor/hhkb/? tmk.github.io/tmk_editor/hhkb/?
github pages github pages
https://help.github.com/articles/user-organization-and-project-pages https://help.github.com/articles/user-organization-and-project-pages
save file button X save file button
https://developer.mozilla.org/en-US/docs/Web/API/Blob https://developer.mozilla.org/en-US/docs/Web/API/Blob
var typedArray = GetTheTypedArraySomehow(); var typedArray = GetTheTypedArraySomehow();
var blob = new Blob([typedArray], {type: "application/octet-binary"}); // pass a useful mime type here var blob = new Blob([typedArray], {type: "application/octet-binary"}); // pass a useful mime type here
@ -23,38 +24,47 @@ TODO
align of wrapped text align of wrapped text
edit action for FN key edit action for FN key
load/save JSON action map support
load/save hex(binary) Macro editor
binary file format
meta info: Where it converts key postion into matrix position at?
date/time Convert table? UI can use position of elemen placing.
keyboard id UI uses matrix posiotn for ID of element.
keymap/actionmap
P load/save JSON
X save hex(binary)
firmware firmware
load binary P load binary
Mass Storage or HID comm P Mass Storage or HID comm
fixed address for keymaps X fixed address for keymaps
action map support
Hex file format
http://en.wikipedia.org/wiki/Intel_HEX ld script/Firmware structure
1.Start code: ':' ----------------------------
2.Byte Count: 2 hex(0-255) Flash Map of ATMega32U4(32KB)
3.Address: 4 hex(0-2^16) +------------+ 0x0000
4.Record Type: 2 hex(00-05) | .vectors | 0xac (43vectors * 4bytes)
00: Data record. which contains 16bit address and data. | .progmem | PROGMEM variables and PSTR
01: End of File record. It must appear in the last line.(usually :00000001FF) | .init0-9 |
02: Extended Segment Address Record. | .text | code
03: Start Segment Address Record. | .fini9-0 |
04: Extended Linear Address Record. Upper two bytes of 32 bit address. | | > text region
05: Start Linear Address Record. |------------| _etext
5.Data: byte_count * hex(a sequence of bytes) | .data |
6.Checksum: 2 hex LSB of 2's complement of the sum of fields: 'Byte Count', 'Address', 'Record Type' and 'Data'. | .bss |
checksum = ~(the sum of bytes)&0xff + 1 = (the sum)&0xff^0xff + 1 | .noinit |
| | > data region
|------------| 0x6800
| .keymap | > keymap region(2KB)
|------------| 0x7000
| bootloader | 4KB
+------------+ 0x7FFF
TMK keymapping mode TMK keymapping mode
-------------------
keymap 8bit code keymap 8bit code
Special 8bit code Fn0-32 can be assigned for action code. Special 8bit code Fn0-32 can be assigned for action code.
actions[] -> --------------- actions[] -> ---------------
@ -114,33 +124,23 @@ TMK keymapping mode
8layers will be available for ATMega32U4 and 4layers for 16U4. This seems like enough in most case. 8layers will be available for ATMega32U4 and 4layers for 16U4. This seems like enough in most case.
HTML Hex file format
Keyboard key element ID http://en.wikipedia.org/wiki/Intel_HEX
a) ID indicates place of look. needs Converter Table. 1.Start code: ':'
b) ID indicates matrix position. 2.Byte Count: 2 hex(0-255)
x c) ID indicates defalut key name like: q, w, ... lshift... 3.Address: 4 hex(0-2^16)
Not good. no consistency of name length. 4.Record Type: 2 hex(00-05)
00: Data record. which contains 16bit address and data.
Javascript 01: End of File record. It must appear in the last line.(usually :00000001FF)
Keymap Array 02: Extended Segment Address Record.
includes matrix postions of the key. 03: Start Segment Address Record.
keymap[LAYER][8][8] = { 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)
Keycode table 6.Checksum: 2 hex LSB of 2's complement of the sum of fields: 'Byte Count', 'Address', 'Record Type' and 'Data'.
keyname => keycode(16bit) checksum = ~(the sum of bytes)&0xff + 1 = (the sum)&0xff^0xff + 1
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.
@ -181,7 +181,7 @@ Key to matrix Table
Keycodes
KC_NO = 0x00, KC_NO = 0x00,
KC_ROLL_OVER, KC_ROLL_OVER,
KC_POST_FAIL, KC_POST_FAIL,

View File

@ -10,12 +10,12 @@ function flatten(obj)
}; };
*/ */
function to_2hexstr(b) function hexstr2(b)
{ {
return ('0'+ b.toString(16)).substr(-2).toUpperCase(); return ('0'+ b.toString(16)).substr(-2).toUpperCase();
}; };
function hex_line(data, address, record_type) function hex_line(address, record_type, data)
{ {
var sum = 0; var sum = 0;
sum += data.length; sum += data.length;
@ -25,40 +25,42 @@ function hex_line(data, address, record_type)
var line = ''; var line = '';
line += ':'; line += ':';
line += to_2hexstr(data.length); line += hexstr2(data.length);
line += to_2hexstr(address >> 8); line += hexstr2(address >> 8);
line += to_2hexstr(address & 0xff); line += hexstr2(address & 0xff);
line += to_2hexstr(record_type); line += hexstr2(record_type);
for (var i = 0; i < data.length; i++) { for (var i = 0; i < data.length; i++) {
sum = (sum + data[i]); sum = (sum + data[i]);
line += to_2hexstr(data[i]); line += hexstr2(data[i]);
} }
line += to_2hexstr((~sum + 1)&0xff); // Checksum line += hexstr2((~sum + 1)&0xff); // Checksum
line +="\r\n"; line +="\r\n";
return line; return line;
} }
function hex_output(keymaps) { function hex_eof()
{
return ":00000001FF\r\n";
}
function hex_output(address, data) {
var output = ''; var output = '';
var bytes = []; var line = [];
// TODO: address // TODO: refine: flatten data into one dimension array
[].concat.apply([], [].concat.apply([], data)).forEach(function(e) {
// TODO: refine line.push(e);
// flatten keymaps into one dimension array if (line.length == 16) {
[].concat.apply([], [].concat.apply([], keymaps)).forEach(function(e) { output += hex_line(address, 0x00, line);
bytes.push(e); address += 16;
if (bytes.length == 16) { line.length = 0; // clear array
output += hex_line(bytes, 0x0123, 0x05);
console.log(bytes);
bytes.length = 0;
} }
}); });
if (bytes.length > 0) { if (line.length > 0) {
console.log(bytes); output += hex_line(address, 0x00, line);
} }
return output; return output;
}; }
function source_output(keymaps) { function source_output(keymaps) {
var output = ''; var output = '';
@ -75,7 +77,11 @@ function source_output(keymaps) {
output += "#include \"action_macro.h\"\n"; output += "#include \"action_macro.h\"\n";
output += "#include \"keymap.h\"\n\n"; output += "#include \"keymap.h\"\n\n";
output += "static const uint16_t PROGMEM fn_actions[] = {\n"; output += "#ifdef KEYMAP_SECTION\n";
output += "const uint16_t fn_actions[] __attribute__ ((section (\".keymap.fn_actions\"))) = {\n";
output += "#else\n";
output += "static const uint16_t fn_actions[] PROGMEM = {\n";
output += "#endif\n";
output += " [0] = ACTION_LAYER_MOMENTARY(0), \n"; output += " [0] = ACTION_LAYER_MOMENTARY(0), \n";
output += " [1] = ACTION_LAYER_MOMENTARY(1), \n"; output += " [1] = ACTION_LAYER_MOMENTARY(1), \n";
output += " [2] = ACTION_LAYER_MOMENTARY(2), \n"; output += " [2] = ACTION_LAYER_MOMENTARY(2), \n";
@ -91,11 +97,19 @@ function source_output(keymaps) {
output += "};\n\n"; output += "};\n\n";
// keymaps // keymaps
output += 'static const uint8_t PROGMEM keymaps[]['; output += "#ifdef KEYMAP_SECTION\n";
output += "const uint8_t keymaps[][";
output += keymaps[0].length; // row output += keymaps[0].length; // row
output += ']['; output += "][";
output += keymaps[0][0].length; // col output += keymaps[0][0].length; // col
output += "] = {\n"; output += "] __attribute__ ((section (\".keymap.keymaps\"))) = {\n";
output += "#else\n";
output += "static const uint8_t keymaps[][";
output += keymaps[0].length; // row
output += "][";
output += keymaps[0][0].length; // col
output += "] PROGMEM = {\n";
output += "#endif\n";
for (var i in keymaps) { for (var i in keymaps) {
output += " {\n"; output += " {\n";
for (var j in keymaps[i]) { for (var j in keymaps[i]) {
@ -129,241 +143,6 @@ function source_output(keymaps) {
return output; return output;
}; };
var id_code = {
'act-no': 0,
'act-roll-over': 1,
'act-post-fail': 2,
'act-undefined': 3,
'act-a': 4,
'act-b': 5,
'act-c': 6,
'act-d': 7,
'act-e': 8,
'act-f': 9,
'act-g': 10,
'act-h': 11,
'act-i': 12,
'act-j': 13,
'act-k': 14,
'act-l': 15,
'act-m': 16,
'act-n': 17,
'act-o': 18,
'act-p': 19,
'act-q': 20,
'act-r': 21,
'act-s': 22,
'act-t': 23,
'act-u': 24,
'act-v': 25,
'act-w': 26,
'act-x': 27,
'act-y': 28,
'act-z': 29,
'act-1': 30,
'act-2': 31,
'act-3': 32,
'act-4': 33,
'act-5': 34,
'act-6': 35,
'act-7': 36,
'act-8': 37,
'act-9': 38,
'act-0': 39,
'act-enter': 40,
'act-escape': 41,
'act-bspace': 42,
'act-tab': 43,
'act-space': 44,
'act-minus': 45,
'act-equal': 46,
'act-lbracket': 47,
'act-rbracket': 48,
'act-bslash': 49,
'act-nonus-hash': 50,
'act-scolon': 51,
'act-quote': 52,
'act-grave': 53,
'act-comma': 54,
'act-dot': 55,
'act-slash': 56,
'act-capslock': 57,
'act-f1': 58,
'act-f2': 59,
'act-f3': 60,
'act-f4': 61,
'act-f5': 62,
'act-f6': 63,
'act-f7': 64,
'act-f8': 65,
'act-f9': 66,
'act-f10': 67,
'act-f11': 68,
'act-f12': 69,
'act-pscreen': 70,
'act-scrolllock': 71,
'act-pause': 72,
'act-insert': 73,
'act-home': 74,
'act-pgup': 75,
'act-delete': 76,
'act-end': 77,
'act-pgdown': 78,
'act-right': 79,
'act-left': 80,
'act-down': 81,
'act-up': 82,
'act-numlock': 83,
'act-kp-slash': 84,
'act-kp-asterisk': 85,
'act-kp-minus': 86,
'act-kp-plus': 87,
'act-kp-enter': 88,
'act-kp-1': 89,
'act-kp-2': 90,
'act-kp-3': 91,
'act-kp-4': 92,
'act-kp-5': 93,
'act-kp-6': 94,
'act-kp-7': 95,
'act-kp-8': 96,
'act-kp-9': 97,
'act-kp-0': 98,
'act-kp-dot': 99,
'act-nonus-bslash': 100,
'act-application': 101,
'act-power': 102,
'act-kp-equal': 103,
'act-f13': 104,
'act-f14': 105,
'act-f15': 106,
'act-f16': 107,
'act-f17': 108,
'act-f18': 109,
'act-f19': 110,
'act-f20': 111,
'act-f21': 112,
'act-f22': 113,
'act-f23': 114,
'act-f24': 115,
'act-execute': 116,
'act-help': 117,
'act-menu': 118,
'act-select': 119,
'act-stop': 120,
'act-again': 121,
'act-undo': 122,
'act-cut': 123,
'act-copy': 124,
'act-paste': 125,
'act-find': 126,
'act--mute': 127,
'act--volup': 128,
'act--voldown': 129,
'act-locking-caps': 130,
'act-locking-num': 131,
'act-locking-scroll': 132,
'act-kp-comma': 133,
'act-kp-equal-as400': 134,
'act-int1': 135,
'act-int2': 136,
'act-int3': 137,
'act-int4': 138,
'act-int5': 139,
'act-int6': 140,
'act-int7': 141,
'act-int8': 142,
'act-int9': 143,
'act-lang1': 144,
'act-lang2': 145,
'act-lang3': 146,
'act-lang4': 147,
'act-lang5': 148,
'act-lang6': 149,
'act-lang7': 150,
'act-lang8': 151,
'act-lang9': 152,
'act-alt-erase': 153,
'act-sysreq': 154,
'act-cancel': 155,
'act-clear': 156,
'act-prior': 157,
'act-return': 158,
'act-separator': 159,
'act-out': 160,
'act-oper': 161,
'act-clear-again': 162,
'act-crsel': 163,
'act-exsel': 164,
'act-reserved-165': 165,
'act-reserved-166': 166,
'act-reserved-167': 167,
'act-reserved-168': 168,
'act-reserved-169': 169,
'act-reserved-170': 170,
'act-reserved-171': 171,
'act-reserved-172': 172,
'act-reserved-173': 173,
'act-reserved-174': 174,
'act-reserved-175': 175,
'act-kp-00': 176,
'act-kp-000': 177,
'act-thousands-separator': 178,
'act-decimal-separator': 179,
'act-currency-unit': 180,
'act-currency-sub-unit': 181,
'act-kp-lparen': 182,
'act-kp-rparen': 183,
'act-kp-lcbracket': 184,
'act-kp-rcbracket': 185,
'act-kp-tab': 186,
'act-kp-bspace': 187,
'act-kp-a': 188,
'act-kp-b': 189,
'act-kp-c': 190,
'act-kp-d': 191,
'act-kp-e': 192,
'act-kp-f': 193,
'act-kp-xor': 194,
'act-kp-hat': 195,
'act-kp-perc': 196,
'act-kp-lt': 197,
'act-kp-gt': 198,
'act-kp-and': 199,
'act-kp-lazyand': 200,
'act-kp-or': 201,
'act-kp-lazyor': 202,
'act-kp-colon': 203,
'act-kp-hash': 204,
'act-kp-space': 205,
'act-kp-atmark': 206,
'act-kp-exclamation': 207,
'act-kp-mem-store': 208,
'act-kp-mem-recall': 209,
'act-kp-mem-clear': 210,
'act-kp-mem-add': 211,
'act-kp-mem-sub': 212,
'act-kp-mem-mul': 213,
'act-kp-mem-div': 214,
'act-kp-plus-minus': 215,
'act-kp-clear': 216,
'act-kp-clear-entry': 217,
'act-kp-binary': 218,
'act-kp-octal': 219,
'act-kp-decimal': 220,
'act-kp-hexadecimal': 221,
'act-reserved-222': 222,
'act-reserved-223': 223,
'act-lctrl': 224,
'act-lshift': 225,
'act-lalt': 226,
'act-lgui': 227,
'act-rctrl': 228,
'act-rshift': 229,
'act-ralt': 230,
'act-rgui': 231,
};
/* keycode to display */ /* keycode to display */
var code_display = [ var code_display = [
// {id, name(text), description(tooltip)} // {id, name(text), description(tooltip)}

1457
editor/hhkb/firmware.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,11 @@
<html> <html>
<head> <head>
<title>Keymap Editor</title> <title>TMK Keymap Editor</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" /> <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script> <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script src="codes.js"></script> <script src="codes.js"></script>
<script src="firmware.js"></script>
<link href='keyboard.css' rel='stylesheet' type='text/css'> <link href='keyboard.css' rel='stylesheet' type='text/css'>
<script> <script>
@ -93,13 +94,30 @@
no_map(), no_map(),
]; ];
// TODO: define proper Fn actions: 32actions*2bytes
var fn_actions = [
0xF1,0xA0,0xF1,0xA1,0xF1,0xA2,0xF1,0xA3,0x01,0x8A,0x02,0x8A,0x04,0x8A,0x08,0x8A,
0xF0,0xA0,0xF0,0xA1,0xF0,0xA2,0xF0,0xA3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
];
// key id under editing // key id under editing
var editing_key; var editing_key;
// layer under editing // layer under editing
var editing_layer = 0; var editing_layer = 0;
$(function() { $(function() {
// TODO: alert when leave or close window // Title
document.title = "TMK Keymap Editor for " + KEYBOARD_ID;
$("#page-title").text("TMK Keymap Editor for " + KEYBOARD_ID);
// lost keymap under edting when leave the page
/* TODO: Needed when released
$(window).bind('beforeunload', function(){
return 'CAUTION: You will lost your change.';
});
*/
// load keymap on keyboard key buttons // load keymap on keyboard key buttons
var load_keymap = function(layer, keymap) { var load_keymap = function(layer, keymap) {
@ -177,24 +195,47 @@
/* /*
* Output options * Output options
*/ */
//$("#keymap-source").resizable(); // resizable textarea //$("#keymap-output").resizable(); // resizable textarea
// TODO: Hex output // Hex Save
$("#keymap-download").click(function(ev, ui) {
var keymap_data = fn_actions.concat(keymaps);
var content = firmware_hex() +
hex_output(KEYMAP_START_ADDRESS, keymap_data) +
hex_eof();
// download hex file
var blob = new Blob([content], {type: "application/octet-stream"});
var hex_link = $("<a/>");
hex_link.attr('href', window.URL.createObjectURL(blob));
hex_link.attr('download', KEYBOARD_ID + "_firmware.hex");
// jQuery click() doesn't work straight for 'a' element
// http://stackoverflow.com/questions/1694595/
hex_link[0].click();
});
// Hex output
$("#keymap-hex-generate").click(function(ev, ui) { $("#keymap-hex-generate").click(function(ev, ui) {
$("#keymap-source").text(hex_output(keymaps)); // TODO: flattened array
var keymap_data = fn_actions.concat(keymaps);
var content = firmware_hex() +
hex_output(KEYMAP_START_ADDRESS, keymap_data) +
hex_eof();
$("#keymap-output").text(content);
}); });
// C source output // C source output
$("#keymap-source-generate").click(function(ev, ui) { $("#keymap-source-generate").click(function(ev, ui) {
$("#keymap-source").text(source_output(keymaps)); $("#keymap-output").text(source_output(keymaps));
}); });
// JSON output // JSON output
//$("#keymap-json-generate").css('display', 'none'); // hide
$("#keymap-json-generate").click(function(ev, ui) { $("#keymap-json-generate").click(function(ev, ui) {
var keymap_output; var keymap_output;
//keymap_output = JSON.stringify(keymaps, null, 4); //keymap_output = JSON.stringify(keymaps, null, 4);
keymap_output = JSON.stringify({ keymaps: keymaps }); keymap_output = JSON.stringify({ keymaps: keymaps });
$("#keymap-source").text(keymap_output); $("#keymap-output").text(keymap_output);
}); });
}); });
@ -202,8 +243,17 @@
</head> </head>
<body> <body>
<h1>TMK Keymap Editor</h1> <h1 id="page-title">TMK Keymap Editor</h1>
See <a href="https://github.com/tmk/tmk_keyboard/blob/master/doc/keymap.md" target="_blank">this</a> for keymap description.
<h3>Instruction</h3>
How to edit keymap
<ul>
<li>Select layer
<li>Select key to edit
<li>Select keycode to assign to the key
<li>Download firmware
</ul>
See <a href="https://github.com/tmk/tmk_keyboard/blob/master/doc/keymap.md" target="_blank">this</a> for detailed description of keymap.
<h2>Keyboard</h2> <h2>Keyboard</h2>
<!-- <!--
@ -302,9 +352,7 @@ Keyboard keys
<!-- <!--
Keycodes Keycodes
TODO: make display name and tooltip better
TODO: better align of buttons TODO: better align of buttons
TODO: get text and title from code table?
--> -->
<h2>Keycodes</h2> <h2>Keycodes</h2>
<div id="keycode_tabs"> <div id="keycode_tabs">
@ -627,16 +675,15 @@ TODO: get text and title from code table?
</div> </div>
</div> </div>
<h3>Firmware Hex File Download:</h3>
<button id="keymap-download" title="save file">Download</button>
<h3>Keymap Output:</h3> <h3>Keymap Output:</h3>
<textarea id="keymap-source" rows="20" cols="80"></textarea> <textarea id="keymap-output" rows="20" cols="80"></textarea>
<br/> <br/>
<button id="keymap-source-generate" title="generate C source code">C source</button>
<button id="keymap-json-generate" title="generate JSON">JSON</button> <button id="keymap-json-generate" title="generate JSON">JSON</button>
<button id="keymap-source-generate" title="generate C source code">C source</button>
<button id="keymap-hex-generate" title="generate Hex">Hex</button> <button id="keymap-hex-generate" title="generate Hex">Hex</button>
<!-- TODO: Hex/load JSON -->
<!--
<button id="keymap-json-load" title="generate JSON">Load JSON</button>
-->
</body> </body>
</html> </html>