misc; now compiling in os x

- also starting work on a new build script (to make an svg of the
  current layout, so it's easier to visualize)
partial-rewrite
Ben Blazak 2012-10-07 00:18:59 -07:00
parent 4b21800302
commit c330126076
9 changed files with 2460 additions and 63 deletions

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 94 KiB

View File

@ -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",
}

View File

@ -33,6 +33,14 @@ The file will contain:
}, },
... ...
}, },
"mappings": {
"physical-positions": [
<string>, ...
],
"matrix-positions": [
<string>, ...
]
},
"miscellaneous": { "miscellaneous": {
"git-commit-date": <string>, "git-commit-date": <string>,
"git-commit-id": <string>, "git-commit-id": <string>,
@ -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""" """Generate static information"""
date = None
if os.name == 'posix':
date = subprocess.getoutput('date --rfc-3339 s')
return { return {
'.meta-data': { '.meta-data': {
'version': 0, # the format version number 'version': 0, # the format version number
'date-generated': date, 'date-generated': current_date,
}, },
'miscellaneous': { 'miscellaneous': {
'git-commit-date': git_commit_date, # should be passed by makefile '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): 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) name = re.search(r'.progmem.data.(_kb_layout\S*)', line).group(1)
# (length for (size of, in bytes) a layer of 1 byte objects)
base_length = int( int( search.group(1), 16 ) / 5 )
next_lines = ''.join([next(f), next(f), next(f)]) search = re.search(r'(0x\S+)\s+(0x\S+)', next(f))
layout_position = re.search( position = int( search.group(1), 16 )
r'(0x\S+)\s+_kb_layout'+'\n', next_lines ) . group(1) length = int( search.group(2), 16 )
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" )
return { return {
'layout-matrices': { 'layout-matrices': {
'_kb_layout': { name: {
'position': layout_position, 'position': position,
'length': base_length, 'length': length,
},
'_kb_layout_press': {
'position': layout_press_position,
'length': base_length * 2,
},
'_kb_layout_release': {
'position': layout_release_position,
'length': base_length * 2,
}, },
}, },
} }
@ -179,7 +160,7 @@ def parse_mapfile(map_file_path):
return output return output
def parse_source_code(source_code_path): def find_keyboard_functions(source_code_path):
"""Parse all files in the source directory""" """Parse all files in the source directory"""
def read_comments(f, line): def read_comments(f, line):
@ -260,13 +241,13 @@ def parse_source_code(source_code_path):
}, },
} }
# --- parse_source_code() --- # --- find_keyboard_functions() ---
# normalize paths # normalize paths
source_dir_path = os.path.abspath(source_code_path) source_code_path = os.path.abspath(source_code_path)
# check paths # check paths
if not os.path.exists(source_code_path): if not os.path.exists(source_code_path):
raise ValueError("invalid 'source_dir_path' given") raise ValueError("invalid 'source_code_path' given")
output = {} output = {}
@ -292,6 +273,24 @@ def parse_source_code(source_code_path):
return output 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): def dict_merge(a, b):
@ -320,6 +319,11 @@ def main():
arg_parser = argparse.ArgumentParser( arg_parser = argparse.ArgumentParser(
description = 'Generate project data for use with the UI' ) 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( arg_parser.add_argument(
'--git-commit-date', '--git-commit-date',
help = ( "should be in the format rfc-3339 " help = ( "should be in the format rfc-3339 "
@ -337,13 +341,20 @@ def main():
'--source-code-path', '--source-code-path',
help = "the path to the source code directory", help = "the path to the source code directory",
required = True ) 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:]) args = arg_parser.parse_args(sys.argv[1:])
output = {} 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_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)) dict_merge(output, gen_derived(output))
print(json.dumps(output, sort_keys=True, indent=4)) print(json.dumps(output, sort_keys=True, indent=4))

View File

@ -20,13 +20,22 @@
# the base name of the file or package to distribute # the base name of the file or package to distribute
NAME := ergodox-firmware NAME := ergodox-firmware
# the name of the keyboard we're building
# - must match the same variable in src/makefile
KEYBOARD := ergodox
# git info # git info
GIT_BRANCH := $(shell git branch -l | grep '*' | cut -c 3-) 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_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-) 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 # 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 # the build dir
BUILD := build BUILD := build
@ -57,10 +66,12 @@ dist:
'../$(BUILD)/$(TARGET)' ) '../$(BUILD)/$(TARGET)' )
# run secondary build scripts # run secondary build scripts
( ./build-scripts/gen-ui-info.py \ ( ./build-scripts/gen-ui-info.py \
--current-date '$(shell $(DATE) --rfc-3339 s)' \
--git-commit-date '$(GIT_COMMIT_DATE)' \ --git-commit-date '$(GIT_COMMIT_DATE)' \
--git-commit-id '$(GIT_COMMIT_ID)' \ --git-commit-id '$(GIT_COMMIT_ID)' \
--map-file-path '$(BUILD)/$(TARGET)/firmware.map' \ --map-file-path '$(BUILD)/$(TARGET)/firmware.map' \
--source-code-path 'src' \ --source-code-path 'src' \
--matrix-file-path 'src/keyboard/$(KEYBOARD)/matrix.h' \
) > '$(BUILD)/$(TARGET)/firmware--ui-info.json' ) > '$(BUILD)/$(TARGET)/firmware--ui-info.json'
# make into a zip archive # make into a zip archive
( cd '$(BUILD)/$(TARGET)'; \ ( cd '$(BUILD)/$(TARGET)'; \

View File

@ -21,7 +21,7 @@
: column by Kevin Ross for Encoder : column by Kevin Ross for Encoder
Includes a short thing about pull-up resistors. 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) (http://wolfstone.halloweenhost.com/Lighting/litlpo_PoweringLEDs.html)
Can you use one resistor for multiple parallel LEDs? No. Or, you can, but Can you use one resistor for multiple parallel LEDs? No. Or, you can, but
it's not the best idea. it's not the best idea.
@ -35,6 +35,11 @@
-> [powering LEDs] -> [powering LEDs]
(http://wolfstone.halloweenhost.com/Lighting/litlpo_PoweringLEDs.html) (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] * [All About Circuits : Reference]
(http://www.allaboutcircuits.com/vol_5/index.html) (http://www.allaboutcircuits.com/vol_5/index.html)
Looks like a great collection of info; didn't get to read much of it. Looks like a great collection of info; didn't get to read much of it.

View File

@ -47,7 +47,7 @@
*/ */
#ifndef kb_layout_get #ifndef kb_layout_get
extern uint8_t PROGMEM \ extern const uint8_t PROGMEM \
_kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS]; _kb_layout[KB_LAYERS][KB_ROWS][KB_COLUMNS];
#define kb_layout_get(layer,row,column) \ #define kb_layout_get(layer,row,column) \
@ -57,7 +57,7 @@
#endif #endif
#ifndef kb_layout_press_get #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]; _kb_layout_press[KB_LAYERS][KB_ROWS][KB_COLUMNS];
#define kb_layout_press_get(layer,row,column) \ #define kb_layout_press_get(layer,row,column) \
@ -67,7 +67,7 @@
#endif #endif
#ifndef kb_layout_release_get #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]; _kb_layout_release[KB_LAYERS][KB_ROWS][KB_COLUMNS];
#define kb_layout_release_get(layer,row,column) \ #define kb_layout_release_get(layer,row,column) \

View File

@ -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 KB_MATRIX_LAYER( // layout: layer 0: default
// unused // 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 KB_MATRIX_LAYER( // press: layer 0: default
// unused // 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 KB_MATRIX_LAYER( // release: layer 0: default
// unused // unused

View File

@ -89,7 +89,7 @@ static const uint8_t PROGMEM endpoint_config_table[] = {
// spec and relevant portions of any USB class specifications! // spec and relevant portions of any USB class specifications!
static uint8_t PROGMEM device_descriptor[] = { static const uint8_t PROGMEM device_descriptor[] = {
18, // bLength 18, // bLength
1, // bDescriptorType 1, // bDescriptorType
0x00, 0x02, // bcdUSB 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 // 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), 0x05, 0x01, // Usage Page (Generic Desktop),
0x09, 0x06, // Usage (Keyboard), 0x09, 0x06, // Usage (Keyboard),
0xA1, 0x01, // Collection (Application), 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 CONFIG1_DESC_SIZE (9+9+9+7)
#define KEYBOARD_HID_DESC_OFFSET (9+9) #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 // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
9, // bLength; 9, // bLength;
2, // bDescriptorType; 2, // bDescriptorType;
@ -191,17 +191,17 @@ struct usb_string_descriptor_struct {
uint8_t bDescriptorType; uint8_t bDescriptorType;
int16_t wString[]; int16_t wString[];
}; };
static struct usb_string_descriptor_struct PROGMEM string0 = { static const struct usb_string_descriptor_struct PROGMEM string0 = {
4, 4,
3, 3,
{0x0409} {0x0409}
}; };
static struct usb_string_descriptor_struct PROGMEM string1 = { static const struct usb_string_descriptor_struct PROGMEM string1 = {
sizeof(STR_MANUFACTURER), sizeof(STR_MANUFACTURER),
3, 3,
STR_MANUFACTURER STR_MANUFACTURER
}; };
static struct usb_string_descriptor_struct PROGMEM string2 = { static const struct usb_string_descriptor_struct PROGMEM string2 = {
sizeof(STR_PRODUCT), sizeof(STR_PRODUCT),
3, 3,
STR_PRODUCT STR_PRODUCT
@ -214,7 +214,7 @@ static struct descriptor_list_struct {
uint16_t wIndex; uint16_t wIndex;
const uint8_t *addr; const uint8_t *addr;
uint8_t length; uint8_t length;
} PROGMEM descriptor_list[] = { } const PROGMEM descriptor_list[] = {
{0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)}, {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
{0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)}, {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
{0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)}, {0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},

View File

@ -116,11 +116,6 @@ all: $(TARGET).hex $(TARGET).eep
@echo @echo
$(SIZE) --target=$(FORMAT) $(TARGET).eep $(SIZE) --target=$(FORMAT) $(TARGET).eep
@echo @echo
@echo '. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .'
@echo
$(SIZE) -C --mcu=atmega32u4 $(TARGET).elf
@echo '. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .'
@echo
@echo 'you can load "$(TARGET).hex" and "$(TARGET).eep" onto the' @echo 'you can load "$(TARGET).hex" and "$(TARGET).eep" onto the'
@echo 'Teensy using the Teensy loader' @echo 'Teensy using the Teensy loader'
@echo @echo