diff --git a/build-scripts/gen-layout.py b/build-scripts/gen-layout.py new file mode 100755 index 0000000..fec5225 --- /dev/null +++ b/build-scripts/gen-layout.py @@ -0,0 +1,351 @@ +#! /usr/bin/env python3 +# ----------------------------------------------------------------------------- +# Copyright (c) 2012 Ben Blazak +# Released under The MIT License (MIT) (see "license.md") +# Project located at +# ----------------------------------------------------------------------------- + +""" +Generate a depiction of the layout (in html + svg) + +Depends on: +- the UI info file (in JSON) +""" + +# ----------------------------------------------------------------------------- + +import argparse +import json +import os +import re +import sys + +# ----------------------------------------------------------------------------- + +class Namespace(): + pass + +template = Namespace() +doc = Namespace() +info = Namespace() + +# ----------------------------------------------------------------------------- + +def main(): + arg_parser = argparse.ArgumentParser( + description = "Generate a picture of the firmware's " + + "keyboard layout" ) + + arg_parser.add_argument( + '--ui-info-file', + required = True ) + + args = arg_parser.parse_args(sys.argv[1:]) + + # constant file paths + args.template_svg_file = './build-scripts/gen_layout/template.svg' + args.template_js_file = './build-scripts/gen_layout/template.js' + + # normalize paths + args.ui_info_file = os.path.abspath(args.ui_info_file) + args.template_svg_file = os.path.abspath(args.template_svg_file) + args.template_js_file = os.path.abspath(args.template_js_file) + + # set vars + doc.main = '' # to store the html document we're generating + template.svg = open(args.template_svg_file).read() + template.js = open(args.template_js_file).read() + info.all = json.loads(open(args.ui_info_file).read()) + + info.matrix_positions = info.all['mappings']['matrix-positions'] + info.matrix_layout = info.all['mappings']['matrix-layout'] + + # prefix + doc.prefix = (""" + + + + + + + + + +""")[1:-1] + + # suffix + doc.suffix = (""" + + + +""")[1:-1] + + # substitute into template + for (layout, layer) in zip( info.matrix_layout, + range(len(info.matrix_layout))): + svg = template.svg + for (name, (code, press, release)) \ + in zip(info.matrix_positions, layout): + replace = '' + if press == 'kbfun_jump_to_bootloader': + replace = '[btldr]' + elif re.search(r'layer', press): + replace = '[layer]' + else: + replace = keycode_to_string.get(code, '[n/a]') + + svg = re.sub( + '>'+name+'<', '>'+replace+'<', svg ) + svg = re.sub( + r"\('(" + name + r".*)'\)", + r"('\1', " + str(layer) + r")", + svg ) + + doc.main += svg + + print(doc.prefix + doc.main + doc.suffix) + +# ----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- + +keycode_to_string = { + 0x01: "Error", # ErrorRollOver + 0x02: "POSTFail", + 0x03: "Error", # ErrorUndefined + 0x04: "a A", + 0x05: "b B", + 0x06: "c C", + 0x07: "d D", + 0x08: "e E", + 0x09: "f F", + 0x0A: "g G", + 0x0B: "h H", + 0x0C: "i I", + 0x0D: "j J", + 0x0E: "k K", + 0x0F: "l L", + 0x10: "m M", + 0x11: "n N", + 0x12: "o O", + 0x13: "p P", + 0x14: "q Q", + 0x15: "r R", + 0x16: "s S", + 0x17: "t T", + 0x18: "u U", + 0x19: "v V", + 0x1A: "w W", + 0x1B: "x X", + 0x1C: "y Y", + 0x1D: "z Z", + 0x1E: "1 !", + 0x1F: "2 @", + 0x20: "3 #", + 0x21: "4 $", + 0x22: "5 %", + 0x23: "6 ^", + 0x24: "7 &", + 0x25: "8 *", + 0x26: "9 (", + 0x27: "0 )", + 0x28: "Return", + 0x29: "Esc", + 0x2A: "Backspace", + 0x2B: "Tab", + 0x2C: "Space", + 0x2D: "- _", + 0x2E: "= +", + 0x2F: "[ {", + 0x30: "] }", + 0x31: "\ |", + 0x32: "# ~", + 0x33: "; :", + 0x34: "\' \"", + 0x35: "` ~", + 0x36: ", <", + 0x37: ". >", + 0x38: "/ ?", + 0x39: "Caps", + 0x3A: "F1", + 0x3B: "F2", + 0x3C: "F3", + 0x3D: "F4", + 0x3E: "F5", + 0x3F: "F6", + 0x40: "F7", + 0x41: "F8", + 0x42: "F9", + 0x43: "F10", + 0x44: "F11", + 0x45: "F12", + 0x46: "PrintScreen", + 0x47: "ScrollLock", + 0x48: "Pause", + 0x49: "Ins", # Insert + 0x4A: "Hm", # Home + 0x4B: "Pg\u2191", # up arrow + 0x4C: "Delete", + 0x4D: "End", + 0x4E: "Pg\u2193", # down arrow + 0x4F: "\u2192", # right arrow + 0x50: "\u2190", # left arrow + 0x51: "\u2193", # down arrow + 0x52: "\u2191", # up arrow + + 0x53: "Num", + 0x54: "/", + 0x55: "*", + 0x56: "-", + 0x57: "+", + 0x58: "Enter", + 0x59: "1 End", + 0x5A: "2 \u2193", # down arrow + 0x5B: "3 Pg\u2193", # down arrow + 0x5C: "4 \u2190", # left arrow + 0x5D: "5", + 0x5E: "6 \u2192", # right arrow + 0x5F: "7 Hm", # Home + 0x60: "8 \u2191", # up arrow + 0x61: "9 Pg\u2191", # up arrow + 0x62: "0 Ins", # Insert + 0x63: ". Del", + + 0x64: "\ |", + 0x65: "App", + 0x66: "Power", + + 0x67: "=", + + 0x68: "F13", + 0x69: "F14", + 0x6A: "F15", + 0x6B: "F16", + 0x6C: "F17", + 0x6D: "F18", + 0x6E: "F19", + 0x6F: "F20", + 0x70: "F21", + 0x71: "F22", + 0x72: "F23", + 0x73: "F24", + 0x74: "Exec", + 0x75: "Help", + 0x76: "Menu", + 0x77: "Select", + 0x78: "Stop", + 0x79: "Again", + 0x7A: "Undo", + 0x7B: "Cut", + 0x7C: "Copy", + 0x7D: "Paste", + 0x7E: "Find", + 0x7F: "Mute", + 0x80: "VolUp", + 0x81: "VolDown", + 0x82: "LockingCapsLock", + 0x83: "LockingNumLock", + 0x84: "LockingScrollLock", + + 0x85: ",", + 0x86: "=", + + 0x87: "Int1", + 0x88: "Int2", + 0x89: "Int3", + 0x8A: "Int4", + 0x8B: "Int5", + 0x8C: "Int6", + 0x8D: "Int7", + 0x8E: "Int8", + 0x8F: "Int9", + 0x90: "LANG1", + 0x91: "LANG2", + 0x92: "LANG3", + 0x93: "LANG4", + 0x94: "LANG5", + 0x95: "LANG6", + 0x96: "LANG7", + 0x97: "LANG8", + 0x98: "LANG9", + 0x99: "AlternateErase", + 0x9A: "SysReq_Attention", + 0x9B: "Cancel", + 0x9C: "Clear", + 0x9D: "Prior", + 0x9E: "Return", + 0x9F: "Separator", + 0xA0: "Out", + 0xA1: "Oper", + 0xA2: "Clear_Again", + 0xA3: "CrSel_Props", + 0xA4: "ExSel", + + 0xB0: "00", + 0xB1: "000", + + 0xB2: "Thousands_Sep", + 0xB3: "Decimal_Sep", + 0xB4: "$", + 0xB5: "Currency_Subunit", + + 0xB6: "(", + 0xB7: ")", + 0xB8: "{", + 0xB9: "}", + + 0xBA: "Tab", + 0xBB: "Backspace", + 0xBC: "A", + 0xBD: "B", + 0xBE: "C", + 0xBF: "D", + 0xC0: "E", + 0xC1: "F", + 0xC2: "XOR", + 0xC3: "^", + 0xC4: "%", + 0xC5: "<", + 0xC6: ">", + 0xC7: "&", + 0xC8: "&&", + 0xC9: "|", + 0xCA: "||", + 0xCB: ":", + 0xCC: "#", + 0xCD: "Space", + 0xCE: "@", + 0xCF: "!", + 0xD0: "Mem_Store", + 0xD1: "Mem_Recall", + 0xD2: "Mem_Clear", + 0xD3: "Mem_+", + 0xD4: "Mem_-", + 0xD5: "Mem_*", + 0xD6: "Mem_/", + 0xD7: "+-", + 0xD8: "Clear", + 0xD9: "ClearEntry", + 0xDA: "Binary", + 0xDB: "Octal", + 0xDC: ".", + 0xDD: "Hexadecimal", + + 0xE0: "L-Ctrl", + 0xE1: "L-Shift", + 0xE2: "L-Alt", + 0xE3: "L-GUI", + 0xE4: "R-Ctrl", + 0xE5: "R-Shift", + 0xE6: "R-Alt", + 0xE7: "R-GUI", + } + +# ----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- + +if __name__ == '__main__': + main() + diff --git a/build-scripts/gen-ui-info.py b/build-scripts/gen-ui-info.py new file mode 100755 index 0000000..2690e2c --- /dev/null +++ b/build-scripts/gen-ui-info.py @@ -0,0 +1,474 @@ +#! /usr/bin/env python3 +# ----------------------------------------------------------------------------- +# Copyright (c) 2012 Ben Blazak +# Released under The MIT License (MIT) (see "license.md") +# Project located at +# ----------------------------------------------------------------------------- + +""" +Generate UI info file (in JSON) + +Depends on: +- the project source code +- the project '.map' file (generated by the compiler) +""" + +_FORMAT_DESCRIPTION = (""" +/* ---------------------------------------------------------------------------- + * Version 0 + * ---------------------------------------------------------------------------- + * Hopefully the add-hoc conventions are clear enough... I didn't feel like + * investing the time in making it a real JSON Schema when there aren't many + * validators, and the most current completed draft at the moment (draft 3) is + * expired... + * ---------------------------------------------------------------------------- + * Please note that in general, fields may be added without changing the + * version number, and that programs using this format are not required to fill + * (or read) any of the given fields. + * ------------------------------------------------------------------------- */ + +var ui_info = { + ".meta-data": { // for the JSON file + "version": "", + "date-generated": "", // format: RFC 3339 + }, + "keyboard-functions": { + "<(function name)>": { + "position": "", // as given by the .map file + "length": "", // as given by the .map file + "comments": { + "name": "", // more user friendly name + "description": "", + "notes": [ + "", + "..." + ], + "..." + } + }, + "..." + }, + "layout-matrices": { + "<(matrix name)>": { + "position": "", // as given by the .map file + "length": "" // as given by the .map file + }, + "..." + }, + "mappings": { + /* + * The mappings prefixed with 'matrix' have their elements in the same + * order as the .hex file (whatever order that is). The mappings + * prefixed with 'physical' will have their elements in an order + * corresponding to thier physical position on the keyboard. You can + * convert between the two using the relative positions of the key-ids + * in 'physical-positions' and 'matrix-positions'. + * + * The current order of 'physical' mappings is: + * -------------------------------------------- + * // left hand, spatial positions + * 00, 01, 02, 03, 04, 05, 06, + * 07, 08, 09, 10, 11, 12, 13, + * 14, 15, 16, 17, 18, 19, + * 20, 21, 22, 23, 24, 25, 26, + * 27, 28, 29, 30, 31, + * 32, 33, + * 34, 35, 36, + * 37, 38, 39, + + * // right hand, spatial positions + * 40, 41, 42, 43, 44, 45, 46, + * 47, 48, 49, 50, 51, 52, 53, + * 54, 55, 56, 57, 58, 59, + * 60, 61, 62, 63, 64, 65, 66, + * 67, 68, 69, 70, 71, + * 72, 73, + * 74, 75, 76, + * 77, 78, 79, + * -------------------------------------------- + */ + + "physical-positions": [ // list of key-ids + "", "..." + ], + "matrix-positions": [ // list of key-ids + "", "..." + ], + "matrix-layout": [ + [ // begin layer + [ // begin key + "", // keycode + "", // press function name (ex: 'kbfun_...') + "" // release function name (ex: 'NULL') + ], + "..." // more keys + ], + "..." // more layers + ] + }, + "miscellaneous": { + "git-commit-date": "", // format: RFC 3339 + "git-commit-id": "", + "number-of-layers": "" + } +} +""")[1:-1] + +# ----------------------------------------------------------------------------- + +import argparse +import json +import os +import re +import subprocess +import sys + +# ----------------------------------------------------------------------------- + +def gen_static(current_date=None, git_commit_date=None, git_commit_id=None): + """Generate static information""" + + return { + '.meta-data': { + 'version': 0, # the format version number + 'date-generated': current_date, + 'description': _FORMAT_DESCRIPTION, + }, + 'miscellaneous': { + 'git-commit-date': git_commit_date, # should be passed by makefile + 'git-commit-id': git_commit_id, # should be passed by makefile + }, + } + +def gen_derived(data): + """ + Generate derived information + Should be called last + """ + return { + 'miscellaneous': { + 'number-of-layers': + int( data['layout-matrices']['_kb_layout']['length']/(6*14) ), + # because 6*14 is the number of bytes/layer for '_kb_layout' + # (which is a uint8_t matrix) + }, + } + +# ----------------------------------------------------------------------------- + +def parse_mapfile(map_file_path): + """Parse the '.map' file""" + + def parse_keyboard_function(f, line): + """Parse keyboard-functions in the '.map' file""" + + search = re.search(r'(0x\S+)\s+(0x\S+)', next(f)) + position = int( search.group(1), 16 ) + length = int( search.group(2), 16 ) + + search = re.search(r'0x\S+\s+(\S+)', next(f)) + name = search.group(1) + + return { + 'keyboard-functions': { + name: { + 'position': position, + 'length': length, + }, + }, + } + + def parse_layout_matrices(f, line): + """Parse layout matrix information in the '.map' file""" + + name = re.search(r'.progmem.data.(_kb_layout\S*)', line).group(1) + + search = re.search(r'(0x\S+)\s+(0x\S+)', next(f)) + position = int( search.group(1), 16 ) + length = int( search.group(2), 16 ) + + return { + 'layout-matrices': { + name: { + 'position': position, + 'length': length, + }, + }, + } + + # --- parse_mapfile() --- + + # normalize paths + map_file_path = os.path.abspath(map_file_path) + # check paths + if not os.path.exists(map_file_path): + raise ValueError("invalid 'map_file_path' given") + + output = {} + + f = open(map_file_path) + + for line in f: + if re.search(r'^\s*\.text\.kbfun_', line): + dict_merge(output, parse_keyboard_function(f, line)) + elif re.search(r'^\s*\.progmem\.data.*layout', line): + dict_merge(output, parse_layout_matrices(f, line)) + + return output + + +def find_keyboard_functions(source_code_path): + """Parse all files in the source directory""" + + def read_comments(f, line): + """ + Read in properly formatted multi-line comments + - Comments must start with '/*' and end with '*/', each on their own + line + """ + comments = '' + while(line.strip() != r'*/'): + comments += line[2:].strip()+'\n' + line = next(f) + return comments + + def parse_comments(comments): + """ + Parse an INI style comment string + - Fields begin with '[field-name]', and continue until the next field, + or the end of the comment + - Fields '[name]', '[description]', and '[note]' are treated specially + """ + + def add_field(output, field, value): + """Put a field+value pair in 'output', the way we want it, if the + pair is valid""" + + value = value.strip() + + if field is not None: + if field in ('name', 'description'): + if field not in output: + output[field] = value + else: + if field == 'note': + field = 'notes' + + if field not in output: + output[field] = [] + + output[field] += [value] + + # --- parse_comments() --- + + output = {} + + field = None + value = None + for line in comments.split('\n'): + line = line.strip() + + if re.search(r'^\[.*\]$', line): + add_field(output, field, value) + field = line[1:-1] + value = None + + else: + if value is None: + value = '' + if len(value) > 0 and value[-1] == '.': + line = ' '+line + value += ' '+line + + add_field(output, field, value) + + return output + + def parse_keyboard_function(f, line, comments): + """Parse keyboard-functions in the source code""" + + search = re.search(r'void\s+(kbfun_\S+)\s*\(void\)', line) + name = search.group(1) + + return { + 'keyboard-functions': { + name: { + 'comments': parse_comments(comments), + }, + }, + } + + # --- find_keyboard_functions() --- + + # normalize paths + source_code_path = os.path.abspath(source_code_path) + # check paths + if not os.path.exists(source_code_path): + raise ValueError("invalid 'source_code_path' given") + + output = {} + + for tup in os.walk(source_code_path): + for file_name in tup[2]: + # normalize paths + file_name = os.path.abspath( os.path.join( tup[0], file_name ) ) + + # ignore non '.c' files + if file_name[-2:] != '.c': + continue + + f = open(file_name) + + comments = '' + for line in f: + if line.strip() == r'/*': + comments = read_comments(f, line) + elif re.search(r'void\s+kbfun_\S+\s*\(void\)', line): + dict_merge( + output, + parse_keyboard_function(f, line, comments) ) + + return output + + +def gen_mappings(matrix_file_path, layout_file_path): + # normalize paths + matrix_file_path = os.path.abspath(matrix_file_path) + layout_file_path = os.path.abspath(layout_file_path) + + def parse_matrix_file(matrix_file_path): + match = re.search( # find the whole 'KB_MATRIX_LAYER' macro + r'#define\s+KB_MATRIX_LAYER\s*\(([^)]+)\)[^{]*\{\{([^#]+)\}\}', + open(matrix_file_path).read() ) + + return { + "mappings": { + "physical-positions": re.findall(r'k..', match.group(1)), + "matrix-positions": re.findall(r'k..|na', match.group(2)), + }, + } + + def parse_layout_file(layout_file_path): + match = re.findall( # find each whole '_kb_layout*' matrix definition + r'(_kb_layout\w*)[^=]*=((?:[^{}]*\{){3}[^=]*(?:[^{}]*\}){3})', + subprocess.getoutput("gcc -E '"+layout_file_path+"'") ) + + layout = {} + # collect all the values + for (name, matrix) in match: + layout[name] = [ + re.findall( # find all numbers and function pointers + r'[x0-9A-F]+|&\w+|NULL', + re.sub( # replace '((void *) 0)' with 'NULL' + r'\(\s*\(\s*void\s*\*\s*\)\s*0\s*\)', + 'NULL', + el ) ) + for el in + re.findall( # find each whole layer + r'(?:[^{}]*\{){2}((?:[^}]|\}\s*,)+)(?:[^{}]*\}){2}', + matrix ) ] + + # make the numbers into actual numbers + layout['_kb_layout'] = \ + [[eval(el) for el in layer] for layer in layout['_kb_layout']] + # remove the preceeding '&' from function pointers + for matrix in ('_kb_layout_press', '_kb_layout_release'): + layout[matrix] = \ + [ [re.sub(r'&', '', el) for el in layer] + for layer in layout[matrix] ] + + return { + "mappings": { + "matrix-layout": + # group them all properly + [ [[c, p, r] for (c, p, r) in zip(code, press, release)] + for (code, press, release) in + zip( layout['_kb_layout'], + layout['_kb_layout_press'], + layout['_kb_layout_release'] ) ] + }, + } + + return dict_merge( + parse_matrix_file(matrix_file_path), + parse_layout_file(layout_file_path) ) + + +# ----------------------------------------------------------------------------- + +def dict_merge(a, b): + """ + Recursively merge two dictionaries + - I was looking around for an easy way to do this, and found something + [here] + (http://www.xormedia.com/recursively-merge-dictionaries-in-python.html). + This is pretty close, but i didn't copy it exactly. + """ + + if not isinstance(a, dict) or not isinstance(b, dict): + return b + + for (key, value) in b.items(): + if key in a: + a[key] = dict_merge(a[key], value) + else: + a[key] = value + + return a + +# ----------------------------------------------------------------------------- + +def main(): + arg_parser = argparse.ArgumentParser( + description = 'Generate project data for use with the UI' ) + + arg_parser.add_argument( + '--current-date', + help = ( "should be in the format rfc-3339 " + + "(e.g. 2006-08-07 12:34:56-06:00)" ), + required = True ) + arg_parser.add_argument( + '--git-commit-date', + help = ( "should be in the format rfc-3339 " + + "(e.g. 2006-08-07 12:34:56-06:00)" ), + required = True ) + arg_parser.add_argument( + '--git-commit-id', + help = "the git commit ID", + required = True ) + arg_parser.add_argument( + '--map-file-path', + help = "the path to the '.map' file", + required = True ) + arg_parser.add_argument( + '--source-code-path', + help = "the path to the source code directory", + required = True ) + arg_parser.add_argument( + '--matrix-file-path', + help = "the path to the matrix file we're using", + required = True ) + arg_parser.add_argument( + '--layout-file-path', + help = "the path to the layout file we're using", + required = True ) + + args = arg_parser.parse_args(sys.argv[1:]) + + output = {} + dict_merge( output, gen_static( args.current_date, + args.git_commit_date, + args.git_commit_id ) ) + dict_merge(output, parse_mapfile(args.map_file_path)) + dict_merge(output, find_keyboard_functions(args.source_code_path)) + dict_merge(output, gen_mappings( args.matrix_file_path, + args.layout_file_path )) + dict_merge(output, gen_derived(output)) + + print(json.dumps(output, sort_keys=True, indent=4)) + +# ----------------------------------------------------------------------------- + +if __name__ == '__main__': + main() + diff --git a/build-scripts/gen_layout/template.js b/build-scripts/gen_layout/template.js new file mode 100644 index 0000000..c3690d0 --- /dev/null +++ b/build-scripts/gen_layout/template.js @@ -0,0 +1,3 @@ +function keyclick(position, layer) { +} + diff --git a/build-scripts/gen_layout/template.svg b/build-scripts/gen_layout/template.svg new file mode 100644 index 0000000..373da08 --- /dev/null +++ b/build-scripts/gen_layout/template.svg @@ -0,0 +1,2109 @@ + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + k57 + k58 + k59 + k5A + k5B + k5C + k5D + k4D + k3D + k2D + k4C + k3C + k2C + k1C + k1D + k4B + k3B + k2B + k1B + k4A + k3A + k2A + k1A + k49 + k39 + k29 + k19 + k48 + k38 + k28 + k47 + k27 + k08 + k07 + k09 + k0C + k56 + k55 + k54 + k52 + k51 + k40 + k30 + k20 + k41 + k31 + k21 + k11 + k10 + k42 + k32 + k22 + k12 + k43 + k33 + k23 + k13 + k44 + k34 + k24 + k14 + k45 + k35 + k25 + k46 + k26 + k05 + k06 + k04 + k01 + k50 + k53 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + k0B + k0A + k02 + k03 + + + + + + + + + + diff --git a/license.md b/license.md index 1a7307e..32f28cf 100644 --- a/license.md +++ b/license.md @@ -1,9 +1,13 @@ # The MIT License (MIT) -Taken from on 2012-03-10 +Retrieved from on 2012-03-10 + +This copyright and licence apply to all files in this project, except where +otherwise noted. If you feel that this infringes on any existing intellectual +property, please email me at the address below. ------------------------------------------------------------------------------- -Copyright © 2012 Ben Blazak +Copyright © 2012 Ben Blazak Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/makefile b/makefile index 2d03791..24612e7 100644 --- a/makefile +++ b/makefile @@ -4,9 +4,10 @@ # This should produce a single file (probably in an archive format) for # distribution, containing everything people will need to use the software. # -# DEPENDENCIES: This is unabashedly dependant on various Unix commands, and -# therefore probably won't work in a Windows environment. I'm sorry... I -# don't know a good portable way to write it. +# DEPENDENCIES: This is unabashedly dependant on (the GNU implementation of) +# various Unix commands, and therefore probably won't work in a Windows +# environment (besides maybe cygwin). Sorry... I don't know a good portable +# way to write it. # # TODO: # - include doc files (and maybe render them in html) @@ -18,23 +19,35 @@ # ----------------------------------------------------------------------------- -# the base name of the file or package to distribute -NAME := ergodox-firmware -# the branch of the git repo we're currently on -BRANCH := $(shell git branch -l | grep '*' | cut -c 3-) -# a version identifier -VERSION := $(shell git log -n 1 | grep 'commit' | cut -c 8-14)--$(shell date +'%Y%m%dT%H%M%S') +include src/makefile-options + +# system specific stuff +UNAME := $(shell uname) +ifeq ($(UNAME),Darwin) + DATE_PROG := gdate +else + DATE_PROG := date +endif + +CURRENT_DATE := $(shell $(DATE_PROG) --rfc-3339 s) + +# git info +GIT_BRANCH := $(shell git branch -l | grep '*' | cut -c 3-) +GIT_COMMIT_DATE := $(shell git log -n 1 --pretty --date=iso | grep 'Date' | cut -c 9- ) +GIT_COMMIT_ID := $(shell git log -n 1 | grep 'commit' | cut -c 8-) # name to use for the final distribution file or package -TARGET := $(NAME)--$(BRANCH)--$(VERSION) +TARGET := ergodox-firmware--$(GIT_BRANCH)--$(shell $(DATE_PROG) -d "$(GIT_COMMIT_DATE)" +'%Y%m%dT%H%M%S')--$(shell echo $(GIT_COMMIT_ID) | cut -c 1-7) -# the build dir +# directories BUILD := build +ROOT := $(BUILD)/$(TARGET) +SCRIPTS := build-scripts # ----------------------------------------------------------------------------- # ----------------------------------------------------------------------------- -.PHONY: all clean dist +.PHONY: all clean checkin build-dir firmware dist zip all: dist @@ -42,18 +55,51 @@ clean: git clean -dX # remove ignored files and directories -rm -r '$(BUILD)' -dist: - # set up the build dir +checkin: + -git commit -a + +build-dir: -rm -r '$(BUILD)/$(TARGET)'* -mkdir -p '$(BUILD)/$(TARGET)' - # make all subprojects + +firmware: cd src; $(MAKE) all - # copy stuff to build dir - # --- from src - ( cd src; \ - cp firmware.hex firmware.eep firmware.map \ - '../$(BUILD)/$(TARGET)' ) - # make into a zip archive + +$(ROOT)/firmware.%: firmware + cp 'src/firmware.$*' '$@' + + +$(ROOT)/firmware--ui-info.json: $(SCRIPTS)/gen-ui-info.py checkin + ( ./'$<' \ + --current-date '$(shell $(DATE_PROG) --rfc-3339 s)' \ + --git-commit-date '$(GIT_COMMIT_DATE)' \ + --git-commit-id '$(GIT_COMMIT_ID)' \ + --map-file-path '$(BUILD)/$(TARGET)/firmware.map' \ + --source-code-path 'src' \ + --matrix-file-path 'src/keyboard/$(KEYBOARD)/matrix.h' \ + --layout-file-path \ + 'src/keyboard/$(KEYBOARD)/layout/$(LAYOUT).c' \ + ) > '$@' + +$(ROOT)/firmware--layout.html: \ + $(SCRIPTS)/gen-layout.py \ + $(ROOT)/firmware--ui-info.json + \ + ( ./'$<' \ + --ui-info-file '$(ROOT)/firmware--ui-info.json' \ + ) > '$@' + + +dist: \ + checkin \ + build-dir \ + $(ROOT)/firmware.hex \ + $(ROOT)/firmware.eep \ + $(ROOT)/firmware.map \ + $(ROOT)/firmware--ui-info.json \ + $(ROOT)/firmware--layout.html + +zip: dist ( cd '$(BUILD)/$(TARGET)'; \ zip '../$(TARGET).zip' \ -r * .* \ diff --git a/readme.md b/readme.md index 730b885..9404d59 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,13 @@ -# [ergodox-firmware][]: Firmware for the [ergoDOX keyboard][] +# [ergodox-firmware][]: Firmware for the [ErgoDox keyboard][] + +Also see the [geekhack] +(http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard) +and [deskthority] +(http://deskthority.net/workshop-f7/split-ergonomic-keyboard-project-t1753.html) +discussion threads. [ergodox-firmware]: https://github.com/benblazak/ergodox-firmware -[ergodox keyboard]: http://geekhack.org/showthread.php?22780-Interest-Check-Custom-split-ergo-keyboard +[ergodox keyboard]: http://ergodox.org/ ## About this File @@ -40,38 +46,17 @@ started this project), but for now: matrix to hardware matrix mapping, and hardware specific documentation. * [src/main.c] (src/main.c) ties it all together. -Open issues and such are tracked [on github] +Open issues, feature requests, and such are tracked [on github] (/benblazak/ergodox-firmware/issues). ## Notes -### (2012-04-11) (first major release on branch 'main') -As of now, it looks like we have a working 6-KRO keyboard firmware for a Teensy -2.0 with a MCP23018 I/O expander. It's scanning at ~167 Hz, most of which is -spent communicating over I²C. This should be fast enough, I think. -Slight improvements might be possible (without finding a microprocessor capable -of > 400 kHz I²C or using SPI, that is, which I imagine would speed things -up a lot - but it'd also be much less convenient). I'll attempt them if I see -the need. - -Also, layers are implemented, but untested, as no keymaps are written to use -them yet. Implementing on-keyboard hardware remapping seems like it'd be very -possible too, but I'd need to try it (and learn how to programmatically store -stuff in program space) to see if it'd work; and I'm not sure of a good way to -do the interface, since different people will likely have different keycap -layouts on the ergoDOX. - -Getting to N-KRO is a goal, but I honestly have no idea whether it'll be -accomplished. Ideally, I'd like a variable-KRO, where the keyboard is 6-KRO -till you press the 7th key (so if you're worried about compatibility, just -don't press more than 6 keys at a time). From what I've read, it might be -possible, but I just finished everything else (so I'm slightly tired), and the -USB spec is scary. - -Discussions about the project as a whole are going on at the forum page (linked -in the title) so if you have any imput (or want to participate in the group -buy!), please stop by. :) . +### Features as of 2012-04-11 : first major release on branch 'main' +* 6KRO +* Teensy 2.0, MCP23018 I/O expander +* ~167 Hz scan rate (most of which is spent communicating via I²C) +* firmware level layers ## Dependencies (for building from source) diff --git a/references.md b/references.md index c8c3bdb..af504f3 100644 --- a/references.md +++ b/references.md @@ -21,7 +21,7 @@ : column by Kevin Ross for Encoder Includes a short thing about pull-up resistors. -* [Powering Light Emitting Diodes(LEDs)] +* [Powering Light Emitting Diodes (LEDs)] (http://wolfstone.halloweenhost.com/Lighting/litlpo_PoweringLEDs.html) Can you use one resistor for multiple parallel LEDs? No. Or, you can, but it's not the best idea. @@ -35,6 +35,11 @@ -> [powering LEDs] (http://wolfstone.halloweenhost.com/Lighting/litlpo_PoweringLEDs.html) +* [Notes on LEDs] + (http://www.gizmology.net/LEDs.htm) + Talks about different types of LEDs, mentioning typical brightnesses, + voltages, and other intersting stuff. + * [All About Circuits : Reference] (http://www.allaboutcircuits.com/vol_5/index.html) Looks like a great collection of info; didn't get to read much of it. diff --git a/src/keyboard.h b/src/keyboard.h deleted file mode 100644 index 6a472b4..0000000 --- a/src/keyboard.h +++ /dev/null @@ -1,22 +0,0 @@ -/* ---------------------------------------------------------------------------- - * keyboard specific exports - * - * Different keyboards are included by modifying a variable in the makefile. - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#undef _str -#undef _expstr -#undef _inc -#define _str(s) #s // stringify -#define _expstr(s) _str(s) // expand -> stringify -#define _inc _expstr(keyboard/MAKEFILE_KEYBOARD.h) // inc(lude) -#include _inc -#undef _str -#undef _expstr -#undef _inc - diff --git a/src/keyboard/ergodox/teensy-2-0--private.h b/src/keyboard/controller.h similarity index 63% rename from src/keyboard/ergodox/teensy-2-0--private.h rename to src/keyboard/controller.h index 231e608..af2d4bb 100644 --- a/src/keyboard/ergodox/teensy-2-0--private.h +++ b/src/keyboard/controller.h @@ -1,5 +1,8 @@ /* ---------------------------------------------------------------------------- - * ergoDOX controller: Teensy 2.0 specific exports : private + * controller specific exports + * + * Files for different keyboards are used by modifying a variable in the + * Makefile * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,13 +10,7 @@ * ------------------------------------------------------------------------- */ -#ifndef TEENSY_2_0_h_PRIVATE - #define TEENSY_2_0_h_PRIVATE - - #include "matrix.h" - - uint8_t teensy_init(void); - uint8_t teensy_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] ); - -#endif +#include "../lib/variable-include.h" +#define INCLUDE EXP_STR( ./MAKEFILE_KEYBOARD/controller.h ) +#include INCLUDE diff --git a/src/keyboard/ergodox.h b/src/keyboard/ergodox.h deleted file mode 100644 index 00ba51e..0000000 --- a/src/keyboard/ergodox.h +++ /dev/null @@ -1,36 +0,0 @@ -/* ---------------------------------------------------------------------------- - * ergoDOX specific exports - * includes (for centralization) the public exports from all subfiles - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#ifndef ERGODOX_h - #define ERGODOX_h - - #include "lib/data-types.h" - - #include "ergodox/layout.h" // number of layers, layout - #include "ergodox/led.h" // logical led controls - #include "ergodox/matrix.h" // kb dimensions, matrix status - #include "ergodox/teensy-2-0.h" // LED controls - - - // note: - // - see your keyswitch specification for the necessary value. for - // cherry mx switches, the switch bounce time is speced to be <= 5ms. - // it looks like most switches are speced to be between 5 and 8 ms. - // - if timing is important, balance this value with the main() loop - // run time (~5ms, last i checked, nearly all of it in the i2c - // update() function) - #define KB_DEBOUNCE_TIME 5 // in ms - - - uint8_t kb_init(void); - uint8_t kb_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]); - -#endif - diff --git a/src/keyboard/ergodox/circuit-diagram.svg b/src/keyboard/ergodox/circuit-diagram.svg index da586fb..d6709d1 100644 --- a/src/keyboard/ergodox/circuit-diagram.svg +++ b/src/keyboard/ergodox/circuit-diagram.svg @@ -26,31 +26,33 @@ inkscape:pageopacity="1" inkscape:pageshadow="2" inkscape:zoom="1.4142136" - inkscape:cx="464.65225" - inkscape:cy="203.44926" + inkscape:cx="455.81585" + inkscape:cy="210.83562" inkscape:document-units="px" inkscape:current-layer="layer7" showgrid="true" inkscape:snap-global="false" - inkscape:snap-bbox="false" + inkscape:snap-bbox="true" inkscape:snap-nodes="false" - inkscape:bbox-nodes="false" + inkscape:bbox-nodes="true" inkscape:snap-bbox-edge-midpoints="false" inkscape:bbox-paths="false" - inkscape:window-width="1920" - inkscape:window-height="997" + inkscape:window-width="1440" + inkscape:window-height="852" inkscape:window-x="0" - inkscape:window-y="30" + inkscape:window-y="0" inkscape:window-maximized="1" - inkscape:snap-bbox-midpoints="false" + inkscape:snap-bbox-midpoints="true" showguides="true" inkscape:guide-bbox="true" - inkscape:object-nodes="true" + inkscape:object-nodes="false" fit-margin-top="15" fit-margin-left="15" fit-margin-bottom="15" fit-margin-right="15" - inkscape:snap-page="true"> + inkscape:snap-page="true" + inkscape:snap-object-midpoints="false" + inkscape:snap-center="true"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1696,7 +1838,7 @@ inkscape:connector-curvature="0" /> @@ -1768,7 +1910,7 @@ @@ -1840,7 +1982,7 @@ @@ -1924,22 +2066,22 @@ sodipodi:nodetypes="ccccccccccccc" /> + sodipodi:nodetypes="ccscccc" /> R = 220 Ω + x="429.96448" + y="346.10483">R = (match to LEDs) PWM PWM PWM row 0 + id="tspan12234">row 5 row 1 + id="tspan12238">row 4 row 2 + id="tspan12240">row 3 row 3 + id="tspan12242">row 2 row 4 + id="tspan12244">row 1 row 5 - col 0 + id="tspan12248">row 0 col 1 - col 2 + id="tspan12254">col D col 3 + id="tspan12258">col B col 4 - col 5 + id="tspan12260">col C col 6 + id="tspan12264">col 7 col 0 + id="tspan12264-1">row 5 col 1 + x="-334.98328" + y="559.83008">row 4 col 2 + x="-334.88953" + y="579.83008">row 3 col 3 + x="-335.12976" + y="599.83008">row 2 col 4 + x="-335.41687" + y="619.83008">row 1 col 5 - col 6 + x="-335.04187" + y="639.83008">row 0 row B + x="-112.33308" + y="558.26935" + id="tspan12234-5">col 5 row A + x="-113.42294" + y="578.09943">col 4 row 9 + x="-113.42294" + y="598.09943">col 3 row 8 + x="-113.42294" + y="618.09943">col 2 row 7 + x="-113.42294" + y="638.09943">col 1 row 6 + x="-112.33308" + y="658.26935">col 0 - - - - - Row and column assignments are to matrix positions, not physical positions + id="tspan3450">- Row and column assignments are to matrix positions, not physical positions + + col 6 + + col 8 + + col 9 + + col A + + * Released under The MIT License (MIT) (see "license.md") @@ -7,12 +7,13 @@ * ------------------------------------------------------------------------- */ -#include "lib/data-types.h" - -#include "ergodox/matrix.h" -#include "ergodox/mcp23018--private.h" -#include "ergodox/teensy-2-0--private.h" +#include +#include +#include "./matrix.h" +#include "./controller/mcp23018--functions.h" +#include "./controller/teensy-2-0--functions.h" +// ---------------------------------------------------------------------------- /* returns * - success: 0 diff --git a/src/keyboard/ergodox/controller.h b/src/keyboard/ergodox/controller.h new file mode 100644 index 0000000..5eb9eb7 --- /dev/null +++ b/src/keyboard/ergodox/controller.h @@ -0,0 +1,27 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX : controller specific exports + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef KEYBOARD__ERGODOX__CONTROLLER_h + #define KEYBOARD__ERGODOX__CONTROLLER_h + + #include + #include + #include "./matrix.h" + + // -------------------------------------------------------------------- + + #include "./controller/teensy-2-0--led.h" + + // -------------------------------------------------------------------- + + uint8_t kb_init(void); + uint8_t kb_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]); + +#endif + diff --git a/src/keyboard/ergodox/mcp23018--private.h b/src/keyboard/ergodox/controller/mcp23018--functions.h similarity index 59% rename from src/keyboard/ergodox/mcp23018--private.h rename to src/keyboard/ergodox/controller/mcp23018--functions.h index a48b9b4..f3e934f 100644 --- a/src/keyboard/ergodox/mcp23018--private.h +++ b/src/keyboard/ergodox/controller/mcp23018--functions.h @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX controller: MCP23018 specific exports : private + * ergoDOX : controller : MCP23018 specific exports : functions * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,14 +7,19 @@ * ------------------------------------------------------------------------- */ -#ifndef MCP23018_h_PRIVATE - #define MCP23018_h_PRIVATE +#ifndef KEYBOARD__ERGODOX__CONTROLLER__MCP23018__FUNCTIONS_h + #define KEYBOARD__ERGODOX__CONTROLLER__MCP23018__FUNCTIONS_h - #include "lib/data-types.h" - #include "matrix.h" + #include + #include + #include "../matrix.h" + + // -------------------------------------------------------------------- #define MCP23018_TWI_ADDRESS 0b0100000 + // -------------------------------------------------------------------- + uint8_t mcp23018_init(void); uint8_t mcp23018_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] ); diff --git a/src/keyboard/ergodox/controller/mcp23018.c b/src/keyboard/ergodox/controller/mcp23018.c new file mode 100644 index 0000000..61429f8 --- /dev/null +++ b/src/keyboard/ergodox/controller/mcp23018.c @@ -0,0 +1,206 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX : controller: MCP23018 specific code + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include +#include +#include +#include "../../../lib/twi.h" // `TWI_FREQ` defined in "teensy-2-0.c" +#include "../options.h" +#include "../matrix.h" +#include "./mcp23018--functions.h" + +// ---------------------------------------------------------------------------- + +// check options +#if (MCP23018__DRIVE_ROWS && MCP23018__DRIVE_COLUMNS) \ + || !(MCP23018__DRIVE_ROWS || MCP23018__DRIVE_COLUMNS) + #error "See 'Pin drive direction' in 'options.h'" +#endif + +// ---------------------------------------------------------------------------- + +// register addresses (see "mcp23018.md") +#define IODIRA 0x00 // i/o direction register +#define IODIRB 0x01 +#define GPPUA 0x0C // GPIO pull-up resistor register +#define GPPUB 0x0D +#define GPIOA 0x12 // general purpose i/o port register (write modifies OLAT) +#define GPIOB 0x13 +#define OLATA 0x14 // output latch register +#define OLATB 0x15 + +// TWI aliases +#define TWI_ADDR_WRITE ( (MCP23018_TWI_ADDRESS<<1) | TW_WRITE ) +#define TWI_ADDR_READ ( (MCP23018_TWI_ADDRESS<<1) | TW_READ ) + +// ---------------------------------------------------------------------------- + +/* returns: + * - success: 0 + * - failure: twi status code + * + * notes: + * - `twi_stop()` must be called *exactly once* for each twi block, the way + * things are currently set up. this may change in the future. + */ +uint8_t mcp23018_init(void) { + uint8_t ret; + + // set pin direction + // - unused : input : 1 + // - input : input : 1 + // - driving : output : 0 + twi_start(); + ret = twi_send(TWI_ADDR_WRITE); + if (ret) goto out; // make sure we got an ACK + twi_send(IODIRA); + #if MCP23018__DRIVE_ROWS + twi_send(0b11111111); // IODIRA + twi_send(0b11000000); // IODIRB + #elif MCP23018__DRIVE_COLUMNS + twi_send(0b10000000); // IODIRA + twi_send(0b11111111); // IODIRB + #endif + twi_stop(); + + // set pull-up + // - unused : on : 1 + // - input : on : 1 + // - driving : off : 0 + twi_start(); + ret = twi_send(TWI_ADDR_WRITE); + if (ret) goto out; // make sure we got an ACK + twi_send(GPPUA); + #if MCP23018__DRIVE_ROWS + twi_send(0b11111111); // GPPUA + twi_send(0b11000000); // GPPUB + #elif MCP23018__DRIVE_COLUMNS + twi_send(0b10000000); // GPPUA + twi_send(0b11111111); // GPPUB + #endif + twi_stop(); + + // set logical value (doesn't matter on inputs) + // - unused : hi-Z : 1 + // - input : hi-Z : 1 + // - driving : hi-Z : 1 + twi_start(); + ret = twi_send(TWI_ADDR_WRITE); + if (ret) goto out; // make sure we got an ACK + twi_send(OLATA); + twi_send(0b11111111); //OLATA + twi_send(0b11111111); //OLATB + +out: + twi_stop(); + return ret; +} + +/* returns: + * - success: 0 + * - failure: twi status code + */ +#if KB_ROWS != 6 || KB_COLUMNS != 14 + #error "Expecting different keyboard dimensions" +#endif +uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { + uint8_t ret, data; + + // initialize things, just to make sure + // - it's not appreciably faster to skip this, and it takes care of the + // case when the i/o expander isn't plugged in during the first + // init() + ret = mcp23018_init(); + + // if there was an error + if (ret) { + // clear our part of the matrix + for (uint8_t row=0; row<=5; row++) + for (uint8_t col=0; col<=6; col++) + matrix[row][col] = 0; + + return ret; + } + + + // -------------------------------------------------------------------- + // update our part of the matrix + + #if MCP23018__DRIVE_ROWS + for (uint8_t row=0; row<=5; row++) { + // set active row low : 0 + // set other rows hi-Z : 1 + twi_start(); + twi_send(TWI_ADDR_WRITE); + twi_send(GPIOB); + twi_send( 0xFF & ~(1<<(5-row)) ); + twi_stop(); + + // read column data + twi_start(); + twi_send(TWI_ADDR_WRITE); + twi_send(GPIOA); + twi_start(); + twi_send(TWI_ADDR_READ); + twi_read(&data); + twi_stop(); + + // update matrix + for (uint8_t col=0; col<=6; col++) { + matrix[row][col] = !( data & (1<) set as + hi-Z without pull-ups, and the other set of pins set as input with + pull-ups. During the update function, we'll cycle through setting the + first set low and checking each pin in the second set. * abbreviations: * IODIR = I/O Direction Register diff --git a/src/keyboard/ergodox/controller/teensy-2-0--functions.h b/src/keyboard/ergodox/controller/teensy-2-0--functions.h new file mode 100644 index 0000000..341b4bf --- /dev/null +++ b/src/keyboard/ergodox/controller/teensy-2-0--functions.h @@ -0,0 +1,23 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX : controller : Teensy 2.0 specific exports : functions + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef KEYBOARD__ERGODOX__CONTROLLER__TEENSY_2_0__FUNCTIONS_h + #define KEYBOARD__ERGODOX__CONTROLLER__TEENSY_2_0__FUNCTIONS_h + + #include + #include + #include "../matrix.h" + + // -------------------------------------------------------------------- + + uint8_t teensy_init(void); + uint8_t teensy_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] ); + +#endif + diff --git a/src/keyboard/ergodox/teensy-2-0.h b/src/keyboard/ergodox/controller/teensy-2-0--led.h similarity index 51% rename from src/keyboard/ergodox/teensy-2-0.h rename to src/keyboard/ergodox/controller/teensy-2-0--led.h index 65fa67d..3718873 100644 --- a/src/keyboard/ergodox/teensy-2-0.h +++ b/src/keyboard/ergodox/controller/teensy-2-0--led.h @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX controller: Teensy 2.0 specific exports + * ergoDOX : controller : Teensy 2.0 specific exports : LED control * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,48 +7,52 @@ * ------------------------------------------------------------------------- */ -#ifndef TEENSY_2_0_h - #define TEENSY_2_0_h +#ifndef KEYBOARD__ERGODOX__CONTROLLER__TEENSY_2_0__LED_h + #define KEYBOARD__ERGODOX__CONTROLLER__TEENSY_2_0__LED_h + #include #include // for the register macros - #include "lib/data-types.h" + // -------------------------------------------------------------------- + + #define _kb_led_1_on() (DDRB |= (1<<5)) + #define _kb_led_1_off() (DDRB &= ~(1<<5)) + #define _kb_led_1_set(n) (OCR1A = (uint8_t)(n)) + #define _kb_led_1_set_percent(n) (OCR1A = (uint8_t)((n) * 0xFF)) + + #define _kb_led_2_on() (DDRB |= (1<<6)) + #define _kb_led_2_off() (DDRB &= ~(1<<6)) + #define _kb_led_2_set(n) (OCR1B = (uint8_t)(n)) + #define _kb_led_2_set_percent(n) (OCR1B = (uint8_t)((n) * 0xFF)) - // LED control - #define _kb_led_1_on() (DDRB |= (1<<6)) - #define _kb_led_1_off() (DDRB &= ~(1<<6)) - #define _kb_led_1_set(n) (OCR1B = (uint8_t)(n)) - #define _kb_led_1_set_percent(n) (OCR1B = (uint8_t)((n) * 0xFF)) - // - #define _kb_led_2_on() (DDRB |= (1<<5)) - #define _kb_led_2_off() (DDRB &= ~(1<<5)) - #define _kb_led_2_set(n) (OCR1A = (uint8_t)(n)) - #define _kb_led_2_set_percent(n) (OCR1A = (uint8_t)((n) * 0xFF)) - // #define _kb_led_3_on() (DDRB |= (1<<7)) #define _kb_led_3_off() (DDRB &= ~(1<<7)) #define _kb_led_3_set(n) (OCR1C = (uint8_t)(n)) #define _kb_led_3_set_percent(n) (OCR1C = (uint8_t)((n) * 0xFF)) - // --- + + #define _kb_led_all_on() do { \ _kb_led_1_on(); \ _kb_led_2_on(); \ _kb_led_3_on(); \ } while(0) + #define _kb_led_all_off() do { \ - _kb_led_1_off(); \ - _kb_led_2_off(); \ - _kb_led_3_off(); \ + _kb_led_1_off(); \ + _kb_led_2_off(); \ + _kb_led_3_off(); \ } while(0) + #define _kb_led_all_set(n) do { \ - _kb_led_1_set(n); \ - _kb_led_2_set(n); \ - _kb_led_3_set(n); \ + _kb_led_1_set(n); \ + _kb_led_2_set(n); \ + _kb_led_3_set(n); \ } while(0) + #define _kb_led_all_set_percent(n) do { \ - _kb_led_1_set_percent(n); \ - _kb_led_2_set_percent(n); \ - _kb_led_3_set_percent(n); \ + _kb_led_1_set_percent(n); \ + _kb_led_2_set_percent(n); \ + _kb_led_3_set_percent(n); \ } while(0) #endif diff --git a/src/keyboard/ergodox/controller/teensy-2-0.c b/src/keyboard/ergodox/controller/teensy-2-0.c new file mode 100644 index 0000000..8b20fa4 --- /dev/null +++ b/src/keyboard/ergodox/controller/teensy-2-0.c @@ -0,0 +1,234 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX : controller: Teensy 2.0 specific code + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +// for "lib/twi.h" +#define TWI_FREQ 400000 + +#include +#include +#include +#include +#include "../../../lib/twi.h" +#include "../options.h" +#include "../matrix.h" +#include "./teensy-2-0--functions.h" +#include "./teensy-2-0--led.h" + +// ---------------------------------------------------------------------------- + +// check options +#if (TEENSY__DRIVE_ROWS && TEENSY__DRIVE_COLUMNS) \ + || !(TEENSY__DRIVE_ROWS || TEENSY__DRIVE_COLUMNS) + #error "See 'Pin drive direction' in 'options.h'" +#endif +// ---------------------------------------------------------------------------- + +// processor frequency (from ) +#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) +#define CPU_16MHz 0x00 +#define CPU_8MHz 0x01 +#define CPU_4MHz 0x02 +#define CPU_2MHz 0x03 +#define CPU_1MHz 0x04 +#define CPU_500kHz 0x05 +#define CPU_250kHz 0x06 +#define CPU_125kHz 0x07 +#define CPU_62kHz 0x08 + + +/* + * pin macros + * - note: you can move the `UNUSED`, `ROW`, and `COLUMN` pins around, but be + * sure to keep the set of all the pins listed constant. other pins are not + * movable, and either are referenced explicitly or have macros defined for + * them elsewhere. + * - note: if you change pin assignments, please be sure to update + * "teensy-2-0.md", and the '.svg' circuit diagram. + */ + +// --- unused +#define UNUSED_0 C, 7 +#define UNUSED_1 D, 7 +#define UNUSED_2 D, 4 // hard to use with breadboard (on the end) +#define UNUSED_3 D, 5 // hard to use with breadboard (on the end) +#define UNUSED_4 E, 6 // hard to use with breadboard (internal) + +// --- rows +#define ROW_0 F, 7 +#define ROW_1 F, 6 +#define ROW_2 F, 5 +#define ROW_3 F, 4 +#define ROW_4 F, 1 +#define ROW_5 F, 0 + +// --- columns +#define COLUMN_7 B, 0 +#define COLUMN_8 B, 1 +#define COLUMN_9 B, 2 +#define COLUMN_A B, 3 +#define COLUMN_B D, 2 +#define COLUMN_C D, 3 +#define COLUMN_D C, 6 + +// --- helpers +#define SET |= +#define CLEAR &=~ + +#define _teensypin_write(register, operation, pin_letter, pin_number) \ + do { \ + ((register##pin_letter) operation (1<<(pin_number))); \ + _delay_us(1); /* allow pins time to stabilize */ \ + } while(0) +#define teensypin_write(register, operation, pin) \ + _teensypin_write(register, operation, pin) + +#define _teensypin_read(pin_letter, pin_number) \ + ((PIN##pin_letter) & (1<<(pin_number))) +#define teensypin_read(pin) \ + _teensypin_read(pin) + +#define teensypin_write_all_unused(register, operation) \ + do { \ + teensypin_write(register, operation, UNUSED_0); \ + teensypin_write(register, operation, UNUSED_1); \ + teensypin_write(register, operation, UNUSED_2); \ + teensypin_write(register, operation, UNUSED_3); \ + teensypin_write(register, operation, UNUSED_4); } \ + while(0) + +#define teensypin_write_all_row(register, operation) \ + do { \ + teensypin_write(register, operation, ROW_0); \ + teensypin_write(register, operation, ROW_1); \ + teensypin_write(register, operation, ROW_2); \ + teensypin_write(register, operation, ROW_3); \ + teensypin_write(register, operation, ROW_4); \ + teensypin_write(register, operation, ROW_5); } \ + while(0) + +#define teensypin_write_all_column(register, operation) \ + do { \ + teensypin_write(register, operation, COLUMN_7); \ + teensypin_write(register, operation, COLUMN_8); \ + teensypin_write(register, operation, COLUMN_9); \ + teensypin_write(register, operation, COLUMN_A); \ + teensypin_write(register, operation, COLUMN_B); \ + teensypin_write(register, operation, COLUMN_C); \ + teensypin_write(register, operation, COLUMN_D); } \ + while(0) + + +/* + * update macros + */ +#define update_rows_for_column(matrix, column) \ + do { \ + /* set column low (set as output) */ \ + teensypin_write(DDR, SET, COLUMN_##column); \ + /* read rows 0..5 and update matrix */ \ + matrix[0x0][0x##column] = ! teensypin_read(ROW_0); \ + matrix[0x1][0x##column] = ! teensypin_read(ROW_1); \ + matrix[0x2][0x##column] = ! teensypin_read(ROW_2); \ + matrix[0x3][0x##column] = ! teensypin_read(ROW_3); \ + matrix[0x4][0x##column] = ! teensypin_read(ROW_4); \ + matrix[0x5][0x##column] = ! teensypin_read(ROW_5); \ + /* set column hi-Z (set as input) */ \ + teensypin_write(DDR, CLEAR, COLUMN_##column); \ + } while(0) + +#define update_columns_for_row(matrix, row) \ + do { \ + /* set row low (set as output) */ \ + teensypin_write(DDR, SET, ROW_##row); \ + /* read columns 7..D and update matrix */ \ + matrix[0x##row][0x7] = ! teensypin_read(COLUMN_7); \ + matrix[0x##row][0x8] = ! teensypin_read(COLUMN_8); \ + matrix[0x##row][0x9] = ! teensypin_read(COLUMN_9); \ + matrix[0x##row][0xA] = ! teensypin_read(COLUMN_A); \ + matrix[0x##row][0xB] = ! teensypin_read(COLUMN_B); \ + matrix[0x##row][0xC] = ! teensypin_read(COLUMN_C); \ + matrix[0x##row][0xD] = ! teensypin_read(COLUMN_D); \ + /* set row hi-Z (set as input) */ \ + teensypin_write(DDR, CLEAR, ROW_##row); \ + } while(0) + +// ---------------------------------------------------------------------------- + +/* returns + * - success: 0 + */ +uint8_t teensy_init(void) { + // CPU speed : should match F_CPU in makefile + #if F_CPU != 16000000 + #error "Expecting different CPU frequency" + #endif + CPU_PRESCALE(CPU_16MHz); + + // onboard LED + // (tied to GND for hardware convenience) + DDRD &= ~(1<<6); // set D(6) as input + PORTD &= ~(1<<6); // set D(6) internal pull-up disabled + + // (tied to Vcc for hardware convenience) + DDRB &= ~(1<<4); // set B(4) as input + PORTB &= ~(1<<4); // set B(4) internal pull-up disabled + + // keyboard LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md") + _kb_led_all_off(); // (just to put the pins in a known state) + TCCR1A = 0b10101001; // set and configure fast PWM + TCCR1B = 0b00001001; // set and configure fast PWM + + // I2C (TWI) + twi_init(); // on pins D(1,0) + + // unused pins + teensypin_write_all_unused(DDR, CLEAR); // set as input + teensypin_write_all_unused(PORT, SET); // set internal pull-up enabled + + // rows and columns + teensypin_write_all_row(DDR, CLEAR); // set as input (hi-Z) + teensypin_write_all_column(DDR, CLEAR); // set as input (hi-Z) + #if TEENSY__DRIVE_ROWS + teensypin_write_all_row(PORT, CLEAR); // pull-up disabled + teensypin_write_all_column(PORT, SET); // pull-up enabled + #elif TEENSY__DRIVE_COLUMNS + teensypin_write_all_row(PORT, SET); // pull-up enabled + teensypin_write_all_column(PORT, CLEAR); // pull-up disabled + #endif + + return 0; // success +} + +/* returns + * - success: 0 + */ +#if KB_ROWS != 6 || KB_COLUMNS != 14 + #error "Expecting different keyboard dimensions" +#endif + +uint8_t teensy_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { + #if TEENSY__DRIVE_ROWS + update_columns_for_row(matrix, 0); + update_columns_for_row(matrix, 1); + update_columns_for_row(matrix, 2); + update_columns_for_row(matrix, 3); + update_columns_for_row(matrix, 4); + update_columns_for_row(matrix, 5); + #elif TEENSY__DRIVE_COLUMNS + update_rows_for_column(matrix, 7); + update_rows_for_column(matrix, 8); + update_rows_for_column(matrix, 9); + update_rows_for_column(matrix, A); + update_rows_for_column(matrix, B); + update_rows_for_column(matrix, C); + update_rows_for_column(matrix, D); + #endif + + return 0; // success +} diff --git a/src/keyboard/ergodox/teensy-2-0.md b/src/keyboard/ergodox/controller/teensy-2-0.md similarity index 75% rename from src/keyboard/ergodox/teensy-2-0.md rename to src/keyboard/ergodox/controller/teensy-2-0.md index 61b47fd..a1df8f6 100644 --- a/src/keyboard/ergodox/teensy-2-0.md +++ b/src/keyboard/ergodox/controller/teensy-2-0.md @@ -2,8 +2,9 @@ ## Pinout and Pin assignments -* `+` indicates pin -* `o` indicates unused pin +* `+` indicates connected pin +* `o` indicates unconnected pin +* `=` is used to list other things the pin is connected to * `-`s inserted between some of the pin functions for readability * `OC**` pins enclosed in parenthesis had lines over them in the pinout @@ -28,27 +29,30 @@ ### Teensy 2.0 Pin Assignments power_negative GND +---.....---+ Vcc power_positive - column6 PB0 + + PF0 row0 - PB1 o + PF1 row1 - PB2 o + PF4 row2 - PB3 o o o + PF5 row3 - (OC1C) LED3 PB7 + PE6 AREF + PF6 row4 - (SCL) I2C PD0 + + PF7 row5 - (SDA) I2C PD1 + + PB6 LED1 (OC1B) - column3 PD2 + + PB5 LED2 (OC1A) - column4 PD3 + + PB4 column0 - column1 PC6 + + PD7 column5 - column2 PC7 +-o-o-o-o-o-+ PD6 onboardLED + column_7 PB0 + + PF0 row_5 + column_8 PB1 + + PF1 row_4 + column_9 PB2 + + PF4 row_3 + column_A PB3 + o o + PF5 row_2 + (OC1C) LED_3 PB7 + PE6 AREF + PF6 row_1 + (SCL) I2C PD0 + + PF7 row_0 + (SDA) I2C PD1 + + PB6 LED_2 (OC1B) + column_B PD2 + + PB5 LED_1 (OC1A) + column_C PD3 + + PB4 = Vcc + column_D PC6 + o PD7 + PC7 o-o-o-o-o-o-+ PD6 onboardLED = GND PD5 --/ | | | \-- PD4 Vcc ----/ | \---- RST GND-------/ * notes: * Row and column assignments are to matrix positions, which may or may - correspond to the physical position of the key: e.g. the key where `row4` - and `column2` cross will be scanned into the matrix at `[4][2]`, wherever - it happens to be located on the keyboard. Mapping from one to the other - (which only matters for defining layouts) is handled elsewhere. + or may not correspond to the physical position of the key: e.g. the key + where `row_4` and `column_2` cross will be scanned into the matrix at + `[4][2]`, wherever it happens to be located on the keyboard. Mapping + from one to the other (which only matters for defining layouts) is + handled elsewhere. + * LEDs are labeled using numbers (starting with '1') instead of letters + (starting with 'A') as on the PCB. * SCL and SDA: Need external pull-up resistors. Sometimes the Teensy internal pull-ups are enough (see datasheet section 20.5.1), but i think for this project we'll want external ones. The general recommendation @@ -75,14 +79,16 @@ * PD6 (the onboard LED) already has a defined level (low), so there's no reason to set internal pull-up enabled on it. If we do, it will source current to the LED, which is fine, but unnecessary. - * We want the columns to be hi-Z when that column's not being scanned, - drive low when it is, and the rows to be input with pull-up enabled. - We'll cycle through driving the columns low and scanning all rows. + * Initially, we want either columns or rows (see <../options.h>) set as + hi-Z without pull-ups, and the other set of pins set as input with + pull-ups. During the update function, we'll cycle through setting the + first set low and checking each pin in the second set. * To set a pin hi-Z on this board, set it as input with pull-up disabled. - * Switching the row pins between hi-Z and drive low (treating them as - if they were open drain) seems just as good as, and a little safer - than, driving them high when the row's not active. + * Switching the driving pins (the first set of pins) between hi-Z and + drive low (treating them as if they were open drain) seems just as + good as, and a little safer than, driving them high when they're not + active. * We need to delay for at least 1 μs between changing the column pins and reading the row pins. I would assume this is to allow the pins time to stabalize. diff --git a/src/keyboard/ergodox/layout.h b/src/keyboard/ergodox/layout.h index e58eb51..b233eeb 100644 --- a/src/keyboard/ergodox/layout.h +++ b/src/keyboard/ergodox/layout.h @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX layout : exports + * ergoDOX : layout exports * * Different layouts are included by modifying a variable in the makefile. * ---------------------------------------------------------------------------- @@ -8,121 +8,16 @@ * Project located at * ------------------------------------------------------------------------- */ -#ifndef LAYOUT_h - #define LAYOUT_h - #include - #include "lib/data-types.h" - #include "lib/key-functions.h" // for `kbfun_funptr_t` +#ifndef KEYBOARD__ERGODOX__LAYOUT_h + #define KEYBOARD__ERGODOX__LAYOUT_h - #include "matrix.h" // for number of rows and columns + // -------------------------------------------------------------------- // include the appropriate keyboard layout header - // for: - // - possible non-default number of layers - // - possible non-default layout matrix definitions - // - possible non-default layout 'get' and 'set' definitions - #undef _str - #undef _expstr - #undef _inc - #define _str(s) #s // stringify - #define _expstr(s) _str(s) // expand -> stringify - #define _inc _expstr(layout/MAKEFILE_KEYBOARD_LAYOUT.h) // inc(lude) - #include _inc - #undef _str - #undef _expstr - #undef _inc - - - // default number of layers - #ifndef KB_LAYERS - #define KB_LAYERS 10 - #endif - - - // default layout 'get' macros and `extern` matrix declarations - // - // these are for when the matrices are stored solely in Flash. layouts - // may redefine them if they wish and use RAM, EEPROM, or any - // combination of the three, as long as they maintain the same - // interface. - // - // - if the macro is overridden, the matrix declaration must be too, - // and vice versa. - // - // - 'set' functions are optional, and should be defined in the layout - // specific '.h'. they'll require the use of the EEPROM, possibly in - // clever conjunction with one of the other two memories (since the - // EEPROM is small). custom key functions will also need to be - // written. - // - // - to override these macros with real functions, set the macro equal - // to itself (e.g. `#define kb_layout_get kb_layout_get`) and provide - // function prototypes in the layout specific '.h' - - #ifndef kb_layout_get - extern uint8_t PROGMEM \ - _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS]; - - #define kb_layout_get(layer,row,column) \ - ( (uint8_t) \ - pgm_read_byte(&( \ - _kb_layout[layer][row][column] )) ) - #endif - - #ifndef kb_layout_press_get - extern kbfun_funptr_t PROGMEM \ - _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS]; - - #define kb_layout_press_get(layer,row,column) \ - ( (kbfun_funptr_t) \ - pgm_read_word(&( \ - _kb_layout_press[layer][row][column] )) ) - #endif - - #ifndef kb_layout_release_get - extern kbfun_funptr_t PROGMEM \ - _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS]; - - #define kb_layout_release_get(layer,row,column) \ - ( (kbfun_funptr_t) \ - pgm_read_word(&( \ - _kb_layout_release[layer][row][column] )) ) - - #endif - - - // default logical LED macros (all defined to nothing) - #ifndef kb_led_num_on - #define kb_led_num_on() - #endif - #ifndef kb_led_num_off - #define kb_led_num_off() - #endif - #ifndef kb_led_caps_on - #define kb_led_caps_on() - #endif - #ifndef kb_led_caps_off - #define kb_led_caps_off() - #endif - #ifndef kb_led_scroll_on - #define kb_led_scroll_on() - #endif - #ifndef kb_led_scroll_off - #define kb_led_scroll_off() - #endif - #ifndef kb_led_compose_on - #define kb_led_compose_on() - #endif - #ifndef kb_led_compose_off - #define kb_led_compose_off() - #endif - #ifndef kb_led_kana_on - #define kb_led_kana_on() - #endif - #ifndef kb_led_kana_off - #define kb_led_kana_off() - #endif + #include "../../lib/variable-include.h" + #define INCLUDE EXP_STR( ./layout/MAKEFILE_KEYBOARD_LAYOUT.h ) + #include INCLUDE #endif diff --git a/src/keyboard/ergodox/layout.md b/src/keyboard/ergodox/layout.md index 732fac7..dade59a 100644 --- a/src/keyboard/ergodox/layout.md +++ b/src/keyboard/ergodox/layout.md @@ -3,33 +3,22 @@ Different layouts are included by modifying a variable in the makefile. To write a new one: -* You must implement everything defined in [layout.h] (layout.h). Take a look - at existing layouts in the 'layout' subdir. - * Currently, see [qwerty.c] (layout/qwerty.c) and [qwerty.h] - (layout/qwerty.h). The latter is only important if you want more than - one layer. And I still need to write the functions to make that possible - (though that shouldn't be hard, I just haven't gotten to it yet). But - (at least for the QWERTY and Dvorak layouts I'd really like to include) - if you indicate it clealy in the layout, and provide complete - initializations for `kb_layout[][][]`, `kb_layout_press[][][]`, and - `kb_layout_release[][][]`, I'll make sure it gets working. -* The number of layers must be defined in the layout *.h file. +* Create new layout files under [layout] (layout) (see [qwerty.h] + (layout/qwerty.h) and [qwerty.c] (layout/qwerty.c)). * Use `0` for no-operation (unused) keys, and `NULL` for no-operation (unused) functions. -* See [matrix.md] (matrix.md) for how the key matrix maps to hardware. +* See [matrix/mapping.h] (matrix/mapping.h) for how the key matrix maps to + hardware. * See [keyboard-usage-page--short-names.h] (../../lib/_usb/keyboard-usage-page--short-names.h) for available keycodes. -* See [key-functions.c] (../../lib/_key-functions.c) for what functions keys +* See [key-functions.c] (../../lib/key-functions.c) for what functions keys can call. -* See [_defaults.h] (layout/_defaults.h) for default function layers and - aliases. ## notes -* Each full layer takes 420 bytes of memory, wherever it's stored. (The matrix - size is 12x7, keycodes are 1 byte each, and function pointers are 2 bytes - each.) +* Each full layer takes 420 bytes of memory (the matrix size is 12x7, keycodes + are 1 byte each, and function pointers are 2 bytes each). ------------------------------------------------------------------------------- diff --git a/src/keyboard/ergodox/layout/default--led-control.h b/src/keyboard/ergodox/layout/default--led-control.h new file mode 100644 index 0000000..847e6da --- /dev/null +++ b/src/keyboard/ergodox/layout/default--led-control.h @@ -0,0 +1,86 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX : layout : default LED control + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef KEYBOARD__ERGODOX__LAYOUT__DEFAULT__LED_CONTROL_h + #define KEYBOARD__ERGODOX__LAYOUT__DEFAULT__LED_CONTROL_h + + // -------------------------------------------------------------------- + + /* + * state and delay macros + */ + + #ifndef kb_led_state_power_on + #define kb_led_state_power_on() do { \ + _kb_led_all_set_percent(MAKEFILE_LED_BRIGHTNESS/10); \ + _kb_led_all_on(); \ + } while(0) + #endif + + // note: need to delay for a total of ~1 second + #ifndef kb_led_delay_usb_init + #define kb_led_delay_usb_init() do { \ + _kb_led_1_set_percent(MAKEFILE_LED_BRIGHTNESS); \ + _delay_ms(333); \ + _kb_led_2_set_percent(MAKEFILE_LED_BRIGHTNESS); \ + _delay_ms(333); \ + _kb_led_3_set_percent(MAKEFILE_LED_BRIGHTNESS); \ + _delay_ms(333); \ + } while(0) + #endif + + #ifndef kb_led_state_ready + #define kb_led_state_ready() do { \ + _kb_led_all_off(); \ + _kb_led_all_set_percent(MAKEFILE_LED_BRIGHTNESS); \ + } while(0) + #endif + + + /* + * logical LED macros + * - unused macros should be defined to nothing + * - they all are here, because they really need to be specified in + * the layout specific file + */ + + #ifndef kb_led_num_on + #define kb_led_num_on() + #endif + #ifndef kb_led_num_off + #define kb_led_num_off() + #endif + #ifndef kb_led_caps_on + #define kb_led_caps_on() + #endif + #ifndef kb_led_caps_off + #define kb_led_caps_off() + #endif + #ifndef kb_led_scroll_on + #define kb_led_scroll_on() + #endif + #ifndef kb_led_scroll_off + #define kb_led_scroll_off() + #endif + #ifndef kb_led_compose_on + #define kb_led_compose_on() + #endif + #ifndef kb_led_compose_off + #define kb_led_compose_off() + #endif + #ifndef kb_led_kana_on + #define kb_led_kana_on() + #endif + #ifndef kb_led_kana_off + #define kb_led_kana_off() + #endif + + +#endif + diff --git a/src/keyboard/ergodox/layout/default--matrix-control.h b/src/keyboard/ergodox/layout/default--matrix-control.h new file mode 100644 index 0000000..d24c0e7 --- /dev/null +++ b/src/keyboard/ergodox/layout/default--matrix-control.h @@ -0,0 +1,81 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX : layout : default matrix control + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef KEYBOARD__ERGODOX__LAYOUT__DEFAULT__MATRIX_CONTROL_h + #define KEYBOARD__ERGODOX__LAYOUT__DEFAULT__MATRIX_CONTROL_h + + #include + #include + #include "../../../lib/data-types/misc.h" + #include "../../../lib/key-functions/public.h" + #include "../matrix.h" + + // -------------------------------------------------------------------- + + #ifndef KB_LAYERS + #define KB_LAYERS 10 + #endif + + // -------------------------------------------------------------------- + + /* + * matrix 'get' macros, and `extern` matrix declarations + * + * These are written for when the matrices are stored solely in Flash. + * Layouts may redefine them if they wish and use Flash, RAM, EEPROM, + * or any combination of the three, as long as they maintain the same + * interface. + * + * - If the macro is overridden, the matrix declaration must be too, + * and vice versa. + * + * - 'set' functions are optional, and should be defined in the layout + * specific '.h'. They'll require the use of the EEPROM, possibly in + * clever conjunction with one of the other two memories (since the + * EEPROM is small). Custom key functions will also need to be + * written. + * + * - To override these macros with real functions, set the macro equal + * to itself (e.g. `#define kb_layout_get kb_layout_get`) and provide + * function prototypes, in the layout specific '.h' + */ + + #ifndef kb_layout_get + extern const uint8_t PROGMEM \ + _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS]; + + #define kb_layout_get(layer,row,column) \ + ( (uint8_t) \ + pgm_read_byte(&( \ + _kb_layout[layer][row][column] )) ) + #endif + + #ifndef kb_layout_press_get + extern const void_funptr_t PROGMEM \ + _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS]; + + #define kb_layout_press_get(layer,row,column) \ + ( (void_funptr_t) \ + pgm_read_word(&( \ + _kb_layout_press[layer][row][column] )) ) + #endif + + #ifndef kb_layout_release_get + extern const void_funptr_t PROGMEM \ + _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS]; + + #define kb_layout_release_get(layer,row,column) \ + ( (void_funptr_t) \ + pgm_read_word(&( \ + _kb_layout_release[layer][row][column] )) ) + + #endif + +#endif + diff --git a/src/keyboard/ergodox/layout/dvorak-kinesis-mod.c b/src/keyboard/ergodox/layout/dvorak-kinesis-mod.c new file mode 100644 index 0000000..ebd3f00 --- /dev/null +++ b/src/keyboard/ergodox/layout/dvorak-kinesis-mod.c @@ -0,0 +1,371 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX layout : QWERTY (modified from the Kinesis layout) + * TODO: rewrite for new kbfun's + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include +#include +#include +#include "../../../lib/data-types/misc.h" +#include "../../../lib/usb/usage-page/keyboard--short-names.h" +#include "../../../lib/key-functions/public.h" +#include "../matrix.h" +#include "../layout.h" + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + +const uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { + + KB_MATRIX_LAYER( // layout: layer 0: default +// unused +0, +// left hand + _equal, _1, _2, _3, _4, _5, _esc, +_backslash, _quote, _comma, _period, _P, _Y, 1, + _tab, _A, _O, _E, _U, _I, + _shiftL, _semicolon, _Q, _J, _K, _X, 1, + _guiL, _grave, _backslash, _arrowL, _arrowR, + _bs, 0, + _del, 0, _ctrlL, + _end, _home, _altL, +// right hand + 3, _6, _7, _8, _9, _0, _dash, +_bracketL, _F, _G, _C, _R, _L, _bracketR, + _D, _H, _T, _N, _S, _slash, + 1, _B, _M, _W, _V, _Z, _shiftR, + _arrowL, _arrowD, _arrowU, _arrowR, _guiR, + 0, _space, +_ctrlR, 0, _enter, + _altR, _pageU, _pageD ), + + + KB_MATRIX_LAYER( // layout: layer 1: function and symbol keys +// unused +0, +// left hand + 0, _F1, _F2, _F3, _F4, _F5, _F11, + 0, _bracketL, _bracketR, _bracketL, _bracketR, 0, 1, + 0, _semicolon, _slash, _dash, _0_kp,_semicolon, + 0, _6_kp, _7_kp, _8_kp, _9_kp, _equal, 2, + 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, + 0, 0, 0, +// right hand +_F12, _F6, _F7, _F8, _F9, _F10, _power, + 0, 0, _dash, _comma, _period,_currencyUnit, _volumeU, + _backslash, _1_kp, _9, _0, _equal, _volumeD, + 2, _8, _2_kp, _3_kp, _4_kp, _5_kp, _mute, + 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, + 0, 0, 0 ), + + + KB_MATRIX_LAYER( // layout: layer 2: keyboard functions +// unused +0, +// left hand + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, + 0, 0, 0, +// right hand + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, + 0, 0, 0 ), + + + KB_MATRIX_LAYER( // layout: layer 3: numpad +// unused +0, +// left hand +0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, +0, _insert, 0, 0, 0, + 0, 0, + 0, 0, 0, + 0, 0, 0, +// right hand +3, 0, 3, _equal_kp, _div_kp, _mul_kp, 0, +0, 0, _7_kp, _8_kp, _9_kp, _sub_kp, 0, + 0, _4_kp, _5_kp, _6_kp, _add_kp, 0, +0, 0, _1_kp, _2_kp, _3_kp, _enter_kp, 0, + 0, 0, _dec_kp, _enter_kp, 0, + 0, _0_kp, +0, 0, 0, +0, 0, 0 ), + +}; + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + +// aliases + +// basic +#define kprrel &kbfun_press_release +#define ktog &kbfun_toggle +#define ktrans &kbfun_transparent +// --- layer push/pop functions +#define lpush1 &kbfun_layer_push_1 +#define lpush2 &kbfun_layer_push_2 +#define lpush3 &kbfun_layer_push_3 +#define lpush4 &kbfun_layer_push_4 +#define lpush5 &kbfun_layer_push_5 +#define lpush6 &kbfun_layer_push_6 +#define lpush7 &kbfun_layer_push_7 +#define lpush8 &kbfun_layer_push_8 +#define lpush9 &kbfun_layer_push_9 +#define lpush10 &kbfun_layer_push_10 +#define lpop1 &kbfun_layer_pop_1 +#define lpop2 &kbfun_layer_pop_2 +#define lpop3 &kbfun_layer_pop_3 +#define lpop4 &kbfun_layer_pop_4 +#define lpop5 &kbfun_layer_pop_5 +#define lpop6 &kbfun_layer_pop_6 +#define lpop7 &kbfun_layer_pop_7 +#define lpop8 &kbfun_layer_pop_8 +#define lpop9 &kbfun_layer_pop_9 +#define lpop10 &kbfun_layer_pop_10 +// --- + +// device +#define dbtldr &kbfun_jump_to_bootloader + +// special +#define sshprre &kbfun_shift_press_release +#define s2kcap &kbfun_2_keys_capslock_press_release +#define slpunum &kbfun_layer_push_numpad +#define slponum &kbfun_layer_pop_numpad + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + +const void_funptr_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { + + KB_MATRIX_LAYER( // press: layer 0: default +// unused +NULL, +// left hand + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, lpush1, + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + s2kcap, kprrel, kprrel, kprrel, kprrel, kprrel, lpush1, + kprrel, kprrel, kprrel, kprrel, kprrel, + kprrel, NULL, + kprrel, NULL, kprrel, + kprrel, kprrel, kprrel, +// right hand + slpunum, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + lpush1, kprrel, kprrel, kprrel, kprrel, kprrel, s2kcap, + kprrel, kprrel, kprrel, kprrel, kprrel, + NULL, kprrel, + kprrel, NULL, kprrel, + kprrel, kprrel, kprrel ), + + + KB_MATRIX_LAYER( // press: layer 1: function and symbol keys +// unused +NULL, +// left hand + NULL, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + ktrans,sshprre,sshprre, kprrel, kprrel, NULL, lpop1, + ktrans, kprrel, kprrel, kprrel, kprrel,sshprre, + ktrans, kprrel, kprrel, kprrel, kprrel,sshprre, lpush2, + ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, + ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, +// right hand + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + ktrans, NULL, kprrel,sshprre,sshprre, kprrel, kprrel, + kprrel, kprrel,sshprre,sshprre,sshprre, kprrel, + lpush2,sshprre, kprrel, kprrel, kprrel, kprrel, kprrel, + ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, + ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans ), + + + KB_MATRIX_LAYER( // press: layer 2: keyboard functions +// unused +NULL, +// left hand + dbtldr, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL, +// right hand + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL ), + + + KB_MATRIX_LAYER( // press: layer 3: numpad +// unused +NULL, +// left hand + ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, kprrel, ktrans, ktrans, ktrans, + ktrans, ktrans, + ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, +// right hand + slponum, ktrans,slponum, kprrel, kprrel, kprrel, ktrans, + ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans, + ktrans, kprrel, kprrel, kprrel, kprrel, ktrans, + ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans, + ktrans, ktrans, kprrel, kprrel, ktrans, + ktrans, kprrel, + ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans ), + +}; + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + +const void_funptr_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { + + KB_MATRIX_LAYER( // release: layer 0: default +// unused +NULL, +// left hand + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, NULL, + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + s2kcap, kprrel, kprrel, kprrel, kprrel, kprrel, lpop1, + kprrel, kprrel, kprrel, kprrel, kprrel, + kprrel, NULL, + kprrel, NULL, kprrel, + kprrel, kprrel, kprrel, +// right hand + NULL, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + lpop1, kprrel, kprrel, kprrel, kprrel, kprrel, s2kcap, + kprrel, kprrel, kprrel, kprrel, kprrel, + NULL, kprrel, + kprrel, NULL, kprrel, + kprrel, kprrel, kprrel ), + + + KB_MATRIX_LAYER( // release: layer 1: function and symbol keys +// unused +NULL, +// left hand + NULL, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + ktrans,sshprre,sshprre, kprrel, kprrel, NULL, NULL, + ktrans, kprrel, kprrel, kprrel, kprrel,sshprre, + ktrans, kprrel, kprrel, kprrel, kprrel,sshprre, lpop2, + ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, + ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, +// right hand + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + ktrans, NULL, kprrel,sshprre,sshprre, kprrel, kprrel, + kprrel, kprrel,sshprre,sshprre,sshprre, kprrel, + lpop2,sshprre, kprrel, kprrel, kprrel, kprrel, kprrel, + ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, + ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans ), + + + KB_MATRIX_LAYER( // release: layer 2: keyboard functions +// unused +NULL, +// left hand + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL, +// right hand + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL ), + + + KB_MATRIX_LAYER( // release: layer 3: numpad +// unused +NULL, +// left hand + ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, kprrel, ktrans, ktrans, ktrans, + ktrans, ktrans, + ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, +// right hand + NULL, ktrans, NULL, kprrel, kprrel, kprrel, ktrans, + ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans, + ktrans, kprrel, kprrel, kprrel, kprrel, ktrans, + ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans, + ktrans, ktrans, kprrel, kprrel, ktrans, + ktrans, kprrel, + ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans ), + + + KB_MATRIX_LAYER( // release: layer 3: nothing (just making sure unused + // functions don't get compiled out) +// unused +NULL, +// other + kprrel, lpush8, lpop8, NULL, NULL, NULL, NULL, NULL, + ktog, lpush9, lpop9, NULL, NULL, NULL, NULL, NULL, + ktrans,lpush10, lpop10, NULL, NULL, NULL, NULL, NULL, + lpush1, lpop1, NULL, NULL, NULL, NULL, NULL, NULL, + lpush2, lpop2, dbtldr, NULL, NULL, NULL, NULL, NULL, + lpush3, lpop3, NULL, NULL, NULL, NULL, NULL, NULL, + lpush4, lpop4, s2kcap, NULL, NULL, NULL, NULL, NULL, + lpush5, lpop5,slpunum, NULL, NULL, NULL, NULL, NULL, + lpush6, lpop6,slponum, NULL, NULL, NULL, NULL, NULL, + lpush7, lpop7, NULL, NULL, NULL, NULL, NULL, NULL ) + +}; + diff --git a/src/keyboard/ergodox/layout/qwerty.h b/src/keyboard/ergodox/layout/dvorak-kinesis-mod.h similarity index 65% rename from src/keyboard/ergodox/layout/qwerty.h rename to src/keyboard/ergodox/layout/dvorak-kinesis-mod.h index a424938..1538974 100644 --- a/src/keyboard/ergodox/layout/qwerty.h +++ b/src/keyboard/ergodox/layout/dvorak-kinesis-mod.h @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX layout : QWERTY : exports + * ergoDOX : layout : Dvorak : exports * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,11 +7,12 @@ * ------------------------------------------------------------------------- */ -#ifndef LAYOUT_QWERTY_h - #define LAYOUT_QWERTY_h +#ifndef KEYBOARD__ERGODOX__LAYOUT__DVORAK_h + #define KEYBOARD__ERGODOX__LAYOUT__DVORAK_h - #include "../led.h" + #include "../controller.h" + // -------------------------------------------------------------------- #define kb_led_num_on() _kb_led_1_on() #define kb_led_num_off() _kb_led_1_off() @@ -20,5 +21,10 @@ #define kb_led_scroll_on() _kb_led_3_on() #define kb_led_scroll_off() _kb_led_3_off() + // -------------------------------------------------------------------- + + #include "./default--led-control.h" + #include "./default--matrix-control.h" + #endif diff --git a/src/keyboard/ergodox/layout/qwerty-kinesis-mod.c b/src/keyboard/ergodox/layout/qwerty-kinesis-mod.c new file mode 100644 index 0000000..a732f1c --- /dev/null +++ b/src/keyboard/ergodox/layout/qwerty-kinesis-mod.c @@ -0,0 +1,371 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX layout : QWERTY (modified from the Kinesis layout) + * TODO: rewrite for new kbfun's + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include +#include +#include +#include "../../../lib/data-types/misc.h" +#include "../../../lib/usb/usage-page/keyboard--short-names.h" +#include "../../../lib/key-functions/public.h" +#include "../matrix.h" +#include "../layout.h" + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + +const uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { + + KB_MATRIX_LAYER( // layout: layer 0: default +// unused +0, +// left hand + _equal, _1, _2, _3, _4, _5, _esc, +_backslash, _Q, _W, _E, _R, _T, 1, + _tab, _A, _S, _D, _F, _G, + _shiftL, _Z, _X, _C, _V, _B, 1, + _guiL, _grave, _backslash, _arrowL, _arrowR, + _bs, 0, + _del, 0, _ctrlL, + _end, _home, _altL, +// right hand + 3, _6, _7, _8, _9, _0, _dash, +_bracketL, _Y, _U, _I, _O, _P, _bracketR, + _H, _J, _K, _L, _semicolon, _quote, + 1, _N, _M, _comma, _period, _slash, _shiftR, + _arrowL, _arrowD, _arrowU, _arrowR, _guiR, + 0, _space, +_ctrlR, 0, _enter, + _altR, _pageU, _pageD ), + + + KB_MATRIX_LAYER( // layout: layer 1: function and symbol keys +// unused +0, +// left hand + 0, _F1, _F2, _F3, _F4, _F5, _F11, + 0, _bracketL, _bracketR, _bracketL, _bracketR, 0, 1, + 0, _semicolon, _slash, _dash, _0_kp,_semicolon, + 0, _6_kp, _7_kp, _8_kp, _9_kp, _equal, 2, + 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, + 0, 0, 0, +// right hand +_F12, _F6, _F7, _F8, _F9, _F10, _power, + 0, 0, _dash, _comma, _period,_currencyUnit, _volumeU, + _backslash, _1_kp, _9, _0, _equal, _volumeD, + 2, _8, _2_kp, _3_kp, _4_kp, _5_kp, _mute, + 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, + 0, 0, 0 ), + + + KB_MATRIX_LAYER( // layout: layer 2: keyboard functions +// unused +0, +// left hand + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, + 0, 0, 0, +// right hand + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, + 0, 0, 0, + 0, 0, 0 ), + + + KB_MATRIX_LAYER( // layout: layer 3: numpad +// unused +0, +// left hand +0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, +0, _insert, 0, 0, 0, + 0, 0, + 0, 0, 0, + 0, 0, 0, +// right hand +3, 0, 3, _equal_kp, _div_kp, _mul_kp, 0, +0, 0, _7_kp, _8_kp, _9_kp, _sub_kp, 0, + 0, _4_kp, _5_kp, _6_kp, _add_kp, 0, +0, 0, _1_kp, _2_kp, _3_kp, _enter_kp, 0, + 0, 0, _dec_kp, _enter_kp, 0, + 0, _0_kp, +0, 0, 0, +0, 0, 0 ), + +}; + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + +// aliases + +// basic +#define kprrel &kbfun_press_release +#define ktog &kbfun_toggle +#define ktrans &kbfun_transparent +// --- layer push/pop functions +#define lpush1 &kbfun_layer_push_1 +#define lpush2 &kbfun_layer_push_2 +#define lpush3 &kbfun_layer_push_3 +#define lpush4 &kbfun_layer_push_4 +#define lpush5 &kbfun_layer_push_5 +#define lpush6 &kbfun_layer_push_6 +#define lpush7 &kbfun_layer_push_7 +#define lpush8 &kbfun_layer_push_8 +#define lpush9 &kbfun_layer_push_9 +#define lpush10 &kbfun_layer_push_10 +#define lpop1 &kbfun_layer_pop_1 +#define lpop2 &kbfun_layer_pop_2 +#define lpop3 &kbfun_layer_pop_3 +#define lpop4 &kbfun_layer_pop_4 +#define lpop5 &kbfun_layer_pop_5 +#define lpop6 &kbfun_layer_pop_6 +#define lpop7 &kbfun_layer_pop_7 +#define lpop8 &kbfun_layer_pop_8 +#define lpop9 &kbfun_layer_pop_9 +#define lpop10 &kbfun_layer_pop_10 +// --- + +// device +#define dbtldr &kbfun_jump_to_bootloader + +// special +#define sshprre &kbfun_shift_press_release +#define s2kcap &kbfun_2_keys_capslock_press_release +#define slpunum &kbfun_layer_push_numpad +#define slponum &kbfun_layer_pop_numpad + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + +const void_funptr_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { + + KB_MATRIX_LAYER( // press: layer 0: default +// unused +NULL, +// left hand + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, lpush1, + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + s2kcap, kprrel, kprrel, kprrel, kprrel, kprrel, lpush1, + kprrel, kprrel, kprrel, kprrel, kprrel, + kprrel, NULL, + kprrel, NULL, kprrel, + kprrel, kprrel, kprrel, +// right hand + slpunum, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + lpush1, kprrel, kprrel, kprrel, kprrel, kprrel, s2kcap, + kprrel, kprrel, kprrel, kprrel, kprrel, + NULL, kprrel, + kprrel, NULL, kprrel, + kprrel, kprrel, kprrel ), + + + KB_MATRIX_LAYER( // press: layer 1: function and symbol keys +// unused +NULL, +// left hand + NULL, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + ktrans,sshprre,sshprre, kprrel, kprrel, NULL, lpop1, + ktrans, kprrel, kprrel, kprrel, kprrel,sshprre, + ktrans, kprrel, kprrel, kprrel, kprrel,sshprre, lpush2, + ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, + ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, +// right hand + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + ktrans, NULL, kprrel,sshprre,sshprre, kprrel, kprrel, + kprrel, kprrel,sshprre,sshprre,sshprre, kprrel, + lpush2,sshprre, kprrel, kprrel, kprrel, kprrel, kprrel, + ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, + ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans ), + + + KB_MATRIX_LAYER( // press: layer 2: keyboard functions +// unused +NULL, +// left hand + dbtldr, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL, +// right hand + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL ), + + + KB_MATRIX_LAYER( // press: layer 3: numpad +// unused +NULL, +// left hand + ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, kprrel, ktrans, ktrans, ktrans, + ktrans, ktrans, + ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, +// right hand + slponum, ktrans,slponum, kprrel, kprrel, kprrel, ktrans, + ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans, + ktrans, kprrel, kprrel, kprrel, kprrel, ktrans, + ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans, + ktrans, ktrans, kprrel, kprrel, ktrans, + ktrans, kprrel, + ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans ), + +}; + +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- + +const void_funptr_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { + + KB_MATRIX_LAYER( // release: layer 0: default +// unused +NULL, +// left hand + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, NULL, + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + s2kcap, kprrel, kprrel, kprrel, kprrel, kprrel, lpop1, + kprrel, kprrel, kprrel, kprrel, kprrel, + kprrel, NULL, + kprrel, NULL, kprrel, + kprrel, kprrel, kprrel, +// right hand + NULL, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + lpop1, kprrel, kprrel, kprrel, kprrel, kprrel, s2kcap, + kprrel, kprrel, kprrel, kprrel, kprrel, + NULL, kprrel, + kprrel, NULL, kprrel, + kprrel, kprrel, kprrel ), + + + KB_MATRIX_LAYER( // release: layer 1: function and symbol keys +// unused +NULL, +// left hand + NULL, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + ktrans,sshprre,sshprre, kprrel, kprrel, NULL, NULL, + ktrans, kprrel, kprrel, kprrel, kprrel,sshprre, + ktrans, kprrel, kprrel, kprrel, kprrel,sshprre, lpop2, + ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, + ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, +// right hand + kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, kprrel, + ktrans, NULL, kprrel,sshprre,sshprre, kprrel, kprrel, + kprrel, kprrel,sshprre,sshprre,sshprre, kprrel, + lpop2,sshprre, kprrel, kprrel, kprrel, kprrel, kprrel, + ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, + ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans ), + + + KB_MATRIX_LAYER( // release: layer 2: keyboard functions +// unused +NULL, +// left hand + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL, +// right hand + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, + NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL ), + + + KB_MATRIX_LAYER( // release: layer 3: numpad +// unused +NULL, +// left hand + ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, ktrans, + ktrans, kprrel, ktrans, ktrans, ktrans, + ktrans, ktrans, + ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans, +// right hand + NULL, ktrans, NULL, kprrel, kprrel, kprrel, ktrans, + ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans, + ktrans, kprrel, kprrel, kprrel, kprrel, ktrans, + ktrans, ktrans, kprrel, kprrel, kprrel, kprrel, ktrans, + ktrans, ktrans, kprrel, kprrel, ktrans, + ktrans, kprrel, + ktrans, ktrans, ktrans, + ktrans, ktrans, ktrans ), + + + KB_MATRIX_LAYER( // release: layer 3: nothing (just making sure unused + // functions don't get compiled out) +// unused +NULL, +// other + kprrel, lpush8, lpop8, NULL, NULL, NULL, NULL, NULL, + ktog, lpush9, lpop9, NULL, NULL, NULL, NULL, NULL, + ktrans,lpush10, lpop10, NULL, NULL, NULL, NULL, NULL, + lpush1, lpop1, NULL, NULL, NULL, NULL, NULL, NULL, + lpush2, lpop2, dbtldr, NULL, NULL, NULL, NULL, NULL, + lpush3, lpop3, NULL, NULL, NULL, NULL, NULL, NULL, + lpush4, lpop4, s2kcap, NULL, NULL, NULL, NULL, NULL, + lpush5, lpop5,slpunum, NULL, NULL, NULL, NULL, NULL, + lpush6, lpop6,slponum, NULL, NULL, NULL, NULL, NULL, + lpush7, lpop7, NULL, NULL, NULL, NULL, NULL, NULL ) + +}; + diff --git a/src/keyboard/ergodox/layout/qwerty-kinesis-mod.h b/src/keyboard/ergodox/layout/qwerty-kinesis-mod.h new file mode 100644 index 0000000..dd0fa66 --- /dev/null +++ b/src/keyboard/ergodox/layout/qwerty-kinesis-mod.h @@ -0,0 +1,30 @@ +/* ---------------------------------------------------------------------------- + * ergoDOX : layout : QWERTY : exports + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef KEYBOARD__ERGODOX__LAYOUT__QWERTY_h + #define KEYBOARD__ERGODOX__LAYOUT__QWERTY_h + + #include "../controller.h" + + // -------------------------------------------------------------------- + + #define kb_led_num_on() _kb_led_1_on() + #define kb_led_num_off() _kb_led_1_off() + #define kb_led_caps_on() _kb_led_2_on() + #define kb_led_caps_off() _kb_led_2_off() + #define kb_led_scroll_on() _kb_led_3_on() + #define kb_led_scroll_off() _kb_led_3_off() + + // -------------------------------------------------------------------- + + #include "./default--led-control.h" + #include "./default--matrix-control.h" + +#endif + diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c deleted file mode 100644 index 1e5490d..0000000 --- a/src/keyboard/ergodox/layout/qwerty.c +++ /dev/null @@ -1,265 +0,0 @@ -/* ---------------------------------------------------------------------------- - * ergoDOX layout : QWERTY - * - * This is an overly basic implementation. It needs to be replaced. - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#include -#include "lib/data-types.h" -#include "lib/usb/usage-page/keyboard--short-names.h" -#include "lib/key-functions.h" - -#include "../matrix.h" -#include "../layout.h" - - -// aliases -#define f_prrel &kbfun_press_release -#define f_toggl &kbfun_toggle -#define f_l_inc &kbfun_layer_inc -#define f_l_dec &kbfun_layer_dec -#define f_l_iex &kbfun_layer_inc_exec -#define f_l_dex &kbfun_layer_dec_exec -#define f_2kcap &kbfun_2_keys_capslock_press_release -#define f_np_to &kbfun_layermask_numpad_toggle -#define f_np_on &kbfun_layermask_numpad_on -#define f_np_of &kbfun_layermask_numpad_off -#define f_btldr &kbfun_jump_to_bootloader - - - -uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 0: default -// unused -0, -// left hand - _grave, _1, _2, _3, _4, _5, _equal, -_bracketL, _Q, _W, _E, _R, _T, _esc, - _tab, _A, _S, _D, _F, _G, - _shiftL, _Z, _X, _C, _V, _B, 1, - _guiL, _arrowL, _arrowU, _arrowD, _arrowR, - _bs, - _del, _ctrlL, - _end, _home, _altL, -// right hand - _backslash, _6, _7, _8, _9, _0, _dash, - _bracketL, _Y, _U, _I, _O, _P, _bracketR, - _H, _J, _K, _L, _semicolon, _quote, - 1, _N, _M, _comma, _period, _slash, _shiftR, - _arrowL, _arrowD, _arrowU, _arrowR, _guiR, - _space, -_ctrlR, _enter, - _altR, _pageU, _pageD ), -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 1: function and symbol keys -// unused -0, -// left hand --1, _F1, _F2, _F3, _F4, _F5, _F11, - 0, _braceL_kp, _braceR_kp, _bracketL, _bracketR, 0, _esc, - 0, _semicolon, _slash, _dash, 0, _colon_kp, - 2, 0, 0, 0, 0, 0, 0, - 0, _arrowL, _arrowU, _arrowD, _arrowR, - _bs, - _del, _ctrlL, - _end, _home, _altL, -// right hand - _F12, _F6, _F7, _F8, _F9, _F10, 0, - 2, 0, _dash, _lt_kp, _gt_kp, _currencyUnit, 0, - _backslash, 0, _parenL_kp, _parenR_kp, _equal, 0, - 0, _mul_kp, 0, 0, 0, 0, 0, - _arrowL, _arrowD, _arrowU, _arrowR, 0, - _space, -_ctrlR, _enter, - _altR, _pageU, _pageD ), -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 2: numpad -// unused -0, -// left hand -0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, - 0, - 0, 0, - 0, 0, 0, -// right hand -//------- ------- ------- ------- ------- ------- ------- - 0, 0, _7_kp, _8_kp, _9_kp, _div_kp, 0, - 0, 0, _4_kp, _5_kp, _6_kp, _mul_kp, 0, - 0, _1_kp, _2_kp, _3_kp, _sub_kp, 0, - 0, 0, _0_kp, _period, 0, _add_kp, 0, - 0, 0, 0, 0, 0, - 0, -0, 0, -0, 0, 0 ) -// ---------------------------------------------------------------------------- -}; - - -kbfun_funptr_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 0: default -// unused -NULL, -// left hand -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, -f_2kcap,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_l_inc, -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel, - f_prrel, f_prrel, - f_prrel,f_prrel,f_prrel, -// right hand - f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_l_inc,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_2kcap, - f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel, -f_prrel, f_prrel, -f_prrel,f_prrel,f_prrel ), -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 1: function and symbol keys -// unused -NULL, -// left hand -f_btldr,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, -f_np_on,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL, -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel, - f_prrel, f_prrel, - f_prrel,f_prrel,f_prrel, -// right hand - f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_np_to,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - NULL,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel, -f_prrel, f_prrel, -f_prrel,f_prrel,f_prrel ), -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 2: numpad -// unused -NULL, -// left hand - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - NULL, - NULL, NULL, - NULL, NULL, NULL, -// right hand - NULL, NULL,f_prrel,f_prrel,f_prrel,f_prrel, NULL, - NULL, NULL,f_prrel,f_prrel,f_prrel,f_prrel, NULL, - NULL,f_prrel,f_prrel,f_prrel,f_prrel, NULL, - NULL, NULL,f_prrel,f_prrel,f_prrel,f_prrel, NULL, - NULL, NULL, NULL, NULL, NULL, - NULL, - NULL, NULL, - NULL, NULL, NULL ) -// ---------------------------------------------------------------------------- -}; - - -kbfun_funptr_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 0: default -// unused -NULL, -// left hand -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, -f_2kcap,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_l_dec, -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel, - f_prrel, f_prrel, - f_prrel,f_prrel,f_prrel, -// right hand - f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_l_dec,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_2kcap, - f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel, -f_prrel, f_prrel, -f_prrel,f_prrel,f_prrel ), -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 1: function and symbol keys -// unused -NULL, -// left hand - NULL,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, -f_np_of,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, NULL, -f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel, - f_prrel, f_prrel, - f_prrel,f_prrel,f_prrel, -// right hand - f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - NULL,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - NULL,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel,f_prrel,f_prrel,f_prrel,f_prrel, - f_prrel, -f_prrel, f_prrel, -f_prrel,f_prrel,f_prrel ), -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 2: numpad -// unused -NULL, -// left hand - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, - NULL, - NULL, NULL, - NULL, NULL, NULL, -// right hand - NULL, NULL,f_prrel,f_prrel,f_prrel,f_prrel, NULL, - NULL, NULL,f_prrel,f_prrel,f_prrel,f_prrel, NULL, - NULL,f_prrel,f_prrel,f_prrel,f_prrel, NULL, - NULL, NULL,f_prrel,f_prrel,f_prrel,f_prrel, NULL, - NULL, NULL, NULL, NULL, NULL, - NULL, - NULL, NULL, - NULL, NULL, NULL ), -// ---------------------------------------------------------------------------- - MATRIX_LAYER( // layer 3: nothing (just making sure unused functions - // don't get compiled out) -// unused -NULL, -// other -f_prrel, NULL, NULL, NULL, NULL, NULL, NULL, -f_toggl, NULL, NULL, NULL, NULL, NULL, NULL, -f_l_inc, NULL, NULL, NULL, NULL, NULL, NULL, -f_l_dec, NULL, NULL, NULL, NULL, NULL, NULL, -f_l_iex, NULL, NULL, NULL, NULL, NULL, NULL, -f_l_dex, NULL, NULL, NULL, NULL, NULL, NULL, -f_2kcap, NULL, NULL, NULL, NULL, NULL, NULL, -f_np_to, NULL, NULL, NULL, NULL, NULL, NULL, -f_np_on, NULL, NULL, NULL, NULL, NULL, NULL, -f_np_of, NULL, NULL, NULL, NULL, NULL, NULL, -f_btldr, NULL, NULL, NULL, NULL, NULL ) -// ---------------------------------------------------------------------------- -}; - diff --git a/src/keyboard/ergodox/led.h b/src/keyboard/ergodox/led.h deleted file mode 100644 index 1a5ff89..0000000 --- a/src/keyboard/ergodox/led.h +++ /dev/null @@ -1,46 +0,0 @@ -/* ---------------------------------------------------------------------------- - * led stuff that isn't microprocessor or layout specific - * - * you should also include this file for low-level led macros, as it will - * always include the file(s) containing those - * - * - low level LED macros (that have to be shared, but aren't really public) - * should all start with '_kb_led_' - * - public LED macros should start with 'kb_led_' - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#ifndef LED_h - #define LED_h - - #include - - #include "teensy-2-0.h" // for low-level led macros - - - #define kb_led_state_power_on() do { \ - _kb_led_all_set_percent(0.05); \ - _kb_led_all_on(); \ - } while(0) - - // note: need to delay for a total of ~1 second - #define kb_led_delay_usb_init() do { \ - _kb_led_1_set_percent(0.5); \ - _delay_ms(333); \ - _kb_led_2_set_percent(0.5); \ - _delay_ms(333); \ - _kb_led_3_set_percent(0.5); \ - _delay_ms(333); \ - } while(0) - - #define kb_led_state_ready() do { \ - _kb_led_all_off(); \ - _kb_led_all_set_percent(0.5); \ - } while(0) - -#endif - diff --git a/src/keyboard/ergodox/matrix.h b/src/keyboard/ergodox/matrix.h index 1903a8f..e062f47 100644 --- a/src/keyboard/ergodox/matrix.h +++ b/src/keyboard/ergodox/matrix.h @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * ergoDOX: keyboard matrix specific exports + * ergoDOX : matrix specific exports * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,17 +7,15 @@ * ------------------------------------------------------------------------- */ -#ifndef MATRIX_h - #define MATRIX_h +#ifndef KEYBOARD__ERGODOX__MATRIX_h + #define KEYBOARD__ERGODOX__MATRIX_h - #include "lib/data-types.h" + // -------------------------------------------------------------------- - #define KB_ROWS 12 // must match real life - #define KB_COLUMNS 7 // must match real life - - extern bool (*kb_is_pressed)[KB_ROWS][KB_COLUMNS]; - extern bool (*kb_was_pressed)[KB_ROWS][KB_COLUMNS]; + #define KB_ROWS 6 // must match real life + #define KB_COLUMNS 14 // must match real life + // -------------------------------------------------------------------- /* mapping from spatial position to matrix position * - spatial position: where the key is spatially, relative to other @@ -29,57 +27,58 @@ * and 'column' are single digit hex numbers corresponding to the * matrix position (which also corresponds to the row and column pin * labels used in the teensy and mcp23018 files) - * - coordinates not listed are unused + * + * - coordinates + * - optional keys + * k15, k16 (left hand thumb group) + * k17, k18 (right hand thumb group) + * - unused keys + * k36, k00 (left hand) + * k37, k0D (right hand) * * --- other info ----------------------------------------------------- - * rows x columns = positions; assigned, unassigned - * per hand: 6 x 7 = 42; 38, 4 - * total: 12 x 7 = 84; 76, 8 + * rows x columns = positions; used, unused + * per hand: 6 x 7 = 42; 40, 2 + * total: 6 x 14 = 84; 80, 4 * - * left hand : cols 0..6, rows 6..B - * right hand : cols 0..6, rows 0..5 + * left hand : rows 0..5, cols 0..6 + * right hand : rows 0..5, cols 7..D * -------------------------------------------------------------------- */ - #define MATRIX_LAYER( \ - /* for unused positions */ \ - na, \ - \ - /* left hand, spatial positions */ \ - kB6,kB5,kB4,kB3,kB2,kB1,kB0, \ - kA6,kA5,kA4,kA3,kA2,kA1,kA0, \ - k96,k95,k94,k93,k92,k91, \ - k86,k85,k84,k83,k82,k81,k80, \ - k76,k75,k74,k73,k72, \ - k64, \ - k63, k60, \ - k65,k62,k61, \ - \ - /* right hand, spatial positions */ \ - k50,k51,k52,k53,k54,k55,k56, \ - k40,k41,k42,k43,k44,k45,k46, \ - k31,k32,k33,k34,k35,k36, \ - k20,k21,k22,k23,k24,k25,k26, \ - k12,k13,k14,k15,k16, \ - k04, \ - k00, k03, \ - k01,k02,k05 ) \ - \ - /* matrix positions */ \ - { { k00,k01,k02,k03,k04,k05, na,}, \ - { na, na,k12,k13,k14,k15,k16,}, \ - { k20,k21,k22,k23,k24,k25,k26,}, \ - { na,k31,k32,k33,k34,k35,k36,}, \ - { k40,k41,k42,k43,k44,k45,k46,}, \ - { k50,k51,k52,k53,k54,k55,k56,}, \ - { k60,k61,k62,k63,k64,k65, na,}, \ - { na, na,k72,k73,k74,k75,k76,}, \ - { k80,k81,k82,k83,k84,k85,k86,}, \ - { na,k91,k92,k93,k94,k95,k96,}, \ - { kA0,kA1,kA2,kA3,kA4,kA5,kA6,}, \ - { kB0,kB1,kB2,kB3,kB4,kB5,kB6 } } + #define KB_MATRIX_LAYER( \ + /* for unused positions */ \ + na, \ + \ + /* left hand, spatial positions */ \ + k50,k51,k52,k53,k54,k55,k56, \ + k40,k41,k42,k43,k44,k45,k46, \ + k30,k31,k32,k33,k34,k35, \ + k20,k21,k22,k23,k24,k25,k26, \ + k10,k11,k12,k13,k14, \ + k03,k15, \ + k02,k16,k05, \ + k01,k04,k06, \ + \ + /* right hand, spatial positions */ \ + k57,k58,k59,k5A,k5B,k5C,k5D, \ + k47,k48,k49,k4A,k4B,k4C,k4D, \ + k38,k39,k3A,k3B,k3C,k3D, \ + k27,k28,k29,k2A,k2B,k2C,k2D, \ + k19,k1A,k1B,k1C,k1D, \ + k18,k0A, \ + k08,k17,k0B, \ + k07,k09,k0C ) \ + \ + /* matrix positions */ \ + {{ na,k01,k02,k03,k04,k05,k06, k07,k08,k09,k0A,k0B,k0C, na }, \ + { k10,k11,k12,k13,k14,k15,k16, k17,k18,k19,k1A,k1B,k1C,k1D }, \ + { k20,k21,k22,k23,k24,k25,k26, k27,k28,k29,k2A,k2B,k2C,k2D }, \ + { k30,k31,k32,k33,k34,k35, na, na,k38,k39,k3A,k3B,k3C,k3D }, \ + { k40,k41,k42,k43,k44,k45,k46, k47,k48,k49,k4A,k4B,k4C,k4D }, \ + { k50,k51,k52,k53,k54,k55,k56, k57,k58,k59,k5A,k5B,k5C,k5D }} - #define MATRIX_LAYER_SET_ALL(na, kxx) \ + #define KB_MATRIX_LAYER_SET_ALL(na, kxx) \ LAYER( \ na, \ \ @@ -88,8 +87,8 @@ kxx,kxx,kxx,kxx,kxx,kxx, \ kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ kxx,kxx,kxx,kxx,kxx, \ - kxx, \ - kxx, kxx, \ + kxx,kxx, \ + kxx,kxx,kxx, \ kxx,kxx,kxx, \ \ kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ @@ -97,10 +96,9 @@ kxx,kxx,kxx,kxx,kxx,kxx, \ kxx,kxx,kxx,kxx,kxx,kxx,kxx, \ kxx,kxx,kxx,kxx,kxx, \ - kxx, \ - kxx, kxx, \ - kxx,kxx,kxx ) - + kxx,kxx, \ + kxx,kxx,kxx, \ + kxx,kxx,kxx ) \ #endif diff --git a/src/keyboard/ergodox/mcp23018.c b/src/keyboard/ergodox/mcp23018.c deleted file mode 100644 index 793d332..0000000 --- a/src/keyboard/ergodox/mcp23018.c +++ /dev/null @@ -1,143 +0,0 @@ -/* ---------------------------------------------------------------------------- - * ergoDOX controller: MCP23018 specific code - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#include -#include "lib/data-types.h" -#include "lib/twi.h" // `TWI_FREQ` defined in "teensy-2-0.c" - -#include "matrix.h" -#include "mcp23018--private.h" - - -// register addresses (see "mcp23018.md") -#define IODIRA 0x00 // i/o direction register -#define IODIRB 0x01 -#define GPPUA 0x0C // GPIO pull-up resistor register -#define GPPUB 0x0D -#define GPIOA 0x12 // general purpose i/o port register (write modifies OLAT) -#define GPIOB 0x13 -#define OLATA 0x14 // output latch register -#define OLATB 0x15 - -// TWI aliases -#define TWI_ADDR_WRITE ( (MCP23018_TWI_ADDRESS<<1) | TW_WRITE ) -#define TWI_ADDR_READ ( (MCP23018_TWI_ADDRESS<<1) | TW_READ ) - - -/* returns: - * - success: 0 - * - failure: twi status code - * - * notes: - * - `twi_stop()` must be called *exactly once* for each twi block, the way - * things are currently set up. this may change in the future. - */ -uint8_t mcp23018_init(void) { - uint8_t ret; - - // set pin direction - // - unused : input : 1 - // - row : input : 1 - // - column : output : 0 - twi_start(); - ret = twi_send(TWI_ADDR_WRITE); - if (ret) goto out; // make sure we got an ACK - twi_send(IODIRA); - twi_send(0b11111111); // IODIRA - twi_send(0b10000000); // IODIRB - twi_stop(); - - // set pull-up - // - unused : on : 1 - // - rows : on : 1 - // - columns : off : 0 - twi_start(); - ret = twi_send(TWI_ADDR_WRITE); - if (ret) goto out; // make sure we got an ACK - twi_send(GPPUA); - twi_send(0b11111111); // GPPUA - twi_send(0b10000000); // GPPUB - twi_stop(); - - // set logical value (doesn't matter on inputs) - // - unused : high (hi-Z) : 1 - // - rows : high (hi-Z) : 1 - // - columns : high (hi-Z) : 1 - twi_start(); - ret = twi_send(TWI_ADDR_WRITE); - if (ret) goto out; // make sure we got an ACK - twi_send(OLATA); - twi_send(0b11111111); //OLATA - twi_send(0b11111111); //OLATB - -out: - twi_stop(); - return ret; -} - -/* returns: - * - success: 0 - * - failure: twi status code - */ -#if KB_ROWS != 12 || KB_COLUMNS != 7 - #error "Expecting different keyboard dimensions" -#endif -uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { - uint8_t ret, data; - - // initialize things, just to make sure - // - it's not appreciably faster to skip this, and it takes care of the - // case when the i/o expander isn't plugged in during the first - // init() - ret = mcp23018_init(); - - // if there was an error - if (ret) { - // clear our part of the matrix - for (uint8_t row=0x6; row<=0xB; row++) - for (uint8_t col=0; col<=6; col++) - matrix[row][col] = 0; - - return ret; - } - - // update our part of the matrix - for (uint8_t col=0; col<=6; col++) { - // set active column low : 0 - // set other columns high (hi-Z) : 1 - twi_start(); - twi_send(TWI_ADDR_WRITE); - twi_send(OLATB); - twi_send( 0xFF & ~(1< + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef KEYBOARD__ERGODOX__OPTIONS_h + #define KEYBOARD__ERGODOX__OPTIONS_h + + // -------------------------------------------------------------------- + + /* + * DRIVE_ROWS and DRIVE_COLUMNS + * - Select which pins will drive (alternate between hi-Z and drive + * low) and which will be inputs + * + * Notes + * - You must set exactly one of each 'TEENSY' macro, and of each + * 'MCP23018' macro + * - If you are using internal diodes (inside the key switches)... then + * i don't know what to tell you. You will set one chip to drive + * rows, and the other to drive columns, but i don't have a key + * switch to check which at the moment, and i couldn't seem to find + * it online. + * - If the diode cathode is towards the square solder pad, set + * #define TEENSY__DRIVE_COLUMNS 1 + * #define MCP23018__DRIVE_COLUMNS 1 + * - If the diode cathode is towards the circular solder pad, set + * #define TEENSY__DRIVE_ROWS 1 + * #define MCP23018__DRIVE_ROWS 1 + */ + #define TEENSY__DRIVE_ROWS 0 + #define TEENSY__DRIVE_COLUMNS 1 + #define MCP23018__DRIVE_ROWS 0 + #define MCP23018__DRIVE_COLUMNS 1 + +#endif diff --git a/src/keyboard/ergodox/teensy-2-0.c b/src/keyboard/ergodox/teensy-2-0.c deleted file mode 100644 index 3f037f0..0000000 --- a/src/keyboard/ergodox/teensy-2-0.c +++ /dev/null @@ -1,195 +0,0 @@ -/* ---------------------------------------------------------------------------- - * ergoDOX controller: Teensy 2.0 specific code - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#include -#include -#include "lib/data-types.h" -#define TWI_FREQ 400000 -#include "lib/twi.h" - -#include "matrix.h" -#include "teensy-2-0.h" -#include "teensy-2-0--private.h" - - -// processor frequency (from ) -#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) -#define CPU_16MHz 0x00 -#define CPU_8MHz 0x01 -#define CPU_4MHz 0x02 -#define CPU_2MHz 0x03 -#define CPU_1MHz 0x04 -#define CPU_500kHz 0x05 -#define CPU_250kHz 0x06 -#define CPU_125kHz 0x07 -#define CPU_62kHz 0x08 - - -/* pin macros - * - note: you can move the `UNUSED`, `ROW`, and `COLUMN` pins around, but be - * sure to keep the set of all the pins listed constant. other pins are not - * movable, and either are referenced explicitly or have macros defined for - * them elsewhere. - * - note: if you change pin assignments, please be sure to update - * "teensy-2-0.md", and the '.svg' circuit diagram. - */ -// --- helpers -#define teensypin_write(register, operation, pin) do { \ - _teensypin_write(register, operation, pin); \ - _delay_us(1); /* allow pins time to stabalize */ \ - } while(0) -#define _teensypin_write(register, operation, pin_letter, pin_number) \ - ((register##pin_letter) operation (1<<(pin_number))) - -#define teensypin_read(pin) \ - _teensypin_read(pin) -#define _teensypin_read(pin_letter, pin_number) \ - ((PIN##pin_letter) & (1<<(pin_number))) - -#define teensypin_write_all_unused(register, operation) \ - do { \ - teensypin_write(register, operation, UNUSED_0); \ - teensypin_write(register, operation, UNUSED_1); \ - teensypin_write(register, operation, UNUSED_2); \ - teensypin_write(register, operation, UNUSED_3); \ - teensypin_write(register, operation, UNUSED_4); \ - teensypin_write(register, operation, UNUSED_5); } \ - while(0) - -#define teensypin_write_all_row(register, operation) \ - do { \ - teensypin_write(register, operation, ROW_0); \ - teensypin_write(register, operation, ROW_1); \ - teensypin_write(register, operation, ROW_2); \ - teensypin_write(register, operation, ROW_3); \ - teensypin_write(register, operation, ROW_4); \ - teensypin_write(register, operation, ROW_5); } \ - while(0) - -#define teensypin_write_all_column(register, operation) \ - do { \ - teensypin_write(register, operation, COLUMN_0); \ - teensypin_write(register, operation, COLUMN_1); \ - teensypin_write(register, operation, COLUMN_2); \ - teensypin_write(register, operation, COLUMN_3); \ - teensypin_write(register, operation, COLUMN_4); \ - teensypin_write(register, operation, COLUMN_5); \ - teensypin_write(register, operation, COLUMN_6); } \ - while(0) - -#define SET |= -#define CLEAR &=~ - -// --- unused -#define UNUSED_0 B, 1 // SPI pin -#define UNUSED_1 B, 2 // SPI pin -#define UNUSED_2 B, 3 // SPI pin -#define UNUSED_3 D, 4 // hard to use with breadboard (on the end) -#define UNUSED_4 D, 5 // hard to use with breadboard (on the end) -#define UNUSED_5 E, 6 // hard to use with breadboard (internal) - -// --- rows -#define ROW_0 F, 0 -#define ROW_1 F, 1 -#define ROW_2 F, 4 -#define ROW_3 F, 5 -#define ROW_4 F, 6 -#define ROW_5 F, 7 - -// --- columns -#define COLUMN_0 B, 4 -#define COLUMN_1 C, 6 -#define COLUMN_2 C, 7 -#define COLUMN_3 D, 2 -#define COLUMN_4 D, 3 -#define COLUMN_5 D, 7 -#define COLUMN_6 B, 0 - - -/* returns - * - success: 0 - */ -uint8_t teensy_init(void) { - CPU_PRESCALE(CPU_16MHz); // speed should match F_CPU in makefile - - // onboard LED - DDRD &= ~(1<<6); // set D(6) as input - PORTD &= ~(1<<6); // set D(6) internal pull-up disabled - - // keyboard LEDs (see "PWM on ports OC1(A|B|C)" in "teensy-2-0.md") - _kb_led_all_off(); // (just to put the pins in a known state) - TCCR1A = 0b10101001; // set and configure fast PWM - TCCR1B = 0b00001001; // set and configure fast PWM - - // I2C (TWI) - twi_init(); // on pins D(1,0) - - // unused pins - teensypin_write_all_unused(DDR, CLEAR); // set as input - teensypin_write_all_unused(PORT, SET); // set internal pull-up enabled - - // rows - teensypin_write_all_row(DDR, CLEAR); // set as input - teensypin_write_all_row(PORT, SET); // set internal pull-up enabled - - // columns - teensypin_write_all_column(DDR, CLEAR); // set as input (hi-Z) - teensypin_write_all_column(PORT, CLEAR); // set internal pull-up - // disabled - - return 0; // success -} - -/* returns - * - success: 0 - */ -#if KB_ROWS != 12 || KB_COLUMNS != 7 - #error "Expecting different keyboard dimensions" -#endif -static inline void _update_rows( - bool matrix[KB_ROWS][KB_COLUMNS], uint8_t column ) { - matrix[0][column] = ! teensypin_read(ROW_0); - matrix[1][column] = ! teensypin_read(ROW_1); - matrix[2][column] = ! teensypin_read(ROW_2); - matrix[3][column] = ! teensypin_read(ROW_3); - matrix[4][column] = ! teensypin_read(ROW_4); - matrix[5][column] = ! teensypin_read(ROW_5); -} -uint8_t teensy_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { - teensypin_write(DDR, SET, COLUMN_0); // set col low (set as output) - _update_rows(matrix, 0); // read row 0..5 & update matrix - teensypin_write(DDR, CLEAR, COLUMN_0); // set col hi-Z (set as input) - - teensypin_write(DDR, SET, COLUMN_1); - _update_rows(matrix, 1); - teensypin_write(DDR, CLEAR, COLUMN_1); - - teensypin_write(DDR, SET, COLUMN_2); - _update_rows(matrix, 2); - teensypin_write(DDR, CLEAR, COLUMN_2); - - teensypin_write(DDR, SET, COLUMN_3); - _update_rows(matrix, 3); - teensypin_write(DDR, CLEAR, COLUMN_3); - - teensypin_write(DDR, SET, COLUMN_4); - _update_rows(matrix, 4); - teensypin_write(DDR, CLEAR, COLUMN_4); - - teensypin_write(DDR, SET, COLUMN_5); - _update_rows(matrix, 5); - teensypin_write(DDR, CLEAR, COLUMN_5); - - teensypin_write(DDR, SET, COLUMN_6); - _update_rows(matrix, 6); - teensypin_write(DDR, CLEAR, COLUMN_6); - - return 0; // success -} - diff --git a/src/keyboard/ergodox/matrix.c b/src/keyboard/layout.h similarity index 57% rename from src/keyboard/ergodox/matrix.c rename to src/keyboard/layout.h index 3a1f9e7..d2ccdee 100644 --- a/src/keyboard/ergodox/matrix.c +++ b/src/keyboard/layout.h @@ -1,5 +1,8 @@ /* ---------------------------------------------------------------------------- - * ergoDOX: keyboard matrix specific code + * layout specific exports + * + * Files for different keyboards are used by modifying a variable in the + * Makefile * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,14 +10,7 @@ * ------------------------------------------------------------------------- */ -#include "lib/data-types.h" - -#include "matrix.h" - - -static bool _kb_is_pressed[KB_ROWS][KB_COLUMNS]; -static bool _kb_was_pressed[KB_ROWS][KB_COLUMNS]; - -bool (*kb_is_pressed)[KB_ROWS][KB_COLUMNS] = &_kb_is_pressed; -bool (*kb_was_pressed)[KB_ROWS][KB_COLUMNS] = &_kb_was_pressed; +#include "../lib/variable-include.h" +#define INCLUDE EXP_STR( ./MAKEFILE_KEYBOARD/layout.h ) +#include INCLUDE diff --git a/src/keyboard/matrix.h b/src/keyboard/matrix.h new file mode 100644 index 0000000..ef3a2d5 --- /dev/null +++ b/src/keyboard/matrix.h @@ -0,0 +1,16 @@ +/* ---------------------------------------------------------------------------- + * matrix specific exports + * + * Files for different keyboards are used by modifying a variable in the + * Makefile + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include "../lib/variable-include.h" +#define INCLUDE EXP_STR( ./MAKEFILE_KEYBOARD/matrix.h ) +#include INCLUDE + diff --git a/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c b/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c index 46e1b20..bd759dc 100644 --- a/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c +++ b/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c @@ -34,16 +34,16 @@ **************************************************************************/ // You can change these to give your code its own name. -#define STR_MANUFACTURER L"MfgName" -#define STR_PRODUCT L"Keyboard" +#define STR_MANUFACTURER L"unspecified" // TODO +#define STR_PRODUCT L"ErgoDox ergonomic keyboard" // Mac OS-X and Linux automatically load the correct drivers. On // Windows, even though the driver is supplied by Microsoft, an // INF file is needed to load the driver. These numbers need to // match the INF file. -#define VENDOR_ID 0x16C0 -#define PRODUCT_ID 0x047C +#define VENDOR_ID 0x1d50 // Openmoko, Inc. +#define PRODUCT_ID 0x6028 // ErgoDox ergonomic keyboard // USB devices are supposed to implment a halt feature, which is @@ -89,7 +89,7 @@ static const uint8_t PROGMEM endpoint_config_table[] = { // spec and relevant portions of any USB class specifications! -static uint8_t PROGMEM device_descriptor[] = { +static const uint8_t PROGMEM device_descriptor[] = { 18, // bLength 1, // bDescriptorType 0x00, 0x02, // bcdUSB @@ -107,7 +107,7 @@ static uint8_t PROGMEM device_descriptor[] = { }; // Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60 -static uint8_t PROGMEM keyboard_hid_report_desc[] = { +static const uint8_t PROGMEM keyboard_hid_report_desc[] = { 0x05, 0x01, // Usage Page (Generic Desktop), 0x09, 0x06, // Usage (Keyboard), 0xA1, 0x01, // Collection (Application), @@ -144,7 +144,7 @@ static uint8_t PROGMEM keyboard_hid_report_desc[] = { #define CONFIG1_DESC_SIZE (9+9+9+7) #define KEYBOARD_HID_DESC_OFFSET (9+9) -static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = { +static const uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = { // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 9, // bLength; 2, // bDescriptorType; @@ -191,17 +191,17 @@ struct usb_string_descriptor_struct { uint8_t bDescriptorType; int16_t wString[]; }; -static struct usb_string_descriptor_struct PROGMEM string0 = { +static const struct usb_string_descriptor_struct PROGMEM string0 = { 4, 3, {0x0409} }; -static struct usb_string_descriptor_struct PROGMEM string1 = { +static const struct usb_string_descriptor_struct PROGMEM string1 = { sizeof(STR_MANUFACTURER), 3, STR_MANUFACTURER }; -static struct usb_string_descriptor_struct PROGMEM string2 = { +static const struct usb_string_descriptor_struct PROGMEM string2 = { sizeof(STR_PRODUCT), 3, STR_PRODUCT @@ -214,7 +214,7 @@ static struct descriptor_list_struct { uint16_t wIndex; const uint8_t *addr; uint8_t length; -} PROGMEM descriptor_list[] = { +} const PROGMEM descriptor_list[] = { {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)}, {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)}, {0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)}, diff --git a/src/lib/data-types/linked-list.c b/src/lib/data-types/linked-list.c deleted file mode 100644 index 97dc1f8..0000000 --- a/src/lib/data-types/linked-list.c +++ /dev/null @@ -1,240 +0,0 @@ -/* ---------------------------------------------------------------------------- - * linked list - * - * Notes: - * - When 'position' is used, it referes to the position of the node in the - * list, not the node's offset. E.g. the node with position == 1 is the - * first node in the list. - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#include -#include "lib/data-types.h" - -#include "linked-list.h" - - -// local macros (undefined later) -#define _NEW_POINTER(type, name) type * name = (type *) malloc(sizeof(type)) -#define _list_t linked_list_t -#define _node_t linked_list_node_t -#define _data_t LINKED_LIST_DATA_TYPE - - -/* - * new() - * - * Returns - * - success: a pointer to a new linked list - * - failure: NULL - */ -_list_t * linked_list_new(void) { - _NEW_POINTER(_list_t, list); - if (!list) return NULL; - - list->head = NULL; - list->tail = NULL; - - list->length = 0; - return list; -} - -/* - * insert() - * - * Arguments - * - index: the index of the position that the new node will occupy. if index - * is negative, we set index += length (as in Python). so: - * - 0 => the first node in the list - * - 1 => the second node in the list - * - -1 => the last node in the list - * - -2 => the second from the last node in the list - * - '0' is undefined (returns 'failure') - * - out of bounds positions wrap around, so: - * - [length] => 0 => the first node in the list - * - -[length+1] => -1 => the last node in the list - * - * Returns - * - success: the pointer to the list that was passed - * - failure: NULL - */ -_list_t * linked_list_insert(_list_t * list, _data_t data, int index) { - _NEW_POINTER(_node_t, node); - if (!node) return NULL; - - node->data = data; - - if (list->length == 0) { - // insert as only node (no others exist yet) - list->head = node; - list->tail = node; - node->next = NULL; - } else { - // find positive, in-bounds index - index = index % list->length; - if (index < 0) - index += list->length; - - if (index == 0) { - // insert as first node - node->next = list->head; - list->head = node; - } else if (index == list->length-1) { - // insert as last node - list->tail->next = node; - list->tail = node; - node->next = NULL; - } else { - // insert as other node - _node_t * previous = list->head; - for (int i=1; inext; - node->next = previous->next; - previous->next = node; - } - } - - list->length++; - return list; -} - -/* - * peek() - * - * Arguments - * - index: [see 'insert()'] - * - * Returns - * - success: the data field of the node at the given index - * - failure: (_data_t) 0 - */ -_data_t linked_list_peek(_list_t * list, int index) { - // if: no nodes exist - if (list->length == 0) - return (_data_t) 0; - - // find positive, in-bounds index - index = index % list->length; - if (index < 0) - index += list->length; - - // if: last node - if (index == list->length-1) - return list->tail->data; - - // else - _node_t * node = list->head; - for (int i=0; inext; - return node->data; -} - -/* - * pop() - * - * Arguments - * - index: [see 'insert()'] - * - * Returns - * - success: the data field of the node at the given index - * - failure: (_data_t) 0 - */ -_data_t linked_list_pop(_list_t * list, int index) { - // if: no nodes exist - if (list->length == 0) - return (_data_t) 0; - - // find positive, in-bounds index - index = index % list->length; - if (index < 0) - index += list->length; - - // vars - _data_t data; - _node_t * node; - - if (index == 0) { - // pop first node - data = list->head->data; - node = list->head; - list->head = node->next; - } else { - // find the index-1'th node - _node_t * previous; - previous = list->head; - for (int i=1; inext; - - // if: last node - if (index == list->length-1) - list->tail = previous; - - // pop the node at index - data = previous->next->data; - node = previous->next; - previous->next = node->next; - } - - free(node); - - list->length--; - return data; -} - -/* - * find() - * TODO - */ -// TODO - -/* - * copy() - * - * Returns - * - success: a new pointer to a (deep) copy of the list that was passed - * - failure: NULL - */ -_list_t * linked_list_copy(_list_t * list) { - _NEW_POINTER(_list_t, copy); - if (!copy) return NULL; - - bool error; - _node_t * node = list->head; - for (uint8_t i=0; i<(list->length); i++) { - error = ! linked_list_insert(copy, node->data, -1); - if (error) { - linked_list_free(copy); - return NULL; - } - node = node->next; - } - - return copy; -} - -/* - * free() - * - Free the memory allocated to all the nodes, then free the memory allocated - * to the list. - */ -void linked_list_free(_list_t * list) { - _node_t * node; - for (uint8_t i=0; i<(list->length); i++) { - node = list->head; - list->head = list->head->next; - free(node); - } - free(list); -} - - -// local macros (undefined here) -#undef _NEW_POINTER -#undef _list_t -#undef _node_t -#undef _data_t - diff --git a/src/lib/data-types/linked-list.h b/src/lib/data-types/linked-list.h deleted file mode 100644 index a73ea82..0000000 --- a/src/lib/data-types/linked-list.h +++ /dev/null @@ -1,55 +0,0 @@ -/* ---------------------------------------------------------------------------- - * linked list : exports - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#ifndef LINKED_LIST_h - #define LINKED_LIST_h - - #include "lib/data-types.h" - - - // default data type for the list - #ifndef LINKED_LIST_DATA_TYPE - #define LINKED_LIST_DATA_TYPE uint8_t - #endif - - - // structs - struct linked_list_node { - LINKED_LIST_DATA_TYPE data; - struct linked_list_node * next; - }; - - struct linked_list { - uint8_t length; - struct linked_list_node * head; - struct linked_list_node * tail; - }; - - // typedefs - typedef struct linked_list linked_list_t; - typedef struct linked_list_node linked_list_node_t; - - // functions - #define _list_t linked_list_t - #define _data_t LINKED_LIST_DATA_TYPE - // TODO - _list_t * linked_list_new (void); - _list_t * linked_list_add_head (_list_t * list, _data_t data); - _list_t * linked_list_add_tail (_list_t * list, _data_t data); - _data_t linked_list_pop_head (_list_t * list); - _data_t linked_list_pop_tail (_list_t * list); - _data_t linked_list_read (_list_t * list, uint8_t position); - _list_t * linked_list_copy (_list_t * list); - void linked_list_free (_list_t * list); - // /TODO - #undef _list_t - #undef _data_t - -#endif - diff --git a/src/lib/data-types.h b/src/lib/data-types/misc.h similarity index 72% rename from src/lib/data-types.h rename to src/lib/data-types/misc.h index 4c625a4..aee38d5 100644 --- a/src/lib/data-types.h +++ b/src/lib/data-types/misc.h @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- - * Common data types + * miscellaneous data types * ---------------------------------------------------------------------------- * Copyright (c) 2012 Ben Blazak * Released under The MIT License (MIT) (see "license.md") @@ -7,13 +7,10 @@ * ------------------------------------------------------------------------- */ -#ifndef DATA_TYPES_h - #define DATA_TYPES_h +#ifndef LIB__DATA_TYPES_h + #define LIB__DATA_TYPES_h - #include - #include - #include - #include "data-types/linked-list.h" + typedef void (*void_funptr_t)(void); #endif diff --git a/src/lib/key-functions--private.h b/src/lib/key-functions--private.h deleted file mode 100644 index ee9c979..0000000 --- a/src/lib/key-functions--private.h +++ /dev/null @@ -1,28 +0,0 @@ -/* ---------------------------------------------------------------------------- - * key functions: private - * - * Things to be used only by keyfunctions. Exported any layouts would like to - * use these functions to help define their own. - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#ifndef KEY_FUNCTIONS_h_PRIVATE - #define KEY_FUNCTIONS_h_PRIVATE - - void _press_release(bool pressed, uint8_t keycode); - void _layer_set_current( - uint8_t value, - uint8_t * current_layer, - uint8_t (*current_layers_)[KB_ROWS][KB_COLUMNS] ); - void _layer_set_mask( - uint8_t layer, - bool positions[KB_ROWS][KB_COLUMNS], - uint8_t (*current_layers)[KB_ROWS][KB_COLUMNS] ); - bool _is_pressed(uint8_t keycode); - -#endif - diff --git a/src/lib/key-functions.c b/src/lib/key-functions.c deleted file mode 100644 index c7f2e2c..0000000 --- a/src/lib/key-functions.c +++ /dev/null @@ -1,510 +0,0 @@ -/* ---------------------------------------------------------------------------- - * key functions: code - * - * These functions may do.. pretty much anything rational that thay like. If - * they want keycodes to be sent to the host in an aggrate report, they're - * responsible for modifying the appropriate report variables. - * ---------------------------------------------------------------------------- - * Copyright (c) 2012 Ben Blazak - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#include -#include "lib-other/pjrc/usb_keyboard/usb_keyboard.h" -#include "lib/data-types.h" -#include "lib/usb/usage-page/keyboard.h" -#include "keyboard.h" - -#include "key-functions.h" -#include "key-functions--private.h" - - -// ---------------------------------------------------------------------------- -// public functions (not for keys) -// ---------------------------------------------------------------------------- - -/* - * Exec key - * - Execute the keypress or keyrelease function (if it exists) of the key at - * the current possition. Pass the keycode at the current position, and pass - * all other arguments as received - */ -void _kbfun_exec_key( KBFUN_FUNCTION_ARGS ) { - kbfun_funptr_t key_function = - ( (pressed_) - ? kb_layout_press_get(layer_, *row_, *col_) - : kb_layout_release_get(layer_, *row_, *col_) ); - - if (key_function) - (*key_function)( - pressed_, - kb_layout_get(layer_, *row_, *col_), - layer_, - row_, - col_, - current_layer_, - current_layers_, - pressed_layers_ ); -} - - -// ---------------------------------------------------------------------------- -// private functions -// ---------------------------------------------------------------------------- - -/* - * Generate a normal keypress or keyrelease - * - * Arguments - * - keycode: the keycode to use - * - pressed: whether to generate a keypress (true) or keyrelease (false) - * - * Note - * - Because of the way USB does things, what this actually does is either add - * or remove 'keycode' from the list of currently pressed keys, to be sent at - * the end of the current cycle (see main.c) - */ -void _press_release(bool pressed, uint8_t keycode) { - // no-op - if (keycode == 0) - return; - - // modifier keys - switch (keycode) { - case KEY_LeftControl: (pressed) - ? (keyboard_modifier_keys |= (1<<0)) - : (keyboard_modifier_keys &= ~(1<<0)); - return; - case KEY_LeftShift: (pressed) - ? (keyboard_modifier_keys |= (1<<1)) - : (keyboard_modifier_keys &= ~(1<<1)); - return; - case KEY_LeftAlt: (pressed) - ? (keyboard_modifier_keys |= (1<<2)) - : (keyboard_modifier_keys &= ~(1<<2)); - return; - case KEY_LeftGUI: (pressed) - ? (keyboard_modifier_keys |= (1<<3)) - : (keyboard_modifier_keys &= ~(1<<3)); - return; - case KEY_RightControl: (pressed) - ? (keyboard_modifier_keys |= (1<<4)) - : (keyboard_modifier_keys &= ~(1<<4)); - return; - case KEY_RightShift: (pressed) - ? (keyboard_modifier_keys |= (1<<5)) - : (keyboard_modifier_keys &= ~(1<<5)); - return; - case KEY_RightAlt: (pressed) - ? (keyboard_modifier_keys |= (1<<6)) - : (keyboard_modifier_keys &= ~(1<<6)); - return; - case KEY_RightGUI: (pressed) - ? (keyboard_modifier_keys |= (1<<7)) - : (keyboard_modifier_keys &= ~(1<<7)); - return; - } - - // all others - for (uint8_t i=0; i<6; i++) { - if (pressed) { - if (keyboard_keys[i] == 0) { - keyboard_keys[i] = keycode; - return; - } - } else { - if (keyboard_keys[i] == keycode) { - keyboard_keys[i] = 0; - return; - } - } - } -} - -/* - * Set current layer - * - Sets any keys currently set to the overall current layer to the new layer, - * and then sets the overall current layer - * - * Arguments - * - layer: the new layer value - * - current_layer: (a pointer to) the overall current layer (see main.c) - * - current_layers: (a pointer to a matrix of) the current layer for each key - * (see main.c and lib/key-functions.h) - * - * Note - * - Leaving all non-current layer values alone allows changing layers while - * maintaining a possibly enabled layer mask (as might be used to implement - * firmware enabled numlock) - */ -void _layer_set_current( - uint8_t layer, - uint8_t * current_layer, - uint8_t (*current_layers)[KB_ROWS][KB_COLUMNS] ) { - - // don't switch to out-of-bounds layers - if ( layer < 0 || layer >= KB_LAYERS ) - return; - - for (uint8_t row=0; row= KB_LAYERS ) - return; - - for (uint8_t row=0; row capslock - * - When assigned to two keys (e.g. the physical left and right shift keys) - * (in both the press and release matrices), pressing and holding down one of - * the keys will make the second key toggle capslock - * - * Note - * - If either of the shifts are pressed when the second key is pressed, they - * wil be released so that capslock will register properly when pressed. - * Capslock will then be pressed and released, and the original state of the - * shifts will be restored - */ -void kbfun_2_keys_capslock_press_release( KBFUN_FUNCTION_ARGS ) { - static uint8_t keys_pressed; - static bool lshift_pressed; - static bool rshift_pressed; - - if (!pressed_) keys_pressed--; - - // take care of the key that was actually pressed - _press_release(pressed_, keycode_); - - // take care of capslock (only on the press of the 2nd key) - if (keys_pressed == 1 && pressed_) { - // save the state of left and right shift - lshift_pressed = _is_pressed(KEY_LeftShift); - rshift_pressed = _is_pressed(KEY_RightShift); - // disable both - _press_release(false, KEY_LeftShift); - _press_release(false, KEY_RightShift); - - // press capslock, then release it - _press_release(true, KEY_CapsLock); - usb_keyboard_send(); - _press_release(false, KEY_CapsLock); - usb_keyboard_send(); - - // restore the state of left and right shift - if (lshift_pressed) - _press_release(true, KEY_LeftShift); - if (rshift_pressed) - _press_release(true, KEY_RightShift); - } - - if (pressed_) keys_pressed++; -} - - -// TODO: maybe the numpad functions (and other logical sets of functions?) need -// to be in (a) seaparate file(s). -/* ---------------------------------------------------------------------------- - * Numpad functions - * - Functions to implement an embedded numpad - * - * Notes - * - The numpad is toggled by shifting (without changing the overall current - * layer) the layer of the keys specified in this function to the value - * specified in the keymap - * - When the numpad is toggled, the numlock is set to on (for active) or off - * (for inactive) as well - * - All these functions cooperate, but if more than one layer mask of this - * type is used (by a different set of functions) at the same time, the - * second will override the first, and any keys covered by both will be reset - * to the overall current layer when either is released (even if the other is - * still pressed) - * ------------------------------------------------------------------------- */ - -// prefix function (undefined later) -// - to keep these names reasonable in this block, and obviously not global -// outside it -// - 'L' is for 'local' -#define L(name) _kbfun_layermask_numpad__##name - -// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - -// vars -static bool L(numpad_activated) = false; -static bool L(layer_mask)[KB_ROWS][KB_COLUMNS] = - MATRIX_LAYER( - // unused - 0, - - // left hand - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, - 0, 0, - 0, 0, 0, - - // right hand - 0, 0, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 0, - 0, 1, 1, 1, 1, 0, - 0, 0, 1, 1, 1, 1, 0, - 0, 0, 0, 0, 0, - 0, - 0, 0, - 0, 0, 0 ); - -// functions -static inline void L(toggle_numlock)(void) { - _press_release(true, KEYPAD_NumLock_Clear); - usb_keyboard_send(); - _press_release(false, KEYPAD_NumLock_Clear); - usb_keyboard_send(); -} - -static void L(toggle_numpad)( - uint8_t numpad_layer, - uint8_t current_layer, - uint8_t (*current_layers)[KB_ROWS][KB_COLUMNS] ) { - - if (L(numpad_activated)) { - // deactivate numpad - _layer_set_mask(current_layer, L(layer_mask), current_layers); - L(numpad_activated) = false; - - // if: numlock on - if (keyboard_leds & (1<<0)) - L(toggle_numlock)(); - } else { - // activate numpad - _layer_set_mask(numpad_layer, L(layer_mask), current_layers); - L(numpad_activated) = true; - - // if: numlock off - if (!(keyboard_leds & (1<<0))) - L(toggle_numlock)(); - } -} - -// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - -/* - * Numpad toggle - * - Toggles the numpad and sets numlock on (for active) or off (for inactive) - * with it, if it's not already in that state - */ -void kbfun_layermask_numpad_toggle( KBFUN_FUNCTION_ARGS ) { - L(toggle_numpad)(keycode_, *current_layer_, current_layers_); -} - -/* - * Numpad on - * - Set the numpad on (along with numlock, if it's not already) - */ -void kbfun_layermask_numpad_on( KBFUN_FUNCTION_ARGS ) { - if (!L(numpad_activated)) - L(toggle_numpad)(keycode_, *current_layer_, current_layers_); -} - -/* - * Numpad off - * - Set the numpad off (along with numlock, if it's not already) - */ -void kbfun_layermask_numpad_off( KBFUN_FUNCTION_ARGS ) { - if (L(numpad_activated)) - L(toggle_numpad)(keycode_, *current_layer_, current_layers_); -} - -// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - -// prefix function (undefined here) -#undef L - -/* ---------------------------------------------------------------------------- - * ------------------------------------------------------------------------- */ - - -// ---------------------------------------------------------------------------- -// public functions (device specific) -// ---------------------------------------------------------------------------- - -void kbfun_jump_to_bootloader( KBFUN_FUNCTION_ARGS ) { - - // from PJRC (slightly modified) - // -#if MAKEFILE_BOARD == teensy-2-0 - // --- for all Teensy boards - cli(); - - // disable watchdog, if enabled - // disable all peripherals - UDCON = 1; - USBCON = (1< - * Released under The MIT License (MIT) (see "license.md") - * Project located at - * ------------------------------------------------------------------------- */ - - -#ifndef KEY_FUNCTIONS_h - #define KEY_FUNCTIONS_h - - #include "lib/data-types.h" - - // -------------------------------------------------------------------- - // include the appropriate 'matrix.h' - // ------- - // we're not simply including 'keyboard.h' here because this header is - // meant to be included by 'keyboard/layout/*.c', which is indirectly - // included by 'keyboard.h'; and that would lead to a circular include, - // which gcc might (depending on the order of include statements it - // encounters) deal with by processing this file before 'matrix.h', - // which would give us undefined macros here - #undef _str - #undef _expstr - #undef _inc - #define _str(s) #s // stringify - #define _expstr(s) _str(s) // expand -> stringify - #define _inc _expstr(keyboard/MAKEFILE_KEYBOARD/matrix.h) // inc(lude) - #include _inc - #undef _str - #undef _expstr - #undef _inc - // -------------------------------------------------------------------- - - - #define KBFUN_FUNCTION_ARGS \ - bool pressed_, \ - uint8_t keycode_, \ - uint8_t layer_, \ - uint8_t * row_, \ - uint8_t * col_, \ - uint8_t * current_layer_, \ - uint8_t (*current_layers_)[KB_ROWS][KB_COLUMNS], \ - uint8_t (*pressed_layers_)[KB_ROWS][KB_COLUMNS] - - typedef void (*kbfun_funptr_t)( KBFUN_FUNCTION_ARGS ); - - void _kbfun_exec_key ( KBFUN_FUNCTION_ARGS ); - - void kbfun_press_release (KBFUN_FUNCTION_ARGS); - void kbfun_toggle (KBFUN_FUNCTION_ARGS); - void kbfun_layer_inc (KBFUN_FUNCTION_ARGS); - void kbfun_layer_dec (KBFUN_FUNCTION_ARGS); - void kbfun_layer_inc_exec (KBFUN_FUNCTION_ARGS); - void kbfun_layer_dec_exec (KBFUN_FUNCTION_ARGS); - void kbfun_2_keys_capslock_press_release (KBFUN_FUNCTION_ARGS); - void kbfun_layermask_numpad_toggle (KBFUN_FUNCTION_ARGS); - void kbfun_layermask_numpad_on (KBFUN_FUNCTION_ARGS); - void kbfun_layermask_numpad_off (KBFUN_FUNCTION_ARGS); - void kbfun_jump_to_bootloader (KBFUN_FUNCTION_ARGS); - -#endif - diff --git a/src/lib/key-functions/private.c b/src/lib/key-functions/private.c new file mode 100644 index 0000000..6501449 --- /dev/null +++ b/src/lib/key-functions/private.c @@ -0,0 +1,121 @@ +/* ---------------------------------------------------------------------------- + * key functions : private : code + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include +#include +#include "../../lib-other/pjrc/usb_keyboard/usb_keyboard.h" +#include "../../lib/usb/usage-page/keyboard.h" +#include "../../keyboard/layout.h" +#include "../../keyboard/matrix.h" +#include "../../main.h" +#include "./public.h" + +// ---------------------------------------------------------------------------- + +/* + * Generate a normal keypress or keyrelease + * + * Arguments + * - press: whether to generate a keypress (true) or keyrelease (false) + * - keycode: the keycode to use + * + * Note + * - Because of the way USB does things, what this actually does is either add + * or remove 'keycode' from the list of currently pressed keys, to be sent at + * the end of the current cycle (see main.c) + */ +void _kbfun_press_release(bool press, uint8_t keycode) { + // no-op + if (keycode == 0) + return; + + // modifier keys + switch (keycode) { + case KEY_LeftControl: (press) + ? (keyboard_modifier_keys |= (1<<0)) + : (keyboard_modifier_keys &= ~(1<<0)); + return; + case KEY_LeftShift: (press) + ? (keyboard_modifier_keys |= (1<<1)) + : (keyboard_modifier_keys &= ~(1<<1)); + return; + case KEY_LeftAlt: (press) + ? (keyboard_modifier_keys |= (1<<2)) + : (keyboard_modifier_keys &= ~(1<<2)); + return; + case KEY_LeftGUI: (press) + ? (keyboard_modifier_keys |= (1<<3)) + : (keyboard_modifier_keys &= ~(1<<3)); + return; + case KEY_RightControl: (press) + ? (keyboard_modifier_keys |= (1<<4)) + : (keyboard_modifier_keys &= ~(1<<4)); + return; + case KEY_RightShift: (press) + ? (keyboard_modifier_keys |= (1<<5)) + : (keyboard_modifier_keys &= ~(1<<5)); + return; + case KEY_RightAlt: (press) + ? (keyboard_modifier_keys |= (1<<6)) + : (keyboard_modifier_keys &= ~(1<<6)); + return; + case KEY_RightGUI: (press) + ? (keyboard_modifier_keys |= (1<<7)) + : (keyboard_modifier_keys &= ~(1<<7)); + return; + } + + // all others + for (uint8_t i=0; i<6; i++) { + if (press) { + if (keyboard_keys[i] == 0) { + keyboard_keys[i] = keycode; + return; + } + } else { + if (keyboard_keys[i] == keycode) { + keyboard_keys[i] = 0; + return; + } + } + } +} + +/* + * Is the given keycode pressed? + */ +bool _kbfun_is_pressed(uint8_t keycode) { + // modifier keys + switch (keycode) { + case KEY_LeftControl: if (keyboard_modifier_keys & (1<<0)) + return true; + case KEY_LeftShift: if (keyboard_modifier_keys & (1<<1)) + return true; + case KEY_LeftAlt: if (keyboard_modifier_keys & (1<<2)) + return true; + case KEY_LeftGUI: if (keyboard_modifier_keys & (1<<3)) + return true; + case KEY_RightControl: if (keyboard_modifier_keys & (1<<4)) + return true; + case KEY_RightShift: if (keyboard_modifier_keys & (1<<5)) + return true; + case KEY_RightAlt: if (keyboard_modifier_keys & (1<<6)) + return true; + case KEY_RightGUI: if (keyboard_modifier_keys & (1<<7)) + return true; + } + + // all others + for (uint8_t i=0; i<6; i++) + if (keyboard_keys[i] == keycode) + return true; + + return false; +} + diff --git a/src/lib/key-functions/private.h b/src/lib/key-functions/private.h new file mode 100644 index 0000000..a24121f --- /dev/null +++ b/src/lib/key-functions/private.h @@ -0,0 +1,26 @@ +/* ---------------------------------------------------------------------------- + * key functions : private : exports + * + * Things to be used only by keyfunctions. Exported so layouts can use these + * functions to help define their own, if they like. + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef LIB__KEY_FUNCTIONS__INTERNAL_h + #define LIB__KEY_FUNCTIONS__INTERNAL_h + + #include + #include + #include "../../keyboard/matrix.h" + + // -------------------------------------------------------------------- + + void _kbfun_press_release (bool press, uint8_t keycode); + bool _kbfun_is_pressed (uint8_t keycode); + +#endif + diff --git a/src/lib/key-functions/public.h b/src/lib/key-functions/public.h new file mode 100644 index 0000000..a8e0beb --- /dev/null +++ b/src/lib/key-functions/public.h @@ -0,0 +1,55 @@ +/* ---------------------------------------------------------------------------- + * key functions : public exports + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef LIB__KEY_FUNCTIONS__COMMON_h + #define LIB__KEY_FUNCTIONS__COMMON_h + + #include + #include + + // -------------------------------------------------------------------- + + // basic + void kbfun_press_release (void); + void kbfun_toggle (void); + void kbfun_transparent (void); + // --- layer push/pop functions + void kbfun_layer_push_1 (void); + void kbfun_layer_push_2 (void); + void kbfun_layer_push_3 (void); + void kbfun_layer_push_4 (void); + void kbfun_layer_push_5 (void); + void kbfun_layer_push_6 (void); + void kbfun_layer_push_7 (void); + void kbfun_layer_push_8 (void); + void kbfun_layer_push_9 (void); + void kbfun_layer_push_10 (void); + void kbfun_layer_pop_1 (void); + void kbfun_layer_pop_2 (void); + void kbfun_layer_pop_3 (void); + void kbfun_layer_pop_4 (void); + void kbfun_layer_pop_5 (void); + void kbfun_layer_pop_6 (void); + void kbfun_layer_pop_7 (void); + void kbfun_layer_pop_8 (void); + void kbfun_layer_pop_9 (void); + void kbfun_layer_pop_10 (void); + // --- + + // device + void kbfun_jump_to_bootloader (void); + + // special + void kbfun_shift_press_release (void); + void kbfun_2_keys_capslock_press_release (void); + void kbfun_layer_push_numpad (void); + void kbfun_layer_pop_numpad (void); + +#endif + diff --git a/src/lib/key-functions/public/basic.c b/src/lib/key-functions/public/basic.c new file mode 100644 index 0000000..da014e3 --- /dev/null +++ b/src/lib/key-functions/public/basic.c @@ -0,0 +1,344 @@ +/* ---------------------------------------------------------------------------- + * key functions : basic : code + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include "../../../main.h" +#include "../../../keyboard/layout.h" +#include "../public.h" +#include "../private.h" + +// ---------------------------------------------------------------------------- + +#define MAX_LAYER_PUSH_POP_FUNCTIONS 10 + +// ---------------------------------------------------------------------------- + +// convenience macros +#define LAYER main_arg_layer +#define LAYER_OFFSET main_arg_layer_offset +#define ROW main_arg_row +#define COL main_arg_col +#define IS_PRESSED main_arg_is_pressed +#define WAS_PRESSED main_arg_was_pressed + +// ---------------------------------------------------------------------------- + +/* + * [name] + * Press|Release + * + * [description] + * Generate a normal keypress or keyrelease + */ +void kbfun_press_release(void) { + uint8_t keycode = kb_layout_get(LAYER, ROW, COL); + _kbfun_press_release(IS_PRESSED, keycode); +} + +/* + * [name] + * Toggle + * + * [description] + * Toggle the key pressed or unpressed + */ +void kbfun_toggle(void) { + uint8_t keycode = kb_layout_get(LAYER, ROW, COL); + + if (_kbfun_is_pressed(keycode)) + _kbfun_press_release(false, keycode); + else + _kbfun_press_release(true, keycode); +} + +/* + * [name] + * Transparent + * + * [description] + * Execute the key that would have been executed if the current layer was not + * active + */ +void kbfun_transparent(void) { + LAYER_OFFSET++; + LAYER = main_layers_peek(LAYER_OFFSET); + main_layers_pressed[ROW][COL] = LAYER; + main_exec_key(); +} + + +/* ---------------------------------------------------------------------------- + * layer push/pop functions + * ------------------------------------------------------------------------- */ + +static layer_ids[MAX_LAYER_PUSH_POP_FUNCTIONS]; + +static void layer_push(uint8_t local_id) { + uint8_t keycode = kb_layout_get(LAYER, ROW, COL); + main_layers_pop_id(layer_ids[local_id]); + layer_ids[local_id] = main_layers_push(keycode); +} + +static void layer_pop(uint8_t local_id) { + main_layers_pop_id(layer_ids[local_id]); + layer_ids[local_id] = 0; +} + +/* + * [name] + * Layer push #1 + * + * [description] + * Push a layer element containing the layer value specified in the keymap to + * the top of the stack, and record the id of that layer element + */ +void kbfun_layer_push_1(void) { + layer_push(1); +} + +/* + * [name] + * Layer pop #1 + * + * [description] + * Pop the layer element created by the corresponding "layer push" function + * out of the layer stack (no matter where it is in the stack, without + * touching any other elements) + */ +void kbfun_layer_pop_1(void) { + layer_pop(1); +} + +/* + * [name] + * Layer push #2 + * + * [description] + * Push a layer element containing the layer value specified in the keymap to + * the top of the stack, and record the id of that layer element + */ +void kbfun_layer_push_2(void) { + layer_push(2); +} + +/* + * [name] + * Layer pop #2 + * + * [description] + * Pop the layer element created by the corresponding "layer push" function + * out of the layer stack (no matter where it is in the stack, without + * touching any other elements) + */ +void kbfun_layer_pop_2(void) { + layer_pop(2); +} + +/* + * [name] + * Layer push #3 + * + * [description] + * Push a layer element containing the layer value specified in the keymap to + * the top of the stack, and record the id of that layer element + */ +void kbfun_layer_push_3(void) { + layer_push(3); +} + +/* + * [name] + * Layer pop #3 + * + * [description] + * Pop the layer element created by the corresponding "layer push" function + * out of the layer stack (no matter where it is in the stack, without + * touching any other elements) + */ +void kbfun_layer_pop_3(void) { + layer_pop(3); +} + +/* + * [name] + * Layer push #4 + * + * [description] + * Push a layer element containing the layer value specified in the keymap to + * the top of the stack, and record the id of that layer element + */ +void kbfun_layer_push_4(void) { + layer_push(4); +} + +/* + * [name] + * Layer pop #4 + * + * [description] + * Pop the layer element created by the corresponding "layer push" function + * out of the layer stack (no matter where it is in the stack, without + * touching any other elements) + */ +void kbfun_layer_pop_4(void) { + layer_pop(4); +} + +/* + * [name] + * Layer push #5 + * + * [description] + * Push a layer element containing the layer value specified in the keymap to + * the top of the stack, and record the id of that layer element + */ +void kbfun_layer_push_5(void) { + layer_push(5); +} + +/* + * [name] + * Layer pop #5 + * + * [description] + * Pop the layer element created by the corresponding "layer push" function + * out of the layer stack (no matter where it is in the stack, without + * touching any other elements) + */ +void kbfun_layer_pop_5(void) { + layer_pop(5); +} + +/* + * [name] + * Layer push #6 + * + * [description] + * Push a layer element containing the layer value specified in the keymap to + * the top of the stack, and record the id of that layer element + */ +void kbfun_layer_push_6(void) { + layer_push(6); +} + +/* + * [name] + * Layer pop #6 + * + * [description] + * Pop the layer element created by the corresponding "layer push" function + * out of the layer stack (no matter where it is in the stack, without + * touching any other elements) + */ +void kbfun_layer_pop_6(void) { + layer_pop(6); +} + +/* + * [name] + * Layer push #7 + * + * [description] + * Push a layer element containing the layer value specified in the keymap to + * the top of the stack, and record the id of that layer element + */ +void kbfun_layer_push_7(void) { + layer_push(7); +} + +/* + * [name] + * Layer pop #7 + * + * [description] + * Pop the layer element created by the corresponding "layer push" function + * out of the layer stack (no matter where it is in the stack, without + * touching any other elements) + */ +void kbfun_layer_pop_7(void) { + layer_pop(7); +} + +/* + * [name] + * Layer push #8 + * + * [description] + * Push a layer element containing the layer value specified in the keymap to + * the top of the stack, and record the id of that layer element + */ +void kbfun_layer_push_8(void) { + layer_push(8); +} + +/* + * [name] + * Layer pop #8 + * + * [description] + * Pop the layer element created by the corresponding "layer push" function + * out of the layer stack (no matter where it is in the stack, without + * touching any other elements) + */ +void kbfun_layer_pop_8(void) { + layer_pop(8); +} + +/* + * [name] + * Layer push #9 + * + * [description] + * Push a layer element containing the layer value specified in the keymap to + * the top of the stack, and record the id of that layer element + */ +void kbfun_layer_push_9(void) { + layer_push(9); +} + +/* + * [name] + * Layer pop #9 + * + * [description] + * Pop the layer element created by the corresponding "layer push" function + * out of the layer stack (no matter where it is in the stack, without + * touching any other elements) + */ +void kbfun_layer_pop_9(void) { + layer_pop(9); +} + +/* + * [name] + * Layer push #10 + * + * [description] + * Push a layer element containing the layer value specified in the keymap to + * the top of the stack, and record the id of that layer element + */ +void kbfun_layer_push_10(void) { + layer_push(10); +} + +/* + * [name] + * Layer pop #10 + * + * [description] + * Pop the layer element created by the corresponding "layer push" function + * out of the layer stack (no matter where it is in the stack, without + * touching any other elements) + */ +void kbfun_layer_pop_10(void) { + layer_pop(10); +} + +/* ---------------------------------------------------------------------------- + * ------------------------------------------------------------------------- */ + diff --git a/src/lib/key-functions/public/device.c b/src/lib/key-functions/public/device.c new file mode 100644 index 0000000..6386666 --- /dev/null +++ b/src/lib/key-functions/public/device.c @@ -0,0 +1,67 @@ +/* ---------------------------------------------------------------------------- + * key functions : device specific : code + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include +#include +#include "../public.h" + + +// ---------------------------------------------------------------------------- +// descriptions +// ---------------------------------------------------------------------------- + +/* + * [name] + * Jump to Bootloader + * + * [description] + * For reflashing the controller + */ +void kbfun_jump_to_bootloader(void); + + +// ---------------------------------------------------------------------------- +#if MAKEFILE_BOARD == teensy-2-0 +// ---------------------------------------------------------------------------- + +// from PJRC (slightly modified) +// +void kbfun_jump_to_bootloader(void) { + // --- for all Teensy boards --- + + cli(); + + // disable watchdog, if enabled + // disable all peripherals + UDCON = 1; + USBCON = (1< + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#include +#include +#include "../../../lib-other/pjrc/usb_keyboard/usb_keyboard.h" +#include "../../../lib/usb/usage-page/keyboard.h" +#include "../../../keyboard/layout.h" +#include "../../../main.h" +#include "../public.h" +#include "../private.h" + +// ---------------------------------------------------------------------------- + +// convenience macros +#define LAYER main_arg_layer +#define LAYER_OFFSET main_arg_layer_offset +#define ROW main_arg_row +#define COL main_arg_col +#define IS_PRESSED main_arg_is_pressed +#define WAS_PRESSED main_arg_was_pressed + + +// ---------------------------------------------------------------------------- + + +/* + * [name] + * Shift + press|release + * + * [description] + * Generate a 'shift' press or release before the normal keypress or + * keyrelease + */ +void kbfun_shift_press_release(void) { + _kbfun_press_release(IS_PRESSED, KEY_LeftShift); + kbfun_press_release(); +} + +/* + * [name] + * Two keys => capslock + * + * [description] + * When assigned to two keys (e.g. the physical left and right shift keys) + * (in both the press and release matrices), pressing and holding down one of + * the keys will make the second key toggle capslock + * + * [note] + * If either of the shifts are pressed when the second key is pressed, they + * wil be released so that capslock will register properly when pressed. + * Capslock will then be pressed and released, and the original state of the + * shifts will be restored + */ +void kbfun_2_keys_capslock_press_release(void) { + static uint8_t keys_pressed; + static bool lshift_pressed; + static bool rshift_pressed; + + uint8_t keycode = kb_layout_get(LAYER, ROW, COL); + + if (!IS_PRESSED) keys_pressed--; + + // take care of the key that was actually pressed + _kbfun_press_release(IS_PRESSED, keycode); + + // take care of capslock (only on the press of the 2nd key) + if (keys_pressed == 1 && IS_PRESSED) { + // save the state of left and right shift + lshift_pressed = _kbfun_is_pressed(KEY_LeftShift); + rshift_pressed = _kbfun_is_pressed(KEY_RightShift); + // disable both + _kbfun_press_release(false, KEY_LeftShift); + _kbfun_press_release(false, KEY_RightShift); + + // press capslock, then release it + _kbfun_press_release(true, KEY_CapsLock); + usb_keyboard_send(); + _kbfun_press_release(false, KEY_CapsLock); + usb_keyboard_send(); + + // restore the state of left and right shift + if (lshift_pressed) + _kbfun_press_release(true, KEY_LeftShift); + if (rshift_pressed) + _kbfun_press_release(true, KEY_RightShift); + } + + if (IS_PRESSED) keys_pressed++; +} + +/* ---------------------------------------------------------------------------- + * numpad functions + * ------------------------------------------------------------------------- */ + +static uint8_t numpad_layer_id; + +static inline void numpad_toggle_numlock(void) { + _kbfun_press_release(true, KEY_LockingNumLock); + usb_keyboard_send(); + _kbfun_press_release(false, KEY_LockingNumLock); + usb_keyboard_send(); +} + +/* + * [name] + * Numpad on + * + * [description] + * Set the numpad to on (put the numpad layer, specified in the keymap, in an + * element at the top of the layer stack, and record that element's id) and + * toggle numlock (regardless of whether or not numlock is currently on) + * + * [note] + * Meant to be assigned (along with "numpad off") instead of a normal numlock + * key + */ +void kbfun_layer_push_numpad(void) { + uint8_t keycode = kb_layout_get(LAYER, ROW, COL); + main_layers_pop_id(numpad_layer_id); + numpad_layer_id = main_layers_push(keycode); + numpad_toggle_numlock(); +} + +/* + * [name] + * Numpad off + * + * [description] + * Set the numpad to off (pop the layer element created by "numpad on" out of + * the stack) and toggle numlock (regardless of whether or not numlock is + * currently on) + * + * [note] + * Meant to be assigned (along with "numpad on") instead of a normal numlock + * key + */ +void kbfun_layer_pop_numpad(void) { + main_layers_pop_id(numpad_layer_id); + numpad_layer_id = 0; + numpad_toggle_numlock(); +} + +/* ---------------------------------------------------------------------------- + * ------------------------------------------------------------------------- */ + diff --git a/src/lib/key-functions/readme.md b/src/lib/key-functions/readme.md new file mode 100644 index 0000000..6e49659 --- /dev/null +++ b/src/lib/key-functions/readme.md @@ -0,0 +1,12 @@ +# src/lib/key-functions + +These functions may do.. pretty much anything rational that they like. If they +want keycodes to be sent to the host in an aggregate report, they're responsible +for modifying the appropriate report variables. + +------------------------------------------------------------------------------- + +Copyright © 2012 Ben Blazak +Released under The MIT License (MIT) (see "license.md") +Project located at + diff --git a/src/lib/twi.h b/src/lib/twi.h index 6221bd5..85acccf 100644 --- a/src/lib/twi.h +++ b/src/lib/twi.h @@ -10,14 +10,7 @@ * ------------------------------------------------------------------------- */ -#undef _str -#undef _expstr -#undef _inc -#define _str(s) #s // stringify -#define _expstr(s) _str(s) // expand -> stringify -#define _inc _expstr(twi/MAKEFILE_BOARD.h) // inc(lude) -#include _inc -#undef _str -#undef _expstr -#undef _inc +#include "../lib/variable-include.h" +#define INCLUDE EXP_STR( ./twi/MAKEFILE_BOARD.h ) +#include INCLUDE diff --git a/src/lib/twi/teensy-2-0.c b/src/lib/twi/teensy-2-0.c index 7c3ed69..c956b38 100644 --- a/src/lib/twi/teensy-2-0.c +++ b/src/lib/twi/teensy-2-0.c @@ -21,10 +21,17 @@ * ------------------------------------------------------------------------- */ -#include -#include "lib/twi.h" +// ---------------------------------------------------------------------------- +// conditional compile +#if MAKEFILE_BOARD == teensy-2-0 +// ---------------------------------------------------------------------------- +#include +#include "./teensy-2-0.h" + +// ---------------------------------------------------------------------------- + void twi_init(void) { // set the prescaler value to 0 TWSR &= ~( (1< // ---------------------------------------------------------------------------- diff --git a/src/lib/usb/usage-page/keyboard--short-names.h b/src/lib/usb/usage-page/keyboard--short-names.h index c611e14..d666b21 100644 --- a/src/lib/usb/usage-page/keyboard--short-names.h +++ b/src/lib/usb/usage-page/keyboard--short-names.h @@ -17,7 +17,7 @@ // ---------------------------------------------------------------------------- -#include "keyboard.h" +#include "./keyboard.h" // ---------------------------------------------------------------------------- diff --git a/src/lib/variable-include.h b/src/lib/variable-include.h new file mode 100644 index 0000000..67ff6d5 --- /dev/null +++ b/src/lib/variable-include.h @@ -0,0 +1,13 @@ +/* ---------------------------------------------------------------------------- + * Macros to help with conditional includes + * ---------------------------------------------------------------------------- + * Copyright (c) 2012 Ben Blazak + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#undef INCLUDE +#define STR(s) #s // stringify +#define EXP_STR(s) STR(s) // expand -> stringify + diff --git a/src/main.c b/src/main.c index 78ec964..ac8cdc4 100644 --- a/src/main.c +++ b/src/main.c @@ -8,14 +8,45 @@ * ------------------------------------------------------------------------- */ +#include +#include #include -#include "lib-other/pjrc/usb_keyboard/usb_keyboard.h" -#include "lib/data-types.h" -#include "lib/key-functions.h" +#include "./lib-other/pjrc/usb_keyboard/usb_keyboard.h" +#include "./lib/key-functions/public.h" +#include "./keyboard/controller.h" +#include "./keyboard/layout.h" +#include "./keyboard/matrix.h" +#include "./main.h" -#include "keyboard.h" +// ---------------------------------------------------------------------------- +#define MAX_ACTIVE_LAYERS 20 +// ---------------------------------------------------------------------------- + +static bool _main_kb_is_pressed[KB_ROWS][KB_COLUMNS]; +bool (*main_kb_is_pressed)[KB_ROWS][KB_COLUMNS] = &_main_kb_is_pressed; + +static bool _main_kb_was_pressed[KB_ROWS][KB_COLUMNS]; +bool (*main_kb_was_pressed)[KB_ROWS][KB_COLUMNS] = &_main_kb_was_pressed; + +uint8_t main_layers_pressed[KB_ROWS][KB_COLUMNS]; + +uint8_t main_loop_row; +uint8_t main_loop_col; + +uint8_t main_arg_layer; +uint8_t main_arg_layer_offset; +uint8_t main_arg_row; +uint8_t main_arg_col; +bool main_arg_is_pressed; +bool main_arg_was_pressed; + +// ---------------------------------------------------------------------------- + +/* + * main() + */ int main(void) { kb_init(); // does controller initialization too @@ -28,24 +59,15 @@ int main(void) { kb_led_state_ready(); for (;;) { - // the overall current layer - static uint8_t current_layer; - // the current layer for each key - static uint8_t current_layers[KB_ROWS][KB_COLUMNS]; - // the layer each key was on when it was last pressed - static uint8_t pressed_layers[KB_ROWS][KB_COLUMNS]; + // swap `main_kb_is_pressed` and `main_kb_was_pressed`, then update + bool (*temp)[KB_ROWS][KB_COLUMNS] = main_kb_was_pressed; + main_kb_was_pressed = main_kb_is_pressed; + main_kb_is_pressed = temp; - // swap `kb_is_pressed` and `kb_was_pressed`, then update - bool (*temp)[KB_ROWS][KB_COLUMNS] = kb_was_pressed; - kb_was_pressed = kb_is_pressed; - kb_is_pressed = temp; - - kb_update_matrix(*kb_is_pressed); + kb_update_matrix(*main_kb_is_pressed); // this loop is responsible to - // - "execute" keys when they change state (call `_kbfun_exec_key()`, - // which will call the appropriate function with the appropriate - // keycode argument from the kb_layout* matrices) + // - "execute" keys when they change state // - keep track of which layers the keys were on when they were pressed // (so they can be released using the function from that layer) // @@ -53,34 +75,42 @@ int main(void) { // - everything else is the key function's responsibility // - see the keyboard layout file ("keyboard/ergodox/layout/*.c") for // which key is assigned which function (per layer) - // - see "lib/key-functions.c" for the function definitions - // - anything passed to the key function by reference is fair game for - // that function to modify - for (uint8_t row=0; row + * Released under The MIT License (MIT) (see "license.md") + * Project located at + * ------------------------------------------------------------------------- */ + + +#ifndef MAIN_h + #define MAIN_h + + #include + #include + #include "./lib/key-functions/public.h" + #include "./keyboard/matrix.h" + + // -------------------------------------------------------------------- + + extern bool (*main_kb_is_pressed)[KB_ROWS][KB_COLUMNS]; + extern bool (*main_kb_was_pressed)[KB_ROWS][KB_COLUMNS]; + + extern uint8_t main_layers_pressed[KB_ROWS][KB_COLUMNS]; + + extern uint8_t main_loop_row; + extern uint8_t main_loop_col; + + extern uint8_t main_arg_layer; + extern uint8_t main_arg_layer_offset; + extern uint8_t main_arg_row; + extern uint8_t main_arg_col; + extern bool main_arg_is_pressed; + extern bool main_arg_was_pressed; + + // -------------------------------------------------------------------- + + void main_exec_key (void); + + uint8_t main_layers_peek (uint8_t offset); + uint8_t main_layers_push (uint8_t layer); + void main_layers_pop_id (uint8_t id); + uint8_t main_layers_get_offset_id (uint8_t id); + + +#endif + diff --git a/src/makefile b/src/makefile index ccdc7ec..dc9bea9 100644 --- a/src/makefile +++ b/src/makefile @@ -13,15 +13,12 @@ # ----------------------------------------------------------------------------- -TARGET := firmware # the name we want for our program binary -FORMAT := ihex # the program binary's format -KEYBOARD := ergodox # keyboard model; see "src/keyboard" for what's available -LAYOUT := qwerty # keyboard layout; see "src/keyboard/*/layout" for what's - # available +include makefile-options -MCU := atmega32u4 # processor type (for teensy 2.0); must match real life -BOARD := teensy-2-0 # see the libraries you're using for what's available -F_CPU := 16000000 # processor speed, in Hz +FORMAT := ihex # the program binary's format +MCU := atmega32u4 # processor type (for teensy 2.0); must match real life +BOARD := teensy-2-0 # see the libraries you're using for what's available +F_CPU := 16000000 # processor speed, in Hz # firmware stuff SRC := $(wildcard *.c) @@ -32,8 +29,11 @@ LAYOUT := $(strip $(LAYOUT)) # --- include stuff SRC += $(wildcard keyboard/$(KEYBOARD)*.c) SRC += $(wildcard keyboard/$(KEYBOARD)/*.c) +SRC += $(wildcard keyboard/$(KEYBOARD)/controller/*.c) SRC += $(wildcard keyboard/$(KEYBOARD)/layout/$(LAYOUT)*.c) # library stuff +# - should be last in the list of files to compile, in case there are default +# macros that have to be overridden in other source files # - add more "*/*/..."s as necessary to compile everything. # - parts of the stuff under "lib" may not be necessary, depending on other # options, but it's all included here. hopefully any unnecessary stuff gets @@ -48,15 +48,17 @@ SRC += $(wildcard lib-other/*/*/*.c) OBJ = $(SRC:%.c=%.o) +# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CFLAGS := -mmcu=$(MCU) # processor type (teensy 2.0); must match real # life CFLAGS += -DF_CPU=$(F_CPU) # processor frequency; must match initialization # in source -CFLAGS += -I. # search for includes in the current directory # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CFLAGS += -DMAKEFILE_BOARD='$(strip $(BOARD))' CFLAGS += -DMAKEFILE_KEYBOARD='$(strip $(KEYBOARD))' CFLAGS += -DMAKEFILE_KEYBOARD_LAYOUT='$(strip $(LAYOUT))' +CFLAGS += -DMAKEFILE_DEBOUNCE_TIME='$(strip $(DEBOUNCE_TIME))' +CFLAGS += -DMAKEFILE_LED_BRIGHTNESS='$(strip $(LED_BRIGHTNESS))' # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CFLAGS += -std=gnu99 # use C99 plus GCC extensions CFLAGS += -Os # optimize for size @@ -83,6 +85,7 @@ LDFLAGS += -Wl,--gc-sections # discard unused functions and data # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . GENDEPFLAGS += -MMD -MP -MF $@.dep # generate dependency files +# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CC := avr-gcc @@ -90,10 +93,10 @@ OBJCOPY := avr-objcopy SIZE := avr-size -# remove whitespace from some of the variables -TARGET := $(strip $(TARGET)) +# remove whitespace from some of the options FORMAT := $(strip $(FORMAT)) + # ----------------------------------------------------------------------------- # ----------------------------------------------------------------------------- @@ -108,11 +111,6 @@ all: $(TARGET).hex $(TARGET).eep @echo $(SIZE) --target=$(FORMAT) $(TARGET).eep @echo - @echo '. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .' - @echo - $(SIZE) -C --mcu=atmega32u4 $(TARGET).elf - @echo '. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .' - @echo @echo 'you can load "$(TARGET).hex" and "$(TARGET).eep" onto the' @echo 'Teensy using the Teensy loader' @echo diff --git a/src/makefile-options b/src/makefile-options new file mode 100644 index 0000000..ab08efa --- /dev/null +++ b/src/makefile-options @@ -0,0 +1,26 @@ +# ----------------------------------------------------------------------------- +# certain compilations options +# ----------------------------------------------------------------------------- +# Copyright (c) 2012 Ben Blazak +# Released under The MIT License (MIT) (see "license.md") +# Project located at +# ----------------------------------------------------------------------------- + + +TARGET := firmware # the name we want for our program binary +KEYBOARD := ergodox # keyboard model; see "src/keyboard" for what's available +LAYOUT := qwerty-kinesis-mod # keyboard layout + # see "src/keyboard/*/layout" for what's + # available + +LED_BRIGHTNESS := 0.5 # a multiplier, with 1 being the max +DEBOUNCE_TIME := 5 # in ms; see keyswitch spec for necessary value; 5ms should + # be good for cherry mx switches + + +# remove whitespace +TARGET := $(strip $(TARGET)) +KEYBOARD := $(strip $(KEYBOARD)) +LAYOUT := $(strip $(LAYOUT)) +DEBOUNCE_TIME := $(strip $(DEBOUNCE_TIME)) +