Merge branch 'master' of github.com:benblazak/ergodox-firmware
commit
d0f31aecde
|
@ -0,0 +1,2 @@
|
|||
This directory is for projects closely related to the firmware.
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
# -----------------------------------------------------------------------------
|
||||
# makefile for the ergoDOX project
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# TODO:
|
||||
# - include doc files (and maybe render them in html)
|
||||
# - include the UI stuff (once it's done)
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
# Released under The MIT License (MIT) (see "license.md")
|
||||
# Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
# 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')
|
||||
|
||||
# name to use for the final distribution file or package
|
||||
TARGET := $(NAME)--$(BRANCH)--$(VERSION)
|
||||
|
||||
# the build dir
|
||||
BUILD := build
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
.PHONY: all clean dist
|
||||
|
||||
all: dist
|
||||
|
||||
clean:
|
||||
git clean -dX # remove ignored files and directories
|
||||
-rm -r '$(BUILD)'
|
||||
|
||||
dist:
|
||||
# set up the build dir
|
||||
-rm -r '$(BUILD)/$(TARGET)'*
|
||||
-mkdir -p '$(BUILD)/$(TARGET)'
|
||||
# make all subprojects
|
||||
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
|
||||
( cd '$(BUILD)/$(TARGET)'; \
|
||||
zip '../$(TARGET).zip' \
|
||||
-r * .* \
|
||||
-x '..*' )
|
||||
|
|
@ -377,6 +377,17 @@
|
|||
|
||||
## Miscellaneous
|
||||
|
||||
### Keyboard Testing Tools
|
||||
|
||||
* [Understanding Rollover]
|
||||
(http://gadzikowski.com/nkeyrollover.html)
|
||||
Includes 3 different tests (2 of which are web based) to see which keys are
|
||||
actually registering as pressed.
|
||||
|
||||
* mentioned on the [Default:NKey Rollover]
|
||||
(http://geekhack.org/showwiki.php?title=NKey+Rollover+-+Overview+Testing+Methodology+and+Results)
|
||||
page (on <http://geekhack.org/>)
|
||||
|
||||
### Typical Keyboard Information
|
||||
|
||||
* [Keyboard Scan Rates]
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
*~
|
||||
*.swp
|
||||
|
||||
*.hex
|
||||
*.eep
|
||||
*.elf
|
||||
*.hex
|
||||
*.map
|
||||
*.o
|
||||
*.o.dep
|
||||
|
|
@ -9,10 +9,9 @@
|
|||
|
||||
#include "lib/data-types.h"
|
||||
|
||||
#define KEYBOARD_INCLUDE_PRIVATE
|
||||
#include "ergodox/matrix.h"
|
||||
#include "ergodox/mcp23018.h"
|
||||
#include "ergodox/teensy-2-0.h"
|
||||
#include "ergodox/mcp23018--private.h"
|
||||
#include "ergodox/teensy-2-0--private.h"
|
||||
|
||||
|
||||
/* returns
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#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/mcp23018.h" // (nothing right now)
|
||||
#include "ergodox/teensy-2-0.h" // LED controls
|
||||
|
||||
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
inkscape:version="0.48.2 r9819"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
height="398.98083"
|
||||
height="416.48083"
|
||||
width="950.8382"
|
||||
sodipodi:docname="_circuit-diagram.svg"
|
||||
sodipodi:docname="circuit-diagram.svg"
|
||||
inkscape:export-filename="/home/ben/Desktop/programs/20120227--ergodox-firmware--for-the-ergodox-keyboard/src/test - circuit diagram/inkscape/_circuit-diagram.png"
|
||||
inkscape:export-xdpi="150"
|
||||
inkscape:export-ydpi="150">
|
||||
|
@ -26,8 +26,8 @@
|
|||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="477.26232"
|
||||
inkscape:cy="197.75046"
|
||||
inkscape:cx="464.65225"
|
||||
inkscape:cy="203.44926"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer7"
|
||||
showgrid="true"
|
||||
|
@ -1924,22 +1924,22 @@
|
|||
sodipodi:nodetypes="ccccccccccccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#007700;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#DotM-10)"
|
||||
d="M 255,127.36218 C 319.96657,67.757371 380.66023,68.094183 381.84624,86.972644 l -0.15377,7.638959"
|
||||
d="M 255,127.36218 C 297.1005,68.254966 399.98689,51.202007 403.41299,89.442314 l 0.023,4.815736"
|
||||
id="path7504"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#007700;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#DotM-10);display:inline"
|
||||
d="M 234.96647,127.29296 C 300.31207,48.235689 400.85603,51.277895 403.56272,86.653429 l -0.15377,7.638959"
|
||||
d="M 234.96647,127.29296 C 305.92363,44.536037 388.15055,41.329164 381.99597,85.946323 l 0.023,8.346065"
|
||||
id="path7504-3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#007700;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#DotM-10-7)"
|
||||
d="m 195,247.36218 c -4.32571,23.55176 70.95424,57.80762 144.21458,54.72312 9.45484,-5.50003 -1.67061,-20.3897 5.26135,-28.19694 38.00964,-42.80905 -0.71668,-177.441227 11.27147,-189.245847 9.78813,-9.032436 -5.54253,-24.848413 5.08961,-28.779094 28.50706,-10.539011 62.33333,12.384603 62.61183,28.039681 l -0.0815,10.708503"
|
||||
d="m 195,247.36218 c -4.32571,23.55176 70.95424,57.80762 144.21458,54.72312 9.45484,-5.50003 -1.67061,-20.3897 5.26135,-28.19694 38.00964,-42.80905 6.84799,-181.553227 13.02147,-196.245847 6.17348,-14.69262 -2.21854,-13.634877 3.33961,-21.779094 5.55815,-8.144217 62.33333,-4.615397 62.61183,28.039681 l -0.0815,10.708503"
|
||||
id="path7758"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccscscc" />
|
||||
sodipodi:nodetypes="ccszzcc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000077;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#DotM-10-7);marker-end:url(#DotM-10-7)"
|
||||
d="m 95.105862,247.67467 c -2.592497,38.06584 1.233202,73.99227 7.071068,109.24799"
|
||||
|
@ -2079,32 +2079,32 @@
|
|||
y="176.07817"
|
||||
id="tspan9630">PWM</tspan></text>
|
||||
<text
|
||||
inkscape:transform-center-y="-9.2023172"
|
||||
inkscape:transform-center-x="4.2210811"
|
||||
transform="matrix(0.88676162,-0.46222703,0.46222703,0.88676162,0,0)"
|
||||
inkscape:transform-center-y="-8.1837146"
|
||||
inkscape:transform-center-x="5.960441"
|
||||
transform="matrix(0.7776191,-0.62873566,0.62873566,0.7776191,0,0)"
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ff7700;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="214.90239"
|
||||
y="211.07732"
|
||||
x="135.67398"
|
||||
y="246.92535"
|
||||
id="text9938"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="214.90239"
|
||||
y="211.07732"
|
||||
x="135.67398"
|
||||
y="246.92535"
|
||||
id="tspan9636">PWM</tspan></text>
|
||||
<text
|
||||
inkscape:transform-center-y="-3.7829232"
|
||||
inkscape:transform-center-x="-6.0157706"
|
||||
transform="matrix(0.89485423,-0.4463585,0.4463585,0.89485423,0,0)"
|
||||
inkscape:transform-center-y="-3.7250803"
|
||||
inkscape:transform-center-x="-6.0517844"
|
||||
transform="matrix(0.89909256,-0.43775858,0.43775858,0.89909256,0,0)"
|
||||
xml:space="preserve"
|
||||
style="font-size:12px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ff7700;fill-opacity:1;stroke:none;display:inline;font-family:Sans"
|
||||
x="221.94164"
|
||||
y="223.0845"
|
||||
x="227.65367"
|
||||
y="215.32523"
|
||||
id="text9941"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="221.94164"
|
||||
y="223.0845"
|
||||
x="227.65367"
|
||||
y="215.32523"
|
||||
id="tspan9632">PWM</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
|
@ -2693,7 +2693,11 @@
|
|||
sodipodi:role="line"
|
||||
id="tspan3445"
|
||||
x="37.24189"
|
||||
y="388.43091">- Please also see documentation (especially the notes) in the *.md files</tspan></text>
|
||||
y="388.43091">- Please also see documentation (especially the notes) in the *.md files</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="37.24189"
|
||||
y="405.93091"
|
||||
id="tspan3451">- Row and column assignments are to matrix positions, not physical positions</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
|
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 152 KiB |
|
@ -15,12 +15,11 @@
|
|||
#include "lib/data-types.h"
|
||||
#include "lib/key-functions.h" // for `kbfun_funptr_t`
|
||||
|
||||
#include "matrix.h" // for number of rows and columns, and layout
|
||||
// to matrix macros
|
||||
#include "matrix.h" // for number of rows and columns
|
||||
|
||||
// include the appropriate keyboard layout header
|
||||
// for:
|
||||
// - number of layers
|
||||
// - possible non-default number of layers
|
||||
// - possible non-default layout matrix definitions
|
||||
// - possible non-default layout 'get' and 'set' definitions
|
||||
#undef _str
|
||||
|
@ -35,6 +34,12 @@
|
|||
#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
|
||||
|
|
|
@ -14,48 +14,252 @@
|
|||
#include "lib/usb/usage-page/keyboard--short-names.h"
|
||||
#include "lib/key-functions.h"
|
||||
|
||||
#define KEYBOARD_INCLUDE_PRIVATE
|
||||
#include "../matrix.h"
|
||||
#include "../layout.h"
|
||||
|
||||
|
||||
// error check: everything below assumes these dimensions
|
||||
#if KB_LAYERS != 1 || KB_ROWS != 12 || KB_COLUMNS != 7
|
||||
#error "Expecting different keyboard dimensions"
|
||||
#endif
|
||||
// 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] = {
|
||||
LAYER( // layer 0: default
|
||||
// ----------------------------------------------------------------------------
|
||||
MATRIX_LAYER( // layer 0: default
|
||||
// unused
|
||||
0,
|
||||
// left hand
|
||||
_grave, _1, _2, _3, _4, _5, _equal,
|
||||
_tab, _Q, _W, _E, _R, _T, _esc,
|
||||
_capsLock, _A, _S, _D, _F, _G,
|
||||
_shiftL, _Z, _X, _C, _V, _B, _ctrlL,
|
||||
_guiL, _arrowL, _arrowU, _arrowD, _arrowR,
|
||||
_bs,
|
||||
_del, _ctrlL,
|
||||
_end, _home, _altL,
|
||||
_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,
|
||||
_ctrlR, _N, _M, _comma, _period, _slash, _shiftR,
|
||||
_arrowL, _arrowD, _arrowU, _arrowR, _guiR,
|
||||
_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 )
|
||||
_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] = {
|
||||
LAYER_SET_ALL(NULL, &kbfun_press) // layer 0: default
|
||||
// ----------------------------------------------------------------------------
|
||||
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] = {
|
||||
LAYER_SET_ALL(NULL, &kbfun_release) // layer 0: default
|
||||
// ----------------------------------------------------------------------------
|
||||
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 )
|
||||
// ----------------------------------------------------------------------------
|
||||
};
|
||||
|
||||
|
|
|
@ -13,14 +13,12 @@
|
|||
#include "../led.h"
|
||||
|
||||
|
||||
#define KB_LAYERS 1 // must match what's defined in "qwerty.c"
|
||||
|
||||
#define kb_led_num_on() _led_1_on()
|
||||
#define kb_led_num_off() _led_1_off()
|
||||
#define kb_led_caps_on() _led_2_on()
|
||||
#define kb_led_caps_off() _led_2_off()
|
||||
#define kb_led_scroll_on() _led_3_on()
|
||||
#define kb_led_scroll_off() _led_3_off()
|
||||
#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()
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
* 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 should all start with '_led_'
|
||||
* - public led macros should start with 'kb_led_'
|
||||
* - 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 <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
|
@ -22,23 +23,23 @@
|
|||
|
||||
|
||||
#define kb_led_state_power_on() do { \
|
||||
_led_all_set_percent(0.05); \
|
||||
_led_all_on(); \
|
||||
_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 { \
|
||||
_led_1_set_percent(0.5); \
|
||||
_kb_led_1_set_percent(0.5); \
|
||||
_delay_ms(333); \
|
||||
_led_2_set_percent(0.5); \
|
||||
_kb_led_2_set_percent(0.5); \
|
||||
_delay_ms(333); \
|
||||
_led_3_set_percent(0.5); \
|
||||
_kb_led_3_set_percent(0.5); \
|
||||
_delay_ms(333); \
|
||||
} while(0)
|
||||
|
||||
#define kb_led_state_ready() do { \
|
||||
_led_all_off(); \
|
||||
_led_all_set_percent(0.5); \
|
||||
_kb_led_all_off(); \
|
||||
_kb_led_all_set_percent(0.5); \
|
||||
} while(0)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,92 +19,88 @@
|
|||
extern bool (*kb_was_pressed)[KB_ROWS][KB_COLUMNS];
|
||||
|
||||
|
||||
#ifdef KEYBOARD_INCLUDE_PRIVATE
|
||||
|
||||
/* mapping from spatial position to matrix position
|
||||
* - spatial position: where the key is spatially, relative to
|
||||
* other keys both on the keyboard and in the layout
|
||||
* - matrix position: the coordinate in the matrix to which
|
||||
* a key is scanned by the update functions
|
||||
*
|
||||
* - location numbers are in the format `row##column`, where
|
||||
* both 'row' 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
|
||||
*
|
||||
* --- other info ---------------------------------------------
|
||||
* rows x columns = positions; assigned, unassigned
|
||||
* per hand: 6 x 7 = 42; 38, 4
|
||||
* total: 12 x 7 = 84; 76, 8
|
||||
*
|
||||
* left hand : cols 0..6, rows 6..B
|
||||
* right hand : cols 0..6, rows 0..5
|
||||
* ------------------------------------------------------------
|
||||
*/
|
||||
#define 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 } }
|
||||
/* mapping from spatial position to matrix position
|
||||
* - spatial position: where the key is spatially, relative to other
|
||||
* keys both on the keyboard and in the layout
|
||||
* - matrix position: the coordinate in the matrix to which a key is
|
||||
* scanned by the update functions
|
||||
*
|
||||
* - location numbers are in the format `row##column`, where both 'row'
|
||||
* 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
|
||||
*
|
||||
* --- other info -----------------------------------------------------
|
||||
* rows x columns = positions; assigned, unassigned
|
||||
* per hand: 6 x 7 = 42; 38, 4
|
||||
* total: 12 x 7 = 84; 76, 8
|
||||
*
|
||||
* left hand : cols 0..6, rows 6..B
|
||||
* right hand : cols 0..6, rows 0..5
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
#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 LAYER_SET_ALL(na, kxx) \
|
||||
LAYER( \
|
||||
na, \
|
||||
\
|
||||
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,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, kxx, \
|
||||
kxx,kxx,kxx )
|
||||
#define MATRIX_LAYER_SET_ALL(na, kxx) \
|
||||
LAYER( \
|
||||
na, \
|
||||
\
|
||||
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,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, kxx, \
|
||||
kxx,kxx,kxx )
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* ergoDOX controller: MCP23018 specific exports
|
||||
* ergoDOX controller: MCP23018 specific exports : private
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
|
@ -7,20 +7,16 @@
|
|||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef MCP23018_h
|
||||
#define MCP23018_h
|
||||
#ifndef MCP23018_h_PRIVATE
|
||||
#define MCP23018_h_PRIVATE
|
||||
|
||||
#include "lib/data-types.h"
|
||||
#include "matrix.h"
|
||||
|
||||
#ifdef KEYBOARD_INCLUDE_PRIVATE
|
||||
#define MCP23018_TWI_ADDRESS 0b0100000
|
||||
|
||||
#define MCP23018_TWI_ADDRESS 0b0100000
|
||||
|
||||
uint8_t mcp23018_init(void);
|
||||
uint8_t mcp23018_update_matrix(
|
||||
bool matrix[KB_ROWS][KB_COLUMNS] );
|
||||
|
||||
#endif
|
||||
uint8_t mcp23018_init(void);
|
||||
uint8_t mcp23018_update_matrix( bool matrix[KB_ROWS][KB_COLUMNS] );
|
||||
|
||||
#endif
|
||||
|
|
@ -11,9 +11,8 @@
|
|||
#include "lib/data-types.h"
|
||||
#include "lib/twi.h" // `TWI_FREQ` defined in "teensy-2-0.c"
|
||||
|
||||
#define KEYBOARD_INCLUDE_PRIVATE
|
||||
#include "matrix.h"
|
||||
#include "mcp23018.h"
|
||||
#include "mcp23018--private.h"
|
||||
|
||||
|
||||
// register addresses (see "mcp23018.md")
|
||||
|
|
|
@ -41,6 +41,11 @@
|
|||
NC o14-------15+ ADDR (see note)
|
||||
|
||||
* 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.
|
||||
* ADDR (pin15): Set slave address to `0b0100000` by connecting to Vss(GND).
|
||||
* The user-defined bits are the three least significant
|
||||
* I2C addresses are 7 bits long (the last bit in the byte is used for
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* ergoDOX controller: Teensy 2.0 specific exports : private
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#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
|
||||
|
|
@ -13,9 +13,9 @@
|
|||
#define TWI_FREQ 400000
|
||||
#include "lib/twi.h"
|
||||
|
||||
#define KEYBOARD_INCLUDE_PRIVATE
|
||||
#include "matrix.h"
|
||||
#include "teensy-2-0.h"
|
||||
#include "teensy-2-0--private.h"
|
||||
|
||||
|
||||
// processor frequency (from <http://www.pjrc.com/teensy/prescaler.html>)
|
||||
|
@ -123,7 +123,7 @@ uint8_t teensy_init(void) {
|
|||
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")
|
||||
_led_all_off(); // (just to put the pins in a known state)
|
||||
_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
|
||||
|
||||
|
|
|
@ -13,54 +13,43 @@
|
|||
#include <avr/io.h> // for the register macros
|
||||
#include "lib/data-types.h"
|
||||
|
||||
#include "matrix.h"
|
||||
|
||||
|
||||
// LED control
|
||||
#define _led_1_on() (DDRB |= (1<<6))
|
||||
#define _led_1_off() (DDRB &= ~(1<<6))
|
||||
#define _led_1_set(n) (OCR1B = (uint8_t)(n))
|
||||
#define _led_1_set_percent(n) (OCR1B = (uint8_t)((n) * 0xFF))
|
||||
#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 _led_2_on() (DDRB |= (1<<5))
|
||||
#define _led_2_off() (DDRB &= ~(1<<5))
|
||||
#define _led_2_set(n) (OCR1A = (uint8_t)(n))
|
||||
#define _led_2_set_percent(n) (OCR1A = (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 _led_3_on() (DDRB |= (1<<7))
|
||||
#define _led_3_off() (DDRB &= ~(1<<7))
|
||||
#define _led_3_set(n) (OCR1C = (uint8_t)(n))
|
||||
#define _led_3_set_percent(n) (OCR1C = (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 _led_all_on() do { \
|
||||
_led_1_on(); \
|
||||
_led_2_on(); \
|
||||
_led_3_on(); \
|
||||
#define _kb_led_all_on() do { \
|
||||
_kb_led_1_on(); \
|
||||
_kb_led_2_on(); \
|
||||
_kb_led_3_on(); \
|
||||
} while(0)
|
||||
#define _led_all_off() do { \
|
||||
_led_1_off(); \
|
||||
_led_2_off(); \
|
||||
_led_3_off(); \
|
||||
#define _kb_led_all_off() do { \
|
||||
_kb_led_1_off(); \
|
||||
_kb_led_2_off(); \
|
||||
_kb_led_3_off(); \
|
||||
} while(0)
|
||||
#define _led_all_set(n) do { \
|
||||
_led_1_set(n); \
|
||||
_led_2_set(n); \
|
||||
_led_3_set(n); \
|
||||
#define _kb_led_all_set(n) do { \
|
||||
_kb_led_1_set(n); \
|
||||
_kb_led_2_set(n); \
|
||||
_kb_led_3_set(n); \
|
||||
} while(0)
|
||||
#define _led_all_set_percent(n) do { \
|
||||
_led_1_set_percent(n); \
|
||||
_led_2_set_percent(n); \
|
||||
_led_3_set_percent(n); \
|
||||
#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); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#ifdef KEYBOARD_INCLUDE_PRIVATE
|
||||
|
||||
uint8_t teensy_init(void);
|
||||
uint8_t teensy_update_matrix(
|
||||
bool matrix[KB_ROWS][KB_COLUMNS] );
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -44,6 +44,11 @@
|
|||
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.
|
||||
* 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
|
||||
|
|
|
@ -10,12 +10,10 @@
|
|||
#ifndef DATA_TYPES_h
|
||||
#define DATA_TYPES_h
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define bool _Bool
|
||||
#define true ((bool)1)
|
||||
#define false ((bool)0)
|
||||
#include "data-types/linked-list.h"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* 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 <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#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; i<index; i++)
|
||||
previous = previous->next;
|
||||
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; i<index; i++)
|
||||
node = node->next;
|
||||
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; i<index; i++)
|
||||
previous = previous->next;
|
||||
|
||||
// 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
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* linked list : exports
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#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
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* ----------------------------------------------------------------------------
|
||||
* 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 <benblazak.dev@gmail.com>
|
||||
* Released under The MIT License (MIT) (see "license.md")
|
||||
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#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
|
||||
|
|
@ -11,108 +11,500 @@
|
|||
* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
#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)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if 0 // not being used right now
|
||||
static uint8_t _inc_current_layer(uint8_t * current_layer) {
|
||||
if (*current_layer < (KB_LAYERS-1))
|
||||
(*current_layer)++;
|
||||
else
|
||||
return 1; // error: can't increase
|
||||
/*
|
||||
* 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_) );
|
||||
|
||||
return 0; // success
|
||||
if (key_function)
|
||||
(*key_function)(
|
||||
pressed_,
|
||||
kb_layout_get(layer_, *row_, *col_),
|
||||
layer_,
|
||||
row_,
|
||||
col_,
|
||||
current_layer_,
|
||||
current_layers_,
|
||||
pressed_layers_ );
|
||||
}
|
||||
|
||||
static uint8_t _dec_current_layer(uint8_t * current_layer) {
|
||||
if (*current_layer > 0)
|
||||
(*current_layer)--;
|
||||
else
|
||||
return 1; // error: can't decrease
|
||||
|
||||
return 0; // success
|
||||
// ----------------------------------------------------------------------------
|
||||
// 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_ROWS; row++)
|
||||
for (uint8_t col=0; col<KB_COLUMNS; col++)
|
||||
// if a key is set to a non-current layer, leave it
|
||||
if ((*current_layers)[row][col] == *current_layer)
|
||||
(*current_layers)[row][col] = layer;
|
||||
|
||||
(*current_layer) = layer;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set layer mask
|
||||
* - Sets the specified key positions to the specified layer
|
||||
*/
|
||||
void _layer_set_mask(
|
||||
uint8_t layer,
|
||||
bool positions[KB_ROWS][KB_COLUMNS],
|
||||
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_ROWS; row++)
|
||||
for (uint8_t col=0; col<KB_COLUMNS; col++)
|
||||
if (positions[row][col])
|
||||
(*current_layers)[row][col] = layer;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is the given keycode pressed?
|
||||
*/
|
||||
bool _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;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// public functions
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Press|Release
|
||||
* - Generate a normal keypress or keyrelease
|
||||
*/
|
||||
void kbfun_press_release( KBFUN_FUNCTION_ARGS ) {
|
||||
_press_release(pressed_, keycode_);
|
||||
}
|
||||
|
||||
/*
|
||||
* Toggle
|
||||
* - Toggle the key pressed or unpressed
|
||||
*/
|
||||
void kbfun_toggle( KBFUN_FUNCTION_ARGS ) {
|
||||
if (_is_pressed(keycode_))
|
||||
_press_release(false, keycode_);
|
||||
else
|
||||
_press_release(true, keycode_);
|
||||
}
|
||||
|
||||
/*
|
||||
* Increase layer
|
||||
* - Increment the current layer by the value specified in the keymap (for all
|
||||
* non-masked keys)
|
||||
*/
|
||||
void kbfun_layer_inc( KBFUN_FUNCTION_ARGS ) {
|
||||
_layer_set_current(
|
||||
(*current_layer_) + keycode_,
|
||||
current_layer_,
|
||||
current_layers_ );
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrease layer
|
||||
* - Decrement the current layer by the value specified in the keymap (for all
|
||||
* non-masked keys)
|
||||
*/
|
||||
void kbfun_layer_dec( KBFUN_FUNCTION_ARGS ) {
|
||||
_layer_set_current(
|
||||
(*current_layer_) - keycode_,
|
||||
current_layer_,
|
||||
current_layers_ );
|
||||
}
|
||||
|
||||
/*
|
||||
* Increase layer, Execute key
|
||||
* - Increment the current layer by the value specified in the keymap (for all
|
||||
* non-masked keys), and execute (usually press|release) the key in the same
|
||||
* position on that new layer
|
||||
*
|
||||
* Note
|
||||
* - Meant to be paired with `kbfun_layer_dec_exec()`
|
||||
*/
|
||||
void kbfun_layer_inc_exec( KBFUN_FUNCTION_ARGS ) {
|
||||
// switch layers
|
||||
_layer_set_current(
|
||||
(*current_layer_) + keycode_,
|
||||
current_layer_,
|
||||
current_layers_ );
|
||||
|
||||
// exececute second key (in the same position)
|
||||
// - `layer_+keycode_` will be constant (under normal circumstances)
|
||||
// between the press and release
|
||||
_kbfun_exec_key(
|
||||
pressed_, 0, layer_+keycode_,
|
||||
row_, col_, current_layer_,
|
||||
current_layers_, pressed_layers_ );
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrease layer, Execute key
|
||||
* - Decrement the current layer by the value specified in the keymap (for all
|
||||
* non-masked keys), and execute (usually press|release) the key in the same
|
||||
* position on that new layer
|
||||
*
|
||||
* Note
|
||||
* - Meant to be paired with `kbfun_layer_inc_exec()`
|
||||
*/
|
||||
void kbfun_layer_dec_exec( KBFUN_FUNCTION_ARGS ) {
|
||||
// switch layers
|
||||
_layer_set_current(
|
||||
(*current_layer_) - keycode_,
|
||||
current_layer_,
|
||||
current_layers_ );
|
||||
|
||||
// exececute second key (in the same position)
|
||||
// - `layer_+keycode_` will be constant (under normal circumstances)
|
||||
// between the press and release
|
||||
_kbfun_exec_key(
|
||||
pressed_, 0, layer_+keycode_,
|
||||
row_, col_, current_layer_,
|
||||
current_layers_, pressed_layers_ );
|
||||
}
|
||||
|
||||
/*
|
||||
* Two keys => 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)
|
||||
// <http://www.pjrc.com/teensy/jump_to_bootloader.html>
|
||||
#if MAKEFILE_BOARD == teensy-2-0
|
||||
// --- for all Teensy boards
|
||||
cli();
|
||||
|
||||
// disable watchdog, if enabled
|
||||
// disable all peripherals
|
||||
UDCON = 1;
|
||||
USBCON = (1<<FRZCLK); // disable USB
|
||||
UCSR1B = 0;
|
||||
_delay_ms(5);
|
||||
|
||||
// --- Teensy 2.0 specific
|
||||
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
|
||||
TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0;
|
||||
DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0;
|
||||
PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
|
||||
asm volatile("jmp 0x7E00");
|
||||
#endif
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void kbfun_press(
|
||||
uint8_t keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col ) {
|
||||
|
||||
// no-op
|
||||
if (keycode == 0)
|
||||
return;
|
||||
|
||||
// modifier keys
|
||||
switch (keycode) {
|
||||
case KEY_LeftControl: keyboard_modifier_keys |= (1<<0);
|
||||
return;
|
||||
case KEY_LeftShift: keyboard_modifier_keys |= (1<<1);
|
||||
return;
|
||||
case KEY_LeftAlt: keyboard_modifier_keys |= (1<<2);
|
||||
return;
|
||||
case KEY_LeftGUI: keyboard_modifier_keys |= (1<<3);
|
||||
return;
|
||||
case KEY_RightControl: keyboard_modifier_keys |= (1<<4);
|
||||
return;
|
||||
case KEY_RightShift: keyboard_modifier_keys |= (1<<5);
|
||||
return;
|
||||
case KEY_RightAlt: keyboard_modifier_keys |= (1<<6);
|
||||
return;
|
||||
case KEY_RightGUI: keyboard_modifier_keys |= (1<<7);
|
||||
return;
|
||||
}
|
||||
|
||||
// all others
|
||||
for (uint8_t i=0; i<6; i++)
|
||||
if (keyboard_keys[i] == 0) {
|
||||
keyboard_keys[i] = keycode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void kbfun_release(
|
||||
uint8_t keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col ) {
|
||||
|
||||
// no-op
|
||||
if (keycode == 0)
|
||||
return;
|
||||
|
||||
// modifier keys
|
||||
switch (keycode) {
|
||||
case KEY_LeftControl: keyboard_modifier_keys &= ~(1<<0);
|
||||
return;
|
||||
case KEY_LeftShift: keyboard_modifier_keys &= ~(1<<1);
|
||||
return;
|
||||
case KEY_LeftAlt: keyboard_modifier_keys &= ~(1<<2);
|
||||
return;
|
||||
case KEY_LeftGUI: keyboard_modifier_keys &= ~(1<<3);
|
||||
return;
|
||||
case KEY_RightControl: keyboard_modifier_keys &= ~(1<<4);
|
||||
return;
|
||||
case KEY_RightShift: keyboard_modifier_keys &= ~(1<<5);
|
||||
return;
|
||||
case KEY_RightAlt: keyboard_modifier_keys &= ~(1<<6);
|
||||
return;
|
||||
case KEY_RightGUI: keyboard_modifier_keys &= ~(1<<7);
|
||||
return;
|
||||
}
|
||||
|
||||
// all others
|
||||
for (uint8_t i=0; i<6; i++)
|
||||
if (keyboard_keys[i] == keycode) {
|
||||
keyboard_keys[i] = 0;
|
||||
break;
|
||||
}
|
||||
// else, function does nothing
|
||||
}
|
||||
|
||||
|
|
|
@ -12,16 +12,53 @@
|
|||
|
||||
#include "lib/data-types.h"
|
||||
|
||||
typedef void (*kbfun_funptr_t)(
|
||||
uint8_t, uint8_t *,
|
||||
uint8_t *, uint8_t * );
|
||||
// --------------------------------------------------------------------
|
||||
// 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
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
void kbfun_press(
|
||||
uint8_t keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col );
|
||||
void kbfun_release(
|
||||
uint8_t keycode, uint8_t * current_layer,
|
||||
uint8_t * row, uint8_t * col );
|
||||
|
||||
#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
|
||||
|
||||
|
|
|
@ -38,6 +38,14 @@
|
|||
// - spec sec 9.4.11 (Standard Device Requests / Synch Frame) (pg 260)
|
||||
|
||||
// TODO
|
||||
// - read the hid usage tables .pdf
|
||||
// - read the hid device class definition .pdf
|
||||
|
||||
// DONE
|
||||
// - read the hid usage tables .pdf
|
||||
// - i think this is more for reference and implementation than
|
||||
// understanding. i've copied the relevant (i think) tables ones into
|
||||
// headers. the unicode usage page, i'll have to look into more later: i'm
|
||||
// not sure if it can be used with keyboards. if so though, i'll have to
|
||||
// look on the unicode website, or elsewhere, coz this .pdf doesn't list
|
||||
// anything about them out, it just references the unicode spec.
|
||||
|
||||
|
|
65
src/main.c
65
src/main.c
|
@ -11,6 +11,7 @@
|
|||
#include <util/delay.h>
|
||||
#include "lib-other/pjrc/usb_keyboard/usb_keyboard.h"
|
||||
#include "lib/data-types.h"
|
||||
#include "lib/key-functions.h"
|
||||
|
||||
#include "keyboard.h"
|
||||
|
||||
|
@ -27,7 +28,12 @@ int main(void) {
|
|||
kb_led_state_ready();
|
||||
|
||||
for (;;) {
|
||||
static uint8_t current_layer = 0;
|
||||
// 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 `kb_is_pressed` and `kb_was_pressed`, then update
|
||||
bool (*temp)[KB_ROWS][KB_COLUMNS] = kb_was_pressed;
|
||||
|
@ -36,41 +42,46 @@ int main(void) {
|
|||
|
||||
kb_update_matrix(*kb_is_pressed);
|
||||
|
||||
// call the appropriate function for each key, then send the usb report
|
||||
// if necessary
|
||||
// - 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), and "lib/key-functions.c"
|
||||
// for their definitions
|
||||
// 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)
|
||||
// - keep track of which layers the keys were on when they were pressed
|
||||
// (so they can be released using the function from that layer)
|
||||
//
|
||||
// note
|
||||
// - 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<KB_ROWS; row++) {
|
||||
for (uint8_t col=0; col<KB_COLUMNS; col++) {
|
||||
|
||||
bool is_pressed = (*kb_is_pressed)[row][col];
|
||||
bool was_pressed = (*kb_was_pressed)[row][col];
|
||||
if (is_pressed != was_pressed) {
|
||||
if (is_pressed) {
|
||||
kbfun_funptr_t press_function =
|
||||
kb_layout_press_get(current_layer, row, col);
|
||||
if (press_function) {
|
||||
(*press_function)(
|
||||
kb_layout_get(current_layer, row, col),
|
||||
¤t_layer, &row, &col );
|
||||
}
|
||||
} else {
|
||||
kbfun_funptr_t release_function =
|
||||
kb_layout_release_get(current_layer, row, col);
|
||||
if (release_function) {
|
||||
(*release_function)(
|
||||
kb_layout_get(current_layer, row, col),
|
||||
¤t_layer, &row, &col );
|
||||
}
|
||||
}
|
||||
|
||||
usb_keyboard_send();
|
||||
_delay_ms(KB_DEBOUNCE_TIME);
|
||||
if (is_pressed != was_pressed) {
|
||||
uint8_t layer = ( (is_pressed)
|
||||
? current_layers[row][col]
|
||||
: pressed_layers[row][col] );
|
||||
|
||||
if (is_pressed)
|
||||
pressed_layers[row][col] = layer;
|
||||
|
||||
_kbfun_exec_key(
|
||||
is_pressed, 0, layer,
|
||||
&row, &col, ¤t_layer,
|
||||
¤t_layers, &pressed_layers );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// send the USB report (even if nothing's changed)
|
||||
usb_keyboard_send();
|
||||
_delay_ms(KB_DEBOUNCE_TIME);
|
||||
|
||||
// update LEDs
|
||||
if (keyboard_leds & (1<<0)) { kb_led_num_on(); }
|
||||
else { kb_led_num_off(); }
|
||||
|
|
38
src/makefile
38
src/makefile
|
@ -1,5 +1,5 @@
|
|||
# -----------------------------------------------------------------------------
|
||||
# makefile for the ergoDOX project
|
||||
# makefile for the ergoDOX firmware
|
||||
#
|
||||
# - .h file dependencies are automatically generated
|
||||
#
|
||||
|
@ -13,18 +13,18 @@
|
|||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
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)
|
||||
SRC := $(wildcard *.c)
|
||||
# keyboard and layout stuff
|
||||
# --- remove whitespace from vars
|
||||
KEYBOARD := $(strip $(KEYBOARD))
|
||||
|
@ -48,7 +48,7 @@ SRC += $(wildcard lib-other/*/*/*.c)
|
|||
OBJ = $(SRC:%.c=%.o)
|
||||
|
||||
|
||||
CFLAGS = -mmcu=$(MCU) # processor type (teensy 2.0); must match real
|
||||
CFLAGS := -mmcu=$(MCU) # processor type (teensy 2.0); must match real
|
||||
# life
|
||||
CFLAGS += -DF_CPU=$(F_CPU) # processor frequency; must match initialization
|
||||
# in source
|
||||
|
@ -76,21 +76,23 @@ CFLAGS += -fdata-sections # / section in the output file if the
|
|||
# unused code.
|
||||
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
LDFLAGS = -Wl,--relax # for some linker optimizations
|
||||
LDFLAGS := -Wl,-Map=$(strip $(TARGET)).map,--cref # generate a link map, with
|
||||
# a cross reference table
|
||||
LDFLAGS += -Wl,--relax # for some linker optimizations
|
||||
LDFLAGS += -Wl,--gc-sections # discard unused functions and data
|
||||
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
GENDEPFLAGS += -MMD -MP -MF $@.dep # generate dependency files
|
||||
|
||||
|
||||
CC = avr-gcc
|
||||
OBJCOPY = avr-objcopy
|
||||
SIZE = avr-size
|
||||
CC := avr-gcc
|
||||
OBJCOPY := avr-objcopy
|
||||
SIZE := avr-size
|
||||
|
||||
|
||||
# remove whitespace from some of the variables
|
||||
TARGET := $(strip $(TARGET))
|
||||
FORMAT := $(strip $(FORMAT))
|
||||
TARGET := $(strip $(TARGET))
|
||||
FORMAT := $(strip $(FORMAT))
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# -----------------------------------------------------------------------------
|
||||
|
@ -120,7 +122,7 @@ all: $(TARGET).hex $(TARGET).eep
|
|||
clean:
|
||||
@echo
|
||||
@echo --- cleaning ---
|
||||
cd .. ; git clean -dX # remove ignored files and directories
|
||||
git clean -dX # remove ignored files and directories
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue