diff --git a/build-scripts/gen-layout-graphic--template.svg b/build-scripts/gen-layout-graphic--template.svg new file mode 100644 index 0000000..373da08 --- /dev/null +++ b/build-scripts/gen-layout-graphic--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/build-scripts/gen-layout-graphic.py b/build-scripts/gen-layout-graphic.py new file mode 100644 index 0000000..a93e116 --- /dev/null +++ b/build-scripts/gen-layout-graphic.py @@ -0,0 +1,266 @@ +!# /usr/bin/env python3 + +import argparse +import json +import sys + +# ----------------------------------------------------------------------------- + +def main(): + arg_parser = argparse.ArgumentParser( + description = "Generate a picture of the firmware's " + + "keyboard layout" ) + + arg_parser.add_argument( + '--map-file', + required = True ) + + arg_parser.add_argument( + '--hex-file', + required = True ) + + arg_parser.add_argument( + '--eep-file', + required = True ) + + args = arg_parser.parse_args(sys.argv[1:]) + +# ----------------------------------------------------------------------------- + +if __name__ == '__main__': + main() + +# ----------------------------------------------------------------------------- + +keycode_to_string = { + 0x01: "ErrorRollOver", + 0x02: "POSTFail", + 0x03: "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: "CapsLock", + 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: "Insert", + 0x4A: "Home", + 0x4B: "PageUp", + 0x4C: "Delete", + 0x4D: "End", + 0x4E: "PageDown", + 0x4F: "\u2192", # right arrow + 0x50: "\u2190", # left arrow + 0x51: "\u2193", # down arrow + 0x52: "\u2191", # up arrow + + 0x53: "NumLock Clear", + 0x54: "/", + 0x55: "*", + 0x56: "-", + 0x57: "+", + 0x58: "Enter(kp)", + 0x59: "1 End", + 0x5A: "2 \u2193", # down arrow + 0x5B: "3 PageDown", + 0x5C: "4 \u2190", # left arrow + 0x5D: "5", + 0x5E: "6 \u2192", # right arrow + 0x5F: "7 Home", + 0x60: "8 \u2191", # up arrow + 0x61: "9 PageUp", + 0x62: "0 Insert", + 0x63: ". Del", + + 0x64: "\ |", + 0x65: "Application", + 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: "VolumeUp", + 0x81: "VolumeDown", + 0x82: "LockingCapsLock", + 0x83: "LockingNumLock", + 0x84: "LockingScrollLock", + + 0x85: ",", + 0x86: "=", + + 0x87: "International1", + 0x88: "International2", + 0x89: "International3", + 0x8A: "International4", + 0x8B: "International5", + 0x8C: "International6", + 0x8D: "International7", + 0x8E: "International8", + 0x8F: "International9", + 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: "Currency_Unit", + 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: "Decimal", + 0xDD: "Hexadecimal", + + 0xE0: "LeftControl", + 0xE1: "LeftShift", + 0xE2: "LeftAlt", + 0xE3: "LeftGUI", + 0xE4: "RightControl", + 0xE5: "RightShift", + 0xE6: "RightAlt", + 0xE7: "RightGUI", + } + diff --git a/build-scripts/gen-ui-info.py b/build-scripts/gen-ui-info.py index 2dbd169..a6df601 100755 --- a/build-scripts/gen-ui-info.py +++ b/build-scripts/gen-ui-info.py @@ -33,6 +33,14 @@ The file will contain: }, ... }, + "mappings": { + "physical-positions": [ + , ... + ], + "matrix-positions": [ + , ... + ] + }, "miscellaneous": { "git-commit-date": , "git-commit-id": , @@ -61,17 +69,13 @@ import sys # ----------------------------------------------------------------------------- -def gen_static(git_commit_date=None, git_commit_id=None): +def gen_static(current_date=None, git_commit_date=None, git_commit_id=None): """Generate static information""" - date = None - if os.name == 'posix': - date = subprocess.getoutput('date --rfc-3339 s') - return { '.meta-data': { 'version': 0, # the format version number - 'date-generated': date, + 'date-generated': current_date, }, 'miscellaneous': { 'git-commit-date': git_commit_date, # should be passed by makefile @@ -118,42 +122,19 @@ def parse_mapfile(map_file_path): } def parse_layout_matrices(f, line): - """Parse (all 3) layout matrices""" + """Parse layout matrix information in the '.map' file""" - search = re.search(r'0x\S+\s+(0x\S+)', line) - # (length for (size of, in bytes) a layer of 1 byte objects) - base_length = int( int( search.group(1), 16 ) / 5 ) + name = re.search(r'.progmem.data.(_kb_layout\S*)', line).group(1) - next_lines = ''.join([next(f), next(f), next(f)]) - layout_position = re.search( - r'(0x\S+)\s+_kb_layout'+'\n', next_lines ) . group(1) - layout_press_position = re.search( - r'(0x\S+)\s+_kb_layout_press'+'\n', next_lines ) . group(1) - layout_release_position = re.search( - r'(0x\S+)\s+_kb_layout_release'+'\n', next_lines ) . group(1) - layout_position = int(layout_position, 16) - layout_press_position = int(layout_press_position, 16) - layout_release_position = int(layout_release_position, 16) - - if not ( layout_position - and layout_press_position - and layout_release_position ): - raise Exception( - "parse_mapfile: not all layout matrices were found" ) + 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': { - '_kb_layout': { - 'position': layout_position, - 'length': base_length, - }, - '_kb_layout_press': { - 'position': layout_press_position, - 'length': base_length * 2, - }, - '_kb_layout_release': { - 'position': layout_release_position, - 'length': base_length * 2, + name: { + 'position': position, + 'length': length, }, }, } @@ -179,7 +160,7 @@ def parse_mapfile(map_file_path): return output -def parse_source_code(source_code_path): +def find_keyboard_functions(source_code_path): """Parse all files in the source directory""" def read_comments(f, line): @@ -260,13 +241,13 @@ def parse_source_code(source_code_path): }, } - # --- parse_source_code() --- + # --- find_keyboard_functions() --- # normalize paths - source_dir_path = os.path.abspath(source_code_path) + source_code_path = os.path.abspath(source_code_path) # check paths if not os.path.exists(source_code_path): - raise ValueError("invalid 'source_dir_path' given") + raise ValueError("invalid 'source_code_path' given") output = {} @@ -292,6 +273,24 @@ def parse_source_code(source_code_path): return output + +def find_mappings(matrix_file_path): + # normalize paths + matrix_file_path = os.path.abspath(matrix_file_path) + + match = re.search( + r'#define\s+KB_MATRIX_LAYER\s*\(([^)]+)\)[^{]*\{\{([^#]+)\}\}', + open(matrix_file_path).read(), + re.MULTILINE ) + + return { + "mappings": { + "physical-positions": re.findall(r'k..', match.group(1)), + "matrix-positions": re.findall(r'k..|na', match.group(2)), + }, + } + + # ----------------------------------------------------------------------------- def dict_merge(a, b): @@ -320,6 +319,11 @@ 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 " @@ -337,13 +341,20 @@ def main(): '--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 ) args = arg_parser.parse_args(sys.argv[1:]) output = {} - dict_merge(output, gen_static(args.git_commit_date, args.git_commit_id)) + 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, parse_source_code(args.source_code_path)) + dict_merge(output, find_keyboard_functions(args.source_code_path)) + dict_merge(output, find_mappings(args.matrix_file_path)) dict_merge(output, gen_derived(output)) print(json.dumps(output, sort_keys=True, indent=4)) diff --git a/makefile b/makefile index 9e3149c..9fb19f0 100644 --- a/makefile +++ b/makefile @@ -20,13 +20,22 @@ # the base name of the file or package to distribute NAME := ergodox-firmware +# the name of the keyboard we're building +# - must match the same variable in src/makefile +KEYBOARD := ergodox # 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-) +UNAME := $(shell uname) +ifeq ($(UNAME),Darwin) + DATE := gdate +else + DATE := date +endif # name to use for the final distribution file or package -TARGET := $(NAME)--$(GIT_BRANCH)--$(shell date -d "$(GIT_COMMIT_DATE)" +'%Y%m%dT%H%M%S')--$(shell echo $(GIT_COMMIT_ID) | cut -c 1-7) +TARGET := $(NAME)--$(GIT_BRANCH)--$(shell $(DATE) -d "$(GIT_COMMIT_DATE)" +'%Y%m%dT%H%M%S')--$(shell echo $(GIT_COMMIT_ID) | cut -c 1-7) # the build dir BUILD := build @@ -57,10 +66,12 @@ dist: '../$(BUILD)/$(TARGET)' ) # run secondary build scripts ( ./build-scripts/gen-ui-info.py \ + --current-date '$(shell $(DATE) --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' \ ) > '$(BUILD)/$(TARGET)/firmware--ui-info.json' # make into a zip archive ( cd '$(BUILD)/$(TARGET)'; \ 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/ergodox/layout/default--matrix-control.h b/src/keyboard/ergodox/layout/default--matrix-control.h index 9047826..d24c0e7 100644 --- a/src/keyboard/ergodox/layout/default--matrix-control.h +++ b/src/keyboard/ergodox/layout/default--matrix-control.h @@ -47,7 +47,7 @@ */ #ifndef kb_layout_get - extern uint8_t PROGMEM \ + extern const uint8_t PROGMEM \ _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS]; #define kb_layout_get(layer,row,column) \ @@ -57,7 +57,7 @@ #endif #ifndef kb_layout_press_get - extern void_funptr_t PROGMEM \ + extern const void_funptr_t PROGMEM \ _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS]; #define kb_layout_press_get(layer,row,column) \ @@ -67,7 +67,7 @@ #endif #ifndef kb_layout_release_get - extern void_funptr_t PROGMEM \ + extern const void_funptr_t PROGMEM \ _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS]; #define kb_layout_release_get(layer,row,column) \ diff --git a/src/keyboard/ergodox/layout/qwerty.c b/src/keyboard/ergodox/layout/qwerty.c index 38d33b5..9159428 100644 --- a/src/keyboard/ergodox/layout/qwerty.c +++ b/src/keyboard/ergodox/layout/qwerty.c @@ -41,7 +41,7 @@ // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- -uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { +const uint8_t PROGMEM _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { // -------------------------------------------------------------------- KB_MATRIX_LAYER( // layout: layer 0: default // unused @@ -113,7 +113,7 @@ _ctrlR, 0, _enter, // ---------------------------------------------------------------------------- -void_funptr_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { +const void_funptr_t PROGMEM _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { // -------------------------------------------------------------------- KB_MATRIX_LAYER( // press: layer 0: default // unused @@ -185,7 +185,7 @@ NULL, // ---------------------------------------------------------------------------- -void_funptr_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { +const void_funptr_t PROGMEM _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS] = { // -------------------------------------------------------------------- KB_MATRIX_LAYER( // release: layer 0: default // unused diff --git a/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c b/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c index 6bbd298..bd759dc 100644 --- a/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c +++ b/src/lib-other/pjrc/usb_keyboard/usb_keyboard.c @@ -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/makefile b/src/makefile index 15d1298..70bd3d3 100644 --- a/src/makefile +++ b/src/makefile @@ -116,11 +116,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