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
test on remote site
----
X 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
X 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
@ -23,38 +24,47 @@ TODO
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
action map support
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.
P load/save JSON
X save hex(binary)
firmware
load binary
Mass Storage or HID comm
fixed address for keymaps
P load binary
P Mass Storage or HID comm
X 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
ld script/Firmware structure
----------------------------
Flash Map of ATMega32U4(32KB)
+------------+ 0x0000
| .vectors | 0xac (43vectors * 4bytes)
| .progmem | PROGMEM variables and PSTR
| .init0-9 |
| .text | code
| .fini9-0 |
| | > text region
|------------| _etext
| .data |
| .bss |
| .noinit |
| | > data region
|------------| 0x6800
| .keymap | > keymap region(2KB)
|------------| 0x7000
| bootloader | 4KB
+------------+ 0x7FFF
TMK keymapping mode
-------------------
keymap 8bit code
Special 8bit code Fn0-32 can be assigned for action code.
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.
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
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
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_ROLL_OVER,
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();
};
function hex_line(data, address, record_type)
function hex_line(address, record_type, data)
{
var sum = 0;
sum += data.length;
@ -25,40 +25,42 @@ function hex_line(data, address, record_type)
var line = '';
line += ':';
line += to_2hexstr(data.length);
line += to_2hexstr(address >> 8);
line += to_2hexstr(address & 0xff);
line += to_2hexstr(record_type);
line += hexstr2(data.length);
line += hexstr2(address >> 8);
line += hexstr2(address & 0xff);
line += hexstr2(record_type);
for (var i = 0; i < data.length; 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";
return line;
}
function hex_output(keymaps) {
function hex_eof()
{
return ":00000001FF\r\n";
}
function hex_output(address, data) {
var output = '';
var bytes = [];
var line = [];
// TODO: address
// TODO: refine
// flatten keymaps into one dimension array
[].concat.apply([], [].concat.apply([], keymaps)).forEach(function(e) {
bytes.push(e);
if (bytes.length == 16) {
output += hex_line(bytes, 0x0123, 0x05);
console.log(bytes);
bytes.length = 0;
// TODO: refine: flatten data into one dimension array
[].concat.apply([], [].concat.apply([], data)).forEach(function(e) {
line.push(e);
if (line.length == 16) {
output += hex_line(address, 0x00, line);
address += 16;
line.length = 0; // clear array
}
});
if (bytes.length > 0) {
console.log(bytes);
if (line.length > 0) {
output += hex_line(address, 0x00, line);
}
return output;
};
}
function source_output(keymaps) {
var output = '';
@ -75,7 +77,11 @@ function source_output(keymaps) {
output += "#include \"action_macro.h\"\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 += " [1] = ACTION_LAYER_MOMENTARY(1), \n";
output += " [2] = ACTION_LAYER_MOMENTARY(2), \n";
@ -91,11 +97,19 @@ function source_output(keymaps) {
output += "};\n\n";
// keymaps
output += 'static const uint8_t PROGMEM keymaps[][';
output += "#ifdef KEYMAP_SECTION\n";
output += "const uint8_t keymaps[][";
output += keymaps[0].length; // row
output += '][';
output += "][";
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) {
output += " {\n";
for (var j in keymaps[i]) {
@ -129,241 +143,6 @@ function source_output(keymaps) {
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 */
var code_display = [
// {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>
<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" />
<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="codes.js"></script>
<script src="firmware.js"></script>
<link href='keyboard.css' rel='stylesheet' type='text/css'>
<script>
@ -93,13 +94,30 @@
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
var editing_key;
// layer under editing
var editing_layer = 0;
$(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
var load_keymap = function(layer, keymap) {
@ -177,24 +195,47 @@
/*
* 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-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
$("#keymap-source-generate").click(function(ev, ui) {
$("#keymap-source").text(source_output(keymaps));
$("#keymap-output").text(source_output(keymaps));
});
// JSON output
//$("#keymap-json-generate").css('display', 'none'); // hide
$("#keymap-json-generate").click(function(ev, ui) {
var keymap_output;
//keymap_output = JSON.stringify(keymaps, null, 4);
keymap_output = JSON.stringify({ keymaps: keymaps });
$("#keymap-source").text(keymap_output);
$("#keymap-output").text(keymap_output);
});
});
@ -202,8 +243,17 @@
</head>
<body>
<h1>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.
<h1 id="page-title">TMK Keymap Editor</h1>
<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>
<!--
@ -302,9 +352,7 @@ Keyboard keys
<!--
Keycodes
TODO: make display name and tooltip better
TODO: better align of buttons
TODO: get text and title from code table?
-->
<h2>Keycodes</h2>
<div id="keycode_tabs">
@ -627,16 +675,15 @@ TODO: get text and title from code table?
</div>
</div>
<h3>Firmware Hex File Download:</h3>
<button id="keymap-download" title="save file">Download</button>
<h3>Keymap Output:</h3>
<textarea id="keymap-source" rows="20" cols="80"></textarea>
<textarea id="keymap-output" rows="20" cols="80"></textarea>
<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-source-generate" title="generate C source code">C source</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>
</html>