Browse Source

Add hex download button

gh-pages
tmk 10 years ago
parent
commit
b37cadd0af
4 changed files with 1616 additions and 333 deletions
  1. 54
    54
      editor/hhkb/MEMO.txt
  2. 41
    262
      editor/hhkb/codes.js
  3. 1457
    0
      editor/hhkb/firmware.js
  4. 64
    17
      editor/hhkb/index.html

+ 54
- 54
editor/hhkb/MEMO.txt View File

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
align of wrapped text align of wrapped text


edit action for FN key 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 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 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[] -> ---------------
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
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.












Keycodes
KC_NO = 0x00, KC_NO = 0x00,
KC_ROLL_OVER, KC_ROLL_OVER,
KC_POST_FAIL, KC_POST_FAIL,

+ 41
- 262
editor/hhkb/codes.js View File

}; };
*/ */


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;


var line = ''; var line = '';
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++) { 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 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; return output;
};
}


function source_output(keymaps) { function source_output(keymaps) {
var output = ''; var output = '';
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";
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]) {
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
- 0
editor/hhkb/firmware.js
File diff suppressed because it is too large
View File


+ 64
- 17
editor/hhkb/index.html View File

<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>
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) {
/* /*
* Output options * Output options
*/ */
//$("#keymap-source").resizable(); // resizable textarea
//$("#keymap-output").resizable(); // resizable textarea

// 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();
});


// TODO: Hex output
// 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);
}); });


}); });
</head> </head>


<body> <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> <h2>Keyboard</h2>
<!-- <!--


<!-- <!--
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">
</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>

Loading…
Cancel
Save