Merge pull request #19 from qmk/master

Merge from qmk
pull/1196/head
Damien 7 years ago committed by GitHub
commit 3e41cde9f9

1
.gitignore vendored

@ -1,5 +1,6 @@
.dep
*.o
*.bin
*.eep
*.elf
*.hex

@ -23,9 +23,9 @@ ifdef master
MASTER = $(master)
endif
ifeq ($(MASTER),right)
ifeq ($(MASTER),right)
OPT_DEFS += -DMASTER_IS_ON_RIGHT
else
else
ifneq ($(MASTER),left)
$(error MASTER does not have a valid value(left/right))
endif
@ -38,7 +38,7 @@ KEYBOARD_C := $(KEYBOARD_PATH)/$(KEYBOARD).c
ifneq ("$(wildcard $(KEYBOARD_C))","")
include $(KEYBOARD_PATH)/rules.mk
else
else
$(error "$(KEYBOARD_C)" does not exist)
endif
@ -49,7 +49,7 @@ ifneq ($(SUBPROJECT),)
ifneq ("$(wildcard $(SUBPROJECT_C))","")
OPT_DEFS += -DSUBPROJECT_$(SUBPROJECT)
include $(SUBPROJECT_PATH)/rules.mk
else
else
$(error "$(SUBPROJECT_PATH)/$(SUBPROJECT).c" does not exist)
endif
endif
@ -83,7 +83,7 @@ ifneq ($(SUBPROJECT),)
endif
endif
# Save the defines and includes here, so we don't include any keymap specific ones
# Save the defines and includes here, so we don't include any keymap specific ones
PROJECT_DEFS := $(OPT_DEFS)
PROJECT_INC := $(VPATH) $(EXTRAINCDIRS) $(SUBPROJECT_PATH) $(KEYBOARD_PATH)
PROJECT_CONFIG := $(CONFIG_H)
@ -139,11 +139,27 @@ ifeq ($(strip $(API_SYSEX_ENABLE)), yes)
MIDI_ENABLE=yes
endif
MUSIC_ENABLE := 0
ifeq ($(strip $(AUDIO_ENABLE)), yes)
OPT_DEFS += -DAUDIO_ENABLE
MUSIC_ENABLE := 1
SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c
SRC += $(QUANTUM_DIR)/audio/audio.c
SRC += $(QUANTUM_DIR)/audio/voices.c
SRC += $(QUANTUM_DIR)/audio/luts.c
endif
ifeq ($(strip $(MIDI_ENABLE)), yes)
OPT_DEFS += -DMIDI_ENABLE
MUSIC_ENABLE := 1
SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c
endif
ifeq ($(MUSIC_ENABLE), 1)
SRC += $(QUANTUM_DIR)/process_keycode/process_music.c
endif
ifeq ($(strip $(COMBO_ENABLE)), yes)
OPT_DEFS += -DCOMBO_ENABLE
SRC += $(QUANTUM_DIR)/process_keycode/process_combo.c
@ -153,14 +169,6 @@ ifeq ($(strip $(VIRTSER_ENABLE)), yes)
OPT_DEFS += -DVIRTSER_ENABLE
endif
ifeq ($(strip $(AUDIO_ENABLE)), yes)
OPT_DEFS += -DAUDIO_ENABLE
SRC += $(QUANTUM_DIR)/process_keycode/process_music.c
SRC += $(QUANTUM_DIR)/audio/audio.c
SRC += $(QUANTUM_DIR)/audio/voices.c
SRC += $(QUANTUM_DIR)/audio/luts.c
endif
ifeq ($(strip $(FAUXCLICKY_ENABLE)), yes)
OPT_DEFS += -DFAUXCLICKY_ENABLE
SRC += $(QUANTUM_DIR)/fauxclicky.c
@ -250,7 +258,7 @@ endif
OUTPUTS := $(KEYMAP_OUTPUT) $(KEYBOARD_OUTPUT)
$(KEYMAP_OUTPUT)_SRC := $(SRC)
$(KEYMAP_OUTPUT)_DEFS := $(OPT_DEFS) -DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYMAP=\"$(KEYMAP)\"
$(KEYMAP_OUTPUT)_DEFS := $(OPT_DEFS) -DQMK_KEYBOARD=\"$(KEYBOARD)\" -DQMK_KEYMAP=\"$(KEYMAP)\"
$(KEYMAP_OUTPUT)_INC := $(VPATH) $(EXTRAINCDIRS)
$(KEYMAP_OUTPUT)_CONFIG := $(CONFIG_H)
$(KEYBOARD_OUTPUT)_SRC := $(CHIBISRC)

@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

@ -1,674 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

@ -1,15 +1,30 @@
Keymap framework - how to define your keymap
============================================
***NOTE: This is not final version, may be inconsistent with source code and changed occasionally for a while.***
***NOTE: This is updated for QMK but this is still work in progress. This may still be inconsistent with the source code.***
QMK is based on TMK. Understanding the essential changes made should help you understand variable names etc.
## TMK vs. QMK
| Firmware |TMK |QMK |
|---------------------------|-----------------------|-------------------------|
| Maintainer |hasu |Jack Humbert et al. |
| Build path customization | `TMK_DIR = ...` | `include .../Makefile` |
| `keymaps` data | 3D array of `uint8_t` holding **keycode** | 3D array of `uint16_t` holding **action code** |
| `fn_actions` data | 1D array of `uint16_t` holding **action code** | 1D array of `uint16_t` holding **action code** |
Since QMK is based on TMK and uses major portion of TMK code as is, understanding the essential changes made should help you understand the code.
## 0. Keymap and layers
**Keymap** is comprised of multiple layers of key layout, you can define **32 layers** at most.
**Layer** is an array of **keycodes** to define **actions** for each physical keys.
respective layers can be validated simultaneously. Layers are indexed with 0 to 31 and higher layer has precedence.
In QMK, **`const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]`** holds multiple **layers** of keymap information in **16 bit** data holding the **action code**. You can define **32 layers** at most.
Keymap: 32 Layers Layer: Keycode matrix
For trivial key definitions, the higher 8 bits of the **action code** are all 0 and the lower 8 bits holds the USB HID usage code generated by the key as **keycode**.
Respective layers can be validated simultaneously. Layers are indexed with 0 to 31 and higher layer has precedence.
Keymap: 32 Layers Layer: action code matrix
----------------- ---------------------
stack of layers array_of_keycode[row][column]
stack of layers array_of_action_code[row][column]
____________ precedence _______________________
/ / | high / ESC / F1 / F2 / F3 ....
31 /___________// | /-----/-----/-----/-----
@ -22,11 +37,15 @@ respective layers can be validated simultaneously. Layers are indexed with 0 to
0 /___________/ V low 0 `--------------------------
Sometimes, the action code stored in keymap may be referred as keycode in some documents due to the TMK history.
### 0.1 Keymap layer status
Keymap layer has its state in two 32 bit parameters:
### 0.1 Keymap status
Keymap has its state in two parameters:
**`default_layer`** indicates a base keymap layer(0-31) which is always valid and to be referred, **`keymap_stat`** is 16bit variable which has current on/off status of layers on its each bit.
* **`default_layer_state`** indicates a base keymap layer(0-31) which is always valid and to be referred.
* **`layer_state`** () has current on/off status of the layer on its each bit.
Keymap has its state in two parameter **`default_layer`** indicates a base keymap layer(0-31) which is always valid and to be referred, **`keymap_stat`** is 16bit variable which has current on/off status of layers on its each bit.
Keymap layer '0' is usually `default_layer` and which is the only valid layer and other layers is initially off after boot up firmware, though, you can configured them in `config.h`.
To change `default_layer` will be useful when you switch key layout completely, say you want Colmak instead of Qwerty.
@ -67,97 +86,132 @@ On the other hand, you shall change `layer_state` to overlay base layer with som
### 0.2 Layer Precedence and Transparency
Note that ***higher layer has higher priority on stack of layers***, namely firmware falls down from top layer to bottom to look up keycode. Once it spots keycode other than **`KC_TRNS`**(transparent) on a layer it stops searching and lower layers aren't referred.
You can place `KC_TRNS` on overlay layer changes just part of layout to fall back on lower or base layer.
Key with `KC_TRANS` doesn't has its own keycode and refers to lower valid layers for keycode, instead.
You can place `KC_TRANS` on overlay layer changes just part of layout to fall back on lower or base layer.
Key with `KC_TRANS` (`KC_TRNS` and `_______` are the alias) doesn't has its own keycode and refers to lower valid layers for keycode, instead.
See example below.
### 0.3 Keymap Example
Keymap is **`keymaps[]`** C array in fact and you can define layers in it with **`KEYMAP()`** C macro and keycodes. To use complex actions you need to define `Fn` keycode in **`fn_actions[]`** array.
Keymap in this QMK is **`static const uint16_t PROGMEM keymaps[]`** C array in fact and you can define layers in it with **`KEYMAP()`** C macro and keycodes. To use complex actions you need to define `Fn` keycode in **`fn_actions[]`** array. It holds the 16 bit quantum keycode (action code).
> Please note that keymap in the TMK, which QMK was forked from, is **`static const uint8_t PROGMEM keymaps[]`** C array which holds the 8 bit keycode (~USB HID usage code).
This is a keymap example for [HHKB](http://en.wikipedia.org/wiki/Happy_Hacking_Keyboard) keyboard.
This example has three layers, 'Qwerty' as base layer, 'Cursor' and 'Mousekey'.
This example has three layers, 'QWERTY' as base layer, 'FN' and 'MOUSE'.
In this example,
`Fn0` is a **momentary layer switching** key, you can use keys on Cursor layer while holding the key.
`MO(layer)` is a **momentary layer switching** key.
`Fn1` is a momentary layer switching key with tapping feature, you can get semicolon **';'** with taping the key and switch layers while holding the key. The word **'tap'** or **'tapping'** mean to press and release a key quickly.
You can find other keymap definitions in file `keymap.c` located on project directories.
```
/*
* dbroqua HHKB Layout
*/
#include "hhkb.h"
#define BASE 0
#define FN 1
#define MOUSE 2
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* BASE Level: Default Layer
* ,-----------------------------------------------------------------------------------------.
* | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | \ | ` |
* |-----------------------------------------------------------------------------------------+
* | Tab | Q | W | E | R | T | Y | U | I | O | P | [ | ] | Bksp |
* |-----------------------------------------------------------------------------------------+
* | Ctrl | A | S | D | F | G | H | J | K | L | ; | ' | Enter |
* |-----------------------------------------------------------------------------------------+
* | Shift | Z | X | C | V | B | N | M | , | . | / | Shift | fn |
* +-----------------------------------------------------------------------------------------+
* | Gui | Alt | Space | AltGr |Mouse|
* `----------------------------------------------------------------´
*/
[BASE] = KEYMAP(
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_GRV, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, \
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(FN), \
KC_LGUI, KC_LALT, /* */ KC_SPC, KC_RALT, MO(MOUSE)
),
/* FN Layer
* ,-----------------------------------------------------------------------------------------.
* | Pwr | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F0 | F11 | F12 | Ins | Del|
* |-----------------------------------------------------------------------------------------+
* | Caps | | | | | | | |PrtSc| Slck| Paus| Up | | |
* |-----------------------------------------------------------------------------------------+
* | | Vol-| Vol+| Mute| | | * | / | Home| PgUp| Left |Right| |
* |-----------------------------------------------------------------------------------------+
* | | Prev| Play| Next| | | + | - | End |PgDwn| Down| | |
* +-----------------------------------------------------------------------------------------+
* | | | | Stop | |
* `----------------------------------------------------------------´
*/
[FN] = KEYMAP(
KC_PWR, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_DEL, \
KC_CAPS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_TRNS, KC_TRNS, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_TRNS, \
KC_TRNS, KC_MPRV, KC_MPLY, KC_MNXT, KC_TRNS, KC_TRNS, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_MSTP, KC_TRNS
),
/* MOUSE Layer
* ,-----------------------------------------------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |-----------------------------------------------------------------------------------------+
* | | | WUp | | | | | | | | Btn1| Up | Btn2| |
* |-----------------------------------------------------------------------------------------+
* | | WLt | WDn | WRt | | | | | | | Left |Right| |
* |-----------------------------------------------------------------------------------------+
* | | | | | | | | | | Btn3| Down| | |
* +-----------------------------------------------------------------------------------------+
* | | | | | |
* `----------------------------------------------------------------´
*/
[MOUSE] = KEYMAP(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_WH_U, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN1, KC_MS_U, KC_BTN2, KC_TRNS, \
KC_TRNS, KC_WH_L, KC_WH_D, KC_WH_R, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_R, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN3, KC_MS_D, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
)
};
`Fn2` is a **toggle layer switch** key, you can stay switched layer after releasing the key unlike momentary switching.
const uint16_t PROGMEM fn_actions[] = {
You can find other keymap definitions in file `keymap.c` located on project directories.
};
static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* 0: Qwerty
* ,-----------------------------------------------------------.
* |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| `|
* |-----------------------------------------------------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]|Backs|
* |-----------------------------------------------------------|
* |Contro| A| S| D| F| G| H| J| K| L|Fn1| '|Enter |
* |-----------------------------------------------------------|
* |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Fn0|
* `-----------------------------------------------------------'
* |Gui|Alt |Space |Alt |Fn2|
* `-------------------------------------------'
*/
KEYMAP(ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSLS,GRV, \
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSPC, \
LCTL,A, S, D, F, G, H, J, K, L, FN1, QUOT,ENT, \
LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH,RSFT,FN0, \
LGUI,LALT, SPC, RALT,FN2),
/* 1: Cursor(HHKB mode)
* ,-----------------------------------------------------------.
* |Pwr| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del|
* |-----------------------------------------------------------|
* |Caps | | | | | | | |Psc|Slk|Pus|Up | |Backs|
* |-----------------------------------------------------------|
* |Contro|VoD|VoU|Mut| | | *| /|Hom|PgU|Lef|Rig|Enter |
* |-----------------------------------------------------------|
* |Shift | | | | | | +| -|End|PgD|Dow|Shift | |
* `-----------------------------------------------------------'
* |Gui |Alt |Space |Alt |Gui|
* `--------------------------------------------'
*/
KEYMAP(PWR, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \
CAPS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS,UP, TRNS,BSPC, \
LCTL,VOLD,VOLU,MUTE,TRNS,TRNS,PAST,PSLS,HOME,PGUP,LEFT,RGHT,ENT, \
LSFT,TRNS,TRNS,TRNS,TRNS,TRNS,PPLS,PMNS,END, PGDN,DOWN,RSFT,TRNS, \
LGUI,LALT, SPC, RALT,RGUI),
/* 2: Mousekey
* ,-----------------------------------------------------------.
* |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del|
* |-----------------------------------------------------------|
* |Tab | | | | | |MwL|MwD|MwU|MwR| | | |Backs|
* |-----------------------------------------------------------|
* |Contro| | | | | |McL|McD|McU|McR| | |Return |
* |-----------------------------------------------------------|
* |Shift | | | | |Mb3|Mb2|Mb1|Mb4|Mb5| |Shift | |
* `-----------------------------------------------------------'
* |Gui |Alt |Mb1 |Alt | |
* `--------------------------------------------'
* Mc: Mouse Cursor / Mb: Mouse Button / Mw: Mouse Wheel
*/
KEYMAP(ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \
TAB, TRNS,TRNS,TRNS,TRNS,TRNS,WH_L,WH_D,WH_U,WH_R,TRNS,TRNS,TRNS,BSPC, \
LCTL,TRNS,ACL0,ACL1,ACL2,TRNS,MS_L,MS_D,MS_U,MS_R,TRNS,QUOT,ENT, \
LSFT,TRNS,TRNS,TRNS,TRNS,BTN3,BTN2,BTN1,BTN4,BTN5,SLSH,RSFT,TRNS, \
LGUI,LALT, BTN1, RALT,TRNS),
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
} else {
unregister_code(KC_RSFT);
}
break;
}
return MACRO_NONE;
};
```
static const uint16_t PROGMEM fn_actions[] = {
ACTION_LAYER_MOMENTARY(1), // FN0
ACTION_LAYER_TAP_KEY(2, KC_SCLN), // FN1
ACTION_LAYER_TOGGLE(2), // FN2
};
## 1. Keycode
See [`tmk_core/common/keycode.h`](../tmk_core/common/keycode.h) or keycode table below for the detail. Keycode is internal **8bit code** to indicate action performed on key in keymap. Keycodes are based on [HID Usage Keyboard/Keypad Page(0x07)](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf) plus special codes in the `0xA5-DF` range.
Keycode has `KC_` prefixed symbol respectively. Most of keycodes like `KC_A` have simple action registers key to host on press and unregister on release, while some of other keycodes has some special actions like `Fn` keys, Media control keys, System control keys and Mousekeys.
keymaps[]
In `KEYMAP()` macro, TMK recommends you to keep prefix part `KC_` of keycode to keep keymap compact. For example, just use `A` instead you place `KC_A` in `KEYMAP()`. But this doesn't apply for QMK.
## 1. Keycode
See [`common/keycode.h`](../common/keycode.h) or keycode table below for the detail. Keycode is internal **8bit code** to indicate action performed on key in keymap. Keycode has `KC_` prefixed symbol respectively. Most of keycodes like `KC_A` have simple action registers key to host on press and unregister on release, while some of other keycodes has some special actions like `Fn` keys, Media control keys, System control keys and Mousekeys.
The `KEYMAP()` macro defines correspondence between the physical key location to the electrical key connection.
***In `KEYMAP()` macro you should omit prefix part `KC_` of keycode to keep keymap compact.*** For example, just use `A` instead you place `KC_A` in `KEYMAP()`. Some keycodes has 4-letter **short name** in addition to descriptive name, you'll prefer short one in `KEYMAP()`.
Some keycodes has 7-letter **short name** such as `KC_COMM` in addition to descriptive name `KC_COMMA`, you'll prefer short one in `KEYMAP()`.
### 1.0 Other key
- `KC_NO` for no action
@ -192,7 +246,10 @@ There are 8 modifiers which has discrimination between left and right.
- `KC_WSCH`, `KC_WHOM`, `KC_WBAK`, `KC_WFWD`, `KC_WSTP`, `KC_WREF`, `KC_WFAV` for web browser operation
### 1.5 Fn key
`KC_FNnn` are keycodes for `Fn` key which not given any actions at the beginning unlike most of keycodes has its own inborn action. To use these keycodes in `KEYMAP()` you need to assign action you want at first. Action of `Fn` key is defined in `fn_actions[]` and its index of the array is identical with number part of `KC_FNnn`. Thus `KC_FN0` keycode indicates the action defined in first element of the array. ***32 `Fn` keys can be defined at most.***
You don't need to use this functionality under QMK since this is a backward compatibility functionality. Unlike TMK, you can write action code itself directly in **`static const uint16_t PROGMEM keymaps[]`** C array using `MO(layer)`, etc.
`KC_FNnn` are keycodes for `Fn` key which not given any actions at the beginning unlike most of keycodes has its own inborn action. To use these keycodes in `KEYMAP()` you need to assign action you want at first. Action of `Fn` key is defined in `fn_actions[]` and its index of the array is identical with number part of `KC_FNnn`. Thus `KC_FN0` keycode indicates the action defined in first element of the array. ***Only 32 `Fn` keys can be defined at most.***
### 1.6 Keycode Table
See keycode table in [`doc/keycode.txt`](./keycode.txt) for description of keycodes.
@ -549,6 +606,9 @@ Layer switching with tap key:
[dual_role]: http://en.wikipedia.org/wiki/Modifier_key#Dual-role_keys
When user hold a key after tap, it repeat the tapped key rather to hold a modifier key.
If you prefer to hold a modifier instead, define `TAPPING_FORCE_HOLD` in `config.h`.
See https://github.com/qmk/qmk_firmware/issues/889 for the detail.
### 4.2 Tap Toggle
This is a feature to assign both toggle layer and momentary switch layer action to just same one physical key. It works as momentary layer switch when holding a key but toggle switch with several taps.
@ -581,15 +641,11 @@ Similar to layer tap toggle, this works as a momentary modifier when holding, bu
## 5. Legacy Keymap
This was used in prior version and still works due to legacy support code in `common/keymap.c`. Legacy keymap doesn't support many of features that new keymap offers. ***It is not recommended to use Legacy Keymap for new project.***
To enable Legacy Keymap support define this macro in `config.h`.
#define USE_LEGACY_KEYMAP
In QMK, `tmk_core/common/keymap.c` is missing and its replacement `quantum/keymap_common.c` lacks Legacy Keymap support.
Legacy Keymap uses two arrays `fn_layer[]` and `fn_keycode[]` to define Fn key. The index of arrays corresponds with postfix number of `Fn` key. Array `fn_layer[]` indicates destination layer to switch and `fn_keycode[]` has keycodes to send when tapping `Fn` key.
In following setting example, `Fn0`, `Fn1` and `Fn2` switch layer to 1, 2 and 2 respectively. `Fn2` registers `Space` key when tapping while `Fn0` and `Fn1` doesn't send any key.
In the following legacy keymap setting example, `Fn0`, `Fn1` and `Fn2` switch layer to 1, 2 and 2 respectively. `Fn2` registers `Space` key when tapping while `Fn0` and `Fn1` doesn't send any key.
static const uint8_t PROGMEM fn_layer[] = {
1, // Fn0
@ -603,6 +659,7 @@ In following setting example, `Fn0`, `Fn1` and `Fn2` switch layer to 1, 2 and 2
KC_SPC, // Fn2
};
Under QMK, these can be realized using action code ACTION_LAYER_TAP_KEY(1, KC_NO), ACTION_LAYER_TAP_KEY(2, KC_NO), and ACTION_LAYER_TAP_KEY(2, KC_SPC) in the `keymaps` directly.
## 6. Terminology
***TBD***

@ -15,8 +15,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_QW] = { /* Qwerty */
{KC_Q, KC_W, KC_E, KC_R, KC_T, KC_TRNS, KC_Y, KC_U, KC_I, KC_O, KC_P },
{KC_A, KC_S, KC_D, KC_F, KC_G, KC_TRNS, KC_H, KC_J, KC_K, KC_L, KC_SCLN },
{KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LALT, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH },
{KC_ESC, KC_TAB, KC_LGUI, KC_LSFT, KC_BSPC, KC_LCTL, KC_SPC, MO(_RS), KC_MINS, KC_QUOT, KC_ENT }
{KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LCTL, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH },
{KC_ESC, KC_TAB, KC_LGUI, KC_LSFT, KC_BSPC, KC_LALT, KC_SPC, MO(_RS), KC_MINS, KC_QUOT, KC_ENT }
},
/*
* ! @ up { } || pgup 7 8 9 *
@ -27,8 +27,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_RS] = { /* [> RAISE <] */
{KC_EXLM, KC_AT, KC_UP, KC_LCBR, KC_RCBR, KC_TRNS, KC_PGUP, KC_7, KC_8, KC_9, KC_ASTR},
{KC_HASH, KC_LEFT, KC_DOWN, KC_RGHT, KC_DLR, KC_TRNS, KC_PGDN, KC_4, KC_5, KC_6, KC_PLUS},
{KC_LBRC, KC_RBRC, KC_LPRN, KC_RPRN, KC_AMPR, KC_LALT, KC_GRV, KC_1, KC_2, KC_3, KC_BSLS},
{TG(_LW), KC_INS, KC_LGUI, KC_LSFT, KC_BSPC, KC_LCTL, KC_SPC, KC_TRNS, KC_DOT, KC_0, KC_EQL}
{KC_LBRC, KC_RBRC, KC_LPRN, KC_RPRN, KC_AMPR, KC_LCTL, KC_GRV, KC_1, KC_2, KC_3, KC_BSLS},
{TG(_LW), KC_INS, KC_LGUI, KC_LSFT, KC_BSPC, KC_LALT, KC_SPC, KC_TRNS, KC_DOT, KC_0, KC_EQL}
},
/*
* insert home up end pgup || up F7 F8 F9 F10
@ -39,8 +39,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_LW] = { /* [> LOWER <] */
{KC_INS, KC_HOME, KC_UP, KC_END, KC_PGUP, KC_TRNS, KC_UP, KC_F7, KC_F8, KC_F9, KC_F10},
{KC_DELT, KC_LEFT, KC_DOWN, KC_RGHT, KC_DOWN, KC_TRNS, KC_DOWN, KC_F4, KC_F5, KC_F6, KC_F11},
{KC_TRNS, KC_VOLU, KC_TRNS, KC_TRNS, RESET, KC_LALT, KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F12},
{KC_TRNS, KC_VOLD, KC_LGUI, KC_LSFT, KC_BSPC, KC_LCTL, KC_SPC, DF(_QW), KC_PSCR, KC_SLCK, KC_PAUS}
{KC_TRNS, KC_VOLU, KC_TRNS, KC_TRNS, RESET, KC_LCTL, KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F12},
{KC_TRNS, KC_VOLD, KC_LGUI, KC_LSFT, KC_BSPC, KC_LALT, KC_SPC, DF(_QW), KC_PSCR, KC_SLCK, KC_PAUS}
}};
const uint16_t PROGMEM fn_actions[] = {

@ -9,18 +9,34 @@ void promicro_bootloader_jmp(bool program);
// The first section contains all of the arguements
// The second converts the arguments into a two-dimensional array
#define KEYMAP( \
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \
k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, \
k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, k4d \
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \
k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, \
k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, k4d \
) \
{ \
{ k00, k01, k02, k03, k04, k05, KC_NO, k06, k07, k08, k09, k0a, k0b }, \
{ k10, k11, k12, k13, k14, k15, KC_NO, k16, k17, k18, k19, k1a, k1b }, \
{ k20, k21, k22, k23, k24, k25, KC_NO, k26, k27, k28, k29, k2a, k2b }, \
{ k30, k31, k32, k33, k34, k35, k46, k36, k37, k38, k39, k3a, k3b }, \
{ k40, k41, k42, k43, k44, k45, k47, k48, k49, k4a, k4b, k4c, k4d } \
{ k00, k01, k02, k03, k04, k05, KC_NO, k06, k07, k08, k09, k0a, k0b }, \
{ k10, k11, k12, k13, k14, k15, KC_NO, k16, k17, k18, k19, k1a, k1b }, \
{ k20, k21, k22, k23, k24, k25, KC_NO, k26, k27, k28, k29, k2a, k2b }, \
{ k30, k31, k32, k33, k34, k35, k46, k36, k37, k38, k39, k3a, k3b }, \
{ k40, k41, k42, k43, k44, k45, k47, k48, k49, k4a, k4b, k4c, k4d } \
}
#endif
// Used to create a keymap using only KC_ prefixed keys.
#define KC_KEYMAP( \
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \
k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, \
k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4a, k4b, k4c, k4d \
) \
{ \
{ KC_##k00, KC_##k01, KC_##k02, KC_##k03, KC_##k04, KC_##k05, KC_NO, KC_##k06, KC_##k07, KC_##k08, KC_##k09, KC_##k0a, KC_##k0b }, \
{ KC_##k10, KC_##k11, KC_##k12, KC_##k13, KC_##k14, KC_##k15, KC_NO, KC_##k16, KC_##k17, KC_##k18, KC_##k19, KC_##k1a, KC_##k1b }, \
{ KC_##k20, KC_##k21, KC_##k22, KC_##k23, KC_##k24, KC_##k25, KC_NO, KC_##k26, KC_##k27, KC_##k28, KC_##k29, KC_##k2a, KC_##k2b }, \
{ KC_##k30, KC_##k31, KC_##k32, KC_##k33, KC_##k34, KC_##k35, KC_##k46, KC_##k36, KC_##k37, KC_##k38, KC_##k39, KC_##k3a, KC_##k3b }, \
{ KC_##k40, KC_##k41, KC_##k42, KC_##k43, KC_##k44, KC_##k45, KC_##k47, KC_##k48, KC_##k49, KC_##k4a, KC_##k4b, KC_##k4c, KC_##k4d } \
}
#endif

@ -50,6 +50,7 @@ const uint16_t PROGMEM fn_actions[] = {
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
static uint8_t mods_pressed;
static bool mod_flag;
switch (id) {
case 0:
@ -61,6 +62,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
/* The key is being pressed.
*/
if (mods_pressed) {
mod_flag = true;
add_key(KC_GRV);
send_keyboard_report();
} else {
@ -70,7 +72,8 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
} else {
/* The key is being released.
*/
if (mods_pressed) {
if (mod_flag) {
mod_flag = false;
del_key(KC_GRV);
send_keyboard_report();
} else {

@ -0,0 +1,86 @@
#include "clueboard.h"
// Helpful defines
#define GRAVE_MODS (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)|MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)|MOD_BIT(KC_LALT)|MOD_BIT(KC_RALT))
#define _______ KC_TRNS
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _BL 0
#define _FL 1
#define _CL 2
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap _BL: Base Layer (Default Layer)
*/
[_BL] = KEYMAP(
F(0), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_GRV, KC_BSPC, KC_PGUP, \
KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGDN, \
KC_BSPC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, KC_NUHS, KC_ENT, \
KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RO, KC_RSFT, KC_UP, \
KC_LCTL, MO(_FL), KC_LGUI,KC_MHEN, KC_SPC,KC_SPC, KC_HENK, KC_RALT, KC_RCTL, KC_RGUI, KC_LEFT, KC_DOWN, KC_RGHT),
/* Keymap _FL: Function Layer
*/
[_FL] = KEYMAP(
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, KC_CAPS, BL_STEP, \
_______, _______, _______,_______,_______,_______,_______,KC_HOME,KC_PGDN,KC_PGUP, KC_END, _______, _______, _______, _______, \
KC_DEL, _______, MO(_CL),_______,_______,_______,_______,KC_LEFT,KC_DOWN,KC_UP, KC_RGHT, _______, _______, _______, \
_______, _______, _______,_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, KC_PGUP, \
_______, _______, _______,_______, _______,_______, _______, _______, _______, MO(_FL), KC_HOME, KC_PGDN, KC_END),
/* Keymap _CL: Control layer
*/
[_CL] = KEYMAP(
_______, _______, _______,_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, RGB_TOG, RGB_VAI, \
_______, _______, _______,_______,RESET, _______,_______,_______,_______,_______, _______, _______, _______, _______, RGB_VAD, \
_______, _______, MO(_CL),_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, \
MO(_FL), _______, _______,_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, MO(_FL), RGB_SAI, \
_______, _______, _______,_______, RGB_MOD, RGB_MOD, _______, _______, _______, _______, RGB_HUD, RGB_SAD, RGB_HUI),
};
/* This is a list of user defined functions. F(N) corresponds to item N
of this list.
*/
const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_FUNCTION(0), // Calls action_function()
};
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
static uint8_t mods_pressed;
static bool mod_flag;
switch (id) {
case 0:
/* Handle the combined Grave/Esc key
*/
mods_pressed = get_mods()&GRAVE_MODS; // Check to see what mods are pressed
if (record->event.pressed) {
/* The key is being pressed.
*/
if (mods_pressed) {
mod_flag = true;
add_key(KC_GRV);
send_keyboard_report();
} else {
add_key(KC_ESC);
send_keyboard_report();
}
} else {
/* The key is being released.
*/
if (mod_flag) {
mod_flag = false;
del_key(KC_GRV);
send_keyboard_report();
} else {
del_key(KC_ESC);
send_keyboard_report();
}
}
break;
}
}

@ -50,6 +50,7 @@ const uint16_t PROGMEM fn_actions[] = {
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
static uint8_t mods_pressed;
static bool mod_flag;
switch (id) {
case 0:
@ -61,6 +62,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
/* The key is being pressed.
*/
if (mods_pressed) {
mod_flag = true;
add_key(KC_GRV);
send_keyboard_report();
} else {
@ -70,7 +72,8 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
} else {
/* The key is being released.
*/
if (mods_pressed) {
if (mod_flag) {
mod_flag = false;
del_key(KC_GRV);
send_keyboard_report();
} else {

@ -50,6 +50,7 @@ const uint16_t PROGMEM fn_actions[] = {
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
static uint8_t mods_pressed;
static bool mod_flag;
switch (id) {
case 0:
@ -61,6 +62,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
/* The key is being pressed.
*/
if (mods_pressed) {
mod_flag = true;
add_key(KC_GRV);
send_keyboard_report();
} else {
@ -70,7 +72,8 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
} else {
/* The key is being released.
*/
if (mods_pressed) {
if (mod_flag) {
mod_flag = false;
del_key(KC_GRV);
send_keyboard_report();
} else {

@ -60,6 +60,7 @@ const uint16_t PROGMEM fn_actions[] = {
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
static uint8_t mods_pressed;
static bool mod_flag;
switch (id) {
case 0:
@ -71,6 +72,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
/* The key is being pressed.
*/
if (mods_pressed) {
mod_flag = true;
add_key(KC_GRV);
send_keyboard_report();
} else {
@ -80,7 +82,8 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
} else {
/* The key is being released.
*/
if (mods_pressed) {
if (mod_flag) {
mod_flag = false;
del_key(KC_GRV);
send_keyboard_report();
} else {

@ -50,6 +50,7 @@ const uint16_t PROGMEM fn_actions[] = {
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
static uint8_t mods_pressed;
static bool mod_flag;
switch (id) {
case 0:
@ -61,6 +62,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
/* The key is being pressed.
*/
if (mods_pressed) {
mod_flag = true;
add_key(KC_GRV);
send_keyboard_report();
} else {
@ -70,7 +72,8 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
} else {
/* The key is being released.
*/
if (mods_pressed) {
if (mod_flag) {
mod_flag = false;
del_key(KC_GRV);
send_keyboard_report();
} else {

@ -47,6 +47,7 @@ const uint16_t PROGMEM fn_actions[] = {
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
static uint8_t mods_pressed;
static bool mod_flag;
switch (id) {
case 0:
@ -58,6 +59,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
/* The key is being pressed.
*/
if (mods_pressed) {
mod_flag = true;
add_key(KC_GRV);
send_keyboard_report();
} else {
@ -67,7 +69,8 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
} else {
/* The key is being released.
*/
if (mods_pressed) {
if (mod_flag) {
mod_flag = false;
del_key(KC_GRV);
send_keyboard_report();
} else {

@ -50,6 +50,7 @@ const uint16_t PROGMEM fn_actions[] = {
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
static uint8_t mods_pressed;
static bool mod_flag;
switch (id) {
case 0:
@ -61,6 +62,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
/* The key is being pressed.
*/
if (mods_pressed) {
mod_flag = true;
add_key(KC_GRV);
send_keyboard_report();
} else {
@ -70,7 +72,8 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
} else {
/* The key is being released.
*/
if (mods_pressed) {
if (mod_flag) {
mod_flag = false;
del_key(KC_GRV);
send_keyboard_report();
} else {

@ -50,6 +50,7 @@ const uint16_t PROGMEM fn_actions[] = {
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
static uint8_t mods_pressed;
static bool mod_flag;
switch (id) {
case 0:
@ -61,6 +62,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
/* The key is being pressed.
*/
if (mods_pressed) {
mod_flag = true;
add_key(KC_GRV);
send_keyboard_report();
} else {
@ -70,7 +72,8 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
} else {
/* The key is being released.
*/
if (mods_pressed) {
if (mod_flag) {
mod_flag = false;
del_key(KC_GRV);
send_keyboard_report();
} else {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

@ -5,8 +5,9 @@
#define BASE 0 // default layer
#define SYMB 1 // symbols
#define MDIA 2 // media keys
#define NAVG 3 // navigation
#define MDIA 2 // media keys and navigation
#define UNI 3 // unicode 1
#define UNI2 4 // unicode 2
enum macros {
RUN
@ -94,11 +95,11 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* ,--------------------------------------------------. ,--------------------------------------------------.
* | Esc/L3 | 1 | 2 | 3 | 4 | 5 | 6 | | 6 | 7 | 8 | 9 | 0 | - | =/L3 |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | Tab/L1 | Q | W | E | R | T | L1 | | L1 | Y | U | I | O | P | \/L1 |
* | Tab/L1 | Q | W | E | R | T | L1 | | L2 | Y | U | I | O | P | \/L1 |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | LCtrl | A | S | D | F | G |------| |------| H | J | K | L |; / L2| ctrl/'|
* | LCtrl | A | S | D | F | G |------| |------| H | J | K | L | ; | ctrl/'|
* |--------+------+------+------+------+------| Hyper| | Meh |------+------+------+------+------+--------|
* | LShift |Z/Ctrl| X | C | V | B | | | | N | M | , | . |//Ctrl| RShift |
* | LShift |Z / L4|X / L2| C | V | B | | | | N | M | , |. / L2|/ / L4| RShift |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* |Grv/L1| UNI |AltShf| Lalt | Ralt | | Lalt | Ralt | LEAD | UNI | ~/L1 |
* `----------------------------------' `----------------------------------'
@ -114,25 +115,25 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Otherwise, it needs KC_*
[BASE] = KEYMAP( // layer 0 : default
// left hand
LT(NAVG,KC_ESC), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6,
LT(UNI,KC_ESC), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6,
LT(SYMB,KC_TAB), KC_Q, KC_W, KC_E, KC_R, KC_T, TG(SYMB),
KC_LCTL, LT(MDIA, KC_A), KC_S, KC_D, KC_F, KC_G,
KC_LSFT, CTL_T(KC_Z), KC_X, KC_C, KC_V, KC_B, ALL_T(KC_NO),
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G,
KC_LSFT, LT(4, KC_Z), LT(MDIA, KC_X), KC_C, KC_V, KC_B, ALL_T(KC_NO),
LT(SYMB,KC_GRV),LCTL(LSFT(KC_U)), LALT(KC_LSFT), KC_RALT,KC_LALT,
ALT_T(KC_APP), KC_HOME,
KC_END,
KC_SPC,KC_TAB,KC_LBRC,
// right hand
KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, LT(NAVG,KC_EQL),
TG(SYMB), KC_Y, KC_U, KC_I, KC_O, KC_P, LT(SYMB, KC_BSLS),
KC_H, KC_J, KC_K, KC_L, LT(MDIA, KC_SCLN),CTL_T(KC_QUOT),
MEH_T(KC_NO),KC_N, KC_M, KC_COMM,KC_DOT, CTL_T(KC_SLSH), KC_RSFT,
KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, LT(UNI,KC_EQL),
TG(MDIA), KC_Y, KC_U, KC_I, KC_O, KC_P, LT(SYMB, KC_BSLS),
KC_H, KC_J, KC_K, KC_L, KC_SCLN,CTL_T(KC_QUOT),
MEH_T(KC_NO),KC_N, KC_M, KC_COMM,LT(MDIA, KC_DOT), LT(UNI2, KC_SLSH), KC_RSFT,
KC_LALT, KC_RALT,KC_LEAD,LCTL(LSFT(KC_U)), LT(SYMB,KC_TILD),
KC_PGUP, KC_INS,
KC_PGDN,
KC_RBRC,KC_BSPC, KC_ENT
KC_RBRC,KC_BSPC, KC_ENT
),
/* Keymap 1: Symbol Layer LCTL(LSFT(KC_U))
/* Keymap 1: Symbol Layer LCTL(LSFT(KC_U))
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 | F6 | | F6 | F7 | F8 | F9 | F10 | F11 | F12 |
@ -177,13 +178,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 2: Media, mouse and navigation
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | gg(1)| | | | | | | | | | | | | |
* | | gg(1)| gg(2)| gg(3)| gg(4)| gg(5)| gg(6)| | gg(6)| gg(7)| gg(8)| gg(9)| gg(0)| | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | MsUp | RUN | | | | | | | Up | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | |MsLeft|MsDown|MsRght| |------| |------| | Left | Down | Right| | Play |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | | | Prev | Next | | |
* | | | | | | | | | | | Prev | Next | | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | Lclk | Rclk | |VolUp |VolDn | Mute | | |
* `----------------------------------' `----------------------------------'
@ -209,7 +210,7 @@ KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, M(RUN), KC_TRNS, KC_TRNS,
F(I3_GO_GROUP_6), F(I3_GO_GROUP_7), F(I3_GO_GROUP_8), F(I3_GO_GROUP_9), F(I3_GO_GROUP_10), KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_LEFT, KC_DOWN, KC_RIGHT, KC_TRNS, KC_MPLY,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS, KC_TRNS,
KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
@ -238,7 +239,7 @@ KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, M(RUN), KC_TRNS, KC_TRNS,
* `--------------------' `--------------------'
*/
// Unicode
[NAVG] = KEYMAP(
[UNI] = KEYMAP(
KC_TRNS, UC(0x250c), UC(0x2510), UC(0x2514), UC(0x2518), UC(0x2502), UC(0x2500),
KC_TRNS, F(EMOJI_SHRUG), F(EMOJI_YAY), F(EMOJI_HUG), F(EMOJI_SMILE), F(EMOJI_SMILE2), KC_TRNS,
KC_TRNS, F(EMOJI_HMM1), F(EMOJI_HMM2), F(EMOJI_BEAR1), F(EMOJI_BEAR2), F(EMOJI_FUU),
@ -257,6 +258,48 @@ KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, M(RUN), KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
/* Keymap 4: Unicode 2
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | ¹ | ² | ³ | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | | | | | | | | | | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | |------| |------| | | | | ¾ | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | ¼ | | | ½ | | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// Unicode 2
[UNI2] = KEYMAP(
KC_TRNS, UC(0x00b9), UC(0x00b2), UC(0x00b3), UC(0x2074), UC(0x2075), UC(0x2076),
KC_TRNS, UC(0x2081), UC(0x2082), UC(0x2083), UC(0x2084), UC(0x2085), UC(0x2086),
KC_TRNS, UC(0x215e), UC(0x215d), UC(0x215c), UC(0x215b), UC(0x215a),
KC_TRNS, KC_TRNS, KC_TRNS, UC(0x2157), UC(0x2156), UC(0x2155), UC(0x2154),
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
// right hand
UC(0x2076), UC(0x2077), UC(0x2078), UC(0x2079), UC(0x2070), UC(0x2103), UC(0x2122),
UC(0x2086), UC(0x2087), UC(0x2088), UC(0x2089), UC(0x2080), UC(0x2044), KC_TRNS,
UC(0x2153), UC(0x2152), UC(0x2151), UC(0x2150), UC(0x00be), KC_TRNS,
UC(0x00bc), UC(0x2159), UC(0x2158), UC(0x00bd), KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
};
const uint16_t PROGMEM fn_actions[] = {
@ -506,8 +549,11 @@ void matrix_scan_user(void) {
#endif
break;
case 4:
ergodox_right_led_1_on(); // TODO: Make a fourth layer
ergodox_right_led_1_on();
ergodox_right_led_3_on();
#ifdef RGBLIGHT_ENABLE
rgblight_setrgb(0xff,0x00,0xff);
#endif
break;
default:
// none

@ -51,10 +51,16 @@ provides standard media control keys, and default arrow keys.
## Layer 3 - Unicode
[![Layer 3 - Unicode](images/deadcyclo-layer-3-navigation.png)](http://www.keyboard-layout-editor.com/#/gists/67d9613dcd873c68693d11863d0fd289)
[![Layer 3 - Unicode](images/deadcyclo-layer-3-unicode.png)](http://www.keyboard-layout-editor.com/#/gists/67d9613dcd873c68693d11863d0fd289)
The unicode layer provides keys for directly typing unicode (utf-8)
## Layer 4 - Unicode 2
[![Layer 43 - Unicode](images/deadcyclo-layer-4-unicode-2.png)](http://www.keyboard-layout-editor.com/#/gists/7b2241110ab8311d9668a0798f3baf4a)
The unicode 2 layer provides keys for directly typing unicode (utf-8)
# Changelog
- 02.01.2017 Added delete key on second layer
@ -63,6 +69,7 @@ The unicode layer provides keys for directly typing unicode (utf-8)
- 24.01.2017 Added unicode keys. Added shrug hug and yay. Moved Navigation to layer 2
- 25.01.2017 Added lots of new emojis and some unicode keys
- 27.01.2017 Added new unicode keys and shortcut for ibus unicode composer key (CTRL+SHIFT+U)
- 11.03.2017 Added additional unicode layer. Moved some layer switch keys to more sane locations
# TODO

@ -0,0 +1,12 @@
# About this keymap
This keymap is based on the qwertz layout.
It has a key for pressing the left control and the left alt key at once.
Linux makes a difference between AltGr and Control + Alt. Some keybindings are easier to press now.
Also, I added a layer for pressing Control + Alt + F-Keys very fast.
# Layer
Each layer in the *keymap.c*-file has a comment showing the mappings of the layer.

@ -0,0 +1,236 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#include "keymap_german.h"
// Layer names
#define BASE 0 // default layer
#define SYMB 1 // symbol layer
#define MDIA 2 // media keys
#define SHRT 3 // shortcut layer
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
*
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | Caps | 1 | 2 | 3 | 4 | 5 |X ` X| | PRSC | 6 | 7 | 8 | 9 | 0 | ß |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | Tab | Q | W | E | R | T | L1 | | L1 | Z | U | I | O | P | Ü |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | Esc | A | S | D | F | G |------| |------| H | J | K | L | Ö | Ä/L2 |
* |--------+------+------+------+------+------| L2 | | L2 |------+------+------+------+------+--------|
* | LShift | Y | X | C | V | B | | | | N | M | , | . | - | RShift |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | LGui | ^ | < | LEFT | RIGHT| | Up | Down | # | + | LCA |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | CTRL | ALT | | Alt |Ctrl/Esc|
* ,------+------+------| |------+--------+------.
* | | | Home | | PgUp | | |
* | Space|Del |------| |------| Bkspc | Enter|
* | | | End | | PgDn | | |
* `--------------------' `----------------------'
*/
// If it accepts an argument (i.e, is a function), it doesn't need KC_.
// Otherwise, it needs KC_*
[BASE] = KEYMAP( // layer 0 : default
// left hand
KC_CAPS, KC_1, KC_2, KC_3, KC_4, KC_5, DE_ACUT,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, TG(SYMB),
KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G,
KC_LSFT, DE_Y, KC_X, KC_C, KC_V, KC_B, ALL_T(KC_NO),
KC_LGUI, DE_CIRC, DE_LESS, KC_LEFT, KC_RIGHT,
KC_LCTRL, KC_LALT,
KC_HOME,
KC_SPC ,KC_DELT,KC_END,
// right hand
KC_PSCREEN, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
TG(MDIA), DE_Z, KC_U, KC_I, KC_O, KC_P, LT(SHRT,DE_UE),
KC_H, KC_J, KC_K, KC_L, DE_OE, LT(MDIA,DE_AE),
MEH_T(KC_NO), KC_N, KC_M, KC_COMM, KC_DOT, DE_MINS, KC_RSFT,
KC_UP, KC_DOWN, DE_HASH, DE_PLUS, LCA_T(KC_NO),
KC_RALT, KC_RCTRL,
KC_PGUP,
KC_PGDN, KC_BSPC, KC_ENT
),
/* Keymap 1: Symbol Layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | F11 |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | ! | @ | { | } | | | | | | Up | 7 | 8 | 9 | * | F12 |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | # | $ | ( | ) | ` |------| |------| Down | 4 | 5 | 6 | + | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | % | ^ | [ | ] | ~ | | | | & | 1 | 2 | 3 | \ | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | | . | 0 | = | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// SYMBOLS
[SYMB] = KEYMAP(
// left hand
KC_TRNS,KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
KC_TRNS,DE_EXLM,DE_AT, DE_LCBR,DE_RCBR,DE_PIPE,KC_TRNS,
KC_TRNS,DE_HASH,DE_DLR, DE_LPRN,DE_RPRN,DE_GRV,
KC_TRNS,DE_PERC,DE_CIRC,DE_LBRC,DE_RBRC,DE_TILD,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,
// right hand
KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
KC_TRNS, KC_UP, KC_7, KC_8, KC_9, DE_ASTR, KC_F12,
KC_DOWN, KC_4, KC_5, KC_6, DE_PLUS, KC_TRNS,
KC_TRNS, DE_AMPR, KC_1, KC_2, KC_3, DE_BSLS, KC_TRNS,
KC_TRNS,KC_DOT, KC_0, DE_EQL, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
/* Keymap 2: Media and mouse keys
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | F11 |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | Lclk | MsUp | Rclk | | | | | |VolDwn| Mute |VolUp | | F12 |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | Btn4 |MsLeft|MsDown|MsRght| Btn5 |------| |------| | Prev | Stop | Play | Next | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | |WhRght|WhDown| WhUp |WhLeft|WhClk | | | |BwSrch|BwBack|BwHome|BwRefr|BwFwd | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | |MsAcl0|MsAcl1|MsAcl2| | | | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | |Brwser|Brwser|
* | Lclk | Rclk |------| |------|Back |Forwd |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// MEDIA AND MOUSE
[MDIA] = KEYMAP(
// left hand
KC_TRNS, KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_TRNS,
KC_TRNS, KC_TRNS, KC_BTN1, KC_MS_U, KC_BTN2, KC_TRNS, KC_TRNS,
KC_TRNS, KC_BTN4, KC_MS_L, KC_MS_D, KC_MS_R, KC_BTN5,
KC_TRNS, KC_WH_L, KC_WH_D, KC_WH_U, KC_WH_R, KC_BTN3, KC_TRNS,
KC_TRNS, KC_TRNS, KC_ACL0, KC_ACL1, KC_ACL2,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_BTN1, KC_BTN2, KC_TRNS,
// right hand
KC_TRNS, KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 , KC_F11,
KC_TRNS, KC_TRNS, KC_VOLD, KC_MUTE, KC_VOLU, KC_TRNS, KC_F12,
KC_TRNS, KC_MPRV, KC_MSTP, KC_MPLY, KC_MNXT, KC_TRNS,
KC_TRNS, KC_WSCH, KC_WBAK, KC_WHOM, KC_WREF, KC_WFWD, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_WBAK, KC_WFWD
),
/* Keymap 3: Linux shortcuts
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | |LCA-F1|LCA-F2|LCA-F3|LCA-F4|LCA-F5| | | |LCA-F6|LCA-F7|LCA-F8|LCA-F9| | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | |LCA-Le| |LCA-Ri| |------| |------| | | | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | | | | | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | |LCA-Le|LCA-Ri| | | | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// Shortcuts
[SHRT] = KEYMAP(
// left hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, LCA(KC_F1), LCA(KC_F2), LCA(KC_F3), LCA(KC_F4), LCA(KC_F5), KC_TRNS,
KC_TRNS, KC_TRNS, LCA(KC_LEFT), KC_TRNS, LCA(KC_RIGHT), KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, LCA(KC_LEFT), LCA(KC_RIGHT),
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
// right hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, LCA(KC_F6), LCA(KC_F7), LCA(KC_F8), LCA(KC_F9), KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
LCA(KC_UP), LCA(KC_DOWN), KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
};
const uint16_t PROGMEM fn_actions[] = {
[1] = ACTION_LAYER_TAP_TOGGLE(SYMB) // FN1 - Momentary Layer 1 (Symbols)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
} else {
unregister_code(KC_RSFT);
}
break;
}
return MACRO_NONE;
};
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
case SYMB:
ergodox_right_led_1_on();
break;
case MDIA:
ergodox_right_led_2_on();
break;
case SHRT:
ergodox_right_led_3_on();
break;
default:
ergodox_board_led_off();
break;
}
};

@ -0,0 +1,177 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#include "bootloader.h"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KEYMAP( // layer 0 : default
// left hand
KC_EQL , KC_1, KC_2, KC_3, KC_4, KC_5, KC_LBRC,
KC_FN25 , KC_Q, KC_W, KC_E, KC_R, KC_T, KC_HOME,
KC_FN27 , KC_A, KC_S, KC_D, KC_F, KC_G,
KC_LSFT , KC_Z, KC_X, KC_C, KC_V, KC_B, KC_PGUP,
KC_LGUI , KC_GRV,KC_LEFT,KC_RGHT,KC_LALT,
KC_NO , KC_NO ,
KC_NO ,
KC_BSPC,KC_DEL ,KC_FN23,
// right hand
KC_RBRC , KC_6, KC_7 , KC_8, KC_9, KC_0, KC_MINS,
KC_END , KC_Y, KC_U , KC_I, KC_O, KC_P, KC_FN28,
KC_H , KC_J, KC_K , KC_L, KC_SCLN,KC_FN30,
KC_PGDN , KC_N, KC_M , KC_COMM,KC_DOT, KC_SLSH,KC_FN29,
KC_RALT , KC_DOWN,KC_UP, KC_NO ,KC_RGUI,
KC_NO , KC_NO,
KC_NO ,
KC_FN29,KC_ENT ,KC_SPC
),
KEYMAP( // layer 1 : function and symbol keys
// left hand
KC_TRNS,KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F11,
KC_TRNS,KC_AT,KC_UNDS ,KC_LBRC,KC_RBRC,KC_CIRC ,KC_TRNS,
KC_TRNS,KC_BSLS,KC_SLSH,KC_LCBR ,KC_RCBR ,KC_ASTR,
KC_TRNS,KC_HASH ,KC_DLR ,KC_PIPE ,KC_TILD ,KC_GRV ,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_FN1,
// right hand
KC_F12, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS,
KC_TRNS,KC_EXLM,LSFT(KC_COMM),LSFT(KC_DOT),KC_EQL,KC_AMPR, KC_TRNS,
LSFT(KC_SLSH),KC_LPRN,KC_RPRN,KC_MINS,LSFT(KC_SCLN),KC_TRNS,
KC_TRNS,KC_PLUS,LSFT(KC_5),LSFT(KC_QUOT),KC_QUOT,KC_SCLN,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS
),
KEYMAP( // layer 2: navigation
// left hand
KC_NO,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_PGUP,KC_HOME,KC_UP ,KC_END,KC_NO ,KC_TRNS,
KC_TRNS,KC_PGDN,KC_LEFT,KC_DOWN,KC_RGHT,KC_NO,
KC_TRNS,KC_NO, KC_NO, KC_NO, KC_NO,KC_NO,KC_NO,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_FN1 ,
// right hand
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS ,KC_TRNS, KC_HOME, KC_TRNS, KC_TRNS, KC_END ,KC_TRNS,
KC_NO, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT,KC_TRNS,
KC_TRNS,KC_TRNS, KC_HOME, KC_UP, KC_END, KC_PGUP,KC_TRNS,
KC_LEFT, KC_DOWN,KC_RGHT,KC_PGDN,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS
),
KEYMAP( // layer 3 : teensy bootloader functions
// left hand
KC_FN0, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_FN1 ,
// right hand
KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS
),
KEYMAP( // layer 4: numpad
// left hand
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,
// right hand
KC_TRNS,KC_NLCK,KC_PSLS,KC_PAST,KC_PAST,KC_PMNS,KC_BSPC,
KC_TRNS,KC_NO, KC_P7, KC_P8, KC_P9, KC_PMNS,KC_BSPC,
KC_NO, KC_P4, KC_P5, KC_P6, KC_PPLS,KC_PENT,
KC_TRNS,KC_NO, KC_P1, KC_P2, KC_P3, KC_PPLS,KC_PENT,
KC_P0, KC_PDOT,KC_SLSH,KC_PENT,KC_PENT,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS
),
};
/* id for user defined functions */
enum function_id {
TEENSY_KEY,
};
/*
* Fn action definition
*/
const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_FUNCTION(TEENSY_KEY), // FN0 - Teensy key
[1] = ACTION_LAYER_SET(0, ON_PRESS),
//[11] = ACTION_MODS_KEY(MOD_LSFT, KC_COMM),
//[12] = ACTION_MODS_KEY(MOD_LSFT, KC_DOT),
//[14] = ACTION_MODS_KEY(MOD_LSFT, KC_SLSH),
//[17] = ACTION_MODS_KEY(MOD_LSFT, KC_SCLN),
//[20] = ACTION_MODS_KEY(MOD_LSFT, KC_5),
//[21] = ACTION_MODS_KEY(MOD_LSFT, KC_QUOT),
[23] = ACTION_LAYER_SET(3, ON_PRESS),
[24] = ACTION_LAYER_SET(2, ON_PRESS),
[25] = ACTION_MODS_TAP_KEY(MOD_LCTL, KC_TAB),
[26] = ACTION_LAYER_SET(1, ON_PRESS),
[27] = ACTION_LAYER_TAP_KEY(1, KC_CAPS),
[28] = ACTION_MODS_TAP_KEY(MOD_RCTL,KC_BSLS),
//[29] = ACTION_LAYER_TOGGLE(4),
[29] = ACTION_MODS_TAP_KEY(MOD_RSFT,KC_ESC),
[30] = ACTION_LAYER_TAP_KEY(1, KC_QUOT),
[31] = ACTION_LAYER_MOMENTARY(2),
//[] = ACTION_LAYER_TAP_KEY(4, KC_S),
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
} else {
unregister_code(KC_RSFT);
}
break;
}
return MACRO_NONE;
};
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
};
void action_function(keyrecord_t *event, uint8_t id, uint8_t opt)
{
if (id == TEENSY_KEY) {
clear_keyboard();
print("\n\nJump to bootloader... ");
wait_ms(250);
bootloader_jump(); // should not return
print("not supported.\n");
}
}

@ -0,0 +1,133 @@
My main layout (Layer 0) is based on qwerty. I tried to fit the layout of the kinesis keyboard onto the ergodox. Furthermore I did some tweaks.
The other layers are seldom used. Except the F Keys and the teensy key. As I own a ergodox I cant press the reset button, so i need a key to send the teensy into reprogram mode.
There is a layer with symbols a numpad. These layers are seldom used. Except the F Keys and the teensy key. As I own a ergodox I need a key to reprogram, because I can't access the reset button.
I am a linux user and need the esc key and str keys often therefore it is easyly accessed. Switching console str+alt+tab+f2 (layer 2 and 2) is tricky but you get it after a while.
As I live in germany and need to type umlaut frquently, i mapped the CAPS to the meta key, and swapped ' and ". So I can type ö with CAPS o + ¨. no need to press o+SHIFT+'
As a note for linux users i use str+p to get last command, instead of using the cursor keys.
HOWTO to convert CAPS to Meta-Key and swap ' with "
* create file with following content
.Xmodmap
clear Lock
keycode 48 = quotedbl apostrophe quotedbl apostrophe
keycode 66 = Multi_key
* apply with
xmodmap .Xmodmap
* convert to xkbmap
xkbcomp $DISPLAY $HOME/.xkbmap
* automatic startup each time you startup x
echo 'xkbcomp $HOME/.xkbmap $DISPLAY' >> ~/.xinitrc
KEYMAP( // layer 0 : default
// left hand
KC_EQL , KC_1, KC_2, KC_3, KC_4, KC_5, KC_LBRC,
KC_FN25 , KC_Q, KC_W, KC_E, KC_R, KC_T, KC_HOME,
KC_FN27 , KC_A, KC_S, KC_D, KC_F, KC_G,
KC_LSFT , KC_Z, KC_X, KC_C, KC_V, KC_B, KC_PGUP,
KC_LGUI , KC_GRV,KC_LEFT,KC_RGHT,KC_LALT,
KC_NO , KC_NO ,
KC_NO ,
KC_BSPC,KC_DEL ,KC_FN23,
// right hand
KC_RBRC , KC_6, KC_7 , KC_8, KC_9, KC_0, KC_MINS,
KC_END , KC_Y, KC_U , KC_I, KC_O, KC_P, KC_FN28,
KC_H , KC_J, KC_K , KC_L, KC_SCLN,KC_FN30,
KC_PGDN , KC_N, KC_M , KC_COMM,KC_DOT, KC_SLSH,KC_FN29,
KC_RALT , KC_DOWN,KC_UP, KC_NO ,KC_RGUI,
KC_NO , KC_NO,
KC_NO ,
KC_FN29,KC_ENT ,KC_SPC
),
KEYMAP( // layer 1 : function and symbol keys
// left hand
KC_TRNS,KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F11,
KC_TRNS,KC_AT,KC_UNDS ,KC_LBRC,KC_RBRC,KC_CIRC ,KC_TRNS,
KC_TRNS,KC_BSLS,KC_SLSH,KC_LCBR ,KC_RCBR ,KC_ASTR,
KC_TRNS,KC_HASH ,KC_DLR ,KC_PIPE ,KC_TILD ,KC_GRV ,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_FN1,
// right hand
KC_F12, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS,
KC_TRNS,KC_EXLM,LSFT(KC_COMM),LSFT(KC_DOT),KC_EQL,KC_AMPR, KC_TRNS,
LSFT(KC_SLSH),KC_LPRN,KC_RPRN,KC_MINS,LSFT(KC_SCLN),KC_TRNS,
KC_TRNS,KC_PLUS,LSFT(KC_5),LSFT(KC_QUOT),KC_QUOT,KC_SCLN,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS
),
KEYMAP( // layer 2: navigation
// left hand
KC_NO,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_PGUP,KC_HOME,KC_UP ,KC_END,KC_NO ,KC_TRNS,
KC_TRNS,KC_PGDN,KC_LEFT,KC_DOWN,KC_RGHT,KC_NO,
KC_TRNS,KC_NO, KC_NO, KC_NO, KC_NO,KC_NO,KC_NO,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_FN1 ,
// right hand
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS ,KC_TRNS, KC_HOME, KC_TRNS, KC_TRNS, KC_END ,KC_TRNS,
KC_NO, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT,KC_TRNS,
KC_TRNS,KC_TRNS, KC_HOME, KC_UP, KC_END, KC_PGUP,KC_TRNS,
KC_LEFT, KC_DOWN,KC_RGHT,KC_PGDN,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS
),
KEYMAP( // layer 3 : teensy bootloader functions
// left hand
KC_FN0, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_FN1 ,
// right hand
KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS
),
KEYMAP( // layer 4: numpad
// left hand
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS,
// right hand
KC_TRNS,KC_NLCK,KC_PSLS,KC_PAST,KC_PAST,KC_PMNS,KC_BSPC,
KC_TRNS,KC_NO, KC_P7, KC_P8, KC_P9, KC_PMNS,KC_BSPC,
KC_NO, KC_P4, KC_P5, KC_P6, KC_PPLS,KC_PENT,
KC_TRNS,KC_NO, KC_P1, KC_P2, KC_P3, KC_PPLS,KC_PENT,
KC_P0, KC_PDOT,KC_SLSH,KC_PENT,KC_PENT,
KC_TRNS,KC_TRNS,
KC_TRNS,
KC_TRNS,KC_TRNS,KC_TRNS
),
};

@ -0,0 +1,223 @@
#include "ergodox.h"
#include "debug.h"
#include "action_layer.h"
#include "version.h"
#define BASE 0 // default layer
#define SYMB 1 // symbols
#define MDIA 2 // media keys
enum custom_keycodes {
PLACEHOLDER = SAFE_RANGE, // can always be here
EPRM,
VRSN,
RGB_SLD
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | \ | 1 | 2 | 3 | 4 | 5 | ESC | | T2 | 6 | 7 | 8 | 9 | 0 | ' |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | Tab | Q | W | E | R | T | TT1 | | TT1 | Y | U | I | O | P | è |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | Caps | A | S | D | F | G |------| |------| H | J | K | L | ò | à |
* |--------+------+------+------+------+------| Alt | | Alt |------+------+------+------+------+--------|
* | LShift | Z | X | C | V | B | | | | N | M | , | . | ù |-/RShift|
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* |</Win | + | - | * |//Ctr | |ì/RAlt| Left | Down | Up | Right | ~L1 |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | Ins | LGui | | Win | Ctrl |
* ,------|------|------| |------+--------+------.
* | | | Home | | PgUp | | |
* |Backsp| Del |------| |------| Enter |Space |
* |ace | | End | | PgDn | | |
* `--------------------' `----------------------'
*/
// If it accepts an argument (i.e, is a function), it doesn't need KC_.
// Otherwise, it needs KC_*
[BASE] = KEYMAP( // layer 0 : default
// left hand
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_ESC,
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, TT(SYMB),
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LALT,
MT(MOD_LGUI,KC_NONUS_BSLASH),KC_PPLS, KC_PMNS,KC_PAST,MT(MOD_LCTL,KC_PSLS),
KC_INS, KC_LGUI,
KC_HOME,
KC_BSPC,KC_DEL, KC_END,
// right hand
TG(MDIA), KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
TT(SYMB), KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC,
KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
KC_LALT, KC_N, KC_M, KC_COMM,KC_DOT, KC_BSLASH, MT(MOD_RSFT,KC_SLSH),
MT(MOD_RALT,KC_EQL), KC_LEFT,KC_DOWN,KC_UP, KC_RIGHT,
KC_LGUI, KC_RCTL,
KC_PGUP,
KC_PGDN, KC_ENT, KC_SPC
),
/* Keymap 1: Symbol Layer
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* |Version | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | F11 |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | ! | @ | { | } | | | | | | | 7 | 8 | 9 | | F12 |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | # | $ | [ | ] | & |------| |------| | 4 | 5 | 6 | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | % | ^ | ( | ) | | | | | | 1 | 2 | 3 | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | | . | | | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | | |
* | | |------| |------| | 0 |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// SYMBOLS
[SYMB] = KEYMAP(
// left hand
M(0), KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
KC_TRNS, KC_EXLM, RALT(KC_SCLN), RALT(KC_LCBR), RALT(KC_RCBR), KC_TILD, KC_TRNS,
KC_TRNS, RALT(KC_QUOT), KC_DLR, RALT(KC_LBRC), RALT(KC_RBRC), KC_CIRC,
KC_TRNS, KC_PERC, LSFT(KC_EQL), LSFT(KC_8), LSFT(KC_9), KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
// right hand
KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
KC_TRNS, KC_TRNS, KC_7, KC_8, KC_9, KC_ASTR, KC_F12,
KC_TRNS, KC_4, KC_5, KC_6, KC_PLUS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_1, KC_2, KC_3, KC_BSLS, KC_TRNS,
KC_DOT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_0
),
/* Keymap 2: Media and mouse keys
*
* ,--------------------------------------------------. ,--------------------------------------------------.
* | | | | | | | | | | | | | | | |
* |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
* | | | | MsUp | | | | | | Lclk | Rclk | | | | |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | |MsLeft|MsDown|MsRght| |------| |------| | | | | | Play |
* |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
* | | | | | | | | | | | | Prev | Next | | |
* `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
* | | | | | | |VolUp |VolDn | Mute | | |
* `----------------------------------' `----------------------------------'
* ,-------------. ,-------------.
* | | | | | |
* ,------|------|------| |------+------+------.
* | | | | | | |Brwser|
* | | |------| |------| |Back |
* | | | | | | | |
* `--------------------' `--------------------'
*/
// MEDIA AND MOUSE
[MDIA] = KEYMAP(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS,
// right hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_BTN1, KC_BTN2, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS,
KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_WBAK
),
};
const uint16_t PROGMEM fn_actions[] = {
[1] = ACTION_LAYER_TAP_TOGGLE(SYMB) // FN1 - Momentary Layer 1 (Symbols)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
}
break;
case 1:
if (record->event.pressed) { // For resetting EEPROM
eeconfig_init();
}
break;
}
return MACRO_NONE;
};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
// dynamically generate these.
case EPRM:
if (record->event.pressed) {
eeconfig_init();
}
return false;
break;
case VRSN:
if (record->event.pressed) {
SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
}
return false;
break;
case RGB_SLD:
if (record->event.pressed) {
#ifdef RGBLIGHT_ENABLE
rgblight_mode(1);
#endif
}
return false;
break;
}
return true;
}
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
// TODO: Make this relevant to the ErgoDox EZ.
case 1:
ergodox_right_led_1_on();
break;
case 2:
ergodox_right_led_2_on();
break;
default:
// none
break;
}
};

@ -0,0 +1,72 @@
# ErgoDox Italian layout
## Layer 0
```
,--------------------------------------------------. ,--------------------------------------------------.
| \ | 1 | 2 | 3 | 4 | 5 | ESC | | T2 | 6 | 7 | 8 | 9 | 0 | ' |
|--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
| Tab | Q | W | E | R | T | TT1 | | TT1 | Y | U | I | O | P | è |
|--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
| Caps | A | S | D | F | G |------| |------| H | J | K | L | ò | à |
|--------+------+------+------+------+------| Alt | | Alt |------+------+------+------+------+--------|
| LShift | Z | X | C | V | B | | | | N | M | , | . | ù |-/RShift|
`--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
|</Win | + | - | * |//Ctr | |ì/RAlt| Left | Down | Up | Right | ~L1 |
`----------------------------------' `----------------------------------'
,-------------. ,-------------.
| Ins | LGui | | Win | Ctrl |
,------|------|------| |------+--------+------.
| | | Home | | PgUp | | |
|Backsp| Del |------| |------| Enter |Space |
|ace | | End | | PgDn | | |
`--------------------' `----------------------'
```
## Layer 1
```
,--------------------------------------------------. ,--------------------------------------------------.
|Version | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | F11 |
|--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
| | ! | @ | { | } | | | | | | | 7 | 8 | 9 | | F12 |
|--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
| | # | $ | [ | ] | & |------| |------| | 4 | 5 | 6 | | |
|--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
| | % | ^ | ( | ) | | | | | | 1 | 2 | 3 | | |
`--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
| | | | | | | . | | | | |
`----------------------------------' `----------------------------------'
,-------------. ,-------------.
| | | | | |
,------|------|------| |------+------+------.
| | | | | | | |
| | |------| |------| | 0 |
| | | | | | | |
`--------------------' `--------------------'
```
## Layer 2
```
,--------------------------------------------------. ,--------------------------------------------------.
| | | | | | | | | | | | | | | |
|--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
| | | | MsUp | | | | | | Lclk | Rclk | | | | |
|--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
| | |MsLeft|MsDown|MsRght| |------| |------| | | | | | Play |
|--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
| | | | | | | | | | | | Prev | Next | | |
`--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
| | | | | | |VolUp |VolDn | Mute | | |
`----------------------------------' `----------------------------------'
,-------------. ,-------------.
| | | | | |
,------|------|------| |------+------+------.
| | | | | | |Brwser|
| | |------| |------| |Back |
| | | | | | | |
`--------------------' `--------------------'
```

@ -0,0 +1,408 @@
#include "ergodox.h"
#include "action_layer.h"
#include "keymap_extras/keymap_german.h"
#define UM 0
#define L0 0 // layer_0
#define L1 1 // layer_1
#define L2 2 // layer_2
#define L3 3 // layer_3
#define L4 4 // layer_4
#define L5 5 // layer_5
#define L6 6 // layer_6
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/*
.------------------------------------.------------------------------------.
|ESC | 1 | 2 | 3 | 4 | 5 | ´ | ` | 6 | 7 | 8 | 9 | 0 | ^ |
!-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
|TAB | X | V | L | C | W |Print| | K | H | G | F | Q | ß |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
|MO(1)| U | I | A | E | O |-----!-----! S | N | R | T | D | Y |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
|LSFT | ü | ö | ä | P | Z |SPACE| | B | M | , | . | J |RSFT |
'-----+----+----+----+----+----------'----------+----+----+----+----+-----'
|LCTL|LGUI|LALT|MO(3)|MO(2)| !MO(2)|MO(3)|APP |RALT|RCTL|
'------------------------' '------------------------'
.-----------. .-----------.
|VOL- |VOL+ | !MUTE |PLAY |
.-----+-----+-----! !-----+-----+-----.
! ! | | ! | ! !
! ! |-----| !-----| ! !
! CTL ! ! ALT ! ! CTL ! ! ALT !
|ENTER|MO(1)| TAB | !ESC |MO(1)|SPACE|
'-----------------' '-----------------'
*/
[L0] = KEYMAP(
KC_ESC, DE_1, DE_2, DE_3, DE_4, DE_5, DE_ACUT,
KC_TAB, DE_X, DE_V, DE_L, DE_C, DE_W, KC_PSCR,
MO(1), DE_U, DE_I, DE_A, DE_E, DE_O,
KC_LSFT, DE_UE, DE_OE, DE_AE, DE_P, DE_Z, KC_SPACE,
KC_LCTL, KC_LGUI, KC_LALT, MO(3), MO(2),
/*-*/ /*-*/ /*-*/ /*-*/ /*-*/ KC_VOLD, KC_VOLU,
/*-*/ /*-*/ /*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ CTL_T(KC_ENTER), MO(1), ALT_T(KC_TAB),
DE_GRV, DE_6, DE_7, DE_8, DE_9, DE_0, DE_CIRC,
KC_TRNS, DE_K, DE_H, DE_G, DE_F, DE_Q, DE_SS,
/*-*/ DE_S, DE_N, DE_R, DE_T, DE_D, DE_Y,
KC_TRNS, DE_B, DE_M, DE_COMM, DE_DOT, DE_J, KC_RSFT,
/*-*/ /*-*/ MO(2), MO(3), KC_APP, KC_RALT, KC_RCTL,
KC_MUTE, KC_MPLY,
KC_TRNS,
CTL_T(KC_ESC), MO(1), ALT_T(KC_SPACE)
),
/*
.------------------------------------.------------------------------------.
| | | | | | | | | | | | | | |
!-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
| | | _ | [ | ] | | | | ! | < | > | = | & | |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
| | \ | / | { | } | * |-----!-----! ? | ( | ) | - | : | @ |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
| | # | $ | | | ~ | | | | + | % | " | ' | ; | |
'-----+----+----+----+----+----------'----------+----+----+----+----+-----'
| | | | | | ! | | | | |
'------------------------' '------------------------'
.-----------. .-----------.
| | | ! | |
.-----+-----+-----! !-----+-----+-----.
! ! | | ! | ! !
! ! !-----! !-----! ! !
| | | | ! | | |
'-----------------' '-----------------'
*/
[L1] = KEYMAP(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, DE_EURO, DE_UNDS, DE_LBRC, DE_RBRC, KC_TRNS, KC_TRNS,
KC_TRNS, DE_BSLS, DE_SLSH, DE_LCBR, DE_RCBR, DE_ASTR,
KC_TRNS, DE_HASH, DE_DLR, DE_PIPE, DE_TILD, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS, KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, DE_EXLM, DE_LESS, DE_MORE, DE_EQL, DE_AMPR, KC_TRNS,
/*-*/ DE_QST, DE_LPRN, DE_RPRN, DE_MINS, DE_COLN, DE_AT,
KC_TRNS, DE_PLUS, DE_PERC, DE_DQOT, DE_QUOT, DE_SCLN, KC_TRNS,
/*-*/ /*-*/ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
/*
* .------------------------------------.------------------------------------.
* | | | | | | | | | | | | | | |
* !-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
* | |PGUP|BSPC| UP |DEL |PGDN| | | | 7 | 8 | 9 | | |
* !-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
* | |HOME|LEFT|DOWN|RGHT|END |-----!-----! | 4 | 5 | 6 | | |
* !-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
* | | | |PREV|NEXT| | | | | 1 | 2 | 3 | | |
* '-----+----+----+----+----+----------'----------+----+----+----+----+-----'
* | | | | | | ! | | | | |
* '------------------------' '------------------------'
* .-----------. .-----------.
* | | | ! | |
* .-----+-----+-----! !-----+-----+-----.
* ! ! | | ! | ! !
* ! ! !-----! !-----! ! !
* | | | | ! | | 0 |
* '-----------------' '-----------------'
*/
[L2] = KEYMAP(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_PGUP, KC_BSPC, KC_UP, KC_DEL, KC_PGDN, KC_TRNS,
KC_TRNS, KC_HOME, KC_LEFT, KC_DOWN, KC_RGHT, KC_END,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS, KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, DE_7, DE_8, DE_9, KC_TRNS, KC_TRNS,
/*-*/ KC_TRNS, DE_4, DE_5, DE_6, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, DE_1, DE_2, DE_3, KC_TRNS, KC_TRNS,
/*-*/ /*-*/ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, DE_0
),
/*
* .------------------------------------.------------------------------------.
* | | F1 | F2 | F3 | F4 | F5 | F6 | | | | | | | |
* !-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
* | | F7 | F8 | F9 | F10| F11| F12 | | |M_WU|M_CU|M_WD| | |
* !-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
* |M_B5 |M_B4|M_B3|M_B2|M_B1| |-----!-----! |M_CL|M_CD|M_CR| | |
* !-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
* | | |M_A2|M_A1|M_A0| | | | | | | | | |
* '-----+----+----+----+----+----------'----------+----+----+----+----+-----'
* | | | | | | ! | | | | |
* '------------------------' '------------------------'
* .-----------. .-----------.
* | | | ! | |
* .-----+-----+-----! !-----+-----+-----.
* ! ! | | ! | ! !
* ! ! !-----! !-----! ! !
* | | | | ! | | |
* '-----------------' '-----------------'
*/
[L3] = KEYMAP(
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6,
KC_TRNS, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,
KC_BTN5, KC_BTN4, KC_BTN3, KC_BTN2, KC_BTN1, KC_TRNS,
KC_TRNS, KC_TRNS, KC_ACL2, KC_ACL1, KC_ACL0, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS, KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_WH_U, KC_MS_U, KC_WH_D, KC_TRNS, KC_TRNS,
/*-*/ KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
/*-*/ /*-*/ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
/*
* .------------------------------------.------------------------------------.
* | | | | | | | | | | | | | | |
* !-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
* | | | | | | | | | | | | | | |
* !-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
* | | | | | | |-----!-----! | | | | | |
* !-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
* | | | | | | | | | | | | | | |
* '-----+----+----+----+----+----------'----------+----+----+----+----+-----'
* | | | | | | ! | | | | |
* '------------------------' '------------------------'
* .-----------. .-----------.
* | | | ! | |
* .-----+-----+-----! !-----+-----+-----.
* ! ! | | ! | ! !
* ! ! !-----! !-----! ! !
* | | | | ! | | |
* '-----------------' '-----------------'
*/
[L4] = KEYMAP(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS, KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
/*-*/ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
/*-*/ /*-*/ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
/*
* .------------------------------------.------------------------------------.
* | | | | | | | | | | | | | | |
* !-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
* | | | | | | | | | | | | | | |
* !-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
* | | | | | | |-----!-----! | | | | | |
* !-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
* | | | | | | | | | | | | | | |
* '-----+----+----+----+----+----------'----------+----+----+----+----+-----'
* | | | | | | ! | | | | |
* '------------------------' '------------------------'
* .-----------. .-----------.
* | | | ! | |
* .-----+-----+-----! !-----+-----+-----.
* ! ! | | ! | ! !
* ! ! !-----! !-----! ! !
* | | | | ! | | |
* '-----------------' '-----------------'
*/
[L5] = KEYMAP(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS, KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
/*-*/ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
/*-*/ /*-*/ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
/*
* .------------------------------------.------------------------------------.
* | | | | | | | | | | | | | | |
* !-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
* | | | | | | | | | | | | | | |
* !-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
* | | | | | | |-----!-----! | | | | | |
* !-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
* | | | | | | | | | | | | | | |
* '-----+----+----+----+----+----------'----------+----+----+----+----+-----'
* | | | | | | ! | | | | |
* '------------------------' '------------------------'
* .-----------. .-----------.
* | | | ! | |
* .-----+-----+-----! !-----+-----+-----.
* ! ! | | ! | ! !
* ! ! !-----! !-----! ! !
* | | | | ! | | |
* '-----------------' '-----------------'
*/
[L6] = KEYMAP(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS, KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS,
/*-*/ /*-*/ /*-*/ /*-*/ KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
/*-*/ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
/*-*/ /*-*/ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS,
KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS
),
};
const uint16_t PROGMEM fn_actions[] = {};
#define UC_MODE_WIN 0
#define UC_MODE_LINUX 1
#define UC_MODE_OSX 2
// TODO: allow default mode to be configured
static uint16_t unicode_mode = UC_MODE_WIN;
uint16_t hextokeycode(uint8_t hex) {
if (hex == 0x0) {
return KC_P0;
}
if (hex < 0xA) {
return KC_P1 + (hex - 0x1);
}
return KC_A + (hex - 0xA);
}
void unicode_action_function(uint16_t hi, uint16_t lo) {
switch (unicode_mode) {
case UC_MODE_WIN:
register_code(KC_LALT);
register_code(KC_PPLS);
unregister_code(KC_PPLS);
register_code(hextokeycode((hi & 0xF0) >> 4));
unregister_code(hextokeycode((hi & 0xF0) >> 4));
register_code(hextokeycode((hi & 0x0F)));
unregister_code(hextokeycode((hi & 0x0F)));
register_code(hextokeycode((lo & 0xF0) >> 4));
unregister_code(hextokeycode((lo & 0xF0) >> 4));
register_code(hextokeycode((lo & 0x0F)));
unregister_code(hextokeycode((lo & 0x0F)));
unregister_code(KC_LALT);
break;
case UC_MODE_LINUX:
register_code(KC_LCTL);
register_code(KC_LSFT);
register_code(KC_U);
unregister_code(KC_U);
register_code(hextokeycode((hi & 0xF0) >> 4));
unregister_code(hextokeycode((hi & 0xF0) >> 4));
register_code(hextokeycode((hi & 0x0F)));
unregister_code(hextokeycode((hi & 0x0F)));
register_code(hextokeycode((lo & 0xF0) >> 4));
unregister_code(hextokeycode((lo & 0xF0) >> 4));
register_code(hextokeycode((lo & 0x0F)));
unregister_code(hextokeycode((lo & 0x0F)));
unregister_code(KC_LCTL);
unregister_code(KC_LSFT);
break;
case UC_MODE_OSX:
break;
}
}
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
if (!record->event.pressed) {
return MACRO_NONE;
}
// MACRODOWN only works in this function
switch(id) {
case UM:
unicode_mode = (unicode_mode + 1) % 2;
break;
default:
break;
}
return MACRO_NONE;
};
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
};
// Runs constantly in the background, in a loop.
void matrix_scan_user(void) {
uint8_t layer = biton32(layer_state);
ergodox_board_led_off();
ergodox_right_led_1_off();
ergodox_right_led_2_off();
ergodox_right_led_3_off();
switch (layer) {
case L1:
ergodox_right_led_1_on();
break;
case L2:
ergodox_right_led_2_on();
break;
case L3:
ergodox_right_led_3_on();
break;
case L4:
ergodox_right_led_1_on();
ergodox_right_led_2_on();
break;
case L5:
ergodox_right_led_1_on();
ergodox_right_led_3_on();
break;
// case L6:
// ergodox_right_led_2_on();
// ergodox_right_led_3_on();
// break;
// case L7:
// ergodox_right_led_1_on();
// ergodox_right_led_2_on();
// ergodox_right_led_3_on();
// break;
default:
ergodox_board_led_off();
break;
}
};

@ -0,0 +1,194 @@
# Neo2 for ErgoDox on QWERTZ
#
# Description
This layout is ment to be used on PCs with DE-de with an additional guest keyboard. E.g. on your PC at work you can use your ergodox with neo but a second keybord is plugged in so your coworkers can enter a few signs if necessary. I live in Germany, so this is my usecase.
# Layers
[Layer0](#layer-0)
Letters, modifiers and volume
[Layer1](#layer-1)
Symbols
[Layer2](#layer-2)
Motion, digits and next/prev Song
[Layer3](#layer-3)
F1 to F12 and mouse actions
[Layer4](#layer-4)
not used
[Layer5](#layer-5)
not used
[Layer6](#layer-6)
not used
## Layer 0
.------------------------------------.------------------------------------.
|ESC | 1 | 2 | 3 | 4 | 5 | ´ | ` | 6 | 7 | 8 | 9 | 0 | ^ |
!-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
|TAB | X | V | L | C | W |Print| | K | H | G | F | Q | ß |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
|MO(1)| U | I | A | E | O |-----!-----! S | N | R | T | D | Y |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
|LSFT | ü | ö | ä | P | Z |SPACE| | B | M | , | . | J |RSFT |
'-----+----+----+----+----+----------'----------+----+----+----+----+-----'
|LCTL|LGUI|LALT|MO(3)|MO(2)| !MO(2)|MO(3)|APP |RALT|RCTL|
'------------------------' '------------------------'
.-----------. .-----------.
|VOL- |VOL+ | !MUTE |PLAY |
.-----+-----+-----! !-----+-----+-----.
! ! | | ! | ! !
! ! |-----| !-----| ! !
! CTL ! ! ALT ! ! CTL ! ! ALT !
|ENTER|MO(1)| TAB | !ESC |MO(1)|SPACE|
'-----------------' '-----------------'
* Left side ESC, TAB, [SymbolLayer], Shift, Ctr, Gui(Windows key), and Alt like normal QWERTZ with neo2.
* Space on right side of left half for mous activity so you don't have to leave the mouse for Space.
* Top row of thumb keys is hard to reach for me, so I put media control on there.
* Thumb keys make use of modifier/tap. E.g. if you tap the Enter key it will be Enter. If you keep it pressed down it will be Ctr. The hold action is written on top of the tap action.
* The small middle thumb keys are not used, es well as the 1.5 sized ones on the left side of the right half.
## Layer 1
.------------------------------------.------------------------------------.
| | | | | | | | | | | | | | |
!-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
| | € | _ | [ | ] | | | | ! | < | > | = | & | |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
| | \ | / | { | } | * |-----!-----! ? | ( | ) | - | : | @ |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
| | # | $ | | | ~ | | | | + | % | " | ' | ; | |
'-----+----+----+----+----+----------'----------+----+----+----+----+-----'
| | | | | | ! | | | | |
'------------------------' '------------------------'
.-----------. .-----------.
| | | ! | |
.-----+-----+-----! !-----+-----+-----.
! ! | | ! | ! !
! ! !-----! !-----! ! !
| | | | ! | | |
'-----------------' '-----------------'
## Layer 2
.------------------------------------.------------------------------------.
| | | | | | | | | | | | | | |
!-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
| |PGUP|BSPC| UP |DEL |PGDN| | | | 7 | 8 | 9 | | |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
| |HOME|LEFT|DOWN|RGHT|END |-----!-----! | 4 | 5 | 6 | | |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
| | | |PREV|NEXT| | | | | 1 | 2 | 3 | | |
'-----+----+----+----+----+----------'----------+----+----+----+----+-----'
| | | | | | ! | | | | |
'------------------------' '------------------------'
.-----------. .-----------.
| | | ! | |
.-----+-----+-----! !-----+-----+-----.
! ! | | ! | ! !
! ! !-----! !-----! ! !
| | | | ! | | 0 |
'-----------------' '-----------------'
## Layer 3
.------------------------------------.------------------------------------.
| | F1 | F2 | F3 | F4 | F5 | F6 | | | | | | | |
!-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
| | F7 | F8 | F9 | F10| F11| F12 | | |M_WU|M_CU|M_WD| | |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
|M_B5 |M_B4|M_B3|M_B2|M_B1| |-----!-----! |M_CL|M_CD|M_CR| | |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
| | |M_A2|M_A1|M_A0| | | | | | | | | |
'-----+----+----+----+----+----------'----------+----+----+----+----+-----'
| | | | | | ! | | | | |
'------------------------' '------------------------'
.-----------. .-----------.
| | | ! | |
.-----+-----+-----! !-----+-----+-----.
! ! | | ! | ! !
! ! !-----! !-----! ! !
| | | | ! | | |
'-----------------' '-----------------'
* M_A Mouse acceleration
* M_B Mouse button
* M_C Mouse cursor
* M_W Mouse wheel
## Layer 4
.------------------------------------.------------------------------------.
| | | | | | | | | | | | | | |
!-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
| | | | | | | | | | | | | | |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
| | | | | | |-----!-----! | | | | | |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
| | | | | | | | | | | | | | |
'-----+----+----+----+----+----------'----------+----+----+----+----+-----'
| | | | | | ! | | | | |
'------------------------' '------------------------'
.-----------. .-----------.
| | | ! | |
.-----+-----+-----! !-----+-----+-----.
! ! | | ! | ! !
! ! !-----! !-----! ! !
| | | | ! | | |
'-----------------' '-----------------'
## Layer 5
.------------------------------------.------------------------------------.
| | | | | | | | | | | | | | |
!-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
| | | | | | | | | | | | | | |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
| | | | | | |-----!-----! | | | | | |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
| | | | | | | | | | | | | | |
'-----+----+----+----+----+----------'----------+----+----+----+----+-----'
| | | | | | ! | | | | |
'------------------------' '------------------------'
.-----------. .-----------.
| | | ! | |
.-----+-----+-----! !-----+-----+-----.
! ! | | ! | ! !
! ! !-----! !-----! ! !
| | | | ! | | |
'-----------------' '-----------------'
## Layer 6
.------------------------------------.------------------------------------.
| | | | | | | | | | | | | | |
!-----+----+----+----+----+----------!-----+----+----+----+----+----+-----!
| | | | | | | | | | | | | | |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
| | | | | | |-----!-----! | | | | | |
!-----+----+----+----x----x----! ! !----x----x----+----+----+-----!
| | | | | | | | | | | | | | |
'-----+----+----+----+----+----------'----------+----+----+----+----+-----'
| | | | | | ! | | | | |
'------------------------' '------------------------'
.-----------. .-----------.
| | | ! | |
.-----+-----+-----! !-----+-----+-----.
! ! | | ! | ! !
! ! !-----! !-----! ! !
| | | | ! | | |
'-----------------' '-----------------'

@ -111,7 +111,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
// Runs just one time when the keyboard initializes.
void matrix_init_user(void) {
eeconfig_init();
};

@ -1,6 +1,6 @@
# The Easy Way
If you have an ErgoDox EZ, the absolute easiest way for you to customize your firmware is using the [graphical configurator](http://configure.ergodox-ez.com), which uses QMK under the hood.
If you have an ErgoDox EZ, the absolute easiest way for you to customize your firmware is using the [graphical configurator](http://configure.ergodox-ez.com), which uses QMK under the hood.
If you can find firmware someone else has made that does what you want, that
is the easiest way to customize your ErgoDox. It requires no programming
@ -69,12 +69,16 @@ files. Check them out with:
The Ez uses the [Teensy Loader](https://www.pjrc.com/teensy/loader.html).
Linux users need to modify udev rules as described on the Teensy Linux page.
Some distributions provide a binary, maybe called `teensy-loader-cli`).
Linux users need to modify udev rules as described on the [Teensy
Linux page]. Some distributions provide a binary, maybe called
`teensy-loader-cli`.
[Teensy Linux page]: https://www.pjrc.com/teensy/loader_linux.html
To flash the firmware:
- Build the firmware with `make keymapname`, for example `make default`
- Build the firmware with `make keymapname`, for example `make default`
- This will result in a hex file called `ergodox_ez_keymapname.hex`, e.g.
`ergodox_ez_default.hex`
@ -87,6 +91,15 @@ To flash the firmware:
- Click the button in the Teensy app to download the firmware.
To flash with ´teensy-loader-cli´:
- Build the firmware with `make keymapname`, for example `make default`
- Run ´<path/to/>teensy_loader_cli --mcu=atmega32u4 -w ergodox_ez_<keymap>.hex´
- Press the Reset button by inserting a paperclip gently into the reset hole
in the top right corder.
## ErgoDox Infinity
The Infinity is two completely independent keyboards, and needs to be flashed
@ -100,7 +113,7 @@ for the left and right halves seperately. To flash them:
- Install the firmware with `sudo make infinity-keymapname-dfu-util`
- Build left hand firmware with `make infinity-keymapname MASTER=right`
- Build right hand firmware with `make infinity-keymapname MASTER=right`
- Plug in the right hand keyboard only.

@ -1,3 +1,3 @@
ifndef MAKEFILE_INCLUDED
include ../../Makefile
endif
endif

@ -0,0 +1,147 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6060
#define DEVICE_VER 0x0001
#define MANUFACTURER Bathroom Epiphanies
#define PRODUCT frosty_flake
#define DESCRIPTION Frosty Flake controller for the CM Storm Quick Fire Rapid
/*
* Frosty Flake Rev. 20140521 made by Bathroom Ephiphanies
* Ported from the Bathroom Epiphanies TMK Firmware:
* https://github.com/BathroomEpiphanies/epiphanies_tmk_keyboard/tree/master/be_controllers
*
*/
/* key matrix size */
#define MATRIX_ROWS 8 // Row0 - Row7 in the schematic
#define MATRIX_COLS 18 // ColA - ColR in the schematic
/*
* Keyboard Matrix Assignments
*/
#define UNUSED_PINS { B0, C4, D3 }
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCING_DELAY 5
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/*
* Force NKRO
*
* Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
* state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
* makefile for this to work.)
*
* If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
* until the next keyboard reset.
*
* NKRO may prevent your keystrokes from being detected in the BIOS, but it is
* fully operational during normal computer usage.
*
* For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
* or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
* bootmagic, NKRO mode will always be enabled until it is toggled again during a
* power-up.
*
*/
//#define FORCE_NKRO
/*
* Magic Key Options
*
* Magic keys are hotkey commands that allow control over firmware functions of
* the keyboard. They are best used in combination with the HID Listen program,
* found here: https://www.pjrc.com/teensy/hid_listen.html
*
* The options below allow the magic key functionality to be changed. This is
* useful if your keyboard/keypad is missing keys and you want magic key support.
*
*/
/* key combination for magic key command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/* control how magic key switches layers */
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
/* override magic key keymap */
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
//#define MAGIC_KEY_HELP1 H
//#define MAGIC_KEY_HELP2 SLASH
//#define MAGIC_KEY_DEBUG D
//#define MAGIC_KEY_DEBUG_MATRIX X
//#define MAGIC_KEY_DEBUG_KBD K
//#define MAGIC_KEY_DEBUG_MOUSE M
//#define MAGIC_KEY_VERSION V
//#define MAGIC_KEY_STATUS S
//#define MAGIC_KEY_CONSOLE C
//#define MAGIC_KEY_LAYER0_ALT1 ESC
//#define MAGIC_KEY_LAYER0_ALT2 GRAVE
//#define MAGIC_KEY_LAYER0 0
//#define MAGIC_KEY_LAYER1 1
//#define MAGIC_KEY_LAYER2 2
//#define MAGIC_KEY_LAYER3 3
//#define MAGIC_KEY_LAYER4 4
//#define MAGIC_KEY_LAYER5 5
//#define MAGIC_KEY_LAYER6 6
//#define MAGIC_KEY_LAYER7 7
//#define MAGIC_KEY_LAYER8 8
//#define MAGIC_KEY_LAYER9 9
//#define MAGIC_KEY_BOOTLOADER PAUSE
//#define MAGIC_KEY_LOCK CAPS
//#define MAGIC_KEY_EEPROM E
//#define MAGIC_KEY_NKRO N
//#define MAGIC_KEY_SLEEP_LED Z
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#endif

@ -0,0 +1,63 @@
#include "frosty_flake.h"
void matrix_init_kb(void) {
// put your keyboard start-up code here
// runs once when the firmware starts up
matrix_init_user();
}
void matrix_scan_kb(void) {
// put your looping keyboard code here
// runs every cycle (a lot)
matrix_scan_user();
}
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
// put your per-action keyboard code here
// runs for every action, just before processing by the firmware
return process_record_user(keycode, record);
}
void led_set_kb(uint8_t usb_led) {
DDRB |= (1<<7);
DDRC |= (1<<5) | (1<<6);
print_dec(usb_led);
if (usb_led & (1<<USB_LED_CAPS_LOCK))
PORTC &= ~(1<<5);
else
PORTC |= (1<<5);
if (usb_led & (1<<USB_LED_NUM_LOCK))
PORTB &= ~(1<<7);
else
PORTB |= (1<<7);
if (usb_led & (1<<USB_LED_SCROLL_LOCK))
PORTC &= ~(1<<6);
else
PORTC |= (1<<6);
led_set_user(usb_led);
}
__attribute__ ((weak))
void matrix_init_user(void) {
}
__attribute__ ((weak))
void matrix_scan_user(void) {
}
__attribute__ ((weak))
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
return true;
}
__attribute__ ((weak))
void led_set_user(uint8_t usb_led) {
}

@ -0,0 +1,50 @@
#ifndef FROSTY_FLAKE_H
#define FROSTY_FLAKE_H
#include "quantum.h"
// This a shortcut to help you visually see your layout.
// The following is an example using the Planck MIT layout
// The first section contains all of the arguements
// The second converts the arguments into a two-dimensional array
/*
Matrix col/row mapping
,----. ,-------------------. ,-------------------. ,-------------------. ,--------------.
| J6 | | I4 | H4 | H2 | H6 | | A7 | E6 | D2 | D4 | | B4 | B7 | B6 | B0 | | C7 | C5 | A5 |
`----' `-------------------' `-------------------' `-------------------' `--------------'
,-------------------------------------------------------------------------. ,--------------. ,-------------------.
| J4 | J7 | I7 | H7 | G7 | G4 | F4 | F7 | E7 | D7 | R7 | R4 | E4 | B2 | | L4 | O4 | Q4 | | K1 | L1 | Q1 | Q0 |
|-------------------------------------------------------------------------| |--------------| |-------------------|
| J2 | J5 | I5 | H5 | G5 | G2 | F2 | F5 | E5 | D5 | R5 | R2 | E2 | B3 | | K4 | O7 | Q7 | | K5 | L5 | Q5 | O5 |
|-------------------------------------------------------------------------| '--------------' |-------------- |
| O5 | J3 | I3 | H3 | G3 | G6 | F6 | F3 | E3 | D3 | R3 | R6 | B1 | | K2 | L2 | Q2 | |
|-------------------------------------------------------------------------| ,----. |-------------------|
| N2 | J1 | I1 | H1 | G1 | G0 | F0 | F1 | E1 | D1 | R0 | N3 | | O6 | | K3 | L3 | Q3 | O3 |
|-------------------------------------------------------------------------| ,--------------. |-------------- |
| A4 | P2 | C6 | K6 | C0 | M3 | D0 | A1 | | O0 | K0 | L0 | | L6 | Q6 | |
`-------------------------------------------------------------------------' `--------------' `-------------------'
*/
#define KEYMAP( \
KJ6, KI4, KH4, KH2, KH6, KA7, KE6, KD2, KD4, KB4, KB7, KB6, KB0, KC7, KC5, KA5, \
KJ4, KJ7, KI7, KH7, KG7, KG4, KF4, KF7, KE7, KD7, KR7, KR4, KE4, KB2, KL4, KO4, KQ4, KK1, KL1, KQ1, KQ0, \
KJ2, KJ5, KI5, KH5, KG5, KG2, KF2, KF5, KE5, KD5, KR5, KR2, KE2, KB3, KK4, KO7, KQ7, KK5, KL5, KQ5, KO5, \
KI2, KJ3, KI3, KH3, KG3, KG6, KF6, KF3, KE3, KD3, KR3, KR6, KB1, KK2, KL2, KQ2, \
KN2, KI6, KJ1, KI1, KH1, KG1, KG0, KF0, KF1, KE1, KD1, KR0, KN3, KO6, KK3, KL3, KQ3, KO3, \
KA4, KP2, KC6, KK6, KC0, KM3, KD0, KA1, KO0, KK0, KL0, KL6, KQ6 \
) \
{ \
/* Columns and rows need to be swapped in the below definition */ \
/* A B C D E F G H I J K L M N O P Q R */ \
/* 0 */ { KC_NO, KB0, KC0, KD0, KC_NO, KF0, KG0, KC_NO, KC_NO, KC_NO, KK0, KL0, KC_NO, KC_NO, KO0, KC_NO, KQ0, KR0 }, \
/* 1 */ { KA1, KB1, KC_NO, KD1, KE1, KF1, KG1, KH1, KI1, KJ1, KK1, KL1, KC_NO, KC_NO, KC_NO, KC_NO, KQ1, KC_NO }, \
/* 2 */ { KC_NO, KB2, KC_NO, KD2, KE2, KF2, KG2, KH2, KI2, KJ2, KK2, KL2, KC_NO, KN2, KC_NO, KP2, KQ2, KR2 }, \
/* 3 */ { KC_NO, KB3, KC_NO, KD3, KE3, KF3, KG3, KH3, KI3, KJ3, KK3, KL3, KM3, KN3, KO3, KC_NO, KQ3, KR3 }, \
/* 4 */ { KA4, KB4, KC_NO, KD4, KE4, KF4, KG4, KH4, KI4, KJ4, KK4, KL4, KC_NO, KC_NO, KO4, KC_NO, KQ4, KR4 }, \
/* 5 */ { KA5, KC_NO, KC5, KD5, KE5, KF5, KG5, KH5, KI5, KJ5, KK5, KL5, KC_NO, KC_NO, KO5, KC_NO, KQ5, KR5 }, \
/* 6 */ { KC_NO, KB6, KC6, KC_NO, KE6, KF6, KG6, KH6, KI6, KJ6, KK6, KL6, KC_NO, KC_NO, KO6, KC_NO, KQ6, KR6 }, \
/* 7 */ { KA7, KB7, KC7, KD7, KE7, KF7, KG7, KH7, KI7, KJ7, KC_NO, KC_NO, KC_NO, KC_NO, KO7, KC_NO, KQ7, KR7 } \
}
#endif

@ -0,0 +1,21 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = no # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,8 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
// place overrides here
#endif

@ -0,0 +1,11 @@
#include "frosty_flake.h"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = KEYMAP(\
KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR,KC_SLCK,KC_PAUS, \
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0,KC_MINS, KC_EQL,KC_BSPC, KC_INS,KC_HOME,KC_PGUP, KC_NLCK,KC_PSLS,KC_PAST,KC_PMNS, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P,KC_LBRC,KC_RBRC,KC_BSLS, KC_DEL, KC_END,KC_PGDN, KC_P7, KC_P8, KC_P9,KC_PPLS, \
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L,KC_SCLN,KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6, \
KC_LSFT,KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M,KC_COMM, KC_DOT,KC_SLSH, KC_RSFT, KC_UP, KC_P1, KC_P2, KC_P3,KC_PENT, \
KC_LCTL,KC_LGUI,KC_LALT, KC_SPC, KC_RALT,KC_RGUI, KC_APP,KC_RCTL, KC_LEFT,KC_DOWN,KC_RGHT, KC_P0,KC_PDOT)
};

@ -0,0 +1 @@
# The default keymap for frosty_flake

@ -0,0 +1,135 @@
/*
Copyright 2017 Gabriel Young <gabeplaysdrums@live.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include <util/delay.h>
#include "print.h"
#include "debug.h"
#include "util.h"
#include "matrix.h"
#ifndef DEBOUNCING_DELAY
# define DEBOUNCING_DELAY 5
#endif
static uint8_t debouncing = DEBOUNCING_DELAY;
static matrix_row_t matrix[MATRIX_ROWS];
static matrix_row_t matrix_debouncing[MATRIX_ROWS];
static matrix_row_t scan_col(void) {
return (
(PINC&(1<<7) ? 0 : ((matrix_row_t)1<<0)) |
(PINB&(1<<5) ? 0 : ((matrix_row_t)1<<1)) |
(PINB&(1<<4) ? 0 : ((matrix_row_t)1<<2)) |
(PINB&(1<<6) ? 0 : ((matrix_row_t)1<<3)) |
(PINB&(1<<1) ? 0 : ((matrix_row_t)1<<4)) |
(PINB&(1<<2) ? 0 : ((matrix_row_t)1<<5)) |
(PINB&(1<<3) ? 0 : ((matrix_row_t)1<<6)) |
(PINB&(1<<0) ? 0 : ((matrix_row_t)1<<7))
);
}
static void select_col(uint8_t col) {
switch (col) {
case 0: PORTD = (PORTD & ~0b01111011) | 0b00011011; break;
case 1: PORTD = (PORTD & ~0b01111011) | 0b01000011; break;
case 2: PORTD = (PORTD & ~0b01111011) | 0b01101010; break;
case 3: PORTD = (PORTD & ~0b01111011) | 0b01111001; break;
case 4: PORTD = (PORTD & ~0b01111011) | 0b01100010; break;
case 5: PORTD = (PORTD & ~0b01111011) | 0b01110001; break;
case 6: PORTD = (PORTD & ~0b01111011) | 0b01100001; break;
case 7: PORTD = (PORTD & ~0b01111011) | 0b01110000; break;
case 8: PORTD = (PORTD & ~0b01111011) | 0b01100000; break;
case 9: PORTD = (PORTD & ~0b01111011) | 0b01101000; break;
case 10: PORTD = (PORTD & ~0b01111011) | 0b00101011; break;
case 11: PORTD = (PORTD & ~0b01111011) | 0b00110011; break;
case 12: PORTD = (PORTD & ~0b01111011) | 0b00100011; break;
case 13: PORTD = (PORTD & ~0b01111011) | 0b01111000; break;
case 14: PORTD = (PORTD & ~0b01111011) | 0b00010011; break;
case 15: PORTD = (PORTD & ~0b01111011) | 0b01101001; break;
case 16: PORTD = (PORTD & ~0b01111011) | 0b00001011; break;
case 17: PORTD = (PORTD & ~0b01111011) | 0b00111011; break;
}
}
void matrix_init(void) {
/* Row output pins */
DDRD |= 0b01111011;
/* Column input pins */
DDRC &= ~0b10000000;
DDRB &= ~0b01111111;
PORTC |= 0b10000000;
PORTB |= 0b01111111;
for (uint8_t i=0; i < MATRIX_ROWS; i++)
matrix[i] = matrix_debouncing[i] = 0;
matrix_init_quantum();
}
uint8_t matrix_scan(void) {
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
select_col(col);
_delay_us(3);
matrix_row_t col_scan = scan_col();
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
bool curr_bit = col_scan & (1<<row);
if (prev_bit != curr_bit) {
matrix_debouncing[row] ^= ((matrix_row_t)1<<col);
debouncing = DEBOUNCING_DELAY;
}
}
}
if (debouncing) {
if (--debouncing)
_delay_ms(1);
else
for (uint8_t i = 0; i < MATRIX_ROWS; i++)
matrix[i] = matrix_debouncing[i];
}
matrix_scan_quantum();
return 1;
}
inline matrix_row_t matrix_get_row(uint8_t row) {
return matrix[row];
}
void matrix_print(void) {
print("\nr\\c ABCDEFGHIJKLMNOPQR\n");
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
matrix_row_t matrix_row = matrix_get_row(row);
xprintf("%02X: ", row);
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
bool curr_bit = matrix_row & (1<<col);
xprintf("%c", curr_bit ? '*' : '.');
}
print("\n");
}
}
uint8_t matrix_key_count(void) {
uint8_t count = 0;
for (uint8_t row = 0; row < MATRIX_ROWS; row++)
count += bitpop32(matrix[row]);
return count;
}

@ -0,0 +1,32 @@
frosty_flake keyboard firmware
======================
This is the firmware for Rev. 20140521 of the Frosty Flake controller by [Bathroom Epiphanies](http://bathroomepiphanies.com/controllers/), a replacement controller for the [Cooler Master Quick Fire Rapid](http://www.coolermaster.com/peripheral/keyboards/quickfirerapid/).
The code was adapted from the [BathroomEpiphanies TMK Firmware](https://github.com/BathroomEpiphanies/epiphanies_tmk_keyboard/tree/master/be_controllers), but has been cleaned up to match the [schematic](https://deskthority.net/wiki/File:Frosty_Flake_Schematics.pdf) and gone through some minor refactoring for QMK.
## Quantum MK Firmware
For the full Quantum feature list, see [the parent readme](/).
## Building
Download or clone the whole firmware and navigate to the keyboards/frosty_flake folder. Once your dev env is setup, you'll be able to type `make` to generate your .hex - you can then use the Teensy Loader to program your .hex file.
Depending on which keymap you would like to use, you will have to compile slightly differently.
### Default
To build with the default keymap, simply run `make default`.
### Other Keymaps
Several version of keymap are available in advance but you are recommended to define your favorite layout yourself. To define your own keymap create a folder with the name of your keymap in the keymaps folder, and see keymap documentation (you can find in top readme.md) and existant keymap files.
To build the firmware binary hex file with a keymap just do `make` with a keymap like this:
```
$ make [default|jack|<name>]
```
Keymaps follow the format **__\<name\>.c__** and are stored in the `keymaps` folder.

@ -0,0 +1,71 @@
# MCU name
#MCU = at90usb1287
MCU = atmega32u2
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= yes # Console for debug(+400)
COMMAND_ENABLE ?= yes # Commands for debug and configuration
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE ?= no # USB Nkey Rollover
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default
MIDI_ENABLE ?= no # MIDI controls
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE ?= no # Audio output on port C6
FAUXCLICKY_ENABLE ?= no # Use buzzer to emulate clicky switches
CUSTOM_MATRIX = yes
SRC += matrix.c

@ -0,0 +1,48 @@
#ifndef MICROSOFT_SCULPT_MOBILE_H
#define MICROSOFT_SCULPT_MOBILE_H
#include "quantum.h"
#define KEYMAP( \
k7Q, k6O, k6P, k6Q, k5O, k5P, k5Q, k7A, k7B, k7C, k7D, k7E, k7F, k1O, k1K, k1L, \
k5A, k5K, k5L, k5M, k5N, k5H, k5I, k2A, k2B, k2C, k2D, k5B, k5C, k5J, k2E, \
k6R, k6D, k6E, k6F, k7I, k7J, k4A, k4B, k4C, k4D, k3A, k3B, k3C, k3D, \
k0J, k6A, k6B, k6C, k7H, k1A, k1B, k5D, k5E, k5F, k5G, k1C, k7P, k2G, \
k2P, k7K, k7L, k7M, k7O, k0A, k0B, k0C, k0D, k0E, k0F, k2L, k6G, k1P,\
k1Q, k4N, k3O,k6N, k3K, k0R, k1M, k6H, k6I, k6J \
) \
{ \
{k0A, k0B, k0C, k0D, k0E, k0F, KC_NO, KC_NO, KC_NO, k0J, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,KC_NO, KC_NO, k0R},\
{k1A, k1B, k1C, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, k1K, k1L, k1M, KC_NO, k1O, k1P, k1Q, KC_NO},\
{k2A, k2B, k2C, k2D, k2E, KC_NO, k2G, KC_NO, KC_NO, KC_NO, KC_NO, k2L, KC_NO, KC_NO, KC_NO, k2P, KC_NO, KC_NO},\
{k3A, k3B, k3C, k3D, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, k3K, KC_NO, KC_NO, KC_NO, k3O, KC_NO, KC_NO, KC_NO},\
{k4A, k4B, k4C, k4D, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, k4N, KC_NO,KC_NO, KC_NO, KC_NO},\
{k5A, k5B, k5C, k5D, k5E, k5F, k5G, k5H, k5I, k5J, k5K, k5L, k5M, k5N, k5O, k5P, k5Q, KC_NO },\
{k6A, k6B, k6C, k6D, k6E, k6F, k6G, k6H, k6I, k6J, KC_NO, KC_NO, KC_NO, k6N, k6O, k6P, k6Q, k6R},\
{k7A, k7B, k7C, k7D, k7E, k7F, KC_NO, k7H, k7I, k7J, k7K, k7L, k7M, KC_NO, k7O, k7P, k7Q, KC_NO},\
}
#define MATRIX_TESTING_KEYMAP( \
k0A, k0B, k0C, k0D, k0E, k0F, k0G, k0H, k0I, k0, k0J, k0K, k0L, k0M, k0N, k0O, k0P, k0Q,\
k1A, k1B, k1C, k1D, k1E, k1F, k1G, k1H, k1I, k1, k1J, k1K, k1L, k1M, k1N, k1O, k1P, k1Q,\
k2A, k2B, k2C, k2D, k2E, k2F, k2G, k2H, k2I, k2, k2J, k2K, k2L, k2M, k2N, k2O, k2P, k2Q,\
k3A, k3B, k3C, k3D, k3E, k3F, k3G, k3H, k3I, k3, k3J, k3K, k3L, k3M, k3N, k3O, k3P, k3Q,\
k4A, k4B, k4C, k4D, k4E, k4F, k4G, k4H, k4I, k4, k4J, k4K, k4L, k4M, k4N, k4O, k4P, k4Q,\
k5A, k5B, k5C, k5D, k5E, k5F, k5G, k5H, k5I, k5, k5J, k5K, k5L, k5M, k5N, k5O, k5P, k5Q,\
k6A, k6B, k6C, k6D, k6E, k6F, k6G, k6H, k6I, k6, k6J, k6K, k6L, k6M, k6N, k6O, k6P, k6Q,\
k7A, k7B, k7C, k7D, k7E, k7F, k7G, k7H, k7I, k7, k7J, k7K, k7L, k7M, k7N, k7O, k7P, k7Q\
) \
{ \
{k0A, k0B, k0C, k0D, k0E, k0F, k0G, k0H, k0I, k0, k0J, k0K, k0L, k0M, k0N, k0O, k0P, k0Q},\
{k1A, k1B, k1C, k1D, k1E, k1F, k1G, k1H, k1I, k1, k1J, k1K, k1L, k1M, k1N, k1O, k1P, k1Q},\
{k2A, k2B, k2C, k2D, k2E, k2F, k2G, k2H, k2I, k2, k2J, k2K, k2L, k2M, k2N, k2O, k2P, k2Q},\
{k3A, k3B, k3C, k3D, k3E, k3F, k3G, k3H, k3I, k3, k3J, k3K, k3L, k3M, k3N, k3O, k3P, k3Q},\
{k4A, k4B, k4C, k4D, k4E, k4F, k4G, k4H, k4I, k4, k4J, k4K, k4L, k4M, k4N, k4O, k4P, k4Q},\
{k5A, k5B, k5C, k5D, k5E, k5F, k5G, k5H, k5I, k5, k5J, k5K, k5L, k5M, k5N, k5O, k5P, k5Q},\
{k6A, k6B, k6C, k6D, k6E, k6F, k6G, k6H, k6I, k6, k6J, k6K, k6L, k6M, k6N, k6O, k6P, k6Q},\
{k7A, k7B, k7C, k7D, k7E, k7F, k7G, k7H, k7I, k7, k7J, k7K, k7L, k7M, k7N, k7O, k7P, k7Q},\
}
#endif

@ -0,0 +1,3 @@
ifndef MAKEFILE_INCLUDED
include ../../../Makefile
endif

@ -0,0 +1,459 @@
/* A library to output the right key shortcut in any common app.
Given a global variable babble_mode to show the environment and a
key that calls the paste macro, do the right type of paste.
Setting the context is done by another macro, or TBD interaction with the host.
Huge thanks to https://en.wikipedia.org/wiki/Table_of_keyboard_shortcuts
and https://github.com/qmk/qmk_firmware/blob/master/keyboards/planck/keymaps/jeebak/keymap.c
*/
#include "babblePaste.h"
#include "action_macro.h"
#ifdef USE_BABLPASTE
// GLOBAL variable to determine mode. Sets startup default if no eeppom
uint8_t babble_mode =0 ;
// small function that we might also want to call from a keymap.
macro_t* switch_babble_mode( uint8_t id) {
babble_mode= id;
return MACRO_NONE; //less typing where called
}
// Today I learned that the preprocessor can not create a switch statement label from an argument
// And else statements have problems, see https://gcc.gnu.org/onlinedocs/gcc-3.0.1/cpp_3.html#SEC15
#define BABLM(ent, macro...) \
if ( ent == shortcut ) \
{ action_macro_play( MACRO(macro)); return MACRO_NONE; }
/* this function runs the appropriate babblepaste macro, given
the global babble_mode, and a shortcut from the ENUM in babblePaste.h
TODO, the pointers in this function should be stored in a PROGMEM array, not ram.
But that requires even more clever preprocessor foo.
*/
const macro_t *babblePaste (keyrecord_t *record, uint8_t shortcut) {
/*
if ( shortcut < BABL_START_NUM || \
shortcut >= (BABL_START_NUM + BABL_NUM_MACROS ) ) {
return MACRO_NONE;
}
*/
#ifdef MS_MODE
if ( BABL_WINDOWS == shortcut ) { return switch_babble_mode(MS_MODE); }
#endif
#ifdef MAC_MODE
if ( BABL_MAC == shortcut) { return switch_babble_mode(MAC_MODE); }
#endif
#ifdef LINUX_MODE
if ( BABL_LINUX == shortcut ) { return switch_babble_mode(LINUX_MODE); }
#endif
#ifdef READMUX_MODE
if ( BABL_READLINE == shortcut ) { switch_babble_mode(READMUX_MODE); return MACRO_NONE; }
#endif
#ifdef VI_MODE
if ( BABL_VI == shortcut ) { return switch_babble_mode(VI_MODE); }
#endif
#ifdef EMACS_MODE
if ( BABL_EMACS == shortcut ) { return switch_babble_mode(EMACS_MODE); }
#endif
switch(babble_mode) {
#ifdef MS_MODE
case MS_MODE:
BABLM( BABL_GO_LEFT_1C, T(LEFT), END );
BABLM( BABL_GO_RIGHT_1C , T(RIGHT), END );
BABLM( BABL_GO_LEFT_WORD, D(LCTL), T(LEFT), U(LCTL), END );
BABLM( BABL_GO_RIGHT_WORD, D(LCTL), T(RIGHT), U(LCTL), END );
BABLM( BABL_GO_START_LINE, T(HOME), END );
BABLM( BABL_GO_END_LINE, T(END), END );
BABLM( BABL_GO_START_DOC, D(LCTL),T(HOME), U(LCTL),END );
BABLM( BABL_GO_END_DOC, D(LCTL),T(END), U(LCTL),END );
BABLM( BABL_GO_NEXT_LINE, T(DOWN), END );
BABLM( BABL_GO_PREV_LINE, T(UP), END );
BABLM( BABL_PGDN, T(PGDN), END );
BABLM( BABL_PGUP, T(PGUP), END );
BABLM( BABL_DEL_RIGHT_1C, T(DEL), END );
BABLM( BABL_DEL_LEFT_WORD, D(LCTL), T(BSPACE), U(LCTL), END );
BABLM( BABL_DEL_RIGHT_WORD, D(LCTL), T(DEL), U(LCTL), END );
BABLM( BABL_DEL_TO_LINE_END, D(RSFT), T(HOME), U(RSFT), T(DEL), END);
BABLM( BABL_DEL_TO_LINE_START, D(RSFT), T(END), U(RSFT), T(DEL), END );
#ifndef BABL_MOVEMENTONLY
BABLM( BABL_UNDO, D(LCTL), T(Z), U(LCTL), END );
BABLM( BABL_REDO, D(LCTL), T(Y), U(LCTL), END );
BABLM( BABL_CUT, D(LCTL), T(X), U(LCTL), END );
BABLM( BABL_COPY, D(LCTL), T(C), U(LCTL), END );
BABLM( BABL_PASTE, D(LCTL), T(V), U(LCTL), END );
BABLM( BABL_SELECT_ALL, D(LCTL), T(A), U(LCTL), END );
BABLM( BABL_FIND, D(LCTL),T(F), U(LCTL),END );
BABLM( BABL_FIND_NEXT, T(F3),END );
BABLM( BABL_FIND_REPLACE, D(LCTL),T(H), U(LCTL),END );
BABLM( BABL_RUNAPP, D(LGUI),T(R), U(LGUI),END );
BABLM( BABL_SWITCH_APP_NEXT, D(LALT),T(TAB), U(LALT),END );
BABLM( BABL_SWITCH_APP_LAST, D(LSFT),D(LALT),T(TAB), U(LALT), U(LSFT),END );
BABLM( BABL_CLOSE_APP, D(LALT),T(F4), U(LALT),END );
BABLM( BABL_HELP, T(F1),END );
#ifndef BABL_NOBROWSER
BABLM( BABL_BROWSER_NEW_TAB, D(LCTL), T(T), U(LCTL),END );
BABLM( BABL_BROWSER_CLOSE_TAB, D(LCTL), T(W), U(LCTL),END );
BABLM( BABL_BROWSER_REOPEN_LAST_TAB, D(LCTL), D(RSFT),T(T), U(RSFT),U(LCTL),END );
BABLM( BABL_BROWSER_NEXT_TAB, D(LCTL), T(TAB), U(LCTL),END );
BABLM( BABL_BROWSER_PREV_TAB, D(LCTL), D(RSFT), T(TAB), U(RSFT), U(LCTL),END );
BABLM( BABL_BROWSER_URL_BAR, D(LCTL), T(L), U(LCTL),END );
BABLM( BABL_BROWSER_FORWARD, D(LALT), T(RIGHT), U(LALT),END );
BABLM( BABL_BROWSER_BACK, D(LALT), T(LEFT), U(LALT),END );
BABLM( BABL_BROWSER_FIND, D(LCTL), T(F), U(LCTL),END );
BABLM( BABL_BROWSER_BOOKMARK, D(LCTL), T(D), U(LCTL),END );
//BABLM( BABL_BROWSER_DEV_TOOLS, T(F12), U(LCTL),END ); // EDGE
BABLM( BABL_BROWSER_DEV_TOOLS, D(LCTL), T(T), U(LCTL),END ); // Chrome
// Chrome
BABLM( BABL_BROWSER_RELOAD, D(LCTL), T(F5), U(LCTL),END ); // hard reload w/o cache
BABLM( BABL_BROWSER_FULLSCREEN, T(F11),END ); //command shift F
BABLM( BABL_BROWSER_ZOOM_IN, D(LCTL), D(RSFT), T(EQL), U(RSFT), U(LCTL),END ); // ctr+ +
BABLM( BABL_BROWSER_ZOOM_OUT, D(LCTL), T(MINS), U(LCTL),END );
#endif
#endif
// Todo, ring bell, flash light, show user this isn't supported
return MACRO_NONE;
#endif /* MS_MODE*/
#ifdef LINUX_MODE
case LINUX_MODE:
BABLM( BABL_GO_LEFT_1C , T(LEFT), END );
BABLM( BABL_GO_RIGHT_1C , T(RIGHT), END );
BABLM( BABL_GO_LEFT_WORD , D(LCTL), T(LEFT), U(LCTL), END );
BABLM( BABL_GO_RIGHT_WORD , D(LCTL), T(RIGHT), U(LCTL), END );
BABLM( BABL_GO_START_LINE , T(HOME), END );
BABLM( BABL_GO_END_LINE , T(END), END );
BABLM( BABL_GO_START_DOC , D(LCTL),T(HOME), U(LCTL),END );
BABLM( BABL_GO_END_DOC , D(LCTL),T(END), U(LCTL),END );
BABLM( BABL_GO_NEXT_LINE , T(DOWN), END );
BABLM( BABL_GO_PREV_LINE , T(UP), END );
BABLM( BABL_PGDN , T(PGDN), END );
BABLM( BABL_PGUP , T(PGUP), END );
BABLM( BABL_DEL_RIGHT_1C , D(DEL), END );
BABLM( BABL_DEL_LEFT_WORD , D(LCTL), T(BSPACE), U(LCTL), END );
BABLM( BABL_DEL_RIGHT_WORD , D(LCTL), T(DEL), U(LCTL), END );
BABLM( BABL_DEL_TO_LINE_END, D(RSFT), T(HOME), U(RSFT), T(DEL), END);
BABLM( BABL_DEL_TO_LINE_START, D(RSFT), T(END), U(RSFT), T(DEL), END );
#ifndef BABL_MOVEMENTONLY
BABLM( BABL_UNDO , D(LCTL), T(Z), U(LCTL), END );
BABLM( BABL_REDO , D(LCTL), T(Y), U(LCTL), END );
BABLM( BABL_CUT , D(LCTL), T(X), U(LCTL), END );
BABLM( BABL_COPY , D(LCTL), T(C), U(LCTL), END );
BABLM( BABL_PASTE , D(LCTL), T(V), U(LCTL), END );
BABLM( BABL_SELECT_ALL, D(LCTL), T(A), U(LCTL), END );
BABLM( BABL_FIND, D(LCTL),T(F), U(LCTL),END );
/* BABLM(BABL_FIND_NEXT , T(F3),END ); KDE */
BABLM( BABL_FIND_NEXT, D(LCTL),T(G), U(LCTL),END ); // Gnome*/
/* BABLM( , D(LCTL),T(R), U(LCTL),END ); KDE */
BABLM( BABL_FIND_REPLACE, D(LCTL),T(H), U(LCTL),END ); // Gnome*/
BABLM( BABL_RUNAPP, D(LALT),T(F2), U(LALT),END );
BABLM( BABL_SWITCH_APP_NEXT, D(LCTL),T(TAB), U(LCTL),END );
BABLM( BABL_SWITCH_APP_LAST, D(LSFT),D(LCTL),T(TAB), U(LCTL), U(LSFT),END );
BABLM( BABL_CLOSE_APP, D(LALT),T(F4), U(LALT),END );
//BABLM( BABL_HELP, END );
#ifndef BABL_NOBROWSER
BABLM( BABL_BROWSER_NEW_TAB, D(LCTL), T(T), U(LCTL),END );
BABLM( BABL_BROWSER_CLOSE_TAB, D(LCTL), T(W), U(LCTL),END );
BABLM( BABL_BROWSER_REOPEN_LAST_TAB, D(LCTL), D(RSFT),T(T), U(RSFT),U(LCTL),END );
BABLM( BABL_BROWSER_NEXT_TAB, D(LCTL), T(TAB), U(LCTL),END );
BABLM( BABL_BROWSER_PREV_TAB, D(LCTL), D(RSFT), T(TAB), U(RSFT), U(LCTL),END );
BABLM( BABL_BROWSER_URL_BAR, D(LCTL), T(L), U(LCTL),END );
BABLM( BABL_BROWSER_FORWARD, D(LALT), T(RIGHT), U(LALT),END );
BABLM( BABL_BROWSER_BACK, D(LALT), T(LEFT), U(LALT),END );
BABLM( BABL_BROWSER_FIND, D(LCTL), T(F), U(LCTL),END );
BABLM( BABL_BROWSER_BOOKMARK, D(LCTL), T(D), U(LCTL),END );
BABLM( BABL_BROWSER_DEV_TOOLS, D(LCTL), T(T), U(LCTL),END ); // Chrome
BABLM( BABL_BROWSER_RELOAD, D(LCTL), T(F5), U(LCTL),END ); // hard reload w/o cache
BABLM( BABL_BROWSER_FULLSCREEN, T(F11),END ); //command shift F
BABLM( BABL_BROWSER_ZOOM_IN, D(LCTL), T(PLUS), U(LCTL),END );
BABLM( BABL_BROWSER_ZOOM_OUT, D(LCTL), T(MINS), U(LCTL),END );
#endif
#endif
return MACRO_NONE;
#endif
#ifdef MAC_MODE
case MAC_MODE:
BABLM( BABL_GO_LEFT_1C , T(LEFT), END );
BABLM( BABL_GO_RIGHT_1C, T(RIGHT), END );
BABLM( BABL_GO_LEFT_WORD , D(LALT), T(LEFT), U(LALT), END );
BABLM( BABL_GO_RIGHT_WORD , D(LALT), T(RIGHT), U(LALT), END );
BABLM( BABL_GO_START_LINE , D(LGUI), T(LEFT), U(LGUI), END );
BABLM( BABL_GO_END_LINE , D(LGUI), T(RIGHT), U(LGUI), END );
BABLM( BABL_GO_START_DOC , D(LGUI),T(UP), U(LGUI),END );
BABLM( BABL_GO_END_DOC , D(LGUI),T(DOWN), U(LGUI),END );
BABLM( BABL_GO_NEXT_LINE , T(DOWN), END );
BABLM( BABL_GO_PREV_LINE , T(UP), END );
BABLM( BABL_PGDN , D(LALT),T(DOWN), U(LALT), END );
BABLM( BABL_PGUP , D(LALT),T(UP), U(LALT), END );
BABLM( BABL_DEL_RIGHT_1C , D(DEL), END );
BABLM( BABL_DEL_LEFT_WORD , D(LALT), T(BSPACE), U(LALT), END );
BABLM( BABL_DEL_RIGHT_WORD, D(LALT), T(DEL), U(LALT), END );
BABLM( BABL_DEL_TO_LINE_END, D(LCTL), T(K), U(LCTL), END );// there must be another way
BABLM( BABL_DEL_TO_LINE_START, D(LGUI), T(BSPACE), U(LGUI), END );
#ifndef BABL_MOVEMENTONLY
BABLM( BABL_UNDO , D(1), D(LGUI), T(Z), U(LGUI), END );
BABLM( BABL_REDO , D(LSFT),D(LGUI), T(Z), U(LSFT),U(LGUI), END );
BABLM( BABL_CUT , D(LGUI), T(X), U(LGUI), END );
BABLM( BABL_COPY , D(LGUI), T(C), U(LGUI), END );
BABLM( BABL_PASTE , D(LGUI), T(V), U(LGUI), END );
BABLM( BABL_SELECT_ALL , D(LGUI), T(A), U(LGUI), END );
BABLM( BABL_FIND , D(LGUI),T(F), U(LGUI),END );
BABLM( BABL_FIND_NEXT, D(LGUI),T(G), U(LGUI),END );
BABLM( BABL_FIND_REPLACE, D(LGUI),T(F), U(LGUI),END );
BABLM( BABL_RUNAPP , D(LGUI),T(R), U(LGUI),END );
BABLM( BABL_SWITCH_APP_NEXT , D(LGUI),T(TAB), U(LGUI),END );
BABLM( BABL_SWITCH_APP_LAST , D(LSFT),D(LGUI),T(TAB), U(LGUI), U(LSFT),END );
BABLM( BABL_CLOSE_APP , D(LGUI),T(Q), U(LGUI),END );
BABLM( BABL_HELP , D(LSFT),D(LGUI),T(SLASH), U(LGUI), U(LSFT),END );
#ifndef BABL_NOBROWSER
BABLM( BABL_BROWSER_NEW_TAB, D(LGUI), T(T), U(LGUI),END );
BABLM( BABL_BROWSER_CLOSE_TAB, D(LGUI), T(W), U(LGUI),END );
BABLM( BABL_BROWSER_REOPEN_LAST_TAB, D(LGUI), D(RSFT),T(T), U(RSFT),U(LGUI),END );
BABLM( BABL_BROWSER_NEXT_TAB, D(LGUI),D(LALT), T(RIGHT),U(LALT), U(LGUI),END );
BABLM( BABL_BROWSER_PREV_TAB, D(LGUI), D(RSFT), T(LEFT), U(RSFT), U(LGUI),END );
BABLM( BABL_BROWSER_URL_BAR, D(LGUI), T(L), U(LGUI),END );
BABLM( BABL_BROWSER_FORWARD, D(LGUI), T(RIGHT), U(LGUI),END );
BABLM( BABL_BROWSER_BACK, D(LGUI), T(LEFT), U(LGUI),END );
BABLM( BABL_BROWSER_FIND, D(LGUI), T(F), U(LGUI),END );
BABLM( BABL_BROWSER_BOOKMARK, D(LGUI), T(D), U(LGUI),END );
//BABLM( BABL_BROWSER_DEV_TOOLS, T(F12), U(LGUI),END ); // EDGE
BABLM( BABL_BROWSER_DEV_TOOLS, D(LGUI), D(LALT), T(I), U(LALT),U(LGUI),END ); // Chrome
// Chrome
BABLM( BABL_BROWSER_RELOAD, D(LGUI), T(R), U(LGUI),END ); // add shift for reload w/o cache
BABLM( BABL_BROWSER_FULLSCREEN, D(LGUI), D(LCTL), T(P), U(LCTL), U(LGUI),END ); //command shift F
BABLM( BABL_BROWSER_ZOOM_IN, D(LGUI), D(RSFT), T(EQL), U(RSFT), U(LGUI),END ); // ctr+ +
BABLM( BABL_BROWSER_ZOOM_OUT, D(LGUI), T(MINS), U(LGUI),END );
#endif
#endif
return MACRO_NONE;
#endif
#ifdef EMACS_MODE
case EMACS_MODE:
switch(shortcut) {
//probably should allow meta to not be ALT
BABLM( BABL_GO_LEFT_1C, T(LEFT), END );
BABLM( BABL_GO_RIGHT_1C, T(RIGHT), END );
BABLM( BABL_GO_LEFT_WORD, D(LALT), T(B), U(LALT), END );
BABLM( BABL_GO_RIGHT_WORD , D(LALT), T(F), U(LALT), END );
BABLM( BABL_GO_START_LINE , D(LCTL), T(A), U(LCTL), END );
BABLM( BABL_GO_END_LINE , D(LCTL), T(E), U(LCTL), END );
BABLM( BABL_GO_START_DOC , D(LALT), D(LSFT), T(COMM),U(LSFT), U(LALT) ,END );
BABLM( BABL_GO_END_DOC , D(LALT), D(LSFT), T(DOT), U(LSFT), U(LALT) ,END );
BABLM( BABL_GO_NEXT_LINE , D(LCTL), T(N), U(LCTL), END );
BABLM( BABL_GO_PREV_LINE , D(LCTL), T(P), U(LCTL), END );
BABLM( BABL_PGDN , D(LCTL), T(V), U(LCTL), END );
BABLM( BABL_PGUP , D(LALT), T(V), U(LALT), END );
BABLM( BABL_DEL_RIGHT_1C, D(LCTL), T(D), U(LCTL),END );
BABLM( BABL_DEL_LEFT_WORD , D(LCTL), T(BSPACE), U(LCTL), END );
BABLM( BABL_DEL_RIGHT_WORD , D(LALT), T(D), U(LALT), END );
BABLM( BABL_DEL_TO_LINE_END, D(LCTL), T(K), U(LCTL), END );
BABLM( BABL_DEL_TO_LINE_START, T(ESC), T(0), D(LCTL), T(K), U(LCTL), END );
#ifndef BABL_MOVEMENTONLY
BABLM( BABL_UNDO , D(LCTL), T(X), U(LCTL),T(C), END );
BABLM( BABL_REDO , D(LCTL), T(X), U(LCTL),T(C), END ); // arguably
BABLM( BABL_CUT , D(LCTL), T(W), U(LCTL), END );
BABLM( BABL_COPY , D(LALT), T(W), U(LALT), END ); //really?
BABLM( BABL_PASTE , D(LCTL), T(Y), U(LCTL), END );
BABLM( BABL_SELECT_ALL ,D(LCTL), T(X), U(LCTL),T(H), END );
BABLM( BABL_FIND , D(LCTL), T(S), U(LCTL),END );
BABLM( BABL_FIND_NEXT , D(LCTL), T(S), U(LCTL),END );
BABLM( BABL_FIND_REPLACE , D(LALT),D(LSFT), T(5),U(LSFT), U(LALT), END );
BABLM( BABL_RUNAPP , D(LALT), T(X), U(LALT),T(S),T(H),T(E),T(L),T(L),END );// arguably
BABLM( BABL_SWITCH_APP_NEXT , D(LCTL), T(X), U(LCTL),T(RIGHT), END ); // arguably
BABLM( BABL_SWITCH_APP_LAST , D(LCTL), T(X), U(LCTL),T(LEFT), END ); // arguably
BABLM( BABL_CLOSE_APP , D(LCTL), T(X), U(LCTL),T(C),END );
BABLM( BABL_HELP , D(LCTL),T(H), U(LCTL),T(A),END); // start search in help
#ifndef BABL_NOBROWSER
/* you get to figure w3 out
BABLM( BABL_BROWSER_NEW_TAB, D(LGUI), T(T), U(LGUI),END );
BABLM( BABL_BROWSER_CLOSE_TAB, D(LGUI), T(W), U(LGUI),END );
BABLM( BABL_BROWSER_REOPEN_LAST_TAB, D(LGUI), D(RSFT),T(T), U(RSFT),U(LGUI),END );
BABLM( BABL_BROWSER_NEXT_TAB, D(LGUI),D(LALT), T(RIGHT),U(LALT), U(LGUI),END );
BABLM( BABL_BROWSER_PREV_TAB, D(LGUI), D(RSFT), T(LEFT), U(RSFT), U(LGUI),END );
BABLM( BABL_BROWSER_URL_BAR, D(LGUI), T(L), U(LGUI),END );
BABLM( BABL_BROWSER_FORWARD, D(LGUI), T(RIGHT), U(LGUI),END );
BABLM( BABL_BROWSER_BACK, D(LGUI), T(LEFT), U(LGUI),END );
BABLM( BABL_BROWSER_FIND, D(LGUI), T(F), U(LGUI),END );
BABLM( BABL_BROWSER_BOOKMARK, D(LGUI), T(D), U(LGUI),END );
//BABLM( BABL_BROWSER_DEV_TOOLS, T(F12), U(LGUI),END ); // EDGE
BABLM( BABL_BROWSER_DEV_TOOLS, D(LGUI), D(LALT), T(I), U(LALT),U(LGUI),END ); // Chrome
// Chrome
BABLM( BABL_BROWSER_RELOAD, D(LGUI), T(R), U(LGUI),END ); // add shift for reload w/o cache
BABLM( BABL_BROWSER_FULLSCREEN, D(LGUI), D(LCTL), T(P), U(LCTL), U(LGUI),END ); //command shift F
BABLM( BABL_BROWSER_ZOOM_IN, D(LGUI), D(RSFT), T(EQL), U(RSFT), U(LGUI),END ); // ctr+ +
BABLM( BABL_BROWSER_ZOOM_OUT, D(LGUI), T(MINS), U(LGUI),END );
*/
#endif
#endif
break;
return MACRO_NONE;
}
#endif
#ifdef VI_MODE
case VI_MODE:
// you have to track the modes yourself. Otherwise motion is awful (bell, bell, bell)
BABLM( BABL_GO_LEFT_1C , T(H), END );
BABLM( BABL_GO_RIGHT_1C , T(L), END );
BABLM( BABL_GO_LEFT_WORD , T(B),END );
BABLM( BABL_GO_RIGHT_WORD , T(W), END );
BABLM( BABL_GO_START_LINE , D(LSFT), T(6),U(LSFT), END ); //^
BABLM( BABL_GO_END_LINE , D(LSFT), T(4),U(LSFT) , END ); //$
BABLM( BABL_GO_START_DOC , T(G),T(G) ,END );
BABLM( BABL_GO_END_DOC , D(LSFT), T(G),U(LSFT),END );
BABLM( BABL_GO_NEXT_LINE , T(J), END );
BABLM( BABL_GO_PREV_LINE, T(K), END );
BABLM( BABL_PGDN ,D(LCTL), T(F), U(LCTL), END );
BABLM( BABL_PGUP , D(LCTL), T(B), U(LCTL), END );
BABLM( BABL_DEL_RIGHT_1C , T(X),END );
BABLM( BABL_DEL_LEFT_WORD , T(D),T(G),T(E),END );
BABLM( BABL_DEL_RIGHT_WORD , T(D),T(W),END );
BABLM( BABL_DEL_TO_LINE_END, T(D),D(LSFT), T(4),U(LSFT) ,END ); // d$
BABLM( BABL_DEL_TO_LINE_START, T(D),D(LSFT), T(6),U(LSFT) ,END );
#ifndef BABL_MOVEMENTONLY
BABLM( BABL_UNDO , T(U), END );
BABLM( BABL_REDO , D(LCTL), T(R), U(LCTL), END );
BABLM( BABL_CUT , T(X), END );
BABLM( BABL_COPY , T(Y),END );
BABLM( BABL_PASTE , T(P), END );
BABLM( BABL_SELECT_ALL , D(LSFT), T(SCLN),U(LSFT),D(LSFT), T(5),U(LSFT),T(Y), END ); // wrong but helpful?
BABLM( BABL_FIND , T(SLASH),END );
BABLM( BABL_FIND_NEXT , T(N),END );
BABLM( BABL_FIND_REPLACE , D(LALT),D(LSFT), T(5),U(LSFT), U(LALT), END );
BABLM( BABL_RUNAPP,END );
BABLM( BABL_SWITCH_APP_NEXT ,END );
BABLM( BABL_SWITCH_APP_LAST ,END );
BABLM(BABL_CLOSE_APP, D(LSFT), T(SCLN),U(LSFT), T(Q), D(RSFT), T(1),U(RSFT), END );
BABLM(BABL_HELP, D(LSFT), T(SCLN),U(LSFT),T(H),END); // start search in help
#ifndef BABL_NOBROWSER
/* you get to figure this out
BABLM( BABL_BROWSER_NEW_TAB, D(LGUI), T(T), U(LGUI),END );
BABLM( BABL_BROWSER_CLOSE_TAB, D(LGUI), T(W), U(LGUI),END );
BABLM( BABL_BROWSER_REOPEN_LAST_TAB, D(LGUI), D(RSFT),T(T), U(RSFT),U(LGUI),END );
BABLM( BABL_BROWSER_NEXT_TAB, D(LGUI),D(LALT), T(RIGHT),U(LALT), U(LGUI),END );
BABLM( BABL_BROWSER_PREV_TAB, D(LGUI), D(RSFT), T(LEFT), U(RSFT), U(LGUI),END );
BABLM( BABL_BROWSER_URL_BAR, D(LGUI), T(L), U(LGUI),END );
BABLM( BABL_BROWSER_FORWARD, D(LGUI), T(RIGHT), U(LGUI),END );
BABLM( BABL_BROWSER_BACK, D(LGUI), T(LEFT), U(LGUI),END );
BABLM( BABL_BROWSER_FIND, D(LGUI), T(F), U(LGUI),END );
BABLM( BABL_BROWSER_BOOKMARK, D(LGUI), T(D), U(LGUI),END );
//BABLM( BABL_BROWSER_DEV_TOOLS, T(F12), U(LGUI),END ); // EDGE
BABLM( BABL_BROWSER_DEV_TOOLS, D(LGUI), D(LALT), T(I), U(LALT),U(LGUI),END ); // Chrome
// Chrome
BABLM( BABL_BROWSER_RELOAD, D(LGUI), T(R), U(LGUI),END ); // add shift for reload w/o cache
BABLM( BABL_BROWSER_FULLSCREEN, D(LGUI), D(LCTL), T(P), U(LCTL), U(LGUI),END ); //command shift F
BABLM( BABL_BROWSER_ZOOM_IN, D(LGUI), T(PLUS), U(LGUI),END );
BABLM( BABL_BROWSER_ZOOM_OUT, D(LGUI), T(MINS), U(LGUI),END );
*/
#endif
#endif
return MACRO_NONE;
#endif
#ifdef READMUX_MODE
// Readline command line editing + tmux windowing
// I havent decided how much to do readline and how much tmux
case READMUX_MODE:
BABLM( BABL_GO_LEFT_1C , T(LEFT), END );
BABLM( BABL_GO_RIGHT_1C , T(RIGHT), END );
BABLM( BABL_GO_LEFT_WORD , D(LALT), T(B), U(LALT), END );
BABLM( BABL_GO_RIGHT_WORD , D(LALT), T(F), U(LALT), END );
BABLM( BABL_GO_START_LINE , D(LCTL), T(A), U(LCTL), END );
BABLM( BABL_GO_END_LINE , D(LCTL), T(E), U(LCTL), END );
//BABLM( BABL_GO_START_DOC ,END );// tmux?
//BABLM( BABL_GO_END_DOC ,END ); // tmux?
BABLM( BABL_GO_NEXT_LINE , D(LCTL), T(N), U(LCTL), END );
BABLM( BABL_GO_PREV_LINE , D(LCTL), T(P), U(LCTL), END );
BABLM( BABL_PGDN , T(PGDN), END );
BABLM( BABL_PGUP , T(PGUP), END );
BABLM( BABL_DEL_RIGHT_1C , D(LCTL), T(D), U(LCTL),END );
BABLM( BABL_DEL_LEFT_WORD , D(LCTL), T(W), U(LCTL), END );
BABLM( BABL_DEL_RIGHT_WORD , D(LALT), T(D), U(LALT), END );
BABLM( BABL_DEL_TO_LINE_END, D(LCTL), T(K), U(LCTL), END );
BABLM( BABL_DEL_TO_LINE_START, D(LCTL), T(U), U(LCTL), END );
#ifndef BABL_MOVEMENTONLY
BABLM( BABL_UNDO , D(LALT), T(R), U(LALT) , END );
BABLM( BABL_REDO , D(LCTL), T(X), U(LCTL),T(C), END ); // arguably
BABLM( BABL_CUT , D(LCTL), T(K), U(LCTL), END ); // wrong half the time
//BABLM( BABL_COPY ,END );
BABLM( BABL_PASTE , D(LCTL), T(Y), U(LCTL), END );
BABLM( BABL_SELECT_ALL , D(LCTL), T(A), T(K), T(Y), U(LCTL) , END );
BABLM( BABL_FIND , D(LCTL), T(R), U(LCTL), END ); // search history
BABLM(BABL_FIND_NEXT, D(LCTL), T(S), U(LCTL), END );
//BABLM( BABL_FIND_REPLACE ,END );
BABLM( BABL_RUNAPP , D(LCTL), T(B), U(LCTL), T(C),END ); //tmux
BABLM( BABL_SWITCH_APP_NEXT , D(LCTL), T(B), U(LCTL), T(N),END ); //tmux
BABLM( BABL_SWITCH_APP_LAST , D(LCTL), T(B), U(LCTL), T(P),END ); //tmux
BABLM( BABL_CLOSE_APP , D(LCTL), T(B), U(LCTL), T(D),END); // usually what I want
// BABLM( BABL_HELP ,END );
#ifndef BABL_NOBROWSER
/* Add lynx shortcuts?
BABLM( BABL_BROWSER_NEW_TAB, D(LGUI), T(T), U(LGUI),END );
BABLM( BABL_BROWSER_CLOSE_TAB, D(LGUI), T(W), U(LGUI),END );
BABLM( BABL_BROWSER_REOPEN_LAST_TAB, D(LGUI), D(RSFT),T(T), U(RSFT),U(LGUI),END );
BABLM( BABL_BROWSER_NEXT_TAB, D(LGUI),D(LALT), T(RIGHT),U(LALT), U(LGUI),END );
BABLM( BABL_BROWSER_PREV_TAB, D(LGUI), D(RSFT), T(LEFT), U(RSFT), U(LGUI),END );
BABLM( BABL_BROWSER_URL_BAR, D(LGUI), T(L), U(LGUI),END );
BABLM( BABL_BROWSER_FORWARD, D(LGUI), T(RIGHT), U(LGUI),END );
BABLM( BABL_BROWSER_BACK, D(LGUI), T(LEFT), U(LGUI),END );
BABLM( BABL_BROWSER_FIND, D(LGUI), T(F), U(LGUI),END );
BABLM( BABL_BROWSER_BOOKMARK, D(LGUI), T(D), U(LGUI),END );
//BABLM( BABL_BROWSER_DEV_TOOLS, T(F12), U(LGUI),END ); // EDGE
BABLM( BABL_BROWSER_DEV_TOOLS, D(LGUI), D(LALT), T(I), U(LALT),U(LGUI),END ); // Chrome
// Chrome
BABLM( BABL_BROWSER_RELOAD, D(LGUI), T(R), U(LGUI),END ); // add shift for reload w/o cache
BABLM( BABL_BROWSER_FULLSCREEN, D(LGUI), D(LCTL), T(P), U(LCTL), U(LGUI),END ); //command shift F
BABLM( BABL_BROWSER_ZOOM_IN, D(LGUI), T(PLUS), U(LGUI),END );
BABLM( BABL_BROWSER_ZOOM_OUT, D(LGUI), T(MINS), U(LGUI),END );
*/
#endif
#endif
return MACRO_NONE;
#endif
default:
return MACRO_NONE;
}
}
#endif

@ -0,0 +1,238 @@
/* A library to output the right key shortcut in any common app.
Given a global variable babble_mode to show the environment and a
key that calls the paste macro, do the right type of paste.
Setting the bable_mode is done by another macro, or TBD interaction with the host.
Huge thanks to https://en.wikipedia.org/wiki/Table_of_keyboard_shortcuts
and jeebak & algernon's keymap
*/
#ifndef _babblePaste_h_included__
#define _babblePaste_h_included__
#include "action_layer.h"
#include "quantum_keycodes.h"
#include "config.h"
#ifdef USE_BABLPASTE
/* ***************************
// Uncomment any modes you want. Whatever mode = 0 will be the default on boot
// Expect to get errors if you comment a feature out and leave it in your keymap.
#define USE_BABLPASTE
//#define MS_MODE 0 // Windows.
//#define MAC_MODE 1
//#define LINUX_MODE 2 //aka gnome+KDE
//#define EMACS_MODE 3
//#define VI_MODE 4
//#define WORDSTAR_MODE 5
//#define READMUX 6 // Readline and tmux
// This removes everything but cursor movement
//#define BABL_MOVEMENTONLY
// and this just removes browser shortcuts
//#define BABL_NOBROWSER
****************************/
// Uncomment if you need more free flash space
// It removes everything but cursor movement
//#define BABL_MOVEMENTONLY
// Define starting number for BABL macros in the macro range.
// Probably can start the default even lower
#define BABL_START_NUM 50
/* Macros handled by babblepaste. Most should be available for all platforms.
Whatever isn't defined will NOP */
enum {
// Movement macros
// left & right
BABL_GO_LEFT_1C= BABL_START_NUM,
BABL_GO_RIGHT_1C,
BABL_GO_LEFT_WORD,
BABL_GO_RIGHT_WORD,
BABL_GO_START_LINE,
BABL_GO_END_LINE,
// now up & down
BABL_GO_START_DOC,
BABL_GO_END_DOC,
BABL_GO_NEXT_LINE,
BABL_GO_PREV_LINE,
BABL_PGDN,
BABL_PGUP,
// And the delete options
//BABL_DEL_LEFT_1C == backspace, so why bother.
BABL_DEL_RIGHT_1C, // usually = Del
BABL_DEL_LEFT_WORD,
BABL_DEL_RIGHT_WORD,
BABL_DEL_TO_LINE_END, // delete from cursor to end of line
BABL_DEL_TO_LINE_START, // delete from cursor to begining line
#ifndef BABL_MOVEMENTONLY
// Cut & Paste
BABL_UNDO,
BABL_REDO,
BABL_CUT,
BABL_COPY,
BABL_PASTE,
BABL_SELECT_ALL,
/* not yet implemented
BABL_SWAP_LAST2C // swap last characters before the cursor
BABL_SWAP_LAST2W // Swap the last two words before the cursor
*/
// find & replace
BABL_FIND,
BABL_FIND_NEXT,
BABL_FIND_REPLACE,
// GUI or app
BABL_RUNAPP,
BABL_SWITCH_APP_NEXT,
BABL_SWITCH_APP_LAST, // previous
BABL_CLOSE_APP,
BABL_HELP,
#ifndef BABL_NOBROWSER
BABL_BROWSER_NEW_TAB,
BABL_BROWSER_CLOSE_TAB,
BABL_BROWSER_REOPEN_LAST_TAB,
BABL_BROWSER_NEXT_TAB,
BABL_BROWSER_PREV_TAB,
BABL_BROWSER_URL_BAR,
BABL_BROWSER_FORWARD,
BABL_BROWSER_BACK,
BABL_BROWSER_FIND,
BABL_BROWSER_BOOKMARK,
BABL_BROWSER_DEV_TOOLS, // hard one to remember
BABL_BROWSER_RELOAD,
BABL_BROWSER_FULLSCREEN,
BABL_BROWSER_ZOOM_IN,
BABL_BROWSER_ZOOM_OUT,
#endif
#endif
// Macros for mode switching
#ifdef MS_MODE
BABL_WINDOWS,
#endif
#ifdef MAC_MODE
BABL_MAC,
#endif
#ifdef LINUX_MODE
BABL_LINUX,
#endif
#ifdef EMACS_MODE
BABL_EMACS,
#endif
#ifdef VI_MODE
BABL_VI,
#endif
#ifdef READMUX_MODE
BABL_READLINE,
#endif
};
// BUG, used to jump to babble functiion. Surely there is a way to calculate size of enum?
#define BABL_NUM_MACROS 48+4 // 48 + # of defined modes.
/* And all the shorthand keymap ready versions */
// First the mode switching macros
#ifdef MS_MODE
#define B_WIN M(BABL_WINDOWS)
#endif
#ifdef MAC_MODE
#define B_MAC M(BABL_MAC)
#endif
#ifdef LINUX_MODE
#define B_LNX M(BABL_LINUX)
#endif
#ifdef EMACS_MODE
#define B_EMAX M(BABL_EMACS)
#endif
#ifdef VI_MODE
#define B_VI M(BABL_VI)
#endif
#ifdef READMUX_MODE
#define B_READ M(BABL_READLINE)
#endif
// and all the movement & action.
#define B_L1C M(BABL_GO_LEFT_1C)
#define B_R1C M(BABL_GO_RIGHT_1C)
#define B_L1W M(BABL_GO_LEFT_WORD)
#define B_R1W M(BABL_GO_RIGHT_WORD)
#define B_GSOL M(BABL_GO_START_LINE)
#define B_GEOL M(BABL_GO_END_LINE)
#define B_GTOP M(BABL_GO_START_DOC)
#define B_GEND M(BABL_GO_END_DOC)
#define B_DOWN M(BABL_GO_NEXT_LINE)
#define B_UP M(BABL_GO_PREV_LINE)
#define B_PGDN M(BABL_PGDN)
#define B_PGUP M(BABL_PGUP)
//#define B_BKSP M(BABL_DEL_LEFT_1C) == backspace so why bother.
#define B_DEL M(BABL_DEL_RIGHT_1C) // usually = Del
#define B_DLW M(BABL_DEL_LEFT_WORD)
#define B_DRW M(BABL_DEL_RIGHT_WORD)
#define B_DEOL M(BABL_DEL_TO_LINE_END) // delete from cursor to end of line
#define B_DSOL M(BABL_DEL_TO_LINE_START) // delete from cursor to begining line
#define B_UNDO M(BABL_UNDO)
#define B_REDO M(BABL_REDO)
#define B_CUT M(BABL_CUT)
#define B_COPY M(BABL_COPY)
#define B_PAST M(BABL_PASTE)
#define B_SELA M(BABL_SELECT_ALL)
#define B_FIND M(BABL_FIND)
#define B_FINDN M(BABL_FIND_NEXT)
#define B_FINDR M(BABL_FIND_REPLACE)
#define B_RAPP M(BABL_RUNAPP)
#define B_NAPP M(BABL_SWITCH_APP_NEXT)
#define B_PAPP M(BABL_SWITCH_APP_LAST) // previous
#define B_CAPP M(BABL_CLOSE_APP)
#define B_HELP M(BABL_HELP)
#define B_NTAB M(BABL_BROWSER_NEW_TAB)
#define B_CTAB M(BABL_BROWSER_CLOSE_TAB)
#define B_ROTB M(BABL_BROWSER_REOPEN_LAST_TAB)
#define B_NXTB M(BABL_BROWSER_NEXT_TAB)
#define B_PTAB M(BABL_BROWSER_PREV_TAB)
#define B_NURL M(BABL_BROWSER_URL_BAR)
#define B_BFWD M(BABL_BROWSER_FORWARD)
#define B_BBAK M(BABL_BROWSER_BACK)
#define B_BFND M(BABL_BROWSER_FIND)
#define B_BOOK M(BABL_BROWSER_BOOKMARK)
#define B_BDEV M(BABL_BROWSER_DEV_TOOLS) // hard one to remember
#define B_BRLD M(BABL_BROWSER_RELOAD)
#define B_BFUlL M(BABL_BROWSER_FULLSCREEN)
#define B_ZMIN M(BABL_BROWSER_ZOOM_IN)
#define B_ZMOT M(BABL_BROWSER_ZOOM_OUT)
/* from action_macro.h
typedef uint8_t macro_t;
#define MACRO_NONE (macro_t*)0
#define MACRO(...) ({ static const macro_t __m[] PROGMEM = { __VA_ARGS__ }; &__m[0]; })
#define MACRO_GET(p) pgm_read_byte(p)
#define BABL_MSTART (entry, os, macro...) ( const macro_t bablDict[entry][os] PROGMEM = { macro... }; )
*/
const macro_t *babblePaste(keyrecord_t *record, uint8_t shortcut);
macro_t* switch_babble_mode( uint8_t id);
#endif
#endif

@ -0,0 +1,123 @@
BabblePaste is a library of common macros used to make sure that
you can have one "paste" button on one layer, and it will do the
right thing on any OS or app. Windows=Ctrl-V. Mac = Command-V and so on.
The babblepaste library looks for the current status in a babble_mode global variable.
To switch modes, run the switch_babble_mode() function, or a pre defined macro.
Currently supported are Windows, OS X, Gnome/kde, Emacs, VI and readline,
across 42+ common macro actions.
###To use the library
1) Paste the following into your config.h.
//////Begin//////
#define USE_BABLPASTE 1
#ifdef USE_BABLPASTE
/* define BabblePaste maps. Whatever = 0 will be the default. */
// MAC_MODE 0
// MS_MODE 1
// LINUX_MODE 2
// EMACS_MODE 3
// VI_MODE 3
// Readline and tmux
// READMUX_MODE 2
// WORDSTAR_MODE 5
#endif
// Uncomment these to remove options an free up flash space
// This removes everything but cursor movement
// BABL_MOVEMENTONLY
// and this just removes browser shortcuts
// BABL_NOBROWSER
///////End///////
2) Add the following to your keymap in the action_get_macro
//////Begin//////
#ifdef USE_BABLPASTE
if( id >= BABL_START_NUM && id < (BABL_START_NUM + BABL_NUM_MACROS ) ) {
if (record->event.pressed) { // is there a case where this isn't desired?
babblePaste ( record, id );
return MACRO_NONE;
}
}
#endif
///////End///////
3) add Babbelpaste actions to your keymap. See the full list in babblePaste.h, or the
list below
B_L1C // go left 1 char
B_R1C // go Right 1 char
B_L1W //GO_LEFT_1 WORD
B_R1W //BABL_GO_RIGHT_1 WORD
B_GSOL // BABL_GOTO_START of _LINE
B_GEOL // BABL_GOTO_END_LINE
B_GTOP //BABL_GOTO_START_DOC
B_GEND //BABL_GO_END_DOC
B_DOWN //BABL_GO_NEXT_LINE
B_UP // BABL_GO_PREV_LINE
B_PGDN //PGDN
B_PGUP //PGUP
// B_BKSP //backspace so why bother.
B_DEL // DEL_RIGHT_1 Char // usually = Del
B_DLW // DEL_LEFT_ 1 WORD)
B_DRW //DEL_RIGHT_1 WORD
B_DEOL // delete from cursor to end of line
B_DSOL // delete from cursor to begining line
B_UNDO //UNDO
B_REDO // REDO
B_CUT // CUT)
B_COPY // COPY)
B_PAST // PASTE)
B_SELA // SELECT_ALL
B_FIND // FIND)
B_FINDN //FIND_NEXT)
B_FINDR // FIND_REPLACE)
B_RAPP // open application launcher
B_NAPP // switch to next app
B_PAPP // switch to previous app
B_CAPP // CLOSE_APP)
B_HELP // HELP)
B_NTAB // BROWSER_NEW_TAB)
B_CTAB //BROWSER_CLOSE_TAB)
B_ROTB //BROWSER_REOPEN_LAST_TAB)
B_NXTB //BROWSER_NEXT_TAB)
B_PTAB //BROWSER_PREV_TAB)
B_NURL //BROWSER_jump to URL_BAR)
B_BFWD // BROWSER_FORWARD (in history)
B_BBAK //BROWSER_BACK (in history)
B_BFND // BROWSER_FIND)
B_BOOK //BROWSER_New BOOKMARK)
B_BDEV //BROWSER_ Open DEV_TOOLS) // hard one to remember
B_BRLD // BROWSER_RELOAD Page
B_BFUlL // BROWSER_FULLSCREEN)
B_ZMIN // BROWSER_ZOOM_IN)
B_ZMOT //BROWSER_ZOOM_OUT)
#### Development notes
-Why a new function? Because it would make the keymap too ugly to put it there.
-Why not return the macro to action_get_macro? Because I kept running into scope problems
and pointers to the wrong type.
-Why not an array of arrays as a lookup instead of a function? That would allow you
to store the lookup table in PROGMEM. True, but that takes more pre-processor skill
than I had.
-Have you tested this on every platform? No. Submit a patch.
### Next steps for someone.
Make it easier to pair macros with modifiers. So key foo will jump to start of line, and
Shift(foo) will jump to the first tab in a browser.
## Thanks
Thanks to https://en.wikipedia.org/wiki/Table_of_keyboard_shortcuts
and https://github.com/qmk/qmk_firmware/blob/master/keyboards/planck/keymaps/jeebak/keymap.c
And of course QMK...

@ -0,0 +1,100 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6060
#define DEVICE_VER 0x0001
#define MANUFACTURER Microsoftplus
#define DESCRIPTION 6000
/* key matrix size */
#define MATRIX_ROWS 8
#define MATRIX_COLS 18
#ifdef ASTAR
#define PRODUCT sculpt mobile astar
/*0 1 2 3 4 5 6 7 8 */
#define MATRIX_ROW_PINS {D7, C6, D4, D0, D1, D3, D2, E2}
/* A B C D E F G H I J K L M N O P Q R */
#define MATRIX_COL_PINS {B4, B5, E6, B7, B6, D6, C7, F7, F6, F4,F5, F1,F0, D5, B0, B1, B2, B3}
#else
#define PRODUCT sculpt mobile teensypp
/* 0 1 2 3 4 5 6 7 */
#define MATRIX_ROW_PINS { F7,F6,F4,F5,F3,F2,F1,F0}
/* A B C D E F G H I J K L M N O P Q R */
#define MATRIX_COL_PINS { B7, D0, D1, D2, D3, D4, D5, D6, D7, E0,E1,C1, C0, C3, C2, C5, C4,C7}
#define UNUSED_PINS { B6,B5,B4,B3,B2,B1,B0 }
#endif
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION ROW2COL
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCING_DELAY 5
/* define if matrix has ghost (lacks anti-ghosting diodes) */
//#define MATRIX_HAS_GHOST
/*
* Magic Key Options
*
* Magic keys are hotkey commands that allow control over firmware functions of
* the keyboard. They are best used in combination with the HID Listen program,
* found here: https://www.pjrc.com/teensy/hid_listen.html
*
* The options below allow the magic key functionality to be changed. This is
* useful if your keyboard/keypad is missing keys and you want magic key support.
*
*/
/* key combination for magic key command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#define PREVENT_STUCK_MODIFIERS
#endif

@ -0,0 +1,21 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = no # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../../Makefile
endif

@ -0,0 +1,8 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
// place overrides here
#endif

@ -0,0 +1,64 @@
#include "MS-sculpt-mobile.h"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/*
*
* |ESC | F1 | F2 | F3 | F4 | F5 | F6 | f7 | F8 | F9 | F10| F11| F12|Vol-|Vol+|Mute|
* -------------------------------------------------------------------------------'
* | ~ | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = |Bakspace| Del |
* --------------------------------------------------------------------------
* | tab | q | w | e | r | t | y | u | i | o | p | [ | ] | \ | |
* -------------------------------------------------------------------------------'
* | caps | a | s | d | f | g | h | j | k | l | ; | ' | enter |PgUp|
* --------------------------------------------------------------------------------
* |Lsft | z | x | c | v | b | n | m | , | . | / | Rsft| Up| PgDn|
* ---------------------------------------------------------------------------------
* |Lctl |Lgui |Lalt | Space |Ralt | FN | Rctl |Left|Down|Rght|
* ---------------------------------------------------------------------------------
*/
[0] = KEYMAP( \
KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_VOLD, KC_VOLU, KC_MUTE,\
KC_GRAVE, KC_1, KC_2, KC_3 ,KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINUS, KC_EQL, KC_BSPC, KC_DEL,\
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS,\
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP,\
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN,\
KC_LCTL, KC_LGUI, KC_LALT, KC_SPACE, KC_RALT, RSFT(KC_1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RIGHT
)
};
const uint16_t PROGMEM fn_actions[] = {
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
} else {
unregister_code(KC_RSFT);
}
break;
}
return MACRO_NONE;
};
void matrix_init_user(void) {
}
void matrix_scan_user(void) {
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
return true;
}
void led_set_user(uint8_t usb_led) {
}

@ -0,0 +1 @@
# The default keymap for microsoft-sculpt-mobile

@ -0,0 +1,21 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = no # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../../Makefile
endif

@ -0,0 +1,32 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
#define USE_BABLPASTE
// Expect to get errors if you comment a feature out and leave it in your keymap.
#ifdef USE_BABLPASTE
//define BabblePaste maps
// Windows.
#define MAC_MODE 0
#define MS_MODE 1
//aka gnome+KDE
//#define LINUX_MODE 2
//#define EMACS_MODE 3
#define VI_MODE 3
// Readline and tmux
#define READMUX_MODE 2
//#define WORDSTAR_MODE 5
#endif
// Uncomment if you need more free flash space
// This removes everything but cursor movement
//#define BABL_MOVEMENTONLY
// and this just removes browser shortcuts
//#define BABL_NOBROWSER
// place overrides here
#endif

@ -0,0 +1,272 @@
#include "MS-sculpt-mobile.h"
#include "action_layer.h"
#include "action_util.h"
#include "babblePaste.h"
#ifdef AUDIO_ENABLE
#include "audio.h"
#endif
#define _QWR 0
#define _CDH 2
#define _SYM 3
#define _MOV 4
#define _TRAN 5
enum layer_keycodes {
QWR,
CDH,
SYM,
MOV,
NUM,
TRAN
};
// Shorter spacing
#define XXXX KC_NO
#define ____ KC_TRNS
// Custom macros
/* Fn Keys */
#define TT_SYM MO(_SYM)
#define TT_MOV KC_FN2
#define TT_NUM MO(_NUM)
#define SSFT ACTION_MODS_ONESHOT(MOD_LSFT)
enum macro_keycodes {
DHPASTE=1,
VIBRK,
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* QWERTY
*
* |ESC | F1 | F2 | F3 | F4 | F5 | F6 | f7 | F8 | F9 | F10| F11| F12|Vol-|Vol+|_CDH|
* -------------------------------------------------------------------------------'
* | ESC | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = |Bakspace| Del|
* ---------------------------------------------------------------------------
* | tab | q | w | e | r | t | y | u | i | o | p | [ | ] | \ | |
* -------------------------------------------------------------------------------'
* |Bak/Mov| a | s | d | f | g | h | j | k | l | ; | ' | enter |PgUp|
* --------------------------------------------------------------------------------
* |Lsft | z | x | c | v | b | n | m | , | . | / | Rsft| Up| PgDn|
* ---------------------------------------------------------------------------------
* |Lctl |Lgui |Lalt | Space/Sym | GUI | Sym | Rctl |Left|Down|Rght|
* ---------------------------------------------------------------------------------
*/
[_QWR] = KEYMAP( \
KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_VOLD, KC_VOLU, CDH,\
KC_ESC, KC_1, KC_2, KC_3 ,KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINUS, KC_EQL, KC_BSPC, KC_DEL,\
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS,\
TT_MOV, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP,\
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT,KC_SLSH,KC_RSFT, KC_UP, KC_PGDN,\
KC_LCTL, KC_LGUI, KC_LALT, KC_FN1, KC_RGUI,TT_SYM,KC_RCTL, KC_LEFT, KC_DOWN, KC_RIGHT
),
[_CDH] = KEYMAP (\
____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, QWR, \
KC_ESC, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, \
KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_B, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, ____, ____, ____,\
TT_MOV, KC_A, KC_R, KC_S, KC_T, KC_G, KC_M, KC_N, KC_E, KC_I, KC_O, KC_QUOT, KC_ENT, KC_2,\
KC_LSFT, KC_Z, KC_X, KC_C, M(DHPASTE), KC_V, KC_K, KC_H, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, ____, KC_1,\
____, ____, ____ , KC_FN1, ____, ____, ____, ____, ____, ____
),
/* SYM
*
* |ESC | F1 | F2 | F3 | F4 | F5 | F6 | f7 | F8 | F9 | F10| F11| F12|Vol-|Vol+|_CDH|
* -------------------------------------------------------------------------------'
* | ESC | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = |Bakspace|Del |
* --------------------------------------------------------------------------
* | ESC: | ^ | { | } | @ | % | | [ | ( | ) | _ | [ | ] | \ | |
* -------------------------------------------------------------------------------'
* |Bak/Mov| ! | # | 0 | = | { | } | - | 1 | + | ] | ` | enter |PgUp|
* --------------------------------------------------------------------------------
* |Lsft | ; | ~ | : | ~ | "|"| $ | * | | . | / | Rsft| Up| PgDn|
* ---------------------------------------------------------------------------------
* |Lctl |Lgui |Lalt | Space/Sym | GUI | Sym | Rctl |Left|Down|Rght|
* ---------------------------------------------------------------------------------
*/
[_SYM] = KEYMAP (\
____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, \
____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, \
M(VIBRK), KC_CIRC, KC_LCBR, KC_RCBR,KC_AT, KC_PERC, ____, KC_LBRC,KC_LPRN,KC_RPRN,KC_UNDS, ____, ____, ____,\
____, KC_EXLM, KC_HASH, KC_0, KC_EQL, KC_LCBR, KC_RCBR,KC_MINS,KC_1, KC_PLUS,KC_RBRC, KC_GRV, ____, ____,\
____, KC_SCLN, KC_TILDE, KC_COLN, KC_TILDE, KC_PIPE, KC_DLR, KC_ASTR, ____, KC_DOT , KC_SLSH, ____, ____, ____,\
____, ____, ____, ____, ____, ____, ____, ____, ____, ____
),
/*
* |ESC | MAC| Win|RdLn| VI | | | | | | | | | | | |
* -------------------------------------------------------------------------------'
* | | | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = |Bakspace| Del|
* ---------------------------------------------------------------------------
* | tab | | |Find| |pTab |DSOL|DelW| Up |DelW|DEOL| [ | ] | \ | |
* -------------------------------------------------------------------------------'
* |Bak/Mov| | | | |nTab |GSOL| <- | Dwn | -> | EOL | ' | enter |PgUp|
* --------------------------------------------------------------------------------
* |Lsft |Undo| Cut|Copy|Pste| | | | | | / | Rsft| Up| PgDn|
* ---------------------------------------------------------------------------------
* |Lctl |Lgui |Lalt | Space/Sym | GUI | Sym | Rctl |Left|Down|Rght|
* ---------------------------------------------------------------------------------
*/
[_MOV] = KEYMAP (\
____, B_MAC,B_WIN,B_READ, B_VI, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, \
____, ____, B_PAPP, B_NAPP, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, \
____, B_UNDO, ____, B_BFND, ____, B_PTAB, B_DSOL, B_DLW, B_UP, B_DRW, B_DEOL, ____, ____, ____, \
____, B_SELA, B_BRLD, ____, ____, B_NXTB, B_GSOL, B_L1C, B_DOWN, B_R1C,B_GEOL, ____, ____, ____,\
____, B_UNDO,B_CUT, B_COPY, B_PAST, B_PAST, ____, ____, ____, ____, ____, ____, ____, ____, \
____, ____, ____, ____, ____, ____, ____, ____, ____, ____
),
[_TRAN] = KEYMAP (\
____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, \
____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, \
____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, \
____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, \
____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, \
____, ____, ____, ____, ____, ____, ____, ____, ____, ____
)
};
const uint16_t PROGMEM fn_actions[] = {
[1] = ACTION_LAYER_TAP_KEY(_SYM,KC_SPACE),
[2] = ACTION_LAYER_TAP_KEY(_MOV,KC_BSPC)
};
#ifdef AUDIO_ENABLE
float tone_startup[][2] = SONG(STARTUP_SOUND);
float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
#endif
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case QWR:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
#endif
layer_off(_CDH);
}
return false;
break;
case CDH:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
layer_on(_CDH);
}
return false;
break;
case SYM:
if (record->event.pressed) {
layer_on(_SYM);
} else {
layer_off(_SYM);
}
return false;
break;
}
return true;
}
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
/* If id is in the range of BABL macros, call the babl function */
/* Any clever remapping with modifiers should happen here e.g. shift bablkey does opposite*/
#ifdef USE_BABLPASTE
if( id >= BABL_START_NUM && id < (BABL_START_NUM + BABL_NUM_MACROS ) ) {
if (record->event.pressed) { // is there a case where this isn't desired?
babblePaste ( record, id );
return MACRO_NONE;
}
}
#endif
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
} else {
unregister_code(KC_RSFT);
}
break;
/* Colemak mod-dh moves the D key to the qwerty V position
This hack makes apple-V_position do what I mean */
case DHPASTE:
if(keyboard_report->mods & MOD_BIT(KC_LGUI) ) {
if (record->event.pressed) {
clear_keyboard_but_mods();
register_code(KC_V);
} else {
unregister_code(KC_V);
}
} else {
if (record->event.pressed) {
register_code(KC_D);
} else {
unregister_code(KC_D);
}
}
break;
case VIBRK: // vi esc:
if (record->event.pressed) {
return MACRO( T(ESC),D(LSFT),T(SCLN),U(LSFT), END );
}
break;
default:
return MACRO_NONE;
}
return MACRO_NONE;
};
void matrix_init_user(void) {
}
void matrix_scan_user(void) {
}
void led_set_user(uint8_t usb_led) {
}

@ -0,0 +1 @@
# A more programmer oriented keymap for microsoft-sculpt-mobile

@ -0,0 +1,58 @@
This is a way to take a Microsoft ergonomic bluetooth keyboard, and make it
into a hard-wired keyboard running QMK.
The keyboard is known under several different names:
Mobile Bluetooth 5000, Mobile 6000, Sculpt mobile, and Asus rebranded
I had a stack of them,since they're cheap on ebay, travel well, and are just ergo enough.
The ribbon cable is 1mm pitch, which is hard to hand solder. I bought a cheap set of
"pitch adapter" boards https://www.amazon.com/Double-Sided-0-4mm-1-0-Adapter-60mmx38mm/dp/B00OK42118
Cut the original ribbon cable sockets off the bluetooth board using a razor, they're hard to desolder.
They're also allow the cable to be inserted on top or bottom.
If I was going to do it again, I'd make the MCU connection come out the top of the keyboard
and avoid the wires dangling out the bottom.
As I was debugging the matrix, I started to get random failures. In desparation I tried a second MCU,
but had the same problems. It turns out that the ribbon cable connections can get worn. Shave a
half millimeter off the end of the ribbon cable & the errors go away.
My method for discovering the matrix was to set up a KEYMAP macro that included all pins.
See MATRIX_TESTING_KEYMAP if you need it. Then set up a keymap that has all printable symbols
in the first 4 rows. test each key & record output. Then switch the printable symbols to the
bottom 4 rows & repeat. This was enough to show the matrix.
The full original keymap for the sculpt is
A B C D E F G H --->
0 b n m , . /
1 g h "
2 7 8 9 0 Del PgUp
3 p [ ] \
4 y u i o
5 ~ - += j k l ; 5
6 a s d q w e, Up left
7 F7 F8 F9 F10 F11 F12 f
-----> I J K L M N O P Q R
0 Caps FN
1 Vol+ mute Rctl vol- pgdn LCTL
2 Rshift LShift
3 Ralt LAlt
4 LGUI
5 6 bakspc 1 2 3 4 F4 F5 F6
6 Down right spc F1 F2 F3 tab
7 r t z x c v enter Esc
This works with 18 cols + 8 rows on a Teensy++, or Arm based Teensy.
The Astar mini has all pins exposed , so you can do 18x8
If you want a speaker, LEDs &etc, you'll need to free up a pin. I recommend joining columns
R and L to the same pin.
Building - add ASTAR=1 to the compile line or leave out for teensy2++

@ -0,0 +1,48 @@
## Project specific files
SRC= babblePaste.c
ifdef ASTAR
CFLAGS=-D ASTAR
OPT_DEFS += -DBOOTLOADER_SIZE=4096
MCU = atmega32u4
OPT_DEFS += -DCATERINA_BOOTLOADER
SCULPT_UPLOAD_COMMAND = while [ ! -r $(USB) ]; do sleep 1; done ; \
avrdude -p $(MCU) -c avr109 -U flash:w:$(TARGET).hex -P $(USB)
else
MCU = at90usb1286
OPT_DEFS += -DBOOTLOADER_SIZE=2048
SCULPT_UPLOAD_COMMAND = teensy_loader_cli -w -mmcu=$(MCU) $(TARGET).hex
endif
F_CPU = 16000000
ARCH = AVR8
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
#
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= no # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= yes # Console for debug(+400)
COMMAND_ENABLE ?= yes # Commands for debug and configuration
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE ?= no # USB Nkey Rollover
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default
MIDI_ENABLE ?= no # MIDI controls
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE ?= no # Audio output on port C6
USB ?= /dev/cu.usbmodem14141
upload: build
$(SCULPT_UPLOAD_COMMAND)

@ -0,0 +1,3 @@
ifndef MAKEFILE_INCLUDED
include ../../Makefile
endif

@ -0,0 +1,10 @@
#include "atreus50.h"
void matrix_init_kb(void) {
// Turn status LED on
//DDRE |= (1<<6);
PORTE |= (1<<6);
matrix_init_user();
};

@ -0,0 +1,36 @@
#ifndef ATREUS50_H
#define ATREUS50_H
#include "quantum.h"
// The first section contains all of the arguements
// The second converts the arguments into a two-dimensional array
#define KEYMAP( \
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \
k30, k31, k32, k33, k34, k35, km0, km1, k36, k37, k38, k39, k3a, k3b \
) \
{ \
{ k00, k01, k02, k03, k04, k05, KC_NO, k06, k07, k08, k09, k0a, k0b }, \
{ k10, k11, k12, k13, k14, k15, KC_NO, k16, k17, k18, k19, k1a, k1b }, \
{ k20, k21, k22, k23, k24, k25, km0, k26, k27, k28, k29, k2a, k2b }, \
{ k30, k31, k32, k33, k34, k35, km1, k36, k37, k38, k39, k3a, k3b } \
}
#define COMPACT_KEYMAP( \
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \
k30, k31, k32, k33, k34, k35, km0, km1, k36, k37, k38, k39, k3a, k3b \
) \
{ \
{ KC_##k00, KC_##k01, KC_##k02, KC_##k03, KC_##k04, KC_##k05, KC_NO, KC_##k06, KC_##k07, KC_##k08, KC_##k09, KC_##k0a, KC_##k0b }, \
{ KC_##k10, KC_##k11, KC_##k12, KC_##k13, KC_##k14, KC_##k15, KC_NO, KC_##k16, KC_##k17, KC_##k18, KC_##k19, KC_##k1a, KC_##k1b }, \
{ KC_##k20, KC_##k21, KC_##k22, KC_##k23, KC_##k24, KC_##k25, KC_##km0, KC_##k26, KC_##k27, KC_##k28, KC_##k29, KC_##k2a, KC_##k2b }, \
{ KC_##k30, KC_##k31, KC_##k32, KC_##k33, KC_##k34, KC_##k35, KC_##km1, KC_##k36, KC_##k37, KC_##k38, KC_##k39, KC_##k3a, KC_##k3b } \
}
#define KC_ KC_TRNS
#endif

@ -0,0 +1,163 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xBB80
#define PRODUCT_ID 0x040D
#define DEVICE_VER 0x0001
#define MANUFACTURER Hexwire
#define PRODUCT Atreus 50 Keyboard
#define DESCRIPTION Atreus layout with extra column
/* key matrix size */
#define MATRIX_ROWS 4
#define MATRIX_COLS 13
/* Planck PCB default pin-out */
#define MATRIX_ROW_PINS { D3, D2, D1, D0 }
#define MATRIX_COL_PINS { D4, D7, E6, B4, B5, B6, B2, B3, B1, F7, F6, F5, F4 }
#define UNUSED_PINS
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
// #define BACKLIGHT_PIN B7
// #define BACKLIGHT_BREATHING
// #define BACKLIGHT_LEVELS 3
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCING_DELAY 5
/* define if matrix has ghost (lacks anti-ghosting diodes) */
//#define MATRIX_HAS_GHOST
/* number of backlight levels */
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/* ws2812 RGB LED */
#define RGB_DI_PIN C6
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 12 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17
#define RGBLIGHT_VAL_STEP 17
/*
* Force NKRO
*
* Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
* state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
* makefile for this to work.)
*
* If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
* until the next keyboard reset.
*
* NKRO may prevent your keystrokes from being detected in the BIOS, but it is
* fully operational during normal computer usage.
*
* For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
* or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
* bootmagic, NKRO mode will always be enabled until it is toggled again during a
* power-up.
*
*/
//#define FORCE_NKRO
/*
* Magic Key Options
*
* Magic keys are hotkey commands that allow control over firmware functions of
* the keyboard. They are best used in combination with the HID Listen program,
* found here: https://www.pjrc.com/teensy/hid_listen.html
*
* The options below allow the magic key functionality to be changed. This is
* useful if your keyboard/keypad is missing keys and you want magic key support.
*
*/
/* key combination for magic key command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/* control how magic key switches layers */
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
/* override magic key keymap */
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
//#define MAGIC_KEY_HELP1 H
//#define MAGIC_KEY_HELP2 SLASH
//#define MAGIC_KEY_DEBUG D
//#define MAGIC_KEY_DEBUG_MATRIX X
//#define MAGIC_KEY_DEBUG_KBD K
//#define MAGIC_KEY_DEBUG_MOUSE M
//#define MAGIC_KEY_VERSION V
//#define MAGIC_KEY_STATUS S
//#define MAGIC_KEY_CONSOLE C
//#define MAGIC_KEY_LAYER0_ALT1 ESC
//#define MAGIC_KEY_LAYER0_ALT2 GRAVE
//#define MAGIC_KEY_LAYER0 0
//#define MAGIC_KEY_LAYER1 1
//#define MAGIC_KEY_LAYER2 2
//#define MAGIC_KEY_LAYER3 3
//#define MAGIC_KEY_LAYER4 4
//#define MAGIC_KEY_LAYER5 5
//#define MAGIC_KEY_LAYER6 6
//#define MAGIC_KEY_LAYER7 7
//#define MAGIC_KEY_LAYER8 8
//#define MAGIC_KEY_LAYER9 9
//#define MAGIC_KEY_BOOTLOADER PAUSE
//#define MAGIC_KEY_LOCK CAPS
//#define MAGIC_KEY_EEPROM E
//#define MAGIC_KEY_NKRO N
//#define MAGIC_KEY_SLEEP_LED Z
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#endif

@ -0,0 +1,6 @@
RGBLIGHT_ENABLE = yes
AUDIO_ENABLE = no
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,250 @@
#include "atreus50.h"
#include "action_layer.h"
#include "eeconfig.h"
#ifdef AUDIO_ENABLE
#include "audio.h"
#endif
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _QWERTY 0
#define _COLEMAK 1
#define _DVORAK 2
#define _LOWER 3
#define _RAISE 4
#define _MOVEMENT 5
#define _ADJUST 16
enum custom_keycodes {
QWERTY = SAFE_RANGE,
COLEMAK,
DVORAK,
LOWER,
RAISE,
MOVEMENT,
BACKLIT
};
// Fillers to make layering more clear
#define _______ KC_TRNS
#define XXXXXXX KC_NO
#define KC_X0 MT(MOD_LCTL, KC_ESC) // Hold for Left Ctrl, Tap for ESC
#define KC_X1 LOWER
#define KC_X2 RAISE
#define KC_X3 MO(_MOVEMENT)
#define KC_X4 MT(MOD_LSFT, KC_ENT) // Hold for Left Shift, Tap for Enter
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_QWERTY] = COMPACT_KEYMAP(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
TAB , Q , W , E , R , T , Y , U , I , O , P ,MINS,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
X0 , A , S , D , F , G , H , J , K , L ,SCLN,QUOT,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
LSFT, Z , X , C , V , B , N , M ,COMM,DOT ,SLSH, X4 ,
//|----+----+----+----+----+----|----+----|----+----+----+----+----+----|
GRV ,LCTL,LALT,LGUI, X1 ,SPC , X3 ,RSFT,BSPC, X2 ,LEFT,DOWN, UP ,RGHT
//`----+----+----+----+----+----+----+----+----+----+----+----+----+----'
),
[_COLEMAK] = COMPACT_KEYMAP(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
TAB , Q , W , F , P , G , J , L , U , Y ,SCLN,MINS,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
X0 , A , R , S , T , D , H , N , E , I , O ,QUOT,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
LSFT, Z , X , C , V , B , K , M ,COMM,DOT ,SLSH, X4 ,
//|----+----+----+----+----+----|----+----|----+----+----+----+----+----|
GRV ,LCTL,LALT,LGUI, X1 ,SPC , X3 ,RSFT,BSPC, X2 ,LEFT,DOWN, UP ,RGHT
//`----+----+----+----+----+----+----+----+----+----+----+----+----+----'
),
[_DVORAK] = COMPACT_KEYMAP(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
TAB ,QUOT,COMM,DOT , P , Y , F , G , C , R , L ,MINS,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
X0 , A , O , E , U , I , D , H , R , N , S ,SLSH,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
LSFT,SCLN, Q , J , K , X , B , M , W , V , Z , X4 ,
//|----+----+----+----+----+----|----+----|----+----+----+----+----+----|
GRV ,LCTL,LALT,LGUI, X1 ,SPC , X3 ,RSFT,BSPC, X2 ,LEFT,DOWN, UP ,RGHT
//`----+----+----+----+----+----+----+----+----+----+----+----+----+----'
),
[_LOWER] = COMPACT_KEYMAP(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
TILD,EXLM, AT ,HASH,DLR ,PERC, CIRC,AMPR,ASTR,LPRN,RPRN,DEL ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
DEL , F1 , F2 , F3 , F4 , F5 , F6 ,UNDS,PLUS,LCBR,RCBR,PIPE,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
, F7 , F8 , F9 ,F10 ,F11 , F12 ,END , , , , ,
//|----+----+----+----+----+----|----+----|----+----+----+----+----+----|
, , , , , , , , , ,MNXT,VOLD,VOLU,MPLY
//`----+----+----+----+----+----+----+----+----+----+----+----+----+----'
),
[_RAISE] = COMPACT_KEYMAP(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
GRV , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 ,DEL ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
DEL , F1 , F2 , F3 , F4 , F5 , F6 ,MINS,EQL ,LBRC,RBRC,BSLS,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
, F7 , F8 , F9 ,F10 ,F11 , F12 ,NUHS,NUBS, , , ,
//|----+----+----+----+----+----|----+----|----+----+----+----+----+----|
, , , , , , , , , ,MNXT,VOLD,VOLU,MPLY
//`----+----+----+----+----+----+----+----+----+----+----+----+----+----'
),
[_MOVEMENT] = COMPACT_KEYMAP(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
TILD,EXLM, AT ,HASH,DLR ,PERC, CIRC,AMPR, UP ,LPRN,RPRN,DEL ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
DEL , F1 , F2 , F3 , F4 , F5 , F6 ,LEFT,DOWN,RGHT,RCBR,PIPE,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
, F7 , F8 , F9 ,F10 ,F11 , F12 ,END , , , , ,
//|----+----+----+----+----+----|----+----|----+----+----+----+----+----|
, , , , , , , ,PGDN,PGUP,MNXT,VOLD,VOLU,MPLY
//`----+----+----+----+----+----+----+----+----+----+----+----+----+----'
),
/* Adjust (Lower + Raise)
* |------+------+------+------+------+------. ,------+------+------+------+------+------|
* | | Reset| | | | | | | | | | | Del |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | | | |Audoff|Aud on|AGnorm| |AGswap|Qwerty|Colemk|Dvorak| | |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | |Voice-|Voice+|Musoff|Mus on| | | | | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | | | | |
* `-------------------------------------------------------------------------------------------------'
*/
[_ADJUST] = KEYMAP( \
_______, RESET, RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, _______, KC_DEL, \
_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______, \
_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
)
};
#ifdef AUDIO_ENABLE
float tone_startup[][2] = {
{NOTE_B5, 20},
{NOTE_B6, 8},
{NOTE_DS6, 20},
{NOTE_B6, 8}
};
float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_dvorak[][2] = SONG(DVORAK_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
#endif
void persistant_default_layer_set(uint16_t default_layer) {
eeconfig_update_default_layer(default_layer);
default_layer_set(default_layer);
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case QWERTY:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
#endif
persistant_default_layer_set(1UL<<_QWERTY);
}
return false;
break;
case COLEMAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
persistant_default_layer_set(1UL<<_COLEMAK);
}
return false;
break;
case DVORAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
#endif
persistant_default_layer_set(1UL<<_DVORAK);
}
return false;
break;
case LOWER:
if (record->event.pressed) {
layer_on(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case RAISE:
if (record->event.pressed) {
layer_on(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case BACKLIT:
if (record->event.pressed) {
register_code(KC_RSFT);
#ifdef BACKLIGHT_ENABLE
backlight_step();
#endif
} else {
unregister_code(KC_RSFT);
}
return false;
break;
}
return true;
};
void matrix_init_user(void) {
#ifdef AUDIO_ENABLE
startup_user();
#endif
}
#ifdef AUDIO_ENABLE
void startup_user()
{
_delay_ms(20); // gets rid of tick
PLAY_NOTE_ARRAY(tone_startup, false, 0);
}
void shutdown_user()
{
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
_delay_ms(150);
stop_all_notes();
}
void music_on_user(void)
{
music_scale_user();
}
void music_scale_user(void)
{
PLAY_NOTE_ARRAY(music_scale, false, 0);
}
#endif

@ -0,0 +1,16 @@
Handwired Atreus50
==================
This firmware is for a Handwired Atreus50 using an Arduino Pro Micro.
## Pinout
The following pins are used:
- Columns 1-13: D4, D7, E6, B4, B5, B6, B2, B3, B1, F7, F6, F5, F4
- Rows 1-4: D3, D2, D1, D0
## Compiling and loading the firmware
To build the firmware, run `make`.
To flash the firemware onto the microcontroller, run `make avrdude`, and press the reset button.

@ -0,0 +1,81 @@
# MCU name
#MCU = at90usb1287
MCU = atmega32u4
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= no # Console for debug(+400)
COMMAND_ENABLE ?= yes # Commands for debug and configuration
NKRO_ENABLE ?= no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
MIDI_ENABLE ?= no # MIDI controls
AUDIO_ENABLE ?= no # Audio output on port C6
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
avrdude: build
ls /dev/tty* > /tmp/1; \
echo "Reset your Pro Micro now"; \
while [[ -z $$USB ]]; do \
sleep 1; \
ls /dev/tty* > /tmp/2; \
USB=`diff /tmp/1 /tmp/2 | grep -o '/dev/tty.*'`; \
done; \
avrdude -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex
.PHONY: avrdude

@ -0,0 +1,3 @@
ifndef MAKEFILE_INCLUDED
include ../../../Makefile
endif

@ -0,0 +1,20 @@
Magicforce 68 Handwired
=======================
This firmware is for a Magicforce 68 that's had its PCB removed and is handwired with an Arduino Micro. NOTE: The Arduino Micro is different than the Arduino *Pro* Micro.
## Wiring Layout
![Wiring Layout](wiring-layout.png)
## Pinout
The following pins are used:
- Columns 1-15: B2, B0, D3, D2, D1, D0, D4, C6, D7, E6, B4, B5, B6, B7, D6
- Rows 1-5: F0, F1, F4, F5, F6
## Compiling and loading the firmware
To build the firmware, run `make`.
To flash the firemware onto the microcontroller, run `make avrdude`, and press the reset button.

@ -0,0 +1,162 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6060
#define DEVICE_VER 0x0001
#define MANUFACTURER Hexwire
#define PRODUCT Magicforce 68
#define DESCRIPTION Handwired Magicforce 68
/* key matrix size */
#define MATRIX_ROWS 5
#define MATRIX_COLS 15
/*
* Keyboard Matrix Assignments
*
* Change this to how you wired your keyboard
* COLS: AVR pins used for columns, left to right
* ROWS: AVR pins used for rows, top to bottom
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
*
*/
#define MATRIX_ROW_PINS { F0, F1, F4, F5, F6 }
#define MATRIX_COL_PINS { B2, B0, D3, D2, D1, D0, D4, C6, D7, E6, B4, B5, B6, B7, D6 }
#define UNUSED_PINS
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
// #define BACKLIGHT_PIN B7
// #define BACKLIGHT_BREATHING
// #define BACKLIGHT_LEVELS 3
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCING_DELAY 5
/* define if matrix has ghost (lacks anti-ghosting diodes) */
//#define MATRIX_HAS_GHOST
/* number of backlight levels */
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/*
* Force NKRO
*
* Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
* state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
* makefile for this to work.)
*
* If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
* until the next keyboard reset.
*
* NKRO may prevent your keystrokes from being detected in the BIOS, but it is
* fully operational during normal computer usage.
*
* For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
* or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
* bootmagic, NKRO mode will always be enabled until it is toggled again during a
* power-up.
*
*/
//#define FORCE_NKRO
/*
* Magic Key Options
*
* Magic keys are hotkey commands that allow control over firmware functions of
* the keyboard. They are best used in combination with the HID Listen program,
* found here: https://www.pjrc.com/teensy/hid_listen.html
*
* The options below allow the magic key functionality to be changed. This is
* useful if your keyboard/keypad is missing keys and you want magic key support.
*
*/
/* key combination for magic key command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/* control how magic key switches layers */
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
/* override magic key keymap */
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
//#define MAGIC_KEY_HELP1 H
//#define MAGIC_KEY_HELP2 SLASH
//#define MAGIC_KEY_DEBUG D
//#define MAGIC_KEY_DEBUG_MATRIX X
//#define MAGIC_KEY_DEBUG_KBD K
//#define MAGIC_KEY_DEBUG_MOUSE M
//#define MAGIC_KEY_VERSION V
//#define MAGIC_KEY_STATUS S
//#define MAGIC_KEY_CONSOLE C
//#define MAGIC_KEY_LAYER0_ALT1 ESC
//#define MAGIC_KEY_LAYER0_ALT2 GRAVE
//#define MAGIC_KEY_LAYER0 0
//#define MAGIC_KEY_LAYER1 1
//#define MAGIC_KEY_LAYER2 2
//#define MAGIC_KEY_LAYER3 3
//#define MAGIC_KEY_LAYER4 4
//#define MAGIC_KEY_LAYER5 5
//#define MAGIC_KEY_LAYER6 6
//#define MAGIC_KEY_LAYER7 7
//#define MAGIC_KEY_LAYER8 8
//#define MAGIC_KEY_LAYER9 9
//#define MAGIC_KEY_BOOTLOADER PAUSE
//#define MAGIC_KEY_LOCK CAPS
//#define MAGIC_KEY_EEPROM E
//#define MAGIC_KEY_NKRO N
//#define MAGIC_KEY_SLEEP_LED Z
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#endif

@ -0,0 +1,67 @@
#include "magicforce68.h"
#define _QWERTY 0
#define _FN1 1
#define _FN2 2
#define KC_ KC_TRNS
#define KC_X0 LT(_FN2, KC_GRV)
#define KC_X1 MO(_FN1)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_QWERTY] = KEYMAP(
/*,----+----+----+----+----+----+----+----+----+----+----+----+----+--------. ,----+----. */
ESC , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 ,MINS,EQL , BSPC , INS ,PGUP,
/*|----`----`----`----`----`----`----`----`----`----`----`----`----`--------| |----`----| */
TAB , Q , W , E , R , T , Y , U , I , O , P ,LBRC,RBRC, BSLS , DEL ,PGDN,
/*|------`----`----`----`----`----`----`----`----`----`----`----`----`------| `----`----' */
X0 , A , S , D , F , G , H , J , K , L ,SCLN,QUOT, ENTER ,
/*|-------`----`----`----`----`----`----`----`----`----`----`----`----------| ,----. */
LSFT , Z , X , C , V , B , N , M ,COMM,DOT ,SLSH, RSFT , UP ,
/*|---------`----`----`----`----`----`----`----`----`----`----`-------------.--|----|----. */
LCTL ,LGUI ,LALT , SPACE , X1 ,RALT ,RCTL , LEFT,DOWN,RGHT
/*`-----+-----+-----+------------------------------+------+-----+-----' `----+----+----' */
),
[_FN1] = KEYMAP(
/*,----+----+----+----+----+----+----+----+----+----+----+----+----+--------. ,----+----. */
GRV , F1 , F2 , F3 , F4 , F5 , F6 , F7 , F8 , F9 ,F10 ,F11 ,F12 , BSPC , VOLU,HOME,
/*|esc-`-1--`-2--`-3--`-4--`-5--`-6--`-7--`-8--`-9--`-0--`mnus`plus`--bksp--| |ins-`pgup| */
, , , UP , , , , , , , , , , , VOLD,END,
/*|tab---`-q--`-w--`-e--`-r--`-t--`-y--`-u--`-i--`-o--`-p--`-{--`-}--`--|---| `del-`pgdn' */
, ,LEFT,DOWN,RGHT, , , , , , , , ,
/*|caps---`-a--`-s--`-d--`-f--`-g--`-h--`-j--`-k--`-l--`-;--`-'--`----enter-| ,----. */
, , , , , , ,MUTE, , , , , MUTE,
/*|shift----`-z--`-x--`-c--`-v--`-b--`-n--`-m--`-,--`-.--`-/--`-------shift-.--|-up-|----. */
, , , , , , , MPRV,MPLY,MNXT
/*`ctrl-+-gui-+-alt-+----------space---------------+-fn---+-alt-+ctrl-' `left+down+rght' */
),
[_FN2] = KEYMAP(
/*,----+----+----+----+----+----+----+----+----+----+----+----+----+--------. ,----+----. */
GRV , F1 , F2 , F3 , F4 , F5 , F6 , F7 , F8 , F9 ,F10 ,F11 ,F12 , BSPC , VOLU,HOME,
/*|esc-`-1--`-2--`-3--`-4--`-5--`-6--`-7--`-8--`-9--`-0--`mnus`plus`--bksp--| |ins-`pgup| */
, , , UP , , , , 7 , 8 , 9 , , , , , VOLD,END,
/*|tab---`-q--`-w--`-e--`-r--`-t--`-y--`-u--`-i--`-o--`-p--`-{--`-}--`--|---| `del-`pgdn' */
, ,LEFT,DOWN,RGHT, , , 4 , 5 , 6 , , , ,
/*|caps---`-a--`-s--`-d--`-f--`-g--`-h--`-j--`-k--`-l--`-;--`-'--`----enter-| ,----. */
, , , , , , 0 , 1 , 2 , 3 , , , MUTE,
/*|shift----`-z--`-x--`-c--`-v--`-b--`-n--`-m--`-,--`-.--`-/--`-------shift-.--|-up-|----. */
, , , , , , , MPRV,MPLY,MNXT
/*`ctrl-+-gui-+-alt-+----------space---------------+-fn---+-alt-+ctrl-' `left+down+rght' */
)
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch(id) {
case 0:
if (record->event.pressed) {
register_code(KC_RSFT);
} else {
unregister_code(KC_RSFT);
}
break;
}
return MACRO_NONE;
};

@ -0,0 +1,8 @@
#include "magicforce68.h"
void matrix_init_kb(void) {
// put your keyboard start-up code here
// runs once when the firmware starts up
matrix_init_user();
}

@ -0,0 +1,20 @@
#ifndef MAGICFORCE68_H
#define MAGICFORCE68_H
#include "quantum.h"
#define KEYMAP( \
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K2E, \
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, K3E, \
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, \
K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3C, K3D, \
K40, K41, K42, K45, K49, K4A, K4B, K4C, K4D, K4E \
) { \
{ KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07, KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K0D, KC_##K0E }, \
{ KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17, KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_##K1E }, \
{ KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27, KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_NO, KC_##K2E }, \
{ KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37, KC_##K38, KC_##K39, KC_##K3A, KC_NO, KC_##K3C, KC_##K3D, KC_##K3E }, \
{ KC_##K40, KC_##K41, KC_##K42, KC_NO, KC_NO, KC_##K45, KC_NO, KC_NO, KC_NO, KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E } \
}
#endif

@ -0,0 +1,83 @@
# MCU name
MCU = atmega32u4
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=512
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= yes # Console for debug(+400)
COMMAND_ENABLE ?= yes # Commands for debug and configuration
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE ?= no # USB Nkey Rollover
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default
MIDI_ENABLE ?= no # MIDI controls
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE ?= no # Audio output on port C6
ifndef QUANTUM_DIR
include ../../../Makefile
endif
avrdude: build
ls /dev/tty* > /tmp/1; \
echo "Reset your Pro Micro now"; \
while [[ -z $$USB ]]; do \
sleep 1; \
ls /dev/tty* > /tmp/2; \
USB=`diff /tmp/1 /tmp/2 | grep -o '/dev/tty.*'`; \
done; \
avrdude -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex
.PHONY: avrdude

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

@ -0,0 +1,3 @@
ifndef MAKEFILE_INCLUDED
include ../../../Makefile
endif

@ -0,0 +1,162 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xBB80
#define PRODUCT_ID 0x0504
#define DEVICE_VER 0x0001
#define MANUFACTURER Hexwire
#define PRODUCT Numpad 20
#define DESCRIPTION Handwired 4x5 numpad
/* key matrix size */
#define MATRIX_ROWS 5
#define MATRIX_COLS 4
/*
* Keyboard Matrix Assignments
*
* Change this to how you wired your keyboard
* COLS: AVR pins used for columns, left to right
* ROWS: AVR pins used for rows, top to bottom
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
*
*/
#define MATRIX_ROW_PINS { F6, B1, B3, B6, B5 }
#define MATRIX_COL_PINS { D1, D0, F5, F4 }
#define UNUSED_PINS
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
// #define BACKLIGHT_PIN B7
// #define BACKLIGHT_BREATHING
// #define BACKLIGHT_LEVELS 3
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCING_DELAY 5
/* define if matrix has ghost (lacks anti-ghosting diodes) */
//#define MATRIX_HAS_GHOST
/* number of backlight levels */
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/*
* Force NKRO
*
* Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
* state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
* makefile for this to work.)
*
* If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
* until the next keyboard reset.
*
* NKRO may prevent your keystrokes from being detected in the BIOS, but it is
* fully operational during normal computer usage.
*
* For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
* or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
* bootmagic, NKRO mode will always be enabled until it is toggled again during a
* power-up.
*
*/
//#define FORCE_NKRO
/*
* Magic Key Options
*
* Magic keys are hotkey commands that allow control over firmware functions of
* the keyboard. They are best used in combination with the HID Listen program,
* found here: https://www.pjrc.com/teensy/hid_listen.html
*
* The options below allow the magic key functionality to be changed. This is
* useful if your keyboard/keypad is missing keys and you want magic key support.
*
*/
/* key combination for magic key command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/* control how magic key switches layers */
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
/* override magic key keymap */
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
//#define MAGIC_KEY_HELP1 H
//#define MAGIC_KEY_HELP2 SLASH
//#define MAGIC_KEY_DEBUG D
//#define MAGIC_KEY_DEBUG_MATRIX X
//#define MAGIC_KEY_DEBUG_KBD K
//#define MAGIC_KEY_DEBUG_MOUSE M
//#define MAGIC_KEY_VERSION V
//#define MAGIC_KEY_STATUS S
//#define MAGIC_KEY_CONSOLE C
//#define MAGIC_KEY_LAYER0_ALT1 ESC
//#define MAGIC_KEY_LAYER0_ALT2 GRAVE
//#define MAGIC_KEY_LAYER0 0
//#define MAGIC_KEY_LAYER1 1
//#define MAGIC_KEY_LAYER2 2
//#define MAGIC_KEY_LAYER3 3
//#define MAGIC_KEY_LAYER4 4
//#define MAGIC_KEY_LAYER5 5
//#define MAGIC_KEY_LAYER6 6
//#define MAGIC_KEY_LAYER7 7
//#define MAGIC_KEY_LAYER8 8
//#define MAGIC_KEY_LAYER9 9
//#define MAGIC_KEY_BOOTLOADER PAUSE
//#define MAGIC_KEY_LOCK CAPS
//#define MAGIC_KEY_EEPROM E
//#define MAGIC_KEY_NKRO N
//#define MAGIC_KEY_SLEEP_LED Z
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#endif

@ -0,0 +1,16 @@
#include "numpad20.h"
#define KC_ KC_TRNS
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = COMPACT_KEYMAP(
LEFT,RGHT, UP ,DOWN, \
P7 , P8 , P9 ,PLUS, \
P4 , P5 , P6 ,MINS, \
P1 , P2 , P3 , ENT, \
P0 ,DOT ,RGHT, TAB \
)
};
const uint16_t PROGMEM fn_actions[] = {
};

@ -0,0 +1,8 @@
#include "numpad20.h"
void matrix_init_kb(void) {
// put your keyboard start-up code here
// runs once when the firmware starts up
matrix_init_user();
}

@ -0,0 +1,20 @@
#ifndef NUMPAD20_H
#define NUMPAD20_H
#include "quantum.h"
#define COMPACT_KEYMAP( \
K00, K01, K02, K03, \
K10, K11, K12, K13, \
K20, K21, K22, K23, \
K30, K31, K32, K33, \
K40, K41, K42, K43 \
) { \
{ KC_##K00, KC_##K01, KC_##K02, KC_##K03 }, \
{ KC_##K10, KC_##K11, KC_##K12, KC_##K13 }, \
{ KC_##K20, KC_##K21, KC_##K22, KC_##K23 }, \
{ KC_##K30, KC_##K31, KC_##K32, KC_##K33 }, \
{ KC_##K40, KC_##K41, KC_##K42, KC_##K43 } \
}
#endif

@ -0,0 +1,83 @@
# MCU name
MCU = atmega32u4
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=512
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= yes # Console for debug(+400)
COMMAND_ENABLE ?= yes # Commands for debug and configuration
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE ?= no # USB Nkey Rollover
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default
MIDI_ENABLE ?= no # MIDI controls
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE ?= no # Audio output on port C6
ifndef QUANTUM_DIR
include ../../../Makefile
endif
avrdude: build
ls /dev/tty* > /tmp/1; \
echo "Reset your Pro Micro now"; \
while [[ -z $$USB ]]; do \
sleep 1; \
ls /dev/tty* > /tmp/2; \
USB=`diff /tmp/1 /tmp/2 | grep -o '/dev/tty.*'`; \
done; \
avrdude -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex
.PHONY: avrdude

@ -0,0 +1,3 @@
ifndef MAKEFILE_INCLUDED
include ../../../Makefile
endif

@ -0,0 +1,162 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xBB80
#define PRODUCT_ID 0x050D
#define DEVICE_VER 0x0001
#define MANUFACTURER Hexwire
#define PRODUCT Ortho 5x13
#define DESCRIPTION Handwired 5x13 ortholinear keyboard
/* key matrix size */
#define MATRIX_ROWS 5
#define MATRIX_COLS 13
/*
* Keyboard Matrix Assignments
*
* Change this to how you wired your keyboard
* COLS: AVR pins used for columns, left to right
* ROWS: AVR pins used for rows, top to bottom
* DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
*
*/
#define MATRIX_ROW_PINS { D3, D2, D1, D0, D4 }
#define MATRIX_COL_PINS { C6, D7, E6, B4, B5, B6, B2, B3, B1, F7, F6, F5, F4 }
#define UNUSED_PINS
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
// #define BACKLIGHT_PIN B7
// #define BACKLIGHT_BREATHING
// #define BACKLIGHT_LEVELS 3
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCING_DELAY 5
/* define if matrix has ghost (lacks anti-ghosting diodes) */
//#define MATRIX_HAS_GHOST
/* number of backlight levels */
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/*
* Force NKRO
*
* Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
* state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
* makefile for this to work.)
*
* If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
* until the next keyboard reset.
*
* NKRO may prevent your keystrokes from being detected in the BIOS, but it is
* fully operational during normal computer usage.
*
* For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
* or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
* bootmagic, NKRO mode will always be enabled until it is toggled again during a
* power-up.
*
*/
//#define FORCE_NKRO
/*
* Magic Key Options
*
* Magic keys are hotkey commands that allow control over firmware functions of
* the keyboard. They are best used in combination with the HID Listen program,
* found here: https://www.pjrc.com/teensy/hid_listen.html
*
* The options below allow the magic key functionality to be changed. This is
* useful if your keyboard/keypad is missing keys and you want magic key support.
*
*/
/* key combination for magic key command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/* control how magic key switches layers */
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
/* override magic key keymap */
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
//#define MAGIC_KEY_HELP1 H
//#define MAGIC_KEY_HELP2 SLASH
//#define MAGIC_KEY_DEBUG D
//#define MAGIC_KEY_DEBUG_MATRIX X
//#define MAGIC_KEY_DEBUG_KBD K
//#define MAGIC_KEY_DEBUG_MOUSE M
//#define MAGIC_KEY_VERSION V
//#define MAGIC_KEY_STATUS S
//#define MAGIC_KEY_CONSOLE C
//#define MAGIC_KEY_LAYER0_ALT1 ESC
//#define MAGIC_KEY_LAYER0_ALT2 GRAVE
//#define MAGIC_KEY_LAYER0 0
//#define MAGIC_KEY_LAYER1 1
//#define MAGIC_KEY_LAYER2 2
//#define MAGIC_KEY_LAYER3 3
//#define MAGIC_KEY_LAYER4 4
//#define MAGIC_KEY_LAYER5 5
//#define MAGIC_KEY_LAYER6 6
//#define MAGIC_KEY_LAYER7 7
//#define MAGIC_KEY_LAYER8 8
//#define MAGIC_KEY_LAYER9 9
//#define MAGIC_KEY_BOOTLOADER PAUSE
//#define MAGIC_KEY_LOCK CAPS
//#define MAGIC_KEY_EEPROM E
//#define MAGIC_KEY_NKRO N
//#define MAGIC_KEY_SLEEP_LED Z
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#endif

@ -0,0 +1,289 @@
#include "ortho5x13.h"
#include "action_layer.h"
#include "eeconfig.h"
#ifdef AUDIO_ENABLE
#include "audio.h"
#endif
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _QWERTY 0
#define _COLEMAK 1
#define _DVORAK 2
#define _LOWER 3
#define _RAISE 4
#define _ADJUST 16
enum custom_keycodes {
QWERTY = SAFE_RANGE,
COLEMAK,
DVORAK,
LOWER,
RAISE,
BACKLIT
};
// Fillers to make layering more clear
#define _______ KC_TRNS
#define XXXXXXX KC_NO
#define KC_L1 LOWER
#define KC_L2 RAISE
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Qwerty
* ,------------------------------------------------------------------------------------------.
* | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = |
* |------+------+------+------+------+------+------+------+------+------+------+------+------|
* | Tab | Q | W | E | R | T | Y | U | I | O | P | [ | ] |
* |------+------+------+------+------+-------------+------+------+------+------+------+------|
* | ` | A | S | D | F | G | H | J | K | L | ; | ' | \ |
* |------+------+------+------+------+------|------+------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | N | M | , | . | / |Enter | Up |
* |------+------+------+------+------+------+------+------+------+------+------+------+------|
* | Hyper| Ctrl | Alt | GUI |Lower | Space |Raise | Bksp |Shift | Left | Down |Right |
* `------------------------------------------------------------------------------------------'
*/
[_QWERTY] = COMPACT_KEYMAP(
//,----+----+----+----+----+----+----+----+----+----+----+----+----.
ESC , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 ,MINS,EQL ,
//|----+----+----+----+----+----+----+----+----+----+----+----+----|
TAB , Q , W , E , R , T , Y , U , I , O , P ,LBRC,RBRC,
//|----+----+----+----+----+----+----+----+----+----+----+----+----|
GRV , A , S , D , F , G , H , J , K , L ,SCLN,QUOT,BSLS,
//|----+----+----+----+----+----+----+----+----+----+----+----+----|
LSFT, Z , X , C , V , B , N , M ,COMM,DOT ,SLSH,ENT , UP ,
//|----+----+----+----+----+---------+----+----+----+----+----+----|
HYPR,LCTL,LALT,LGUI, L1 , SPACE , L2 ,BSPC,RSFT,LEFT,RGHT,DOWN
//`----+----+----+----+----+---------+----+----+----+----+----+----'
),
/* Colemak
* ,-----------------------------------------------------------------------------------.
* | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Tab | Q | W | F | P | G | J | L | U | Y | ; | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | R | S | T | D | H | N | E | I | O | " |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | K | M | , | . | / |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_COLEMAK] = {
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
{KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_DEL},
{KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT},
{KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT },
{BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
/* Dvorak
* ,-----------------------------------------------------------------------------------.
* | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Tab | " | , | . | P | Y | F | G | C | R | L | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | O | E | U | I | D | H | T | N | S | / |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_DVORAK] = {
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
{KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_DEL},
{KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH},
{KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT },
{BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
/* Lower
* ,-----------------------------------------------------------------------------------.
* | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Del | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | | |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | Next | Vol- | Vol+ | Play |
* `-----------------------------------------------------------------------------------'
*/
[_LOWER] = {
{KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC},
{KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL},
{KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE},
{_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS),S(KC_NUBS),_______, _______, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
},
/* Raise
* ,-----------------------------------------------------------------------------------.
* | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Del | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / | | |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | Next | Vol- | Vol+ | Play |
* `-----------------------------------------------------------------------------------'
*/
[_RAISE] = {
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL},
{KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS},
{_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, _______, _______, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
},
/* Adjust (Lower + Raise)
* ,-----------------------------------------------------------------------------------.
* | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | Reset| | | | | | | | | | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | |Audoff|Aud on|AGnorm|AGswap|Qwerty|Colemk|Dvorak| | |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | |Voice-|Voice+|Musoff|Mus on| | | | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_ADJUST] = {
{KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12},
{_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL},
{_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______},
{_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
}
};
#ifdef AUDIO_ENABLE
float tone_startup[][2] = {
{NOTE_B5, 20},
{NOTE_B6, 8},
{NOTE_DS6, 20},
{NOTE_B6, 8}
};
float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_dvorak[][2] = SONG(DVORAK_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
#endif
void persistant_default_layer_set(uint16_t default_layer) {
eeconfig_update_default_layer(default_layer);
default_layer_set(default_layer);
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case QWERTY:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
#endif
persistant_default_layer_set(1UL<<_QWERTY);
}
return false;
break;
case COLEMAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
persistant_default_layer_set(1UL<<_COLEMAK);
}
return false;
break;
case DVORAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
#endif
persistant_default_layer_set(1UL<<_DVORAK);
}
return false;
break;
case LOWER:
if (record->event.pressed) {
layer_on(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case RAISE:
if (record->event.pressed) {
layer_on(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case BACKLIT:
if (record->event.pressed) {
register_code(KC_RSFT);
#ifdef BACKLIGHT_ENABLE
backlight_step();
#endif
} else {
unregister_code(KC_RSFT);
}
return false;
break;
}
return true;
};
void matrix_init_user(void) {
#ifdef AUDIO_ENABLE
startup_user();
#endif
}
#ifdef AUDIO_ENABLE
void startup_user()
{
_delay_ms(20); // gets rid of tick
PLAY_NOTE_ARRAY(tone_startup, false, 0);
}
void shutdown_user()
{
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
_delay_ms(150);
stop_all_notes();
}
void music_on_user(void)
{
music_scale_user();
}
void music_scale_user(void)
{
PLAY_NOTE_ARRAY(music_scale, false, 0);
}
#endif

@ -0,0 +1,8 @@
#include "ortho5x13.h"
void matrix_init_kb(void) {
// put your keyboard start-up code here
// runs once when the firmware starts up
matrix_init_user();
}

@ -0,0 +1,36 @@
#ifndef ORTHO5X13_H
#define ORTHO5X13_H
#include "quantum.h"
#define KEYMAP( \
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, \
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, \
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, \
k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, \
k40, k41, k42, k43, k44, k45, k47, k48, k49, k4a, k4b, k4c \
) \
{ \
{ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c }, \
{ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c }, \
{ k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c }, \
{ k30, k31, k32, k33, k34, k35, k35, k37, k38, k39, k3a, k3b, k3c }, \
{ k40, k41, k42, k43, k44, k45, KC_NO, k47, k48, k49, k4a, k4b, k4c } \
}
#define COMPACT_KEYMAP( \
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, \
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, \
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, \
k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, \
k40, k41, k42, k43, k44, k45, k47, k48, k49, k4a, k4b, k4c \
) \
{ \
{ KC_##k00, KC_##k01, KC_##k02, KC_##k03, KC_##k04, KC_##k05, KC_##k06, KC_##k07, KC_##k08, KC_##k09, KC_##k0a, KC_##k0b, KC_##k0c }, \
{ KC_##k10, KC_##k11, KC_##k12, KC_##k13, KC_##k14, KC_##k15, KC_##k16, KC_##k17, KC_##k18, KC_##k19, KC_##k1a, KC_##k1b, KC_##k1c }, \
{ KC_##k20, KC_##k21, KC_##k22, KC_##k23, KC_##k24, KC_##k25, KC_##k26, KC_##k27, KC_##k28, KC_##k29, KC_##k2a, KC_##k2b, KC_##k2c }, \
{ KC_##k30, KC_##k31, KC_##k32, KC_##k33, KC_##k34, KC_##k35, KC_##k35, KC_##k37, KC_##k38, KC_##k39, KC_##k3a, KC_##k3b, KC_##k3c }, \
{ KC_##k40, KC_##k41, KC_##k42, KC_##k43, KC_##k44, KC_##k45, KC_NO, KC_##k47, KC_##k48, KC_##k49, KC_##k4a, KC_##k4b, KC_##k4c } \
}
#endif

@ -0,0 +1,83 @@
# MCU name
MCU = atmega32u4
# Processor frequency.
# This will define a symbol, F_CPU, in all source code files equal to the
# processor frequency in Hz. You can then use this symbol in your source code to
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
#
# This will be an integer division of F_USB below, as it is sourced by
# F_USB after it has run through any CPU prescalers. Note that this value
# does not *change* the processor frequency - it should merely be updated to
# reflect the processor speed set externally so that the code can use accurate
# software delays.
F_CPU = 16000000
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH = AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB = $(F_CPU)
# Interrupt driven control endpoint task(+60)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=512
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= yes # Console for debug(+400)
COMMAND_ENABLE ?= yes # Commands for debug and configuration
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE ?= no # USB Nkey Rollover
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default
MIDI_ENABLE ?= no # MIDI controls
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE ?= no # Audio output on port C6
ifndef QUANTUM_DIR
include ../../../Makefile
endif
avrdude: build
ls /dev/tty* > /tmp/1; \
echo "Reset your Pro Micro now"; \
while [[ -z $$USB ]]; do \
sleep 1; \
ls /dev/tty* > /tmp/2; \
USB=`diff /tmp/1 /tmp/2 | grep -o '/dev/tty.*'`; \
done; \
avrdude -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex
.PHONY: avrdude

@ -0,0 +1,276 @@
// This is the 'classic' fixed-space bitmap font for Adafruit_GFX since 1.0.
// See gfxfont.h for newer custom bitmap font info.
#ifndef FONT5X7_H
#define FONT5X7_H
#ifdef __AVR__
#include <avr/io.h>
#include <avr/pgmspace.h>
#elif defined(ESP8266)
#include <pgmspace.h>
#else
#define PROGMEM
#endif
// Standard ASCII 5x7 font
static const unsigned char font[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00,
0x3E, 0x5B, 0x4F, 0x5B, 0x3E,
0x3E, 0x6B, 0x4F, 0x6B, 0x3E,
0x1C, 0x3E, 0x7C, 0x3E, 0x1C,
0x18, 0x3C, 0x7E, 0x3C, 0x18,
0x1C, 0x57, 0x7D, 0x57, 0x1C,
0x1C, 0x5E, 0x7F, 0x5E, 0x1C,
0x00, 0x18, 0x3C, 0x18, 0x00,
0xFF, 0xE7, 0xC3, 0xE7, 0xFF,
0x00, 0x18, 0x24, 0x18, 0x00,
0xFF, 0xE7, 0xDB, 0xE7, 0xFF,
0x30, 0x48, 0x3A, 0x06, 0x0E,
0x26, 0x29, 0x79, 0x29, 0x26,
0x40, 0x7F, 0x05, 0x05, 0x07,
0x40, 0x7F, 0x05, 0x25, 0x3F,
0x5A, 0x3C, 0xE7, 0x3C, 0x5A,
0x7F, 0x3E, 0x1C, 0x1C, 0x08,
0x08, 0x1C, 0x1C, 0x3E, 0x7F,
0x14, 0x22, 0x7F, 0x22, 0x14,
0x5F, 0x5F, 0x00, 0x5F, 0x5F,
0x06, 0x09, 0x7F, 0x01, 0x7F,
0x00, 0x66, 0x89, 0x95, 0x6A,
0x60, 0x60, 0x60, 0x60, 0x60,
0x94, 0xA2, 0xFF, 0xA2, 0x94,
0x08, 0x04, 0x7E, 0x04, 0x08,
0x10, 0x20, 0x7E, 0x20, 0x10,
0x08, 0x08, 0x2A, 0x1C, 0x08,
0x08, 0x1C, 0x2A, 0x08, 0x08,
0x1E, 0x10, 0x10, 0x10, 0x10,
0x0C, 0x1E, 0x0C, 0x1E, 0x0C,
0x30, 0x38, 0x3E, 0x38, 0x30,
0x06, 0x0E, 0x3E, 0x0E, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5F, 0x00, 0x00,
0x00, 0x07, 0x00, 0x07, 0x00,
0x14, 0x7F, 0x14, 0x7F, 0x14,
0x24, 0x2A, 0x7F, 0x2A, 0x12,
0x23, 0x13, 0x08, 0x64, 0x62,
0x36, 0x49, 0x56, 0x20, 0x50,
0x00, 0x08, 0x07, 0x03, 0x00,
0x00, 0x1C, 0x22, 0x41, 0x00,
0x00, 0x41, 0x22, 0x1C, 0x00,
0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
0x08, 0x08, 0x3E, 0x08, 0x08,
0x00, 0x80, 0x70, 0x30, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0x60, 0x60, 0x00,
0x20, 0x10, 0x08, 0x04, 0x02,
0x3E, 0x51, 0x49, 0x45, 0x3E,
0x00, 0x42, 0x7F, 0x40, 0x00,
0x72, 0x49, 0x49, 0x49, 0x46,
0x21, 0x41, 0x49, 0x4D, 0x33,
0x18, 0x14, 0x12, 0x7F, 0x10,
0x27, 0x45, 0x45, 0x45, 0x39,
0x3C, 0x4A, 0x49, 0x49, 0x31,
0x41, 0x21, 0x11, 0x09, 0x07,
0x36, 0x49, 0x49, 0x49, 0x36,
0x46, 0x49, 0x49, 0x29, 0x1E,
0x00, 0x00, 0x14, 0x00, 0x00,
0x00, 0x40, 0x34, 0x00, 0x00,
0x00, 0x08, 0x14, 0x22, 0x41,
0x14, 0x14, 0x14, 0x14, 0x14,
0x00, 0x41, 0x22, 0x14, 0x08,
0x02, 0x01, 0x59, 0x09, 0x06,
0x3E, 0x41, 0x5D, 0x59, 0x4E,
0x7C, 0x12, 0x11, 0x12, 0x7C,
0x7F, 0x49, 0x49, 0x49, 0x36,
0x3E, 0x41, 0x41, 0x41, 0x22,
0x7F, 0x41, 0x41, 0x41, 0x3E,
0x7F, 0x49, 0x49, 0x49, 0x41,
0x7F, 0x09, 0x09, 0x09, 0x01,
0x3E, 0x41, 0x41, 0x51, 0x73,
0x7F, 0x08, 0x08, 0x08, 0x7F,
0x00, 0x41, 0x7F, 0x41, 0x00,
0x20, 0x40, 0x41, 0x3F, 0x01,
0x7F, 0x08, 0x14, 0x22, 0x41,
0x7F, 0x40, 0x40, 0x40, 0x40,
0x7F, 0x02, 0x1C, 0x02, 0x7F,
0x7F, 0x04, 0x08, 0x10, 0x7F,
0x3E, 0x41, 0x41, 0x41, 0x3E,
0x7F, 0x09, 0x09, 0x09, 0x06,
0x3E, 0x41, 0x51, 0x21, 0x5E,
0x7F, 0x09, 0x19, 0x29, 0x46,
0x26, 0x49, 0x49, 0x49, 0x32,
0x03, 0x01, 0x7F, 0x01, 0x03,
0x3F, 0x40, 0x40, 0x40, 0x3F,
0x1F, 0x20, 0x40, 0x20, 0x1F,
0x3F, 0x40, 0x38, 0x40, 0x3F,
0x63, 0x14, 0x08, 0x14, 0x63,
0x03, 0x04, 0x78, 0x04, 0x03,
0x61, 0x59, 0x49, 0x4D, 0x43,
0x00, 0x7F, 0x41, 0x41, 0x41,
0x02, 0x04, 0x08, 0x10, 0x20,
0x00, 0x41, 0x41, 0x41, 0x7F,
0x04, 0x02, 0x01, 0x02, 0x04,
0x40, 0x40, 0x40, 0x40, 0x40,
0x00, 0x03, 0x07, 0x08, 0x00,
0x20, 0x54, 0x54, 0x78, 0x40,
0x7F, 0x28, 0x44, 0x44, 0x38,
0x38, 0x44, 0x44, 0x44, 0x28,
0x38, 0x44, 0x44, 0x28, 0x7F,
0x38, 0x54, 0x54, 0x54, 0x18,
0x00, 0x08, 0x7E, 0x09, 0x02,
0x18, 0xA4, 0xA4, 0x9C, 0x78,
0x7F, 0x08, 0x04, 0x04, 0x78,
0x00, 0x44, 0x7D, 0x40, 0x00,
0x20, 0x40, 0x40, 0x3D, 0x00,
0x7F, 0x10, 0x28, 0x44, 0x00,
0x00, 0x41, 0x7F, 0x40, 0x00,
0x7C, 0x04, 0x78, 0x04, 0x78,
0x7C, 0x08, 0x04, 0x04, 0x78,
0x38, 0x44, 0x44, 0x44, 0x38,
0xFC, 0x18, 0x24, 0x24, 0x18,
0x18, 0x24, 0x24, 0x18, 0xFC,
0x7C, 0x08, 0x04, 0x04, 0x08,
0x48, 0x54, 0x54, 0x54, 0x24,
0x04, 0x04, 0x3F, 0x44, 0x24,
0x3C, 0x40, 0x40, 0x20, 0x7C,
0x1C, 0x20, 0x40, 0x20, 0x1C,
0x3C, 0x40, 0x30, 0x40, 0x3C,
0x44, 0x28, 0x10, 0x28, 0x44,
0x4C, 0x90, 0x90, 0x90, 0x7C,
0x44, 0x64, 0x54, 0x4C, 0x44,
0x00, 0x08, 0x36, 0x41, 0x00,
0x00, 0x00, 0x77, 0x00, 0x00,
0x00, 0x41, 0x36, 0x08, 0x00,
0x02, 0x01, 0x02, 0x04, 0x02,
0x3C, 0x26, 0x23, 0x26, 0x3C,
0x1E, 0xA1, 0xA1, 0x61, 0x12,
0x3A, 0x40, 0x40, 0x20, 0x7A,
0x38, 0x54, 0x54, 0x55, 0x59,
0x21, 0x55, 0x55, 0x79, 0x41,
0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut
0x21, 0x55, 0x54, 0x78, 0x40,
0x20, 0x54, 0x55, 0x79, 0x40,
0x0C, 0x1E, 0x52, 0x72, 0x12,
0x39, 0x55, 0x55, 0x55, 0x59,
0x39, 0x54, 0x54, 0x54, 0x59,
0x39, 0x55, 0x54, 0x54, 0x58,
0x00, 0x00, 0x45, 0x7C, 0x41,
0x00, 0x02, 0x45, 0x7D, 0x42,
0x00, 0x01, 0x45, 0x7C, 0x40,
0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut
0xF0, 0x28, 0x25, 0x28, 0xF0,
0x7C, 0x54, 0x55, 0x45, 0x00,
0x20, 0x54, 0x54, 0x7C, 0x54,
0x7C, 0x0A, 0x09, 0x7F, 0x49,
0x32, 0x49, 0x49, 0x49, 0x32,
0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut
0x32, 0x4A, 0x48, 0x48, 0x30,
0x3A, 0x41, 0x41, 0x21, 0x7A,
0x3A, 0x42, 0x40, 0x20, 0x78,
0x00, 0x9D, 0xA0, 0xA0, 0x7D,
0x3D, 0x42, 0x42, 0x42, 0x3D, // O-umlaut
0x3D, 0x40, 0x40, 0x40, 0x3D,
0x3C, 0x24, 0xFF, 0x24, 0x24,
0x48, 0x7E, 0x49, 0x43, 0x66,
0x2B, 0x2F, 0xFC, 0x2F, 0x2B,
0xFF, 0x09, 0x29, 0xF6, 0x20,
0xC0, 0x88, 0x7E, 0x09, 0x03,
0x20, 0x54, 0x54, 0x79, 0x41,
0x00, 0x00, 0x44, 0x7D, 0x41,
0x30, 0x48, 0x48, 0x4A, 0x32,
0x38, 0x40, 0x40, 0x22, 0x7A,
0x00, 0x7A, 0x0A, 0x0A, 0x72,
0x7D, 0x0D, 0x19, 0x31, 0x7D,
0x26, 0x29, 0x29, 0x2F, 0x28,
0x26, 0x29, 0x29, 0x29, 0x26,
0x30, 0x48, 0x4D, 0x40, 0x20,
0x38, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x38,
0x2F, 0x10, 0xC8, 0xAC, 0xBA,
0x2F, 0x10, 0x28, 0x34, 0xFA,
0x00, 0x00, 0x7B, 0x00, 0x00,
0x08, 0x14, 0x2A, 0x14, 0x22,
0x22, 0x14, 0x2A, 0x14, 0x08,
0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old code
0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block
0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block
0x00, 0x00, 0x00, 0xFF, 0x00,
0x10, 0x10, 0x10, 0xFF, 0x00,
0x14, 0x14, 0x14, 0xFF, 0x00,
0x10, 0x10, 0xFF, 0x00, 0xFF,
0x10, 0x10, 0xF0, 0x10, 0xF0,
0x14, 0x14, 0x14, 0xFC, 0x00,
0x14, 0x14, 0xF7, 0x00, 0xFF,
0x00, 0x00, 0xFF, 0x00, 0xFF,
0x14, 0x14, 0xF4, 0x04, 0xFC,
0x14, 0x14, 0x17, 0x10, 0x1F,
0x10, 0x10, 0x1F, 0x10, 0x1F,
0x14, 0x14, 0x14, 0x1F, 0x00,
0x10, 0x10, 0x10, 0xF0, 0x00,
0x00, 0x00, 0x00, 0x1F, 0x10,
0x10, 0x10, 0x10, 0x1F, 0x10,
0x10, 0x10, 0x10, 0xF0, 0x10,
0x00, 0x00, 0x00, 0xFF, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0xFF, 0x10,
0x00, 0x00, 0x00, 0xFF, 0x14,
0x00, 0x00, 0xFF, 0x00, 0xFF,
0x00, 0x00, 0x1F, 0x10, 0x17,
0x00, 0x00, 0xFC, 0x04, 0xF4,
0x14, 0x14, 0x17, 0x10, 0x17,
0x14, 0x14, 0xF4, 0x04, 0xF4,
0x00, 0x00, 0xFF, 0x00, 0xF7,
0x14, 0x14, 0x14, 0x14, 0x14,
0x14, 0x14, 0xF7, 0x00, 0xF7,
0x14, 0x14, 0x14, 0x17, 0x14,
0x10, 0x10, 0x1F, 0x10, 0x1F,
0x14, 0x14, 0x14, 0xF4, 0x14,
0x10, 0x10, 0xF0, 0x10, 0xF0,
0x00, 0x00, 0x1F, 0x10, 0x1F,
0x00, 0x00, 0x00, 0x1F, 0x14,
0x00, 0x00, 0x00, 0xFC, 0x14,
0x00, 0x00, 0xF0, 0x10, 0xF0,
0x10, 0x10, 0xFF, 0x10, 0xFF,
0x14, 0x14, 0x14, 0xFF, 0x14,
0x10, 0x10, 0x10, 0x1F, 0x00,
0x00, 0x00, 0x00, 0xF0, 0x10,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x38, 0x44, 0x44, 0x38, 0x44,
0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta
0x7E, 0x02, 0x02, 0x06, 0x06,
0x02, 0x7E, 0x02, 0x7E, 0x02,
0x63, 0x55, 0x49, 0x41, 0x63,
0x38, 0x44, 0x44, 0x3C, 0x04,
0x40, 0x7E, 0x20, 0x1E, 0x20,
0x06, 0x02, 0x7E, 0x02, 0x02,
0x99, 0xA5, 0xE7, 0xA5, 0x99,
0x1C, 0x2A, 0x49, 0x2A, 0x1C,
0x4C, 0x72, 0x01, 0x72, 0x4C,
0x30, 0x4A, 0x4D, 0x4D, 0x30,
0x30, 0x48, 0x78, 0x48, 0x30,
0xBC, 0x62, 0x5A, 0x46, 0x3D,
0x3E, 0x49, 0x49, 0x49, 0x00,
0x7E, 0x01, 0x01, 0x01, 0x7E,
0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
0x44, 0x44, 0x5F, 0x44, 0x44,
0x40, 0x51, 0x4A, 0x44, 0x40,
0x40, 0x44, 0x4A, 0x51, 0x40,
0x00, 0x00, 0xFF, 0x01, 0x03,
0xE0, 0x80, 0xFF, 0x00, 0x00,
0x08, 0x08, 0x6B, 0x6B, 0x08,
0x36, 0x12, 0x36, 0x24, 0x36,
0x06, 0x0F, 0x09, 0x0F, 0x06,
0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x00, 0x10, 0x10, 0x00,
0x30, 0x40, 0xFF, 0x01, 0x01,
0x00, 0x1F, 0x01, 0x01, 0x1E,
0x00, 0x19, 0x1D, 0x17, 0x12,
0x00, 0x3C, 0x3C, 0x3C, 0x3C,
0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP
};
#endif // FONT5X7_H

@ -16,7 +16,7 @@
#define SLAVE_BUFFER_SIZE 0x10
// i2c SCL clock frequency
#define SCL_CLOCK 100000L
#define SCL_CLOCK 400000L
extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE];
@ -28,4 +28,22 @@ uint8_t i2c_master_read(int);
void i2c_reset_state(void);
void i2c_slave_init(uint8_t address);
static inline unsigned char i2c_start_read(unsigned char addr) {
return i2c_master_start((addr << 1) | I2C_READ);
}
static inline unsigned char i2c_start_write(unsigned char addr) {
return i2c_master_start((addr << 1) | I2C_WRITE);
}
// from SSD1306 scrips
extern unsigned char i2c_rep_start(unsigned char addr);
extern void i2c_start_wait(unsigned char addr);
extern unsigned char i2c_readAck(void);
extern unsigned char i2c_readNak(void);
extern unsigned char i2c_read(unsigned char ack);
#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak();
#endif

@ -0,0 +1,25 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = no # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = no # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
ONEHAND_ENABLE = no # Enable one-hand typing
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,45 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define USE_I2C
//#define USE_SERIAL
//#define MASTER_RIGHT
#define FLIP_HALF
#define SSD1306OLED
#define PREVENT_STUCK_MODIFIERS
#define TAPPING_FORCE_HOLD
#define TAPPING_TERM 100
#undef RGBLED_NUM
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 6
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17
#define RGBLIGHT_VAL_STEP 17
#ifdef SUBPROJECT_rev1
#include "../../rev1/config.h"
#endif
#ifdef SUBPROJECT_rev2
#include "../../rev2/config.h"
#endif

@ -0,0 +1,356 @@
#include "lets_split.h"
#include "bootloader.h"
#include "action_layer.h"
#include "eeconfig.h"
#include "tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/Peripheral/TWI.h"
#ifdef AUDIO_ENABLE
#include "audio.h"
#endif
extern keymap_config_t keymap_config;
//Following line allows macro to read current RGB settings
extern rgblight_config_t rgblight_config;
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _QWERTY 0
#define _COLEMAK 1
#define _DVORAK 2
#define _LOWER 3
#define _RAISE 4
#define _ADJUST 16
enum custom_keycodes {
QWERTY = SAFE_RANGE,
COLEMAK,
DVORAK,
LOWER,
RAISE,
ADJUST,
BACKLIT,
RGBLED_TOGGLE,
RGBLED_STEP_MODE,
RGBLED_INCREASE_HUE,
RGBLED_DECREASE_HUE,
RGBLED_INCREASE_SAT,
RGBLED_DECREASE_SAT,
RGBLED_INCREASE_VAL,
RGBLED_DECREASE_VAL,
};
enum macro_keycodes {
KC_SAMPLEMACRO,
};
// Fillers to make layering more clear
#define _______ KC_TRNS
#define XXXXXXX KC_NO
//Macros
#define M_SAMPLE M(KC_SAMPLEMACRO)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Qwerty
* ,-----------------------------------------------------------------------------------.
* | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | S | D | F | G | H | J | K | L | ; | " |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* |Adjust| Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_QWERTY] = KEYMAP( \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \
KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , \
ADJUST, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
),
/* Colemak
* ,-----------------------------------------------------------------------------------.
* | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | R | S | T | D | H | N | E | I | O | " |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | K | M | , | . | / |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* |Adjust| Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_COLEMAK] = KEYMAP( \
KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, \
KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT , \
ADJUST, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
),
/* Dvorak
* ,-----------------------------------------------------------------------------------.
* | Tab | " | , | . | P | Y | F | G | C | R | L | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | O | E | U | I | D | H | T | N | S | / |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* |Adjust| Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_DVORAK] = KEYMAP( \
KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC, \
KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH, \
KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT , \
ADJUST, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
),
/* Lower
* ,-----------------------------------------------------------------------------------.
* | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Del | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | | \ | | |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | | |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | Next | Vol- | Vol+ | Play |
* `-----------------------------------------------------------------------------------'
*/
[_LOWER] = KEYMAP( \
KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, \
KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, \
_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS),S(KC_NUBS),_______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
),
/* Raise
* ,-----------------------------------------------------------------------------------.
* | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Del | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / | | |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | Next | Vol- | Vol+ | Play |
* `-----------------------------------------------------------------------------------'
*/
[_RAISE] = KEYMAP( \
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, \
KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, \
_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
),
/* Adjust (Lower + Raise)
* ,-----------------------------------------------------------------------------------.
* | | Reset| | | | | | | | | | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak| | |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | | | | | | | | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_ADJUST] = KEYMAP( \
_______, RESET, _______, M_SAMPLE, _______, _______, _______, _______, _______, _______, _______, KC_DEL, \
_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
)
};
#ifdef AUDIO_ENABLE
float tone_startup[][2] = SONG(STARTUP_SOUND);
float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_dvorak[][2] = SONG(DVORAK_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
float tone_plover[][2] = SONG(PLOVER_SOUND);
float tone_plover_gb[][2] = SONG(PLOVER_GOODBYE_SOUND);
float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
#endif
// define variables for reactive RGB
bool TOG_STATUS = false;
int RGB_current_mode;
void persistant_default_layer_set(uint16_t default_layer) {
eeconfig_update_default_layer(default_layer);
default_layer_set(default_layer);
}
// Setting ADJUST layer RGB back to default
void update_tri_layer_RGB(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
rgblight_mode(RGB_current_mode);
layer_on(layer3);
} else {
layer_off(layer3);
}
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case QWERTY:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
#endif
persistant_default_layer_set(1UL<<_QWERTY);
}
return false;
break;
case COLEMAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
persistant_default_layer_set(1UL<<_COLEMAK);
}
return false;
break;
case DVORAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
#endif
persistant_default_layer_set(1UL<<_DVORAK);
}
return false;
break;
case LOWER:
if (record->event.pressed) {
//not sure how to have keyboard check mode and set it to a variable, so my work around
//uses another variable that would be set to true after the first time a reactive key is pressed.
if (TOG_STATUS) { //TOG_STATUS checks is another reactive key currently pressed, only changes RGB mode if returns false
} else {
TOG_STATUS = !TOG_STATUS;
rgblight_mode(16);
}
layer_on(_LOWER);
update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
} else {
rgblight_mode(RGB_current_mode); // revert RGB to initial mode prior to RGB mode change
TOG_STATUS = false;
layer_off(_LOWER);
update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case RAISE:
if (record->event.pressed) {
//not sure how to have keyboard check mode and set it to a variable, so my work around
//uses another variable that would be set to true after the first time a reactive key is pressed.
if (TOG_STATUS) { //TOG_STATUS checks is another reactive key currently pressed, only changes RGB mode if returns false
} else {
TOG_STATUS = !TOG_STATUS;
rgblight_mode(15);
}
layer_on(_RAISE);
update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
} else {
rgblight_mode(RGB_current_mode); // revert RGB to initial mode prior to RGB mode change
layer_off(_RAISE);
TOG_STATUS = false;
update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case BACKLIT:
if (record->event.pressed) {
register_code(KC_RSFT);
#ifdef BACKLIGHT_ENABLE
backlight_step();
#endif
} else {
unregister_code(KC_RSFT);
}
return false;
break;
//led operations - RGB mode change now updates the RGB_current_mode to allow the right RGB mode to be set after reactive keys are released
case RGB_MOD:
if (record->event.pressed) {
rgblight_mode(RGB_current_mode);
rgblight_step();
RGB_current_mode = rgblight_config.mode;
}
return false;
break;
}
return true;
}
void matrix_init_user(void) {
#ifdef AUDIO_ENABLE
startup_user();
#endif
RGB_current_mode = rgblight_config.mode;
}
//SSD1306 OLED init and update loop, make sure to add #define SSD1306OLED in config.h
#ifdef SSD1306OLED
void matrix_master_OLED_init (void) {
TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 800000));
iota_gfx_init(); // turns on the display
}
void matrix_scan_user(void) {
iota_gfx_task(); // this is what updates the display continuously
}
#endif
#ifdef AUDIO_ENABLE
void startup_user()
{
_delay_ms(20); // gets rid of tick
PLAY_NOTE_ARRAY(tone_startup, false, 0);
}
void shutdown_user()
{
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
_delay_ms(150);
stop_all_notes();
}
void music_on_user(void)
{
music_scale_user();
}
void music_scale_user(void)
{
PLAY_NOTE_ARRAY(music_scale, false, 0);
}
#endif
/*
* Macro definition
*/
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
if (!eeconfig_is_enabled()) {
eeconfig_init();
}
switch (id) {
case KC_SAMPLEMACRO:
if (record->event.pressed){
return MACRO (I(10), T(H), T(E), T(L), T(L), T(O), T(SPACE), T(W), T(O), T(R), T(L), T(D), END);
}
}
return MACRO_NONE;
}

@ -0,0 +1,25 @@
SSD1306 OLED Display via I2C
======
Features
--------
Some features supported by the firmware:
* I2C connection between the two halves is required as the OLED display will use this connection as well. Note this
requires pull-up resistors on the data and clock lines.
* OLED display will connect from either side
Wiring
------
Work in progress...
OLED Configuration
-------------------------------
Work in progress...

@ -0,0 +1,5 @@
RGBLIGHT_ENABLE = yes
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,108 @@
Hexwire's Let's Split Layout
============================
### Changes from default layout
- Main layer
- The right space bar key has been changed to backspace, as I only hit space with my left thumb
- Backtick is at the lower right and also serves goes to the 3rd function layer when held
- Enter key acts as shift when held
- Escape key acts as control when held
- Minus key at upper right
- Lower layer
- Numbers are on the lower layer, to make it easier to use a numpad on the right hand
- Arrow keys
- Straight and curly brackets in the middle two columns
- Screenshot keys for MacOS
- Upper layer
- Symbols are on the upper layer
- Media keys
- Page Up/Down, Home/End
- 3rd function layer
- Function keys
## Layouts
### Qwerty
```
,----+----+----+----+----+----. ,----+----+----+----+----+----.
TAB , Q , W , E , R , T , Y , U , I , O , P ,MINS,
|----+----+----+----+----+----| |----+----+----+----+----+----|
X0 , A , S , D , F , G , H , J , K , L ,SCLN,QUOT,
|----+----+----+----+----+----| |----+----+----+----+----+----|
LSFT, Z , X , C , V , B , N , M ,COMM,DOT ,SLSH, X4 ,
|----+----+----+----+----+----| |----+----+----+----+----+----|
X3 ,LCTL,LALT,LGUI, X1 ,SPC , BSPC, X2 ,LEFT,DOWN, UP ,RGHT
`----+----+----+----+----+----' `----+----+----+----+----+----'
```
### Colemak
```
,----+----+----+----+----+----. ,----+----+----+----+----+----.
TAB , Q , W , F , P , G , J , L , U , Y ,SCLN,MINS,
|----+----+----+----+----+----| |----+----+----+----+----+----|
X0 , A , R , S , T , D , H , N , E , I , O ,QUOT,
|----+----+----+----+----+----| |----+----+----+----+----+----|
LSFT, Z , X , C , V , B , K , M ,COMM,DOT ,SLSH, X4 ,
|----+----+----+----+----+----| |----+----+----+----+----+----|
X3 ,LCTL,LALT,LGUI, X1 ,SPC , BSPC, X2 ,LEFT,DOWN, UP ,RGHT
`----+----+----+----+----+----' `----+----+----+----+----+----'
```
### Dvorak
```
,----+----+----+----+----+----. ,----+----+----+----+----+----.
TAB ,QUOT,COMM,DOT , P , Y , F , G , C , R , L ,MINS,
|----+----+----+----+----+----| |----+----+----+----+----+----|
X0 , A , O , E , U , I , D , H , R , N , S ,SLSH,
|----+----+----+----+----+----| |----+----+----+----+----+----|
LSFT,SCLN, Q , J , K , X , B , M , W , V , Z , X4 ,
|----+----+----+----+----+----| |----+----+----+----+----+----|
X3 ,LCTL,LALT,LGUI, X1 ,SPC , BSPC, X2 ,LEFT,DOWN, UP ,RGHT
`----+----+----+----+----+----' `----+----+----+----+----+----'
```
### Lower
```
,----+----+----+----+----+----. ,----+----+----+----+----+----.
, 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 , ,
|----+----+----+----+----+----| |----+----+----+----+----+----|
DEL ,CAPP,LEFT,RGHT, UP ,LBRC, RBRC, P4 , P5 , P6 ,PLUS,PIPE,
|----+----+----+----+----+----| |----+----+----+----+----+----|
,CPYP, , ,DOWN,LCBR, RCBR, P1 , P2 , P3 ,MINS, ,
|----+----+----+----+----+----| |----+----+----+----+----+----|
, , , , , , DEL , , P0 ,PDOT, ,
`----+----+----+----+----+----' `----+----+----+----+----+----'
```
### Raise
```
,----+----+----+----+----+----. ,----+----+----+----+----+----.
,EXLM, AT ,HASH,DLR ,PERC, CIRC,AMPR,ASTR,LPRN,RPRN, ,
|----+----+----+----+----+----| |----+----+----+----+----+----|
DEL ,MPRV,MNXT,VOLU,PGUP,UNDS, EQL ,HOME, , , ,BSLS,
|----+----+----+----+----+----| |----+----+----+----+----+----|
MUTE,MSTP,MPLY,VOLD,PGDN,MINS, PLUS,END , , , , ,
|----+----+----+----+----+----| |----+----+----+----+----+----|
, , , , , , , , , , ,
`----+----+----+----+----+----' `----+----+----+----+----+----'
```
### 3rd function layer
```
,----+----+----+----+----+----. ,----+----+----+----+----+----.
F12 , F1 , F2 , F3 , F4 , F5 , F6 , F7 , F8 , F9 ,F10 ,F11 ,
|----+----+----+----+----+----| |----+----+----+----+----+----|
, , , , , , , , , , , ,
|----+----+----+----+----+----| |----+----+----+----+----+----|
, , , , , , , , , , , ,
|----+----+----+----+----+----| |----+----+----+----+----+----|
, , , , , , , , , , ,
`----+----+----+----+----+----' `----+----+----+----+----+----'
```

@ -0,0 +1,70 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define USE_SERIAL
#define TAPPING_TERM 150
#undef RGBLED_NUM
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 8
#define RGBLIGHT_HUE_STEP 8
#define RGBLIGHT_SAT_STEP 8
#define RGBLIGHT_VAL_STEP 8
#ifdef SUBPROJECT_rev1
#include "../../rev1/config.h"
#define COMPACT_KEYMAP( \
k00, k01, k02, k03, k04, k05, k40, k41, k42, k43, k44, k45, \
k10, k11, k12, k13, k14, k15, k50, k51, k52, k53, k54, k55, \
k20, k21, k22, k23, k24, k25, k60, k61, k62, k63, k64, k65, \
k30, k31, k32, k33, k34, k35, k70, k71, k72, k73, k74, k75 \
) \
{ \
{ KC_##k00, KC_##k01, KC_##k02, KC_##k03, KC_##k04, KC_##k05 }, \
{ KC_##k10, KC_##k11, KC_##k12, KC_##k13, KC_##k14, KC_##k15 }, \
{ KC_##k20, KC_##k21, KC_##k22, KC_##k23, KC_##k24, KC_##k25 }, \
{ KC_##k30, KC_##k31, KC_##k32, KC_##k33, KC_##k34, KC_##k35 }, \
{ KC_##k40, KC_##k41, KC_##k42, KC_##k43, KC_##k44, KC_##k45 }, \
{ KC_##k50, KC_##k51, KC_##k52, KC_##k53, KC_##k54, KC_##k55 }, \
{ KC_##k60, KC_##k61, KC_##k62, KC_##k63, KC_##k64, KC_##k65 }, \
{ KC_##k70, KC_##k71, KC_##k72, KC_##k73, KC_##k74, KC_##k75 } \
}
#endif
#ifdef SUBPROJECT_rev2
#include "../../rev2/config.h"
#define COMPACT_KEYMAP( \
k00, k01, k02, k03, k04, k05, k45, k44, k43, k42, k41, k40, \
k10, k11, k12, k13, k14, k15, k55, k54, k53, k52, k51, k50, \
k20, k21, k22, k23, k24, k25, k65, k64, k63, k62, k61, k60, \
k30, k31, k32, k33, k34, k35, k75, k74, k73, k72, k71, k70 \
) \
{ \
{ KC_##k00, KC_##k01, KC_##k02, KC_##k03, KC_##k04, KC_##k05 }, \
{ KC_##k10, KC_##k11, KC_##k12, KC_##k13, KC_##k14, KC_##k15 }, \
{ KC_##k20, KC_##k21, KC_##k22, KC_##k23, KC_##k24, KC_##k25 }, \
{ KC_##k30, KC_##k31, KC_##k32, KC_##k33, KC_##k34, KC_##k35 }, \
{ KC_##k40, KC_##k41, KC_##k42, KC_##k43, KC_##k44, KC_##k45 }, \
{ KC_##k50, KC_##k51, KC_##k52, KC_##k53, KC_##k54, KC_##k55 }, \
{ KC_##k60, KC_##k61, KC_##k62, KC_##k63, KC_##k64, KC_##k65 }, \
{ KC_##k70, KC_##k71, KC_##k72, KC_##k73, KC_##k74, KC_##k75 } \
}
#endif
#ifdef SUBPROJECT_rev2fliphalf
#include "../../rev2fliphalf/config.h"
#endif

@ -0,0 +1,205 @@
#include "lets_split.h"
#include "action_layer.h"
#include "eeconfig.h"
extern keymap_config_t keymap_config;
#define _QWERTY 0
#define _COLEMAK 1
#define _DVORAK 2
#define _LOWER 3
#define _RAISE 4
#define _FN3 5
#define _FN4 6
#define _ADJUST 16
enum custom_keycodes {
QWERTY = SAFE_RANGE,
COLEMAK,
DVORAK,
LOWER,
RAISE,
FN3,
FN4,
ADJUST,
};
#define KC_ KC_TRNS
#define _______ KC_TRNS
#define KC_CAPW LGUI(LSFT(KC_3)) // Capture whole screen
#define KC_CPYW LGUI(LSFT(LCTL(KC_3))) // Copy whole screen
#define KC_CAPP LGUI(LSFT(KC_4)) // Capture portion of screen
#define KC_CPYP LGUI(LSFT(LCTL(KC_4))) // Copy portion of screen
#define KC_X0 MT(MOD_LCTL, KC_ESC)
#define KC_X1 LOWER
#define KC_X2 RAISE
#define KC_X3 LT(_FN3, KC_GRV)
#define KC_X4 MT(MOD_LSFT, KC_ENT)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_QWERTY] = COMPACT_KEYMAP(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
TAB , Q , W , E , R , T , Y , U , I , O , P ,MINS,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
X0 , A , S , D , F , G , H , J , K , L ,SCLN,QUOT,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
LSFT, Z , X , C , V , B , N , M ,COMM,DOT ,SLSH, X4 ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
X3 ,LCTL,LALT,LGUI, X1 ,SPC , BSPC, X2 ,LEFT,DOWN, UP ,RGHT
//`----+----+----+----+----+----' `----+----+----+----+----+----'
),
[_COLEMAK] = COMPACT_KEYMAP(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
TAB , Q , W , F , P , G , J , L , U , Y ,SCLN,MINS,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
X0 , A , R , S , T , D , H , N , E , I , O ,QUOT,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
LSFT, Z , X , C , V , B , K , M ,COMM,DOT ,SLSH, X4 ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
X3 ,LCTL,LALT,LGUI, X1 ,SPC , BSPC, X2 ,LEFT,DOWN, UP ,RGHT
//`----+----+----+----+----+----' `----+----+----+----+----+----'
),
[_DVORAK] = COMPACT_KEYMAP(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
TAB ,QUOT,COMM,DOT , P , Y , F , G , C , R , L ,MINS,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
X0 , A , O , E , U , I , D , H , R , N , S ,SLSH,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
LSFT,SCLN, Q , J , K , X , B , M , W , V , Z , X4 ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
X3 ,LCTL,LALT,LGUI, X1 ,SPC , BSPC, X2 ,LEFT,DOWN, UP ,RGHT
//`----+----+----+----+----+----' `----+----+----+----+----+----'
),
[_LOWER] = COMPACT_KEYMAP(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
, 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 , ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
DEL ,CAPP,LEFT,RGHT, UP ,LBRC, RBRC, P4 , P5 , P6 ,PLUS,PIPE,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
,CPYP, , ,DOWN,LCBR, RCBR, P1 , P2 , P3 ,MINS, ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
, , , , , , DEL , , P0 ,PDOT, ,
//`----+----+----+----+----+----' `----+----+----+----+----+----'
),
[_RAISE] = COMPACT_KEYMAP(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
,EXLM, AT ,HASH,DLR ,PERC, CIRC,AMPR,ASTR,LPRN,RPRN, ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
DEL ,MPRV,MNXT,VOLU,PGUP,UNDS, EQL ,HOME, , , ,BSLS,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
MUTE,MSTP,MPLY,VOLD,PGDN,MINS, PLUS,END , , , , ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
, , , , , , , , , , ,
//`----+----+----+----+----+----' `----+----+----+----+----+----'
),
[_FN3] = COMPACT_KEYMAP(
//,----+----+----+----+----+----. ,----+----+----+----+----+----.
F12 , F1 , F2 , F3 , F4 , F5 , F6 , F7 , F8 , F9 ,F10 ,F11 ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
, , , , , , , , , , , ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
, , , , , , , , , , , ,
//|----+----+----+----+----+----| |----+----+----+----+----+----|
, , , , , , , , , , ,
//`----+----+----+----+----+----' `----+----+----+----+----+----'
),
/* Adjust (Lower + Raise)
* ,-----------------------------------------------------------------------------------.
* | | Reset|RGB Tg|RGB Md|Hue Up|Hue Dn|Sat Up|Sat Dn|Val Up|Val Dn| | |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak| | |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | | | | | | | | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_ADJUST] = KEYMAP( \
_______, RESET , RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, _______, _______, \
_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
)
};
#ifdef AUDIO_ENABLE
float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_dvorak[][2] = SONG(DVORAK_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
#endif
void persistant_default_layer_set(uint16_t default_layer) {
eeconfig_update_default_layer(default_layer);
default_layer_set(default_layer);
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case QWERTY:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
#endif
persistant_default_layer_set(1UL<<_QWERTY);
}
return false;
break;
case COLEMAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
persistant_default_layer_set(1UL<<_COLEMAK);
}
return false;
break;
case DVORAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
#endif
persistant_default_layer_set(1UL<<_DVORAK);
}
return false;
break;
case LOWER:
if (record->event.pressed) {
layer_on(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case RAISE:
if (record->event.pressed) {
layer_on(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case ADJUST:
if (record->event.pressed) {
layer_on(_ADJUST);
} else {
layer_off(_ADJUST);
}
return false;
break;
}
return true;
}

@ -0,0 +1,34 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define USE_SERIAL
#define MASTER_LEFT
// #define _MASTER_RIGHT
// #define EE_HANDS
#ifdef SUBPROJECT_rev1
#include "../../rev1/config.h"
#endif
#ifdef SUBPROJECT_rev2
#include "../../rev2/config.h"
#endif
#ifdef SUBPROJECT_rev2fliphalf
#include "../../rev2fliphalf/config.h"
#endif

@ -0,0 +1,219 @@
#include "lets_split.h"
#include "action_layer.h"
#include "eeconfig.h"
extern keymap_config_t keymap_config;
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _QWERTY 0
#define _COLEMAK 1
#define _DVORAK 2
#define _LOWER 3
#define _RAISE 4
#define _ADJUST 16
enum custom_keycodes {
QWERTY = SAFE_RANGE,
COLEMAK,
DVORAK,
LOWER,
RAISE,
ADJUST,
};
// Fillers to make layering more clear
#define _______ KC_TRNS
#define XXXXXXX KC_NO
// Custom macros
#define CTL_ESC CTL_T(KC_ESC) // Tap for Esc, hold for Ctrl
#define SFT_ENT SFT_T(KC_ENT) // Tap for Enter, hold for Shift
#define HPR_TAB ALL_T(KC_TAB) // Tap for Tab, hold for Hyper (Super+Ctrl+Alt+Shift)
#define MEH_GRV MEH_T(KC_GRV) // Tap for Backtick, hold for Meh (Ctrl+Alt+Shift)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Qwerty
* ,-----------------------------------------. ,-----------------------------------------.
* | Tab | Q | W | E | R | T | | Y | U | I | O | P | Bksp |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | Esc | A | S | D | F | G | | H | J | K | L | ; | " |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | | N | M | , | . | / |Enter |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | ` | Ctrl | Alt | GUI |Lower |Space | |Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------' `-----------------------------------------'
*/
[_QWERTY] = KEYMAP( \
HPR_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \
CTL_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, SFT_ENT, \
MEH_GRV, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT
),
/* Colemak
* ,-----------------------------------------. ,-----------------------------------------.
* | Tab | Q | W | F | P | G | | J | L | U | Y | ; | Bksp |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | Esc | A | R | S | T | D | | H | N | E | I | O | " |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | | K | M | , | . | / |Enter |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | ` | Ctrl | Alt | GUI |Lower |Space | |Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------' `-----------------------------------------'
*/
[_COLEMAK] = KEYMAP( \
HPR_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, \
CTL_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, SFT_ENT, \
MEH_GRV, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT
),
/* Dvorak
* ,-----------------------------------------. ,-----------------------------------------.
* | Tab | " | , | . | P | Y | | F | G | C | R | L | Bksp |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | Esc | A | O | E | U | I | | D | H | T | N | S | - |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | Shift| ; | Q | J | K | X | | B | M | W | V | Z |Enter |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | ` | Ctrl | Alt | GUI |Lower |Space | |Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------' `-----------------------------------------'
*/
[_DVORAK] = KEYMAP( \
HPR_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC, \
CTL_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_MINS, \
KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, SFT_ENT, \
MEH_GRV, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT
),
/* Lower
* ,-----------------------------------------. ,-----------------------------------------.
* | 0 | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Del |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | $ | F1 | F2 | F3 | F4 | F5 | | F6 | 4 | 5 | 6 | | |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | | F7 | F8 | F9 | F10 | F11 | | F12 | 1 | 2 | 3 | | |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | | | | | | | | | | Next | Vol- | Vol+ | Play |
* `-----------------------------------------' `-----------------------------------------'
*/
[_LOWER] = KEYMAP( \
ALL_T(KC_0), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, \
CTL_T(KC_DLR), KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_4, KC_5, KC_6, _______, _______, \
_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_1, KC_2, KC_3, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY
),
/* Raise
* ,-----------------------------------------. ,-----------------------------------------.
* | ~ | ! | @ | # | $ | % | | ^ | & | * | ( | ) | Del |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | | | | | | | | _ | ? | + | { | } | | |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | | | | | | | | - | / | = | [ | ] | \ |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | | | | | | | | | | Home |PageDn|PageUp| End |
* `-----------------------------------------' `-----------------------------------------'
*/
[_RAISE] = KEYMAP( \
ALL_T(KC_TILD), KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL, \
_______, _______, _______, _______, _______, _______, KC_UNDS, KC_QUES, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, \
_______, _______, _______, _______, _______, _______, KC_MINS, KC_SLSH, KC_EQL, KC_LBRC, KC_RBRC, SFT_T(KC_BSLS), \
_______, _______, _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END
),
/* Adjust (Lower + Raise)
* ,-----------------------------------------. ,-----------------------------------------.
* | | Reset| | | | | | | | | | | Reset|
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | | | |Aud on|Audoff|AGnorm| |AGswap|Qwerty|Colemk|Dvorak| | |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | | | | | | | | | | | | | |
* |------+------+------+------+------+------| |------+------+------+------+------+------|
* | | | | | | | | | | | | | |
* `-----------------------------------------' `-----------------------------------------'
*/
[_ADJUST] = KEYMAP( \
_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET, \
_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
)
};
#ifdef AUDIO_ENABLE
float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_dvorak[][2] = SONG(DVORAK_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
#endif
void persistant_default_layer_set(uint16_t default_layer) {
eeconfig_update_default_layer(default_layer);
default_layer_set(default_layer);
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case QWERTY:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
#endif
persistant_default_layer_set(1UL<<_QWERTY);
}
return false;
break;
case COLEMAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
persistant_default_layer_set(1UL<<_COLEMAK);
}
return false;
break;
case DVORAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
#endif
persistant_default_layer_set(1UL<<_DVORAK);
}
return false;
break;
case LOWER:
if (record->event.pressed) {
layer_on(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case RAISE:
if (record->event.pressed) {
layer_on(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case ADJUST:
if (record->event.pressed) {
layer_on(_ADJUST);
} else {
layer_off(_ADJUST);
}
return false;
break;
}
return true;
}

@ -0,0 +1,88 @@
# smt's Let's Split keymap
This keymap is ported from my Planck keymap.
## Qwerty
```
,-----------------------------------------. ,-----------------------------------------.
| Tab | Q | W | E | R | T | | Y | U | I | O | P | Bksp |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| Esc | A | S | D | F | G | | H | J | K | L | ; | " |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| Shift| Z | X | C | V | B | | N | M | , | . | / |Enter |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| ` | Ctrl | Alt | GUI |Lower |Space | |Space |Raise | Left | Down | Up |Right |
`-----------------------------------------' `-----------------------------------------'
```
## Colemak
```
,-----------------------------------------. ,-----------------------------------------.
| Tab | Q | W | F | P | G | | J | L | U | Y | ; | Bksp |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| Esc | A | R | S | T | D | | H | N | E | I | O | " |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| Shift| Z | X | C | V | B | | K | M | , | . | / |Enter |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| ` | Ctrl | Alt | GUI |Lower |Space | |Space |Raise | Left | Down | Up |Right |
`-----------------------------------------' `-----------------------------------------'
```
## Dvorak
```
,-----------------------------------------. ,-----------------------------------------.
| Tab | " | , | . | P | Y | | F | G | C | R | L | Bksp |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| Esc | A | O | E | U | I | | D | H | T | N | S | - |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| Shift| ; | Q | J | K | X | | B | M | W | V | Z |Enter |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| ` | Ctrl | Alt | GUI |Lower |Space | |Space |Raise | Left | Down | Up |Right |
`-----------------------------------------' `-----------------------------------------'
```
## Lower
```
,-----------------------------------------. ,-----------------------------------------.
| 0 | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Del |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| $ | F1 | F2 | F3 | F4 | F5 | | F6 | 4 | 5 | 6 | | |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| | F7 | F8 | F9 | F10 | F11 | | F12 | 1 | 2 | 3 | | |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| | | | | | | | | | Next | Vol- | Vol+ | Play |
`-----------------------------------------' `-----------------------------------------'
```
## Raise
```
,-----------------------------------------. ,-----------------------------------------.
| ~ | ! | @ | # | $ | % | | ^ | & | * | ( | ) | Del |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| | | | | | | | _ | ? | + | { | } | | |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| | | | | | | | - | / | = | [ | ] | \ |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| | | | | | | | | | Home |PageDn|PageUp| End |
`-----------------------------------------' `-----------------------------------------'
```
## Adjust (Lower + Raise)
```
,-----------------------------------------. ,-----------------------------------------.
| | Reset| | | | | | | | | | | Reset|
|------+------+------+------+------+------| |------+------+------+------+------+------|
| | | |Aud on|Audoff|AGnorm| |AGswap|Qwerty|Colemk|Dvorak| | |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| | | | | | | | | | | | | |
|------+------+------+------+------+------| |------+------+------+------+------+------|
| | | | | | | | | | | | | |
`-----------------------------------------' `-----------------------------------------'
```

@ -226,9 +226,7 @@ uint8_t matrix_scan(void)
TXLED0;
error_count = 0;
}
matrix_scan_quantum();
return ret;
}

@ -63,6 +63,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/* ws2812 RGB LED */
#define RGB_DI_PIN D3
#define RGBLIGHT_TIMER
#define RGBLED_NUM 16 // Number of LEDs
#define ws2812_PORTREG PORTD
#define ws2812_DDRREG DDRD
/*
* Feature disable options
* These options are also useful to firmware size reduction.

@ -5,6 +5,13 @@
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
#endif
#ifdef SSD1306OLED
void led_set_kb(uint8_t usb_led) {
// put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
led_set_user(usb_led);
}
#endif
void matrix_init_kb(void) {
#ifdef AUDIO_ENABLE
@ -30,3 +37,4 @@ void shutdown_user(void) {
stop_all_notes();
#endif
}

@ -6,23 +6,66 @@
//void promicro_bootloader_jmp(bool program);
#include "quantum.h"
#ifdef USE_I2C
#include <stddef.h>
#ifdef __AVR__
#include <avr/io.h>
#include <avr/interrupt.h>
#endif
#ifdef SSD1306OLED
extern bool iota_gfx_init(void);
extern void iota_gfx_task(void);
extern bool iota_gfx_off(void);
extern bool iota_gfx_on(void);
extern void iota_gfx_flush(void);
extern void iota_gfx_write_char(uint8_t c);
extern void iota_gfx_write(const char *data);
extern void iota_gfx_write_P(const char *data);
extern void iota_gfx_clear_screen(void);
#endif
#endif
//void promicro_bootloader_jmp(bool program);
#ifndef FLIP_HALF
//Standard Keymap
#define KEYMAP( \
k00, k01, k02, k03, k04, k05, k45, k44, k43, k42, k41, k40, \
k10, k11, k12, k13, k14, k15, k55, k54, k53, k52, k51, k50, \
k20, k21, k22, k23, k24, k25, k65, k64, k63, k62, k61, k60, \
k30, k31, k32, k33, k34, k35, k75, k74, k73, k72, k71, k70 \
k40, k41, k42, k43, k44, k45, k05, k04, k03, k02, k01, k00, \
k50, k51, k52, k53, k54, k55, k15, k14, k13, k12, k11, k10, \
k60, k61, k62, k63, k64, k65, k25, k24, k23, k22, k21, k20, \
k70, k71, k72, k73, k74, k75, k35, k34, k33, k32, k31, k30 \
) \
{ \
{ k45, k44, k43, k42, k41, k40 }, \
{ k55, k54, k53, k52, k51, k50 }, \
{ k65, k64, k63, k62, k61, k60 }, \
{ k75, k74, k73, k72, k71, k70 }, \
{ k00, k01, k02, k03, k04, k05 }, \
{ k10, k11, k12, k13, k14, k15 }, \
{ k20, k21, k22, k23, k24, k25 }, \
{ k30, k31, k32, k33, k34, k35 } \
}
#else
// Keymap with one side flipped
#define KEYMAP( \
k00, k01, k02, k03, k04, k05, k40, k41, k42, k43, k44, k45, \
k10, k11, k12, k13, k14, k15, k50, k51, k52, k53, k54, k55, \
k20, k21, k22, k23, k24, k25, k60, k61, k62, k63, k64, k65, \
k30, k31, k32, k33, k34, k35, k70, k71, k72, k73, k74, k75 \
) \
{ \
{ k00, k01, k02, k03, k04, k05 }, \
{ k10, k11, k12, k13, k14, k15 }, \
{ k20, k21, k22, k23, k24, k25 }, \
{ k30, k31, k32, k33, k34, k35 }, \
{ k40, k41, k42, k43, k44, k45 }, \
{ k50, k51, k52, k53, k54, k55 }, \
{ k60, k61, k62, k63, k64, k65 }, \
{ k70, k71, k72, k73, k74, k75 } \
{ k45, k44, k43, k42, k41, k40 }, \
{ k55, k54, k53, k52, k51, k50 }, \
{ k65, k64, k63, k62, k61, k60 }, \
{ k75, k74, k73, k72, k71, k70 } \
}
#endif
#endif

@ -1,32 +0,0 @@
#include "lets_split.h"
#ifdef AUDIO_ENABLE
float tone_startup[][2] = SONG(STARTUP_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
#endif
void matrix_init_kb(void) {
#ifdef AUDIO_ENABLE
_delay_ms(20); // gets rid of tick
PLAY_NOTE_ARRAY(tone_startup, false, 0);
#endif
// // green led on
// DDRD |= (1<<5);
// PORTD &= ~(1<<5);
// // orange led on
// DDRB |= (1<<0);
// PORTB &= ~(1<<0);
matrix_init_user();
};
void shutdown_user(void) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
_delay_ms(150);
stop_all_notes();
#endif
}

@ -1,28 +0,0 @@
#ifndef REV2FLIPHALF_H
#define REV2FLIPHALF_H
#include "../lets_split.h"
//void promicro_bootloader_jmp(bool program);
#include "quantum.h"
//void promicro_bootloader_jmp(bool program);
#define KEYMAP( \
k00, k01, k02, k03, k04, k05, k40, k41, k42, k43, k44, k45, \
k10, k11, k12, k13, k14, k15, k50, k51, k52, k53, k54, k55, \
k20, k21, k22, k23, k24, k25, k60, k61, k62, k63, k64, k65, \
k30, k31, k32, k33, k34, k35, k70, k71, k72, k73, k74, k75 \
) \
{ \
{ k00, k01, k02, k03, k04, k05 }, \
{ k10, k11, k12, k13, k14, k15 }, \
{ k20, k21, k22, k23, k24, k25 }, \
{ k30, k31, k32, k33, k34, k35 }, \
{ k40, k41, k42, k43, k44, k45 }, \
{ k50, k51, k52, k53, k54, k55 }, \
{ k60, k61, k62, k63, k64, k65 }, \
{ k70, k71, k72, k73, k74, k75 } \
}
#endif

@ -1,5 +0,0 @@
BACKLIGHT_ENABLE = no
ifndef QUANTUM_DIR
include ../../../Makefile
endif

@ -1,7 +1,8 @@
SRC += matrix.c \
i2c.c \
split_util.c \
serial.c
serial.c\
ssd1306.c
# MCU name
#MCU = at90usb1287
@ -73,15 +74,3 @@ USE_I2C ?= yes
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
CUSTOM_MATRIX = yes
avrdude: build
ls /dev/tty* > /tmp/1; \
echo "Reset your Pro Micro now"; \
while [[ -z $$USB ]]; do \
sleep 1; \
ls /dev/tty* > /tmp/2; \
USB=`diff /tmp/1 /tmp/2 | grep -o '/dev/tty.*'`; \
done; \
avrdude -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex
.PHONY: avrdude

@ -21,7 +21,7 @@ static void setup_handedness(void) {
#ifdef EE_HANDS
isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS);
#else
// I2C_MASTER_RIGHT is deprecated use MASTER_RIGHT instead since this works for both serial and i2c
// I2c_MASTER_RIGHT ish deprecate use MASTER_RIGHT instead since this works for both serial and i2c:
#if defined(I2C_MASTER_RIGHT) || defined(MASTER_RIGHT)
isLeftHand = !has_usb();
#else
@ -33,6 +33,9 @@ static void setup_handedness(void) {
static void keyboard_master_setup(void) {
#ifdef USE_I2C
i2c_master_init();
#ifdef SSD1306OLED
matrix_master_OLED_init ();
#endif
#else
serial_master_init();
#endif

@ -19,4 +19,6 @@ void split_keyboard_setup(void);
bool has_usb(void);
void keyboard_slave_loop(void);
void matrix_master_OLED_init (void);
#endif

@ -0,0 +1,468 @@
#include "config.h"
#include "i2c.h"
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include "print.h"
#include "lets_split.h"
#include "common/glcdfont.c"
#ifdef ADAFRUIT_BLE_ENABLE
#include "adafruit_ble.h"
#endif
#ifdef PROTOCOL_LUFA
#include "lufa.h"
#endif
#include "sendchar.h"
#include "pincontrol.h"
//assign the right code to your layers
#define _BASE 0
#define _LOWER 8
#define _RAISE 16
#define _FNLAYER 64
#define _NUMLAY 128
#define _NLOWER 136
#define _NFNLAYER 192
#define _MOUSECURSOR 256
#define _ADJUST 65560
// Set this to 1 to help diagnose early startup problems
// when testing power-on with ble. Turn it off otherwise,
// as the latency of printing most of the debug info messes
// with the matrix scan, causing keys to drop.
#define DEBUG_TO_SCREEN 0
// Controls the SSD1306 128x32 OLED display via i2c
#define i2cAddress 0x3C
#define DisplayHeight 32
#define DisplayWidth 128
#define FontHeight 8
#define FontWidth 6
#define MatrixRows (DisplayHeight / FontHeight)
#define MatrixCols (DisplayWidth / FontWidth)
struct CharacterMatrix {
uint8_t display[MatrixRows][MatrixCols];
uint8_t *cursor;
bool dirty;
};
static struct CharacterMatrix display;
//static uint16_t last_battery_update;
//static uint32_t vbat;
//#define BatteryUpdateInterval 10000 /* milliseconds */
#define ScreenOffInterval 300000 /* milliseconds */
#if DEBUG_TO_SCREEN
static uint8_t displaying;
#endif
static uint16_t last_flush;
enum ssd1306_cmds {
DisplayOff = 0xAE,
DisplayOn = 0xAF,
SetContrast = 0x81,
DisplayAllOnResume = 0xA4,
DisplayAllOn = 0xA5,
NormalDisplay = 0xA6,
InvertDisplay = 0xA7,
SetDisplayOffset = 0xD3,
SetComPins = 0xda,
SetVComDetect = 0xdb,
SetDisplayClockDiv = 0xD5,
SetPreCharge = 0xd9,
SetMultiPlex = 0xa8,
SetLowColumn = 0x00,
SetHighColumn = 0x10,
SetStartLine = 0x40,
SetMemoryMode = 0x20,
ColumnAddr = 0x21,
PageAddr = 0x22,
ComScanInc = 0xc0,
ComScanDec = 0xc8,
SegRemap = 0xa0,
SetChargePump = 0x8d,
ExternalVcc = 0x01,
SwitchCapVcc = 0x02,
ActivateScroll = 0x2f,
DeActivateScroll = 0x2e,
SetVerticalScrollArea = 0xa3,
RightHorizontalScroll = 0x26,
LeftHorizontalScroll = 0x27,
VerticalAndRightHorizontalScroll = 0x29,
VerticalAndLeftHorizontalScroll = 0x2a,
};
// Write command sequence.
// Returns true on success.
static inline bool _send_cmd1(uint8_t cmd) {
bool res = false;
if (i2c_start_write(i2cAddress)) {
xprintf("failed to start write to %d\n", i2cAddress);
goto done;
}
if (i2c_master_write(0x0 /* command byte follows */)) {
print("failed to write control byte\n");
goto done;
}
if (i2c_master_write(cmd)) {
xprintf("failed to write command %d\n", cmd);
goto done;
}
res = true;
done:
i2c_master_stop();
return res;
}
// Write 2-byte command sequence.
// Returns true on success
static inline bool _send_cmd2(uint8_t cmd, uint8_t opr) {
if (!_send_cmd1(cmd)) {
return false;
}
return _send_cmd1(opr);
}
// Write 3-byte command sequence.
// Returns true on success
static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) {
if (!_send_cmd1(cmd)) {
return false;
}
if (!_send_cmd1(opr1)) {
return false;
}
return _send_cmd1(opr2);
}
#define send_cmd1(c) if (!_send_cmd1(c)) {goto done;}
#define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;}
#define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;}
static void matrix_clear(struct CharacterMatrix *matrix);
static void clear_display(void) {
matrix_clear(&display);
// Clear all of the display bits (there can be random noise
// in the RAM on startup)
send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1);
send_cmd3(ColumnAddr, 0, DisplayWidth - 1);
if (i2c_start_write(i2cAddress)) {
goto done;
}
if (i2c_master_write(0x40)) {
// Data mode
goto done;
}
for (uint8_t row = 0; row < MatrixRows; ++row) {
for (uint8_t col = 0; col < DisplayWidth; ++col) {
i2c_master_write(0);
}
}
display.dirty = false;
done:
i2c_master_stop();
}
#if DEBUG_TO_SCREEN
#undef sendchar
static int8_t capture_sendchar(uint8_t c) {
sendchar(c);
iota_gfx_write_char(c);
if (!displaying) {
iota_gfx_flush();
}
return 0;
}
#endif
bool iota_gfx_init(void) {
bool success = false;
send_cmd1(DisplayOff);
send_cmd2(SetDisplayClockDiv, 0x80);
send_cmd2(SetMultiPlex, DisplayHeight - 1);
send_cmd2(SetDisplayOffset, 0);
send_cmd1(SetStartLine | 0x0);
send_cmd2(SetChargePump, 0x14 /* Enable */);
send_cmd2(SetMemoryMode, 0 /* horizontal addressing */);
/// Flips the display orientation 0 degrees
send_cmd1(SegRemap | 0x1);
send_cmd1(ComScanDec);
/*
// the following Flip the display orientation 180 degrees
send_cmd1(SegRemap);
send_cmd1(ComScanInc);
// end flip */
send_cmd2(SetComPins, 0x2);
send_cmd2(SetContrast, 0x8f);
send_cmd2(SetPreCharge, 0xf1);
send_cmd2(SetVComDetect, 0x40);
send_cmd1(DisplayAllOnResume);
send_cmd1(NormalDisplay);
send_cmd1(DeActivateScroll);
send_cmd1(DisplayOn);
send_cmd2(SetContrast, 0); // Dim
clear_display();
success = true;
iota_gfx_flush();
#if DEBUG_TO_SCREEN
print_set_sendchar(capture_sendchar);
#endif
done:
return success;
}
bool iota_gfx_off(void) {
bool success = false;
send_cmd1(DisplayOff);
success = true;
done:
return success;
}
bool iota_gfx_on(void) {
bool success = false;
send_cmd1(DisplayOn);
success = true;
done:
return success;
}
static void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) {
*matrix->cursor = c;
++matrix->cursor;
if (matrix->cursor - &matrix->display[0][0] == sizeof(matrix->display)) {
// We went off the end; scroll the display upwards by one line
memmove(&matrix->display[0], &matrix->display[1],
MatrixCols * (MatrixRows - 1));
matrix->cursor = &matrix->display[MatrixRows - 1][0];
memset(matrix->cursor, ' ', MatrixCols);
}
}
static void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) {
matrix->dirty = true;
if (c == '\n') {
// Clear to end of line from the cursor and then move to the
// start of the next line
uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols;
while (cursor_col++ < MatrixCols) {
matrix_write_char_inner(matrix, ' ');
}
return;
}
matrix_write_char_inner(matrix, c);
}
void iota_gfx_write_char(uint8_t c) {
matrix_write_char(&display, c);
}
static void matrix_write(struct CharacterMatrix *matrix, const char *data) {
const char *end = data + strlen(data);
while (data < end) {
matrix_write_char(matrix, *data);
++data;
}
}
void iota_gfx_write(const char *data) {
matrix_write(&display, data);
}
static void matrix_write_P(struct CharacterMatrix *matrix, const char *data) {
while (true) {
uint8_t c = pgm_read_byte(data);
if (c == 0) {
return;
}
matrix_write_char(matrix, c);
++data;
}
}
void iota_gfx_write_P(const char *data) {
matrix_write_P(&display, data);
}
static void matrix_clear(struct CharacterMatrix *matrix) {
memset(matrix->display, ' ', sizeof(matrix->display));
matrix->cursor = &matrix->display[0][0];
matrix->dirty = true;
}
void iota_gfx_clear_screen(void) {
matrix_clear(&display);
}
static void matrix_render(struct CharacterMatrix *matrix) {
last_flush = timer_read();
iota_gfx_on();
#if DEBUG_TO_SCREEN
++displaying;
#endif
// Move to the home position
send_cmd3(PageAddr, 0, MatrixRows - 1);
send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1);
if (i2c_start_write(i2cAddress)) {
goto done;
}
if (i2c_master_write(0x40)) {
// Data mode
goto done;
}
for (uint8_t row = 0; row < MatrixRows; ++row) {
for (uint8_t col = 0; col < MatrixCols; ++col) {
const uint8_t *glyph = font + (matrix->display[row][col] * (FontWidth - 1));
for (uint8_t glyphCol = 0; glyphCol < FontWidth - 1; ++glyphCol) {
uint8_t colBits = pgm_read_byte(glyph + glyphCol);
i2c_master_write(colBits);
}
// 1 column of space between chars (it's not included in the glyph)
i2c_master_write(0);
}
}
matrix->dirty = false;
done:
i2c_master_stop();
#if DEBUG_TO_SCREEN
--displaying;
#endif
}
void iota_gfx_flush(void) {
matrix_render(&display);
}
static void matrix_update(struct CharacterMatrix *dest,
const struct CharacterMatrix *source) {
if (memcmp(dest->display, source->display, sizeof(dest->display))) {
memcpy(dest->display, source->display, sizeof(dest->display));
dest->dirty = true;
}
}
static void render_status_info(void) {
#if DEBUG_TO_SCREEN
if (debug_enable) {
return;
}
#endif
struct CharacterMatrix matrix;
matrix_clear(&matrix);
matrix_write_P(&matrix, PSTR("USB: "));
#ifdef PROTOCOL_LUFA
switch (USB_DeviceState) {
case DEVICE_STATE_Unattached:
matrix_write_P(&matrix, PSTR("Unattached"));
break;
case DEVICE_STATE_Suspended:
matrix_write_P(&matrix, PSTR("Suspended"));
break;
case DEVICE_STATE_Configured:
matrix_write_P(&matrix, PSTR("Connected"));
break;
case DEVICE_STATE_Powered:
matrix_write_P(&matrix, PSTR("Powered"));
break;
case DEVICE_STATE_Default:
matrix_write_P(&matrix, PSTR("Default"));
break;
case DEVICE_STATE_Addressed:
matrix_write_P(&matrix, PSTR("Addressed"));
break;
default:
matrix_write_P(&matrix, PSTR("Invalid"));
}
#endif
// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
char buf[40];
snprintf(buf,sizeof(buf), "Undef-%ld", layer_state);
matrix_write_P(&matrix, PSTR("\n\nLayer: "));
switch (layer_state) {
case _BASE:
matrix_write_P(&matrix, PSTR("Default"));
break;
case _RAISE:
matrix_write_P(&matrix, PSTR("Raise"));
break;
case _LOWER:
matrix_write_P(&matrix, PSTR("Lower"));
break;
case _ADJUST:
matrix_write_P(&matrix, PSTR("ADJUST"));
break;
default:
matrix_write(&matrix, buf);
}
// Host Keyboard LED Status
char led[40];
snprintf(led, sizeof(led), "\n%s %s %s",
(host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) ? "NUMLOCK" : " ",
(host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) ? "CAPS" : " ",
(host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) ? "SCLK" : " ");
matrix_write(&matrix, led);
matrix_update(&display, &matrix);
}
void iota_gfx_task(void) {
render_status_info();
if (display.dirty) {
iota_gfx_flush();
}
if (timer_elapsed(last_flush) > ScreenOffInterval) {
iota_gfx_off();
}
}

@ -48,19 +48,19 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* MOVE
* ,-----------------------------------------------------------------------------------.
* | H(3) | H(F1)| H(F2)| H(F3)| H(F4)| H(F5)| H(8) | Home | Up | End | H(7) | Esc |
* | H(F7)| H(F8)| H(6) | H(5) | H(4) | H(F9)|H(F10)| Home | Up | End | H(A) | Esc |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | H(4) | H(F6)| H(F7)| H(F8)| H(F9)|H(F10)| H(9) | Left | Down | Right| Caps | Del |
* | H(F3)| H(F4)| H(3) | H(2) | H(1) | H(F5)| H(F6)| Left | Down | Right| Caps | Del |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | |H(F11)|H(F12)| H(0) | H(1) | H(2) | H(A) | Pg Dn| Pg Up| H(5) | H(6) | |
* | | H(0) | H(9) | H(8) | H(7) | H(F1)| H(F2)| Pg Dn| Pg Up|H(F11)|H(F12)| |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_MOVE] = {
{H(KC_3), H(KC_F1),H(KC_F2),H(KC_F3),H(KC_F4),H(KC_F5),H(KC_8), KC_HOME, KC_UP, KC_END, H(KC_7), KC_ESC },
{H(KC_4), H(KC_F6),H(KC_F7),H(KC_F8),H(KC_F9),H(KC_F10),H(KC_9),KC_LEFT, KC_DOWN, KC_RGHT, KC_CAPS, KC_DEL },
{_______, H(KC_F11),H(KC_F12),H(KC_0),H(KC_1),H(KC_2), H(KC_A), KC_PGDN, KC_PGUP, H(KC_5), H(KC_6), _______},
{H(KC_F7),H(KC_F8),H(KC_6), H(KC_5), H(KC_4), H(KC_F9),H(KC_F10),KC_HOME,KC_UP, KC_END, H(KC_A), KC_ESC },
{H(KC_F3),H(KC_F4),H(KC_3), H(KC_2), H(KC_1), H(KC_F5),H(KC_F6),KC_LEFT, KC_DOWN, KC_RGHT, KC_CAPS, KC_DEL },
{_______, H(KC_0), H(KC_9), H(KC_8), H(KC_7), H(KC_F1),H(KC_F2),KC_PGDN,KC_PGUP,H(KC_F11),H(KC_F12),_______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
},

@ -0,0 +1,29 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -0,0 +1,29 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -14,4 +14,27 @@
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -0,0 +1,29 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -0,0 +1,29 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -6,4 +6,27 @@
#define FORCE_NKRO
#define WORKMAN_SOUND COLEMAK_SOUND
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -0,0 +1,4 @@
TAP_DANCE_ENABLE = yes
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -22,23 +22,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x3060
#define DEVICE_VER 0x0001
#define MANUFACTURER Wootpatoot
#define PRODUCT Lets Split v2
#define DESCRIPTION A split keyboard for the cheap makers
#define PRODUCT_ID 0x6060
#define MANUFACTURER Ortholinear Keyboards
#define PRODUCT The Planck Keyboard
#define DESCRIPTION A compact ortholinear keyboard
/* key matrix size */
// Rows are doubled-up
#define MATRIX_ROWS 8
#define MATRIX_COLS 6
#define MATRIX_ROWS 4
#define MATRIX_COLS 12
// wiring of each half
#define MATRIX_ROW_PINS { D7, E6, B4, B5 }
//#define MATRIX_COL_PINS { F6, F7, B1, B3, B2, B6 }
#define MATRIX_COL_PINS { B6, B2, B3, B1, F7, F6 } //uncomment this line and comment line above if you need to reverse left-to-right key order
/* Planck PCB default pin-out */
#define MATRIX_ROW_PINS { D0, D5, B5, B6 }
#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }
#define UNUSED_PINS
//#define CATERINA_BOOTLOADER
#define AUDIO_VOICES
#define BACKLIGHT_PIN B7
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
@ -47,7 +47,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
//#define MATRIX_HAS_GHOST
/* number of backlight levels */
// #define BACKLIGHT_LEVELS 3
#define BACKLIGHT_LEVELS 3
/* Set 0 if debouncing isn't needed */
#define DEBOUNCING_DELAY 5
@ -62,12 +62,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/* ws2812 RGB LED */
#define RGB_DI_PIN D3
#define RGBLIGHT_TIMER
#define RGBLED_NUM 12 // Number of LEDs
#define ws2812_PORTREG PORTD
#define ws2812_DDRREG DDRD
/* Tap Dance */
#define TAPPING_TERM 150
/*
* Feature disable options
@ -75,10 +71,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* disable debug print */
// #define NO_DEBUG
//#define NO_DEBUG
/* disable print */
// #define NO_PRINT
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
@ -87,5 +83,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#ifdef SUBPROJECT_rev3
#include "rev3/config.h"
#endif
#ifdef SUBPROJECT_rev4
#include "rev4/config.h"
#endif
#endif
#endif

@ -0,0 +1,336 @@
// This is the canonical layout file for the Quantum project. If you want to add another keyboard,
// this is the style you want to emulate.
#include "planck.h"
#include "action_layer.h"
#ifdef AUDIO_ENABLE
#include "audio.h"
#endif
#include "eeconfig.h"
extern keymap_config_t keymap_config;
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _QWERTY 0
#define _COLEMAK 1
#define _DVORAK 2
#define _LOWER 3
#define _RAISE 4
#define _PLOVER 5
#define _ADJUST 16
enum planck_keycodes {
QWERTY = SAFE_RANGE,
COLEMAK,
DVORAK,
PLOVER,
LOWER,
RAISE,
BACKLIT,
EXT_PLV
};
// Fillers to make layering more clear
#define _______ KC_TRNS
#define XXXXXXX KC_NO
// Tap Dance Declarations
enum {
ESC_CAP = 0,
LFT_HOM,
DWN_PDN,
UPP_PUP,
RGT_END
};
// Dylan's additions
#define C_A_DEL LALT(LCTL(KC_DEL))
#define C_A_INS LALT(LCTL(KC_INS))
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Qwerty
* ,-----------------------------------------------------------------------------------.
* | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | S | D | F | G | H | J | K | L | ; | " |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_QWERTY] = {
{KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC },
{TD(ESC_CAP), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT },
{KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, SFT_T(KC_ENT)},
{BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT }
},
/* Colemak
* ,-----------------------------------------------------------------------------------.
* | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | R | S | T | D | H | N | E | I | O | " |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | K | M | , | . | / |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_COLEMAK] = {
{KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC},
{KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT},
{KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT },
{BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
/* Dvorak
* ,-----------------------------------------------------------------------------------.
* | Tab | " | , | . | P | Y | F | G | C | R | L | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | O | E | U | I | D | H | T | N | S | / |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Brite| Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_DVORAK] = {
{KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC},
{KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_SLSH},
{KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_ENT },
{BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
/* Lower
* ,-----------------------------------------------------------------------------------.
* | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Del | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | END | HOME |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | Next | Vol- | Vol+ | Play |
* `-----------------------------------------------------------------------------------'
*/
[_LOWER] = {
{KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC},
{KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE},
{_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS),S(KC_NUBS),KC_END, KC_HOME, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
},
/* Raise
* ,-----------------------------------------------------------------------------------.
* | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Del | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | F7 | F8 | F9 | F10 | F11 | F12 |ISO # |ISO / |PG DN |PG UP |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | Next | Vol- | Vol+ | Play |
* `-----------------------------------------------------------------------------------'
*/
[_RAISE] = {
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
{KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS},
{_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_NUHS, KC_NUBS, KC_PGDN, KC_PGUP, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
},
/* Plover layer (http://opensteno.org)
* ,-----------------------------------------------------------------------------------.
* | # | # | # | # | # | # | # | # | # | # | # | # |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | S | T | P | H | * | * | F | P | L | T | D |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* |TogOut| S | K | W | R | * | * | R | B | G | S | Z |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Exit | | | A | O | | E | U | | | |
* `-----------------------------------------------------------------------------------'
*/
[_PLOVER] = {
{KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1, KC_1 },
{XXXXXXX, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC},
{XXXXXXX, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT},
{EXT_PLV, XXXXXXX, XXXXXXX, KC_C, KC_V, XXXXXXX, XXXXXXX, KC_N, KC_M, XXXXXXX, XXXXXXX, XXXXXXX}
},
/* Adjust (Lower + Raise)
* ,-----------------------------------------------------------------------------------.
* | | Reset| | | | | | | | | | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak|Plover| |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof| | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | | | | |
* `-----------------------------------------------------------------------------------'
*/
[_ADJUST] = {
{_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL},
{_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, PLOVER, _______},
{_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, C_A_INS, C_A_DEL}
}
};
qk_tap_dance_action_t tap_dance_actions[] = {
[ESC_CAP] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS),
[LFT_HOM] = ACTION_TAP_DANCE_DOUBLE(KC_LEFT, KC_HOME),
[DWN_PDN] = ACTION_TAP_DANCE_DOUBLE(KC_DOWN, KC_PGDN),
[UPP_PUP] = ACTION_TAP_DANCE_DOUBLE(KC_UP, KC_PGUP),
[RGT_END] = ACTION_TAP_DANCE_DOUBLE(KC_RGHT, KC_END)
};
#ifdef AUDIO_ENABLE
float tone_startup[][2] = SONG(SONIC_RING); //plug in
float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_dvorak[][2] = SONG(DVORAK_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
float tone_plover[][2] = SONG(PLOVER_SOUND);
float tone_plover_gb[][2] = SONG(PLOVER_GOODBYE_SOUND);
float music_scale[][2] = SONG(ZELDA_PUZZLE); //music mode
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
#endif
void persistant_default_layer_set(uint16_t default_layer) {
eeconfig_update_default_layer(default_layer);
default_layer_set(default_layer);
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case QWERTY:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
#endif
persistant_default_layer_set(1UL<<_QWERTY);
}
return false;
break;
case COLEMAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
persistant_default_layer_set(1UL<<_COLEMAK);
}
return false;
break;
case DVORAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
#endif
persistant_default_layer_set(1UL<<_DVORAK);
}
return false;
break;
case LOWER:
if (record->event.pressed) {
layer_on(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case RAISE:
if (record->event.pressed) {
layer_on(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case BACKLIT:
if (record->event.pressed) {
register_code(KC_RSFT);
#ifdef BACKLIGHT_ENABLE
backlight_step();
#endif
} else {
unregister_code(KC_RSFT);
}
return false;
break;
case PLOVER:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
stop_all_notes();
PLAY_NOTE_ARRAY(tone_plover, false, 0);
#endif
layer_off(_RAISE);
layer_off(_LOWER);
layer_off(_ADJUST);
layer_on(_PLOVER);
if (!eeconfig_is_enabled()) {
eeconfig_init();
}
keymap_config.raw = eeconfig_read_keymap();
keymap_config.nkro = 1;
eeconfig_update_keymap(keymap_config.raw);
}
return false;
break;
case EXT_PLV:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_plover_gb, false, 0);
#endif
layer_off(_PLOVER);
}
return false;
break;
}
return true;
}
void matrix_init_user(void) {
#ifdef AUDIO_ENABLE
startup_user();
#endif
}
#ifdef AUDIO_ENABLE
void startup_user()
{
_delay_ms(20); // gets rid of tick
PLAY_NOTE_ARRAY(tone_startup, false, 0);
}
void shutdown_user()
{
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
_delay_ms(150);
stop_all_notes();
}
void music_on_user(void)
{
music_scale_user();
}
void music_scale_user(void)
{
PLAY_NOTE_ARRAY(music_scale, false, 0);
}
#endif

@ -0,0 +1,29 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -0,0 +1,29 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -0,0 +1,29 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -11,15 +11,17 @@ extern keymap_config_t keymap_config;
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _DVORAK 0
#define _QWERTY 1
#define _LOWER 2
#define _RAISE 3
#define _QWERTY 0
#define _COLEMAK 1
#define _DVORAK 2
#define _LOWER 3
#define _RAISE 4
#define _ADJUST 16
enum planck_keycodes {
DVORAK = SAFE_RANGE,
QWERTY,
QWERTY = SAFE_RANGE,
COLEMAK,
DVORAK,
LOWER,
RAISE,
BACKLIT
@ -29,60 +31,84 @@ enum planck_keycodes {
#define _______ KC_TRNS
#define XXXXXXX KC_NO
// Custom macros
#define CTL_ESC CTL_T(KC_ESC) // Tap for Esc, hold for Ctrl
#define SFT_ENT SFT_T(KC_ENT) // Tap for Enter, hold for Shift
#define HPR_TAB ALL_T(KC_TAB) // Tap for Tab, hold for Hyper (Super+Ctrl+Alt+Shift)
#define MEH_GRV MEH_T(KC_GRV) // Tap for Backtick, hold for Meh (Ctrl+Alt+Shift)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Dvorak
/* Qwerty
* ,-----------------------------------------------------------------------------------.
* | Tab | " | , | . | P | Y | F | G | C | R | L | Bksp |
* | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | O | E | U | I | D | H | T | N | S | - |
* | Esc | A | S | D | F | G | H | J | K | L | ; | " |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter |
* | Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | ` | Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
* | ` | Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_DVORAK] = {
{KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC},
{KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_MINS},
{SFT_T(KC_ESC), KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, SFT_T(KC_ENT)},
{ALL_T(KC_GRV), KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
[_QWERTY] = {
{HPR_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC},
{CTL_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT},
{KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, SFT_ENT},
{MEH_GRV, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
/* Qwerty
/* Colemak
* ,-----------------------------------------------------------------------------------.
* | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp |
* | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | S | D | F | G | H | J | K | L | ; | " |
* | Esc | A | R | S | T | D | H | N | E | I | O | " |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
* | Shift| Z | X | C | V | B | K | M | , | . | / |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | ` | Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
* | ` | Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_QWERTY] = {
{_______, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC},
{_______, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT},
{_______, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
[_COLEMAK] = {
{HPR_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC},
{CTL_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT},
{KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, SFT_ENT},
{MEH_GRV, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
/* Dvorak
* ,-----------------------------------------------------------------------------------.
* | Tab | " | , | . | P | Y | F | G | C | R | L | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | O | E | U | I | D | H | T | N | S | - |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | ` | Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_DVORAK] = {
{HPR_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC},
{CTL_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_MINS},
{KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, SFT_ENT},
{MEH_GRV, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
/* Lower
* ,-----------------------------------------------------------------------------------.
* | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del |
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | F1 | F2 | F3 | F4 | F5 | F6 | 4 | 5 | 6 | Home |PageUp|
* | $ | F1 | F2 | F3 | F4 | F5 | F6 | 4 | 5 | 6 | | |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | F7 | F8 | F9 | F10 | F11 | F12 | 1 | 2 | 3 | End |PageDn|
* | | F7 | F8 | F9 | F10 | F11 | F12 | 1 | 2 | 3 | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | Next | Vol- | Vol+ | Play |
* `-----------------------------------------------------------------------------------'
*/
[_LOWER] = {
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL},
{_______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_4, KC_5, KC_6, KC_HOME, KC_PGUP},
{_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_1, KC_2, KC_3, KC_END, KC_PGDN},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
{ALL_T(KC_0), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL},
{CTL_T(KC_DLR), KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_4, KC_5, KC_6, _______, _______},
{_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_1, KC_2, KC_3, _______, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
},
/* Raise
@ -93,21 +119,21 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | | | | | | - | / | = | [ | ] | \ |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | Next | Vol- | Vol+ | Play |
* | | | | | | | | | Home |PageDn|PageUp| End |
* `-----------------------------------------------------------------------------------'
*/
[_RAISE] = {
{KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL},
{_______, _______, _______, _______, _______, _______, KC_UNDS, KC_QUES, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE},
{_______, _______, _______, _______, _______, _______, KC_MINS, KC_SLSH, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
{ALL_T(KC_TILD), KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL},
{_______, _______, _______, _______, _______, _______, KC_UNDS, KC_QUES, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE},
{_______, _______, _______, _______, _______, _______, KC_MINS, KC_SLSH, KC_EQL, KC_LBRC, KC_RBRC, SFT_T(KC_BSLS)},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END}
},
/* Adjust (Lower + Raise)
* ,-----------------------------------------------------------------------------------.
* | | Reset| | | | | | | | | | Del |
* | | Reset| | | | | | | | | | Reset|
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | |Aud on|Audoff|AGnorm|AGswap|Dvorak|Qwerty| | | |
* | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak| | |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof| | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
@ -115,8 +141,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `-----------------------------------------------------------------------------------'
*/
[_ADJUST] = {
{_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL},
{_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, DVORAK, QWERTY, _______, _______, _______},
{_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET},
{_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______},
{_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
}
@ -128,6 +154,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
float tone_startup[][2] = SONG(STARTUP_SOUND);
float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
float tone_dvorak[][2] = SONG(DVORAK_SOUND);
float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
@ -142,21 +169,30 @@ void persistant_default_layer_set(uint16_t default_layer) {
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case DVORAK:
case QWERTY:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
#endif
persistant_default_layer_set(1UL<<_DVORAK);
persistant_default_layer_set(1UL<<_QWERTY);
}
return false;
break;
case QWERTY:
case COLEMAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
persistant_default_layer_set(1UL<<_QWERTY);
persistant_default_layer_set(1UL<<_COLEMAK);
}
return false;
break;
case DVORAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
#endif
persistant_default_layer_set(1UL<<_DVORAK);
}
return false;
break;

@ -4,49 +4,70 @@ This keymap is primarily based on the default Planck keymap.
Notable differences from the default are:
1. **Dvorak by default**
- **[Mod-Tap](https://github.com/jackhumbert/qmk_firmware/wiki#fun-with-modifier-keys) keys**
I happen to type in Dvorak, and prefer that layer to be the default on my keyboard. This is easy enough to switch around with Qwerty, Colemak, or whatever.
- `Esc/Ctrl`
2. **Right Shift**
I am experimenting with using Left Shift as a mod-tap key for Escape, similar to how I use the Enter key. It's set up like this on my Minivan, so in the interest of consistency...
I use both the left and right shift keys when I type. When I want to modify a key with shift, I hold shift with the hand opposite the one typing the key. In the default keymap, Enter is where shift would be on a standard keyboard layout. Oh, muscle memory.
- `Enter/Shift`
Thankfully, QMK supports [mod-tap](https://github.com/jackhumbert/qmk_firmware/wiki#fun-with-modifier-keys) keys, and this allows me to set the Enter key to send a modifier (MOD_LSFT) when held, and KC_ENT when tapped. Awesome!
I use both the left and right shift keys when I type. When I want to modify a key with shift, I hold shift with the hand opposite the one typing the key. In the default keymap, Enter is where shift would be on a standard keyboard layout. Oh, muscle memory.
3. Escape
- `Tab/Hyper` (Super+Ctrl+Shift+Alt)
I am experimenting with using Left Shift as a mod-tap key for Escape, similar to how I use the Enter key. It's set up like this on my Minivan, so in the interest of consistency...
It's great to be able to use Tab as a custom modifier key. I tend to use [Hyper](http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/) commands for various OS-specific operations depending on what machine I'm working on.
4. Backtick
- `Backtick/Meh` (Ctrl+Shift+Alt)
I don't currently have LEDs on any of my keyboards, and even if I did, I don't think I would want their controls on a base layer.
Why use backtick in the lower left corner? I use it as my tmux prefix key, so I need to type it more frequently than most people. Putting it on the base layer works well for me. The "Meh" mapping is just a less-cool "Hyper"; the same, just without Super.
So, why use backtick in the lower left corner? I use it as my tmux prefix key, so I need to type it more frequently than most people. Putting it on the base layer works well for me.
- **Swapped responsibilities of "lower" and "raise" layers**
## Dvorak (default)
I prefer to use symbols via the "raise" layer, and numbers via the "lower" layer.
- **Removed Plover layer**
I don't intend to use stenography anytime soon, so Plover just didn't have a place in my keymap.
## Qwerty
```
,-----------------------------------------------------------------------------------.
| Tab | " | , | . | P | Y | F | G | C | R | L | Bksp |
| Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp |
|------+------+------+------+------+-------------+------+------+------+------+------|
| Esc | A | O | E | U | I | D | H | T | N | S | - |
| Esc | A | S | D | F | G | H | J | K | L | ; | " |
|------+------+------+------+------+------|------+------+------+------+------+------|
| Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter |
| Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
|------+------+------+------+------+------+------+------+------+------+------+------|
| ` | Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
| ` | Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right |
`-----------------------------------------------------------------------------------'
```
## Qwerty (same as default)
## Colemak
```
,-----------------------------------------------------------------------------------.
| Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp |
| Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp |
|------+------+------+------+------+-------------+------+------+------+------+------|
| Esc | A | S | D | F | G | H | J | K | L | ; | " |
| Esc | A | R | S | T | D | H | N | E | I | O | " |
|------+------+------+------+------+------|------+------+------+------+------+------|
| Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
| Shift| Z | X | C | V | B | K | M | , | . | / |Enter |
|------+------+------+------+------+------+------+------+------+------+------+------|
| ` | Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right |
`-----------------------------------------------------------------------------------'
```
## Dvorak
```
,-----------------------------------------------------------------------------------.
| Tab | " | , | . | P | Y | F | G | C | R | L | Bksp |
|------+------+------+------+------+-------------+------+------+------+------+------|
| Esc | A | O | E | U | I | D | H | T | N | S | - |
|------+------+------+------+------+------|------+------+------+------+------+------|
| Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter |
|------+------+------+------+------+------+------+------+------+------+------+------|
| ` | Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
`-----------------------------------------------------------------------------------'
@ -54,15 +75,15 @@ Notable differences from the default are:
## Lower
This is where I put the number row, a numpad cluster, function keys, and some light navigation via Home/End/PageUp/PageDn. Like the "Raise" layer, the top row is redundant to help with Planck compatibility.
This is where I put the number row, a numpad cluster, function keys, and media controls.
```
,-----------------------------------------------------------------------------------.
| ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del |
|------+------+------+------+------+-------------+------+------+------+------+------|
| | F1 | F2 | F3 | F4 | F5 | F6 | 4 | 5 | 6 | Home |PageUp|
| $ | F1 | F2 | F3 | F4 | F5 | F6 | 4 | 5 | 6 | | |
|------+------+------+------+------+------|------+------+------+------+------+------|
| | F7 | F8 | F9 | F10 | F11 | F12 | 1 | 2 | 3 | End |PageDn|
| | F7 | F8 | F9 | F10 | F11 | F12 | 1 | 2 | 3 | | |
|------+------+------+------+------+------+------+------+------+------+------+------|
| | | | | | | | Next | Vol- | Vol+ | Play |
`-----------------------------------------------------------------------------------'
@ -70,7 +91,7 @@ This is where I put the number row, a numpad cluster, function keys, and some li
## Raise
As a developer, it makes the most sense for me to group all the commonly-used symbols that don't fit on the main layer. In particular, having the dual-column of parens-braces-brackets really helps a lot.
As a developer, it makes the most sense for me to group all the commonly-used symbols that don't fit on the main layer. In particular, having the dual-column of parens-braces-brackets really helps a lot. I've also added cursorkeys to correspond to the arrows.
I haven't completely filled this layer, which leaves room for future mappings and macros.
@ -82,21 +103,21 @@ I haven't completely filled this layer, which leaves room for future mappings an
|------+------+------+------+------+------|------+------+------+------+------+------|
| | | | | | | - | / | = | [ | ] | \ |
|------+------+------+------+------+------+------+------+------+------+------+------|
| | | | | | | | Next | Vol- | Vol+ | Play |
| | | | | | | | | Home |PageDn|PageUp| End |
`-----------------------------------------------------------------------------------'
```
## Adjust (Lower + Raise)
Utility layer. This is where I'd switch to Qwerty, or ~~fool around with~~ adjust the audio/music settings.
Utility layer. This is where I'd switch between Qwerty and Dvorak, ~~fool around with~~ adjust the audio/music settings, or put the Planck into bootloader mode.
```
,-----------------------------------------------------------------------------------.
| | Reset| | | | | | | | | | Del |
| | Reset| | | | | | | | | | Reset|
|------+------+------+------+------+-------------+------+------+------+------+------|
| | | |Aud on|AudOff|AGnorm|AGswap|Dvorak|Qwerty| | | |
| | | |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|Dvorak| | |
|------+------+------+------+------+------|------+------+------+------+------+------|
| |Voice-|Voice+|Mus on|MusOff|MidiOn|MidOff| | | | | |
| |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof| | | | | |
|------+------+------+------+------+------+------+------+------+------+------+------|
| | | | | | | | | | | |
`-----------------------------------------------------------------------------------'

@ -20,4 +20,27 @@
sei(); \
} while(0)
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -0,0 +1,29 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -0,0 +1,29 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -0,0 +1,29 @@
# Zach Planck Makefile
# Max .hex size is about 28636 bytes
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
TAP_DANCE_ENABLE = yes # Enable TapDance functionality
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = no # Mouse keys(+4700)
EXTRAKEY_ENABLE = no # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = no # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
USB_6KRO_ENABLE = no # 6key Rollover
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = no # Audio output on port C6
#VARIABLE_TRACE = no # Debug changes to variable values
UNICODE_ENABLE = no # Unicode (can't be used with unicodemap)
UNICODEMAP_ENABLE = yes # Enable extended unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,94 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6060
#define MANUFACTURER Ortholinear Keyboards
#define PRODUCT The Planck Keyboard
#define DESCRIPTION A compact ortholinear keyboard
/* key matrix size */
#define MATRIX_ROWS 4
#define MATRIX_COLS 12
/* Planck PCB default pin-out */
#define MATRIX_ROW_PINS { D0, D5, B5, B6 }
#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }
#define UNUSED_PINS
#define BACKLIGHT_PIN B7
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST
//#define BACKLIGHT_BREATHING // LED breathing
/* number of backlight levels */
#define BACKLIGHT_LEVELS 5
/* Set 0 if debouncing isn't needed */
#define DEBOUNCING_DELAY 5
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
//#define LOCKING_SUPPORT_ENABLE
#undef LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
//#define LOCKING_RESYNC_ENABLE
#undef LOCKING_RESYNC_ENABLE
/* key combination for command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
#undef NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
#define NO_ACTION_MACRO
#define NO_ACTION_FUNCTION
#define PREVENT_STUCK_MODIFIERS
//#define DYNAMIC_MACRO_ENABLE // Enable if you need to use the macro functionality
//#define SPACE_CADET // Parenthesis on L/R shift
#ifdef SUBPROJECT_rev3
#include "rev3/config.h"
#endif
#ifdef SUBPROJECT_rev4
#include "rev4/config.h"
#endif
#endif

@ -0,0 +1,48 @@
// Zach Nielsen Custom Planck Keyboard layout
#include "planck.h"
#define PLANCK_YES // This is the Planck
#include "zach_common_functions.c"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_COLEMAK] = { /* Base Layer */
{KC_ESC, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_QUOT, KC_BSPC},
{KC_BSPC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_ENT},
{SHFT_CAP,KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT},
{CTRLB, TD(SUP), KC_LALT, KC_LCTL, TD(LOW), KC_SPC, KC_SPC, TD(RAI), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
[_SWCOLE] = { /* Software Colemak */
{_______, CM_Q, CM_W, CM_F, CM_P, CM_G, CM_J, CM_L, CM_U, CM_Y, KC_QUOT, _______},
{_______, CM_A, CM_R, CM_S, CM_T, CM_D, CM_H, CM_N, CM_E, CM_I, CM_O, _______},
{_______, CM_Z, CM_X, CM_C, CM_V, CM_B, CM_K, CM_M, CM_COMM, CM_DOT, CM_SLSH, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
},
[_RAISE] = { /* RAISE - Numpad and Unicode symbols */
{KC_GRV, SUPA2, FACE, DISFACE, SHRUG, PLUMIN, IBANG, KC_7, KC_8, KC_9, KC_COLN, _______},
{KC_DEL, DEGREE, MICRO, WOMEGA, OMEGA, PENGY, KC_ENT, KC_4, KC_5, KC_6, KC_SLSH, KC_ASTR},
{_______, KC_COLN, TFLIP, LAROW, RAROW, DUCK, KC_SPC, KC_1, KC_2, KC_3, KC_MINS, KC_PLUS},
{_______, KC_PIPE, TPUT, _______, _______, KC_TAB, KC_TAB, _______, KC_0, KC_0, KC_DOT, KC_EQL}
},
[_LOWER] = { /* LOWER - Symbols, Paging, CtrAltDel */
{KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_QUES, KC_DQT, KC_DEL},
{KC_DEL, KC_LBRC, KC_RBRC, KC_MINS, KC_UNDS, KC_HOME, KC_END, KC_LPRN, KC_RPRN, KC_SLSH, KC_SCLN, KC_PGUP},
{CPYPST, XXXXXXX, C(KC_X), KC_LABK, KC_RABK, XXXXXXX, XXXXXXX, KC_LCBR, KC_RCBR, KC_BSLS, KC_COLN, KC_PGDN},
{_______, _______, _______, _______, _______, KC_TAB, KC_TAB, _______, _______, _______, _______, _______}
},
[_ADJUST] = { /* ADJUST - Macros, Layer Switching, Function Keys */
{UNIWIN, XXXXXXX, XXXXXXX, PENGY, DUCK, KC_INS, KC_NLCK, KC_F1, KC_F2, KC_F3, KC_F4, XXXXXXX},
{UNILIN, XXXXXXX, XXXXXXX, RANDIG, RANDIG, SWCOLE, COLEMAK, KC_F5, KC_F6, KC_F7, KC_F8, XXXXXXX},
{_______, CADKEY, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_F9, KC_F10, KC_F11, KC_F12, XXXXXXX},
{_______, _______, _______, _______, _______, RESET, RESET, _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX}
},
[_UNICODES] = { /* UNICODES - Extra layer for unicode stuff */
{_______, TFLIP, XXXXXXX, XXXXXXX, IBANG, roman7, XXXXXXX, XXXXXXX, ROMAN7, XXXXXXX, XXXXXXX, _______},
{KC_DEL, TPUT, FACE, DISFACE, SHRUG, roman4, roman5, roman6, ROMAN4, ROMAN5, ROMAN6, _______},
{XXXXXXX, XXXXXXX, XXXXXXX, LAROW, RAROW, roman1, roman2, roman3, ROMAN1, ROMAN2, ROMAN3, XXXXXXX},
{_______, _______, _______, _______, _______, KC_SPC, KC_SPC, _______, _______, _______, _______, _______}
}
};

@ -0,0 +1,447 @@
#ifndef ZACH_COMMON_FUNCTIONS
#define ZACH_COMMON_FUNCTIONS
#include "eeconfig.h"
#include "action_layer.h"
#include "keymap_colemak.h"
extern keymap_config_t keymap_config;
// Fillers to make layering more clear
#define _______ KC_TRNS
#define XXXXXXX KC_NO
#define C(n) RCTL(n)
#define CADKEY RCTL(RALT(KC_DEL))
void tap(uint16_t keycode){
register_code(keycode);
unregister_code(keycode);
};
void persistant_default_layer_set(uint16_t default_layer){
eeconfig_update_default_layer(default_layer);
default_layer_set(default_layer);
};
// Automatic number generation of important keywords
enum my_keycodes{
// Layer numbers
_COLEMAK = 0,
_SWCOLE,
_RAISE,
_LOWER,
_ADJUST,
_UNICODES,
// These use process_record_user()
COLEMAK = SAFE_RANGE,
SWCOLE,
LOWER,
RAISE,
SHFT_CAP,
CTRLB,
CPYPST,
FACE,
UNIWIN,
UNILIN,
DISFACE,
TFLIP,
TPUT,
SHRUG,
RANDIG,
// Tap_Dance nums
RAI = 0,
LOW,
SUP
};
#ifdef AUDIO_ENABLE
#include "audio.h"
float tone_startup[][2] = SONG(STARTUP_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
float tone_swcole[][2] = SONG(QWERTY_SOUND);
float tone_capslock_on[][2] = SONG(CAPS_LOCK_ON_SOUND);
float tone_capslock_off[][2] = SONG(CAPS_LOCK_OFF_SOUND);
float tone_ctrl_mod[][2] = SONG(COIN_SOUND);
float tone_copy[][2] = SONG(SCROLL_LOCK_ON_SOUND);
float tone_paste[][2] = SONG(SCROLL_LOCK_OFF_SOUND);
float uniwin[][2] = SONG(UNICODE_WINDOWS);
float unilin[][2] = SONG(UNICODE_LINUX);
#endif
#ifdef TAP_DANCE_ENABLE
#define TAPPING_TERM 200
void dance_raise_press(qk_tap_dance_state_t *state, void *user_data){// Called on each tap
switch(state->count){ // Only turn the layer on once
case 1:
layer_off(_UNICODES);
layer_on(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
break;
}
};
void dance_raise_lift(qk_tap_dance_state_t *state, void *user_data){ // Called on release
switch(state->count){
case 1: // Normal action. Turn off layers
layer_off(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
layer_off(_UNICODES);
break;
}
};
/////////////////////////////////////////////////////////////////////
void dance_lower_press(qk_tap_dance_state_t *state, void *user_data){// Called on tap
switch(state->count){
case 1: // Turn on lower
layer_off(_UNICODES);
layer_on(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
break;
}
};
void dance_lower_lift(qk_tap_dance_state_t *state, void *user_data){ // Called on release
switch(state->count){
case 1: // Normal action. Turn off layers
layer_off(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
layer_off(_UNICODES);
break;
case 2: // Turn on _UNICODES layer
layer_off(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
layer_on(_UNICODES);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_ctrl_mod, false, 0);
#endif
break;
}
};
/////////////////////////////////////////////////////////////////////
void dance_super_press(qk_tap_dance_state_t *state, void *user_data){ // Called on down
if(state->count == 1){
register_code(KC_LGUI);
}
}
void dance_super_done(qk_tap_dance_state_t *state, void *user_data){ // Called on timeout
switch(state->count){
case 2:
register_code(KC_LGUI);
tap(KC_L);
unregister_code(KC_LGUI);
break;
}
}
void dance_super_lift(qk_tap_dance_state_t *state, void *user_data){ // Called on up
unregister_code(KC_LGUI);
}
qk_tap_dance_action_t tap_dance_actions[] = {
[RAI] = ACTION_TAP_DANCE_FN_ADVANCED(dance_raise_press, NULL, dance_raise_lift),
[LOW] = ACTION_TAP_DANCE_FN_ADVANCED(dance_lower_press, NULL, dance_lower_lift),
[SUP] = ACTION_TAP_DANCE_FN_ADVANCED(dance_super_press, dance_super_done, dance_super_lift)
};
#endif
//#ifdef UNICODE_ENABLE
// Unicode shortcuts
#define IBANG X(0x203D)
#define RAROW X(0x2192)
#define LAROW X(0x2190)
#define DEGREE X(0x00B0)
#define OMEGA X(0x03A9)
#define WOMEGA X(0x03C9)
#define MICRO X(0x00B5)
#define PLUMIN X(0x00B1)
#define SUPA2 X(0x00B2)
#define ROMAN1 X(0x2160)
#define ROMAN2 X(0x2161)
#define ROMAN3 X(0x2162)
#define ROMAN4 X(0x2163)
#define ROMAN5 X(0x2164)
#define ROMAN6 X(0x2165)
#define ROMAN7 X(0x2166)
#define roman1 X(0x2170)
#define roman2 X(0x2171)
#define roman3 X(0x2172)
#define roman4 X(0x2173)
#define roman5 X(0x2174)
#define roman6 X(0x2175)
#define roman7 X(0x2176)
#ifdef UNICODEMAP_ENABLE // For Unicode characters larger than 0x8000. Send with X(<unicode>)
enum Ext_Unicode{
PENGUIN = 0,
BOAR,
MONKEY,
DRAGON,
CHICK,
TUMBLER
};
const uint32_t PROGMEM unicode_map[] = {
[PENGUIN] = 0x1F427,
[BOAR] = 0x1F417,
[MONKEY] = 0x1F412,
[DRAGON] = 0x1F409,
[CHICK] = 0x1F425,
[TUMBLER] = 0x1F943
};
#define PENGY X(PENGUIN)
#define BOARY X(BOAR)
#define MNKY X(MONKEY)
#define DRGN X(DRAGON)
#define DUCK X(CHICK)
#define TMBL X(TUMBLER)
#endif
//#endif
static uint16_t key_timer;
static uint8_t caps_status = 0;
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case COLEMAK:
if(record->event.pressed){
persistant_default_layer_set(1UL<<_COLEMAK);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
}
return false;
break;
case SWCOLE:
if(record->event.pressed){
persistant_default_layer_set(1UL<<_SWCOLE);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_swcole, false, 0);
#endif
}
return false;
break;
case RAISE:
if(record->event.pressed){
layer_on(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case LOWER:
if(record->event.pressed){
layer_on(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case SHFT_CAP:
if(record->event.pressed){
key_timer = timer_read(); // if the key is being pressed, we start the timer.
register_code(KC_LSHIFT);
} else { // this means the key was just released (tap or "held down")
if(timer_elapsed(key_timer) < 152){ // Time in ms, the threshold we pick for counting something as a tap.
tap(KC_CAPS);
if(caps_status == 0){
caps_status = 1;
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_capslock_on, false, 0);
#endif
} else {
caps_status = 0;
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_capslock_off, false, 0);
#endif
}
}
unregister_code(KC_LSHIFT);
}
return false;
break;
case CTRLB: // Control-B on tap (bold)
if(record->event.pressed){
key_timer = timer_read(); // if the key is being pressed, we start the timer.
register_code(KC_LCTL);
} else { // this means the key was just released (tap or "held down")
if (timer_elapsed(key_timer) < 152) { // Time in ms, the threshold we pick for counting something as a tap.
tap(KC_B);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_ctrl_mod, false, 0);
#endif
#ifdef BACKLIGHT_BREATHING
breathing_speed_set(2);
breathing_pulse();
#endif
}
unregister_code(KC_LCTL);
}
return false;
break;
case CPYPST: // One key copy/paste
if(record->event.pressed){
key_timer = timer_read();
} else {
if (timer_elapsed(key_timer) > 152) { // Hold, copy
register_code(KC_LCTL);
tap(KC_C);
unregister_code(KC_LCTL);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_copy, false, 0);
#endif
} else { // Tap, paste
register_code(KC_LCTL);
tap(KC_V);
unregister_code(KC_LCTL);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_paste, false, 0);
#endif
}
}
return false;
break;
#ifdef UNICODE_ENABLE
case UNIWIN:
if(record->event.pressed){
set_unicode_input_mode(UC_WIN);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(uniwin, false, 0);
#endif
}
return false;
break;
case UNILIN:
if(record->event.pressed){
set_unicode_input_mode(UC_LNX);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(unilin, false, 0);
#endif
}
return false;
break;
case DISFACE: // ಠ_ಠ
if(record->event.pressed){
process_unicode((0x0CA0|QK_UNICODE), record); // Eye
register_code(KC_RSFT);
tap(KC_MINS);
unregister_code(KC_RSFT);
process_unicode((0x0CA0|QK_UNICODE), record); // Eye
}
return false;
break;
case TFLIP: // (╯°□°)╯ ︵ ┻━┻
if(record->event.pressed){
register_code(KC_RSFT);
tap(KC_9);
unregister_code(KC_RSFT);
process_unicode((0x256F|QK_UNICODE), record); // Arm
process_unicode((0x00B0|QK_UNICODE), record); // Eye
process_unicode((0x25A1|QK_UNICODE), record); // Mouth
process_unicode((0x00B0|QK_UNICODE), record); // Eye
register_code(KC_RSFT);
tap(KC_0);
unregister_code(KC_RSFT);
process_unicode((0x256F|QK_UNICODE), record); // Arm
tap(KC_SPC);
process_unicode((0x0361|QK_UNICODE), record); // Flippy
tap(KC_SPC);
process_unicode((0x253B|QK_UNICODE), record); // Table
process_unicode((0x2501|QK_UNICODE), record); // Table
process_unicode((0x253B|QK_UNICODE), record); // Table
}
return false;
break;
case TPUT: // ┬──┬ ( ゜-゜ノ)
if(record->event.pressed){
process_unicode((0x252C|QK_UNICODE), record); // Table
process_unicode((0x2500|QK_UNICODE), record); // Table
process_unicode((0x2500|QK_UNICODE), record); // Table
process_unicode((0x252C|QK_UNICODE), record); // Table
tap(KC_SPC);
process_unicode((0x30CE|QK_UNICODE), record); // Arm
register_code(KC_RSFT);
tap(KC_9);
unregister_code(KC_RSFT);
tap(KC_SPC);
process_unicode((0x309C|QK_UNICODE), record); // Eye
tap(KC_MINS);
process_unicode((0x309C|QK_UNICODE), record); // Eye
process_unicode((0x30CE|QK_UNICODE), record); // Arm
register_code(KC_RSFT);
tap(KC_0);
unregister_code(KC_RSFT);
}
return false;
break;
case SHRUG: // ¯\_(ツ)_/¯
if(record->event.pressed){
process_unicode((0x00AF|QK_UNICODE), record); // Hand
tap(KC_BSLS); // Arm
register_code(KC_RSFT);
tap(KC_UNDS); // Arm
tap(KC_LPRN); // Head
unregister_code(KC_RSFT);
process_unicode((0x30C4|QK_UNICODE), record); // Face
register_code(KC_RSFT);
tap(KC_RPRN); // Head
tap(KC_UNDS); // Arm
unregister_code(KC_RSFT);
tap(KC_SLSH); // Arm
process_unicode((0x00AF|QK_UNICODE), record); // Hand
}
return false;
break;
#endif
case FACE: // (o_O)
if(record->event.pressed){
register_code(KC_RSFT);
tap(KC_LPRN);
unregister_code(KC_RSFT);
tap(KC_O);
register_code(KC_RSFT);
tap(KC_UNDS);
tap(KC_O);
tap(KC_RPRN);
unregister_code(KC_RSFT);
}
return false;
break;
case RANDIG:
if (record->event.pressed) {
tap_random_base64();
}
return false;
break;
}
return true;
};
void matrix_init_user(void){ // Run once at startup
#ifdef AUDIO_ENABLE
_delay_ms(50); // gets rid of tick
PLAY_NOTE_ARRAY(tone_startup, false, 0);
#endif
}
#ifdef AUDIO_ENABLE
void play_goodbye_tone(void){
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
_delay_ms(150);
}
void shutdown_user(){
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
_delay_ms(150);
stop_all_notes();
}
void music_on_user(void){ // Run when the music layer is turned on
PLAY_NOTE_ARRAY(tone_startup, false, 0);
}
void music_off_user(void){ // Run when music is turned off
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
}
#endif
#endif

@ -56,13 +56,13 @@ EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= no # Console for debug(+400)
COMMAND_ENABLE ?= no # Commands for debug and configuration
NKRO_ENABLE ?= no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
BACKLIGHT_ENABLE ?= yes # Enable keyboard backlight functionality
MIDI_ENABLE ?= yes # MIDI controls
AUDIO_ENABLE ?= yes # Audio output on port C6
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight.
API_SYSEX_ENABLE = yes
API_SYSEX_ENABLE = no
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend

@ -0,0 +1,29 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -0,0 +1,29 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -0,0 +1,29 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -9,15 +9,17 @@
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _DVORAK 0
#define _QWERTY 1
#define _LOWER 2
#define _RAISE 3
#define _QWERTY 0
#define _COLEMAK 1
#define _DVORAK 2
#define _LOWER 3
#define _RAISE 4
#define _ADJUST 16
enum preonic_keycodes {
DVORAK = SAFE_RANGE,
QWERTY,
QWERTY = SAFE_RANGE,
COLEMAK,
DVORAK,
LOWER,
RAISE,
BACKLIT
@ -27,69 +29,96 @@ enum preonic_keycodes {
#define _______ KC_TRNS
#define XXXXXXX KC_NO
// Custom macros
#define CTL_ESC CTL_T(KC_ESC) // Tap for Esc, hold for Ctrl
#define SFT_ENT SFT_T(KC_ENT) // Tap for Enter, hold for Shift
#define HPR_TAB ALL_T(KC_TAB) // Tap for Tab, hold for Hyper (Super+Ctrl+Alt+Shift)
#define MEH_GRV MEH_T(KC_GRV) // Tap for Backtick, hold for Meh (Ctrl+Alt+Shift)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Dvorak
/* Qwerty
* ,-----------------------------------------------------------------------------------.
* | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Tab | " | , | . | P | Y | F | G | C | R | L | Bksp |
* | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | O | E | U | I | D | H | T | N | S | - |
* | Esc | A | S | D | F | G | H | J | K | L | ; | " |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter |
* | Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | ` | Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
* | ` | Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_DVORAK] = {
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
{KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC},
{KC_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_MINS},
{SFT_T(KC_ESC), KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, SFT_T(KC_ENT)},
{ALL_T(KC_GRV), KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
[_QWERTY] = {
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
{HPR_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC},
{CTL_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT},
{KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, SFT_ENT},
{MEH_GRV, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
/* Qwerty
/* Colemak
* ,-----------------------------------------------------------------------------------.
* | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp |
* | Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | S | D | F | G | H | J | K | L | ; | " |
* | Esc | A | R | S | T | D | H | N | E | I | O | " |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
* | Shift| Z | X | C | V | B | K | M | , | . | / |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | ` | Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
* | ` | Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_QWERTY] = {
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______},
{_______, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, _______},
{_______, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT},
{_______, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
[_COLEMAK] = {
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
{HPR_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC},
{CTL_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT},
{KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, SFT_ENT},
{MEH_GRV, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
/* Dvorak
* ,-----------------------------------------------------------------------------------.
* | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | Tab | " | , | . | P | Y | F | G | C | R | L | Bksp |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | Esc | A | O | E | U | I | D | H | T | N | S | - |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | ` | Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right |
* `-----------------------------------------------------------------------------------'
*/
[_DVORAK] = {
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC},
{HPR_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC},
{CTL_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_MINS},
{KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, SFT_ENT},
{MEH_GRV, KC_LCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
/* Lower
* ,-----------------------------------------------------------------------------------.
* | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del |
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del |
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | F1 | F2 | F3 | F4 | F5 | F6 | 4 | 5 | 6 | Home |PageUp|
* | $ | F1 | F2 | F3 | F4 | F5 | F6 | 4 | 5 | 6 | | |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | F7 | F8 | F9 | F10 | F11 | F12 | 1 | 2 | 3 | End |PageDn|
* | | F7 | F8 | F9 | F10 | F11 | F12 | 1 | 2 | 3 | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | Next | Vol- | Vol+ | Play |
* `-----------------------------------------------------------------------------------'
*/
[_LOWER] = {
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL},
{KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL},
{_______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_4, KC_5, KC_6, KC_HOME, KC_PGUP},
{_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_1, KC_2, KC_3, KC_END, KC_PGDN},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
{ALL_T(KC_GRV), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL},
{ALL_T(KC_0), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL},
{CTL_T(KC_DLR), KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_4, KC_5, KC_6, _______, _______},
{_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_1, KC_2, KC_3, _______, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
},
/* Raise
@ -102,24 +131,24 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | | | | | | | - | / | = | [ | ] | \ |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | | | | | | | Next | Vol- | Vol+ | Play |
* | | | | | | | | | Home |PageDn|PageUp| End |
* `-----------------------------------------------------------------------------------'
*/
[_RAISE] = {
{KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL},
{KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL},
{_______, _______, _______, _______, _______, _______, KC_UNDS, KC_QUES, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE},
{_______, _______, _______, _______, _______, _______, KC_MINS, KC_SLSH, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
{ALL_T(KC_TILD), KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL},
{ALL_T(KC_TILD), KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL},
{_______, _______, _______, _______, _______, _______, KC_UNDS, KC_QUES, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE},
{_______, _______, _______, _______, _______, _______, KC_MINS, KC_SLSH, KC_EQL, KC_LBRC, KC_RBRC, SFT_T(KC_BSLS)},
{_______, _______, _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END}
},
/* Adjust (Lower + Raise)
* ,-----------------------------------------------------------------------------------.
* | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 |
* |------+------+------+------+------+------+------+------+------+------+------+------|
* | | Reset| | | | | | | | | | Del |
* | | Reset| | | | | | | | | | Reset|
* |------+------+------+------+------+-------------+------+------+------+------+------|
* | | | |Aud on|AudOff|AGnorm|AGswap|Dvorak|Qwerty| | | |
* | | | |Aud on|AudOff|AGnorm|AGswap|Qwerty|Colemk|Dvorak| | |
* |------+------+------+------+------+------|------+------+------+------+------+------|
* | |Voice-|Voice+|Mus on|MusOff|MidiOn|MidOff| | | | | |
* |------+------+------+------+------+------+------+------+------+------+------+------|
@ -128,8 +157,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[_ADJUST] = {
{KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12},
{_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL},
{_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, DVORAK, QWERTY, _______, _______, _______},
{_______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET},
{_______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______},
{_______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
}
@ -145,8 +174,9 @@ float tone_startup[][2] = {
{NOTE_B6, 8}
};
float tone_dvorak[][2] = SONG(DVORAK_SOUND);
float tone_qwerty[][2] = SONG(QWERTY_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
float tone_dvorak[][2] = SONG(DVORAK_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
@ -160,21 +190,30 @@ void persistant_default_layer_set(uint16_t default_layer) {
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case DVORAK:
case QWERTY:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
#endif
persistant_default_layer_set(1UL<<_DVORAK);
persistant_default_layer_set(1UL<<_QWERTY);
}
return false;
break;
case QWERTY:
case COLEMAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
persistant_default_layer_set(1UL<<_QWERTY);
persistant_default_layer_set(1UL<<_COLEMAK);
}
return false;
break;
case DVORAK:
if (record->event.pressed) {
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
#endif
persistant_default_layer_set(1UL<<_DVORAK);
}
return false;
break;

@ -4,53 +4,76 @@ This keymap is primarily based on the default Preonic keymap, which in turn is d
Notable differences from the default are:
1. **Dvorak by default**
- **[Mod-Tap](https://github.com/jackhumbert/qmk_firmware/wiki#fun-with-modifier-keys) keys**
I happen to type in Dvorak, and prefer that layer to be the default on my keyboard. This is easy enough to switch around with Qwerty, Colemak, or whatever.
- `Esc/Ctrl`
2. **Right Shift**
I am experimenting with using Left Shift as a mod-tap key for Escape, similar to how I use the Enter key. It's set up like this on my Minivan, so in the interest of consistency...
I use both the left and right shift keys when I type. When I want to modify a key with shift, I hold shift with the hand opposite the one typing the key. In the default keymap, Enter is where shift would be on a standard keyboard layout. Oh, muscle memory.
- `Enter/Shift`
Thankfully, QMK supports [mod-tap](https://github.com/jackhumbert/qmk_firmware/wiki#fun-with-modifier-keys) keys, and this allows me to set the Enter key to send a modifier (MOD_LSFT) when held, and KC_ENT when tapped. Awesome!
I use both the left and right shift keys when I type. When I want to modify a key with shift, I hold shift with the hand opposite the one typing the key. In the default keymap, Enter is where shift would be on a standard keyboard layout. Oh, muscle memory.
3. Escape
- `Tab/Hyper` (Super+Ctrl+Shift+Alt)
I am experimenting with using Left Shift as a mod-tap key for Escape, similar to how I use the Enter key. It's set up like this on my Minivan, so in the interest of consistency...
It's great to be able to use Tab as a custom modifier key. I tend to use [Hyper](http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/) commands for various OS-specific operations depending on what machine I'm working on.
4. Backtick
- `Backtick/Meh` (Ctrl+Shift+Alt)
I don't currently have LEDs on any of my keyboards, and even if I did, I don't think I would want their controls on a base layer.
Why use backtick in the lower left corner? I use it as my tmux prefix key, so I need to type it more frequently than most people. Putting it on the base layer works well for me. The "Meh" mapping is just a less-cool "Hyper"; the same, just without Super.
So, why use backtick in the lower left corner? I use it as my tmux prefix key, so I need to type it more frequently than most people. Putting it on the base layer works well for me.
- **Swapped responsibilities of "lower" and "raise" layers**
## Dvorak (default)
I prefer to use symbols via the "raise" layer, and numbers via the "lower" layer.
- **Removed Plover layer**
I don't intend to use stenography anytime soon, so Plover just didn't have a place in my keymap.
## Qwerty
```
,-----------------------------------------------------------------------------------.
| ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
|------+------+------+------+------+------+------+------+------+------+------+------|
| Tab | " | , | . | P | Y | F | G | C | R | L | Bksp |
| Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp |
|------+------+------+------+------+-------------+------+------+------+------+------|
| Esc | A | O | E | U | I | D | H | T | N | S | - |
| Esc | A | S | D | F | G | H | J | K | L | ; | " |
|------+------+------+------+------+------|------+------+------+------+------+------|
| Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter |
| Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
|------+------+------+------+------+------+------+------+------+------+------+------|
| ` | Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
`-----------------------------------------------------------------------------------'
```
## Qwerty (same as default)
## Colemak
```
,-----------------------------------------------------------------------------------.
| ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
|------+------+------+------+------+------+------+------+------+------+------+------|
| Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp |
| Tab | Q | W | F | P | G | J | L | U | Y | ; | Bksp |
|------+------+------+------+------+-------------+------+------+------+------+------|
| Esc | A | S | D | F | G | H | J | K | L | ; | " |
| Esc | A | R | S | T | D | H | N | E | I | O | " |
|------+------+------+------+------+------|------+------+------+------+------+------|
| Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
| Shift| Z | X | C | V | B | K | M | , | . | / |Enter |
|------+------+------+------+------+------+------+------+------+------+------+------|
| ` | Ctrl | Alt | GUI |Lower |Space |Space |Raise | Left | Down | Up |Right |
`-----------------------------------------------------------------------------------'
```
## Dvorak
```
,-----------------------------------------------------------------------------------.
| ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
|------+------+------+------+------+------+------+------+------+------+------+------|
| Tab | " | , | . | P | Y | F | G | C | R | L | Bksp |
|------+------+------+------+------+-------------+------+------+------+------+------|
| Esc | A | O | E | U | I | D | H | T | N | S | - |
|------+------+------+------+------+------|------+------+------+------+------+------|
| Shift| ; | Q | J | K | X | B | M | W | V | Z |Enter |
|------+------+------+------+------+------+------+------+------+------+------+------|
| ` | Ctrl | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
`-----------------------------------------------------------------------------------'
@ -58,17 +81,17 @@ Notable differences from the default are:
## Lower
This is where I put the number row, a numpad cluster, function keys, and some light navigation via Home/End/PageUp/PageDn. Like the "Raise" layer, the top row is redundant to help with Planck compatibility.
This is where I put the number row, a numpad cluster, function keys, and media controls. Like the "Raise" layer, the top row is redundant to help with Planck compatibility.
```
,-----------------------------------------------------------------------------------.
| ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del |
|------+------+------+------+------+------+------+------+------+------+------+------|
| ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Del |
|------+------+------+------+------+-------------+------+------+------+------+------|
| | F1 | F2 | F3 | F4 | F5 | F6 | 4 | 5 | 6 | Home |PageUp|
| $ | F1 | F2 | F3 | F4 | F5 | F6 | 4 | 5 | 6 | | |
|------+------+------+------+------+------|------+------+------+------+------+------|
| | F7 | F8 | F9 | F10 | F11 | F12 | 1 | 2 | 3 | End |PageDn|
| | F7 | F8 | F9 | F10 | F11 | F12 | 1 | 2 | 3 | | |
|------+------+------+------+------+------+------+------+------+------+------+------|
| | | | | | | | Next | Vol- | Vol+ | Play |
`-----------------------------------------------------------------------------------'
@ -76,7 +99,7 @@ This is where I put the number row, a numpad cluster, function keys, and some li
## Raise
As a developer, it makes the most sense for me to group all the commonly-used symbols that don't fit on the main layer. In particular, having the dual-column of parens-braces-brackets really helps a lot.
As a developer, it makes the most sense for me to group all the commonly-used symbols that don't fit on the main layer. In particular, having the dual-column of parens-braces-brackets really helps a lot. I've also added cursorkeys to correspond to the arrows.
I haven't completely filled this layer, which leaves room for future mappings and macros.
@ -90,21 +113,21 @@ I haven't completely filled this layer, which leaves room for future mappings an
|------+------+------+------+------+------|------+------+------+------+------+------|
| | | | | | | - | / | = | [ | ] | \ |
|------+------+------+------+------+------+------+------+------+------+------+------|
| | | | | | | | Next | Vol- | Vol+ | Play |
| | | | | | | | | Home |PageDn|PageUp| End |
`-----------------------------------------------------------------------------------'
```
## Adjust (Lower + Raise)
Utility layer. This is where I'd switch to Qwerty, or ~~fool around with~~ adjust the audio/music settings.
Utility layer. This is where I'd switch between Qwerty and Dvorak, ~~fool around with~~ adjust the audio/music settings, or put the Preonic into bootloader mode.
```
,-----------------------------------------------------------------------------------.
| F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 |
|------+------+------+------+------+------+------+------+------+------+------+------|
| | Reset| | | | | | | | | | Del |
| | Reset| | | | | | | | | | Reset|
|------+------+------+------+------+-------------+------+------+------+------+------|
| | | |Aud on|AudOff|AGnorm|AGswap|Dvorak|Qwerty| | | |
| | | |Aud on|AudOff|AGnorm|AGswap|Qwerty|Colemk|Dvorak| | |
|------+------+------+------+------+------|------+------+------+------+------+------|
| |Voice-|Voice+|Mus on|MusOff|MidiOn|MidOff| | | | | |
|------+------+------+------+------+------+------+------+------+------+------+------|

@ -0,0 +1,29 @@
# Zach Preonic Makefile
# Max .hex size is about 28636 bytes
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
TAP_DANCE_ENABLE = yes # Enable TapDance functionality
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = no # Mouse keys(+4700)
EXTRAKEY_ENABLE = no # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = no # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
USB_6KRO_ENABLE = no # 6key Rollover
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = yes # Audio output on port C6
#VARIABLE_TRACE = no # Debug changes to variable values
UNICODE_ENABLE = no # Unicode
UNICODEMAP_ENABLE = yes # Enable extended unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,95 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6061
#define DEVICE_VER 0x0001
#define MANUFACTURER Ortholinear Keyboards
#define PRODUCT The Preonic Keyboard
#define DESCRIPTION A compact ortholinear keyboard
/* key matrix size */
#define MATRIX_ROWS 5
#define MATRIX_COLS 12
/* Planck PCB default pin-out */
#define MATRIX_ROW_PINS { D2, D5, B5, B6, D3 }
#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }
#define UNUSED_PINS
#define BACKLIGHT_PIN B7
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST
#define BACKLIGHT_BREATHING // LED breathing
/* number of backlight levels */
#define BACKLIGHT_LEVELS 5
/* Set 0 if debouncing isn't needed */
#define DEBOUNCING_DELAY 5
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
//#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
//#define LOCKING_RESYNC_ENABLE
/* key combination for command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/* ws2812 RGB LED */
//#define RGB_DI_PIN D1
//#define RGBLIGHT_TIMER
//#define RGBLED_NUM 28 // Number of LEDs
//#define RGBLIGHT_HUE_STEP 10
//#define RGBLIGHT_SAT_STEP 17
//#define RGBLIGHT_VAL_STEP 17
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
#define NO_ACTION_MACRO
#define NO_ACTION_FUNCTION
#define PREVENT_STUCK_MODIFIERS
//#define DYNAMIC_MACRO_ENABLE // Enable if you need to use the macro functionality
//#define SPACE_CADET // Parenthesis on L/R shift
#endif

@ -0,0 +1,54 @@
// Zach Nielsen Custom Preonic Keyboard layout
#include "preonic.h"
#define PREONIC_YES // This is the Preonic
#include "zach_common_functions.c"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_COLEMAK] = { /* Base Layer */
{KC_ESC, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC},
{KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_QUOT, KC_ENT},
{KC_BSPC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_ENT},
{SHFT_CAP, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT},
{CTRLB, TD(SUP), KC_LALT, KC_LCTL, TD(LOW), KC_SPC, KC_SPC, TD(RAI), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT}
},
[_SWCOLE] = { /* Software Colemak */
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______},
{_______, CM_Q, CM_W, CM_F, CM_P, CM_G, CM_J, CM_L, CM_U, CM_Y, KC_QUOT, _______},
{_______, CM_A, CM_R, CM_S, CM_T, CM_D, CM_H, CM_N, CM_E, CM_I, CM_O, _______},
{_______, CM_Z, CM_X, CM_C, CM_V, CM_B, CM_K, CM_M, CM_COMM, CM_DOT, CM_SLSH, _______},
{_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
},
[_RAISE] = { /* RAISE - Numpad and Unicode symbols */
{KC_TILD, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______},
{KC_GRV, SUPA2, FACE, DISFACE, SHRUG, PLUMIN, IBANG, KC_7, KC_8, KC_9, KC_COLN, _______},
{KC_DEL, DEGREE, MICRO, WOMEGA, OMEGA, XXXXXXX, KC_ENT, KC_4, KC_5, KC_6, KC_SLSH, KC_ASTR},
{_______, KC_COLN, TFLIP, LAROW, RAROW, XXXXXXX, KC_SPC, KC_1, KC_2, KC_3, KC_MINS, KC_PLUS},
{_______, KC_PIPE, TPUT, _______, _______, KC_TAB, KC_TAB, _______, KC_0, KC_0, KC_DOT, KC_EQL}
},
[_LOWER] = { /* LOWER - Symbols, Paging, CtrAltDel */
{KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_QUES, KC_DQT, KC_DEL},
{KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_QUES, KC_DQT, KC_DEL},
{KC_DEL, KC_LBRC, KC_RBRC, KC_MINS, KC_UNDS, KC_HOME, KC_END, KC_LPRN, KC_RPRN, KC_SLSH, KC_SCLN, KC_PGUP},
{CPYPST, XXXXXXX, C(KC_X), KC_LABK, KC_RABK, XXXXXXX, XXXXXXX, KC_LCBR, KC_RCBR, KC_BSLS, KC_COLN, KC_PGDN},
{_______, _______, _______, _______, _______, KC_TAB, KC_TAB, _______, _______, _______, _______, _______}
},
[_ADJUST] = { /* ADJUST - Macros, Layer Switching, Function Keys */
{UNIWIN, XXXXXXX, XXXXXXX, RANDIG, RANDIG, KC_INS, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, AU_TOG, MU_TOG},
{UNILIN, SUPA2, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_F1, KC_F2, KC_F3, KC_F4, XXXXXXX},
{XXXXXXX, DEGREE, IBANG, LAROW, RAROW, SWCOLE, COLEMAK, KC_F5, KC_F6, KC_F7, KC_F8, BL_INC},
{_______, CADKEY, MICRO, WOMEGA, OMEGA, XXXXXXX, XXXXXXX, KC_F9, KC_F10, KC_F11, KC_F12, BL_DEC},
{_______, _______, _______, _______, _______, RESET, RESET, _______, XXXXXXX, MUV_DE, MUV_IN, BL_TOGG}
},
[_UNICODES] = { /* UNICODES - Extra layer for unicode stuff */
{_______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______},
{_______, TFLIP, XXXXXXX, XXXXXXX, IBANG, roman7, XXXXXXX, XXXXXXX, ROMAN7, XXXXXXX, XXXXXXX, _______},
{KC_DEL, TPUT, FACE, DISFACE, SHRUG, roman4, roman5, roman6, ROMAN4, ROMAN5, ROMAN6, _______},
{XXXXXXX, XXXXXXX, XXXXXXX, LAROW, RAROW, roman1, roman2, roman3, ROMAN1, ROMAN2, ROMAN3, XXXXXXX},
{_______, _______, _______, _______, _______, KC_SPC, KC_SPC, _______, _______, _______, _______, _______}
}
};

@ -0,0 +1,447 @@
#ifndef ZACH_COMMON_FUNCTIONS
#define ZACH_COMMON_FUNCTIONS
#include "eeconfig.h"
#include "action_layer.h"
#include "keymap_colemak.h"
extern keymap_config_t keymap_config;
// Fillers to make layering more clear
#define _______ KC_TRNS
#define XXXXXXX KC_NO
#define C(n) RCTL(n)
#define CADKEY RCTL(RALT(KC_DEL))
void tap(uint16_t keycode){
register_code(keycode);
unregister_code(keycode);
};
void persistant_default_layer_set(uint16_t default_layer){
eeconfig_update_default_layer(default_layer);
default_layer_set(default_layer);
};
// Automatic number generation of important keywords
enum my_keycodes{
// Layer numbers
_COLEMAK = 0,
_SWCOLE,
_RAISE,
_LOWER,
_ADJUST,
_UNICODES,
// These use process_record_user()
COLEMAK = SAFE_RANGE,
SWCOLE,
LOWER,
RAISE,
SHFT_CAP,
CTRLB,
CPYPST,
FACE,
UNIWIN,
UNILIN,
DISFACE,
TFLIP,
TPUT,
SHRUG,
RANDIG,
// Tap_Dance nums
RAI = 0,
LOW,
SUP
};
#ifdef AUDIO_ENABLE
#include "audio.h"
float tone_startup[][2] = SONG(STARTUP_SOUND);
float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
float tone_colemak[][2] = SONG(COLEMAK_SOUND);
float tone_swcole[][2] = SONG(QWERTY_SOUND);
float tone_capslock_on[][2] = SONG(CAPS_LOCK_ON_SOUND);
float tone_capslock_off[][2] = SONG(CAPS_LOCK_OFF_SOUND);
float tone_ctrl_mod[][2] = SONG(COIN_SOUND);
float tone_copy[][2] = SONG(SCROLL_LOCK_ON_SOUND);
float tone_paste[][2] = SONG(SCROLL_LOCK_OFF_SOUND);
float uniwin[][2] = SONG(UNICODE_WINDOWS);
float unilin[][2] = SONG(UNICODE_LINUX);
#endif
#ifdef TAP_DANCE_ENABLE
#define TAPPING_TERM 200
void dance_raise_press(qk_tap_dance_state_t *state, void *user_data){// Called on each tap
switch(state->count){ // Only turn the layer on once
case 1:
layer_off(_UNICODES);
layer_on(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
break;
}
};
void dance_raise_lift(qk_tap_dance_state_t *state, void *user_data){ // Called on release
switch(state->count){
case 1: // Normal action. Turn off layers
layer_off(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
layer_off(_UNICODES);
break;
}
};
/////////////////////////////////////////////////////////////////////
void dance_lower_press(qk_tap_dance_state_t *state, void *user_data){// Called on tap
switch(state->count){
case 1: // Turn on lower
layer_off(_UNICODES);
layer_on(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
break;
}
};
void dance_lower_lift(qk_tap_dance_state_t *state, void *user_data){ // Called on release
switch(state->count){
case 1: // Normal action. Turn off layers
layer_off(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
layer_off(_UNICODES);
break;
case 2: // Turn on _UNICODES layer
layer_off(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
layer_on(_UNICODES);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_ctrl_mod, false, 0);
#endif
break;
}
};
/////////////////////////////////////////////////////////////////////
void dance_super_press(qk_tap_dance_state_t *state, void *user_data){ // Called on down
if(state->count == 1){
register_code(KC_LGUI);
}
}
void dance_super_done(qk_tap_dance_state_t *state, void *user_data){ // Called on timeout
switch(state->count){
case 2:
register_code(KC_LGUI);
tap(KC_L);
unregister_code(KC_LGUI);
break;
}
}
void dance_super_lift(qk_tap_dance_state_t *state, void *user_data){ // Called on up
unregister_code(KC_LGUI);
}
qk_tap_dance_action_t tap_dance_actions[] = {
[RAI] = ACTION_TAP_DANCE_FN_ADVANCED(dance_raise_press, NULL, dance_raise_lift),
[LOW] = ACTION_TAP_DANCE_FN_ADVANCED(dance_lower_press, NULL, dance_lower_lift),
[SUP] = ACTION_TAP_DANCE_FN_ADVANCED(dance_super_press, dance_super_done, dance_super_lift)
};
#endif
//#ifdef UNICODE_ENABLE
// Unicode shortcuts
#define IBANG X(0x203D)
#define RAROW X(0x2192)
#define LAROW X(0x2190)
#define DEGREE X(0x00B0)
#define OMEGA X(0x03A9)
#define WOMEGA X(0x03C9)
#define MICRO X(0x00B5)
#define PLUMIN X(0x00B1)
#define SUPA2 X(0x00B2)
#define ROMAN1 X(0x2160)
#define ROMAN2 X(0x2161)
#define ROMAN3 X(0x2162)
#define ROMAN4 X(0x2163)
#define ROMAN5 X(0x2164)
#define ROMAN6 X(0x2165)
#define ROMAN7 X(0x2166)
#define roman1 X(0x2170)
#define roman2 X(0x2171)
#define roman3 X(0x2172)
#define roman4 X(0x2173)
#define roman5 X(0x2174)
#define roman6 X(0x2175)
#define roman7 X(0x2176)
#ifdef UNICODEMAP_ENABLE // For Unicode characters larger than 0x8000. Send with X(<unicode>)
enum Ext_Unicode{
PENGUIN = 0,
BOAR,
MONKEY,
DRAGON,
CHICK,
TUMBLER
};
const uint32_t PROGMEM unicode_map[] = {
[PENGUIN] = 0x1F427,
[BOAR] = 0x1F417,
[MONKEY] = 0x1F412,
[DRAGON] = 0x1F409,
[CHICK] = 0x1F425,
[TUMBLER] = 0x1F943
};
#define PENGY X(PENGUIN)
#define BOARY X(BOAR)
#define MNKY X(MONKEY)
#define DRGN X(DRAGON)
#define DUCK X(CHICK)
#define TMBL X(TUMBLER)
#endif
//#endif
static uint16_t key_timer;
static uint8_t caps_status = 0;
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case COLEMAK:
if(record->event.pressed){
persistant_default_layer_set(1UL<<_COLEMAK);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_colemak, false, 0);
#endif
}
return false;
break;
case SWCOLE:
if(record->event.pressed){
persistant_default_layer_set(1UL<<_SWCOLE);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_swcole, false, 0);
#endif
}
return false;
break;
case RAISE:
if(record->event.pressed){
layer_on(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_RAISE);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case LOWER:
if(record->event.pressed){
layer_on(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
} else {
layer_off(_LOWER);
update_tri_layer(_LOWER, _RAISE, _ADJUST);
}
return false;
break;
case SHFT_CAP:
if(record->event.pressed){
key_timer = timer_read(); // if the key is being pressed, we start the timer.
register_code(KC_LSHIFT);
} else { // this means the key was just released (tap or "held down")
if(timer_elapsed(key_timer) < 152){ // Time in ms, the threshold we pick for counting something as a tap.
tap(KC_CAPS);
if(caps_status == 0){
caps_status = 1;
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_capslock_on, false, 0);
#endif
} else {
caps_status = 0;
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_capslock_off, false, 0);
#endif
}
}
unregister_code(KC_LSHIFT);
}
return false;
break;
case CTRLB: // Control-B on tap (bold)
if(record->event.pressed){
key_timer = timer_read(); // if the key is being pressed, we start the timer.
register_code(KC_LCTL);
} else { // this means the key was just released (tap or "held down")
if (timer_elapsed(key_timer) < 152) { // Time in ms, the threshold we pick for counting something as a tap.
tap(KC_B);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_ctrl_mod, false, 0);
#endif
#ifdef BACKLIGHT_BREATHING
breathing_speed_set(2);
breathing_pulse();
#endif
}
unregister_code(KC_LCTL);
}
return false;
break;
case CPYPST: // One key copy/paste
if(record->event.pressed){
key_timer = timer_read();
} else {
if (timer_elapsed(key_timer) > 152) { // Hold, copy
register_code(KC_LCTL);
tap(KC_C);
unregister_code(KC_LCTL);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_copy, false, 0);
#endif
} else { // Tap, paste
register_code(KC_LCTL);
tap(KC_V);
unregister_code(KC_LCTL);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(tone_paste, false, 0);
#endif
}
}
return false;
break;
#ifdef UNICODE_ENABLE
case UNIWIN:
if(record->event.pressed){
set_unicode_input_mode(UC_WIN);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(uniwin, false, 0);
#endif
}
return false;
break;
case UNILIN:
if(record->event.pressed){
set_unicode_input_mode(UC_LNX);
#ifdef AUDIO_ENABLE
PLAY_NOTE_ARRAY(unilin, false, 0);
#endif
}
return false;
break;
case DISFACE: // ಠ_ಠ
if(record->event.pressed){
process_unicode((0x0CA0|QK_UNICODE), record); // Eye
register_code(KC_RSFT);
tap(KC_MINS);
unregister_code(KC_RSFT);
process_unicode((0x0CA0|QK_UNICODE), record); // Eye
}
return false;
break;
case TFLIP: // (╯°□°)╯ ︵ ┻━┻
if(record->event.pressed){
register_code(KC_RSFT);
tap(KC_9);
unregister_code(KC_RSFT);
process_unicode((0x256F|QK_UNICODE), record); // Arm
process_unicode((0x00B0|QK_UNICODE), record); // Eye
process_unicode((0x25A1|QK_UNICODE), record); // Mouth
process_unicode((0x00B0|QK_UNICODE), record); // Eye
register_code(KC_RSFT);
tap(KC_0);
unregister_code(KC_RSFT);
process_unicode((0x256F|QK_UNICODE), record); // Arm
tap(KC_SPC);
process_unicode((0x0361|QK_UNICODE), record); // Flippy
tap(KC_SPC);
process_unicode((0x253B|QK_UNICODE), record); // Table
process_unicode((0x2501|QK_UNICODE), record); // Table
process_unicode((0x253B|QK_UNICODE), record); // Table
}
return false;
break;
case TPUT: // ┬──┬ ( ゜-゜ノ)
if(record->event.pressed){
process_unicode((0x252C|QK_UNICODE), record); // Table
process_unicode((0x2500|QK_UNICODE), record); // Table
process_unicode((0x2500|QK_UNICODE), record); // Table
process_unicode((0x252C|QK_UNICODE), record); // Table
tap(KC_SPC);
process_unicode((0x30CE|QK_UNICODE), record); // Arm
register_code(KC_RSFT);
tap(KC_9);
unregister_code(KC_RSFT);
tap(KC_SPC);
process_unicode((0x309C|QK_UNICODE), record); // Eye
tap(KC_MINS);
process_unicode((0x309C|QK_UNICODE), record); // Eye
process_unicode((0x30CE|QK_UNICODE), record); // Arm
register_code(KC_RSFT);
tap(KC_0);
unregister_code(KC_RSFT);
}
return false;
break;
case SHRUG: // ¯\_(ツ)_/¯
if(record->event.pressed){
process_unicode((0x00AF|QK_UNICODE), record); // Hand
tap(KC_BSLS); // Arm
register_code(KC_RSFT);
tap(KC_UNDS); // Arm
tap(KC_LPRN); // Head
unregister_code(KC_RSFT);
process_unicode((0x30C4|QK_UNICODE), record); // Face
register_code(KC_RSFT);
tap(KC_RPRN); // Head
tap(KC_UNDS); // Arm
unregister_code(KC_RSFT);
tap(KC_SLSH); // Arm
process_unicode((0x00AF|QK_UNICODE), record); // Hand
}
return false;
break;
#endif
case FACE: // (o_O)
if(record->event.pressed){
register_code(KC_RSFT);
tap(KC_LPRN);
unregister_code(KC_RSFT);
tap(KC_O);
register_code(KC_RSFT);
tap(KC_UNDS);
tap(KC_O);
tap(KC_RPRN);
unregister_code(KC_RSFT);
}
return false;
break;
case RANDIG:
if (record->event.pressed) {
tap_random_base64();
}
return false;
break;
}
return true;
};
void matrix_init_user(void){ // Run once at startup
#ifdef AUDIO_ENABLE
_delay_ms(50); // gets rid of tick
PLAY_NOTE_ARRAY(tone_startup, false, 0);
#endif
}
#ifdef AUDIO_ENABLE
void play_goodbye_tone(void){
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
_delay_ms(150);
}
void shutdown_user(){
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
_delay_ms(150);
stop_all_notes();
}
void music_on_user(void){ // Run when the music layer is turned on
PLAY_NOTE_ARRAY(tone_startup, false, 0);
}
void music_off_user(void){ // Run when music is turned off
PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
}
#endif
#endif

@ -58,13 +58,13 @@ EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= no # Console for debug(+400)
COMMAND_ENABLE ?= no # Commands for debug and configuration
NKRO_ENABLE ?= no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
BACKLIGHT_ENABLE ?= yes # Enable keyboard backlight functionality
MIDI_ENABLE ?= yes # MIDI controls
AUDIO_ENABLE ?= yes # Audio output on port C6
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight.
API_SYSEX_ENABLE ?= yes
API_SYSEX_ENABLE ?= no
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend

@ -0,0 +1,24 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = no # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = no # Commands for debug and configuration
SLEEP_LED_ENABLE = no # Enables your LED to breathe while your computer is sleeping.
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = no # Audio output on port C6
UNICODEMAP_ENABLE = no # This allows sending unicode symbols using X(<unicode>) in your keymap.
UNICODE_ENABLE =no # Unicode
UCIS_ENABLE = no # Keep in mind that not all will work (See WinCompose for details on Windows).
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
SLEEP_LED_ENABLE = no# Breathing sleep LED during USB suspend
API_SYSEX_ENABLE = no # This enables using the Quantum SYSEX API to send strings
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,96 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_H_ADMSTROK
#define CONFIG_H_ADMSTROK
#include "config_common.h"
#include "../../config.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6060
#define DEVICE_VER 0x0003
#define MANUFACTURER SATAN
#define PRODUCT GH60
#define DESCRIPTION QMK keyboard firmware for Satan GH60 with WS2812 support
/* key matrix size */
#define MATRIX_ROWS 5
#define MATRIX_COLS 14
// ROWS: Top to bottom, COLS: Left to right
#define MATRIX_ROW_PINS { D0, D1, D2, D3, D5 }
#define MATRIX_COL_PINS { F0, F1, E6, C7, C6, B7, D4, B1, B0, B5, B4, D7, D6, B3 }
#define UNUSED_PINS
#define BACKLIGHT_PIN B6
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST
/* Set 0 if debouncing isn't needed */
#define DEBOUNCING_DELAY 5
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/* key combination for command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/* Backlight configuration */
#define BACKLIGHT_LEVELS 4
/* Underlight configuration */
#define RGB_DI_PIN E2
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 8 // Number of LEDs
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17
#define RGBLIGHT_VAL_STEP 17
#define DISABLE_SPACE_CADET_ROLLOVER
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
#endif

@ -0,0 +1,195 @@
#include "satan.h"
static uint16_t key_timer;
bool checktime(void){
return (timer_elapsed(key_timer) < 150) ? true : false;
};
// general keydefs
#define norm 0 // Default layer
#define elev 1 // Layer directional keys
#define supr 2 // F-keys and mediakeys
#define spac 3 //
#define FNO1 4 //
#define FNO2 5 //
#define FNO3 6 //
#define MAC0 M(0) //
#define MAC1 M(1) //
#define MAC2 M(2) //
#define MAC3 M(3) //
#define MAC4 M(4) //
#define MAC5 M(5) //
#define MAC6 M(6) //
#define MAC7 M(7) //
#define MAC8 M(8) //
#define MAC9 M(9) //
#define GRAV KC_GRV //
#define MEDI F(FNO1)//
// General shortenings
#define ESCA KC_ESC
#define MINS KC_MINS
#define EQUL KC_EQL
#define BSPC KC_BSPC
#define DELE KC_DEL
#define LBRC KC_LBRC
#define RBRC KC_RBRC
#define ALTR KC_RALT
#define SCLN KC_SCLN
#define QUOT KC_QUOT
#define NUHS KC_NUHS
#define ENTE KC_ENT
#define NUBS KC_NUBS // Less/ greater sign
#define COMM KC_COMM // Comma
#define FSTO KC_DOT // Full stop
#define SLSH KC_SLSH
#define ALTL KC_LALT
#define GUIL KC_LGUI
#define GUIR KC_RGUI
#define MENO KC_MENU
// The F-row/layer:
#define FK01 KC_F1
#define FK02 KC_F2
#define FK03 KC_F3
#define FK04 KC_F4
#define FK05 KC_F5
#define FK06 KC_F6
#define FK07 KC_F7
#define FK08 KC_F8
#define FK09 KC_F9
#define FK10 KC_F10
#define FK11 KC_F11
#define FK12 KC_F12
#define FK13 KC_F13
#define FK14 KC_F14
// Special Actions and Media Keys
#define INSE KC_INS // Insert here
#define HOME KC_HOME // Go to beginning of line
#define ENDI KC_END // go to end of line
#define PSCR KC_PSCR // Print Screen
#define SLCK KC_SLCK // go to end of line
#define PGDN KC_PGDN // go to end of line
#define PGUP KC_PGUP // go to end of line
#define PLPS KC_MPLY // Play/Pause
#define PAUS KC_PAUS // Pause button
#define MUTE KC_MUTE // Mute sound
#define VOLU KC_VOLU // Volume increase
#define VOLD KC_VOLD // Volume decrease
#define MNXT KC_MNXT // next track
#define MPRV KC_MPRV // prev track
#define MSTP KC_MSTP // stop playing
#define MSEL KC_MSEL // Select media (Start playing it)
#define MAIL KC_MAIL // Open default mail app
#define CALC KC_CALC // Open default calculator app
#define MYCM KC_MYCM // Open default file manager
//#define LILO KC_XXXXXX // Reserved for later
//#define LIHI KC_XXXXXX // Reserved for later
// dual-role shortcuts
#define DUTB LT(elev, KC_TAB) // `tabs` layer on hold and tab on tap
#define DUSP LT(spac, KC_SPACE) // `spce` layer on hold and space on tap
#define LOCK LGUI(KC_L) // lock computer (win)
// Space Admiral Strokers
#define SADL MAC0 // Hold for lshift and { on tap
#define SADR MAC1 // Hold for rshift and } on tap
#define CADL MAC2 // Hold for lctrl and [ on tap
#define CADR MAC3 // Hold for rctrl and ] on tap
// arrow cluster duality bottom right corner
#define ARLF ALT_T(KC_LEFT) // Left arrow
#define ARRT CTL_T(KC_RIGHT)// Right arrow
#define ARUP SFT_T(KC_UP) // Up arrow
#define ARDN GUI_T(KC_DOWN) // Down arrow
// brackets
#define NOCL RALT(KC_7) // [
#define NOCR RALT(KC_0) // ]
#define NOPL LSFT(KC_8) // (
#define NOPR LSFT(KC_9) // )
#define NOAL KC_NUBS // <
#define NOAR LSFT(KC_NUBS) // >
#define NOBL RALT(KC_8) // [
#define NOBR RALT(KC_9) // ]
// increase readability
#define XXXX KC_TRNS
#define DEAD KC_NO
#define SCAN KC_TRNS // Scandinavian keys, the Row 5 key 5 is actually Row 1 key 15 on the PCB
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[ norm ] = KEYMAP( // Normal scandinavian mapping (danish has QUOT and SCLN wapped)
GRAV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, MINS, EQUL, BSPC, DELE,\
DUTB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, LBRC, RBRC, DEAD,\
ALTR, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, SCLN, QUOT, NUHS, ENTE,\
SADL, NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, COMM, FSTO, SLSH, SADR, DEAD,\
CADL, ALTL, GUIL, DUSP, GUIR, MEDI, MENO, CADR),
[ elev ] = KEYMAP( // The f-Row (with f13-14), Special keys and media keys
LOCK, FK01, FK02, FK03, FK04, FK05, FK06, FK07, FK08, FK09, FK10, FK11, FK12, FK13, FK14,\
XXXX, XXXX, XXXX, XXXX, MAIL, XXXX, XXXX, HOME, INSE, PSCR, SLCK, PAUS, PGUP, XXXX,\
XXXX, XXXX, XXXX, XXXX, MYCM, XXXX, XXXX, MPRV, PAUS, MNXT, XXXX, XXXX, PGDN, ENDI,\
XXXX, XXXX, XXXX, XXXX, CALC, XXXX, XXXX, XXXX, MUTE, VOLD, VOLU, XXXX, ARUP, DEAD,\
XXXX, XXXX, XXXX, PLPS, XXXX, ARLF, ARDN, ARRT),
[ spac ] = KEYMAP( // The space controls (by pressing space)
XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX,\
XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX,\
XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX,\
XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, DEAD,\
XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX),
[ supr ] = KEYMAP( // Additional layer for later use.
XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX,\
XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX,\
XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX,\
XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, DEAD,\
XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX),
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { // MACRODOWN only works in this function
switch(id) {
case 0: //MAC0 - Hold for lshift and { on tap
if (record->event.pressed) {
key_timer = timer_read();
return MACRO(D(LSFT), END );
} else {
return checktime() ? MACRO(U(LSFT),D(RALT),T(7),U(RALT),END): MACRO(U(LSFT),END);
}; break;
case 1: //MAC1 - Hold for rshift and } on tap
if (record->event.pressed) {
key_timer = timer_read();
return MACRO(D(RSFT), END );
} else {
return checktime() ? MACRO(U(RSFT),D(RALT),T(0),U(RALT),END): MACRO(U(RSFT),END);
}; break;
case 2: //MAC2 - Hold for lctrl and [ on tap
if (record->event.pressed) {
key_timer = timer_read();
return MACRO(D(LCTL), END );
} else {return checktime() ? MACRO(U(LCTL),D(RALT),T(8),U(RALT),END):MACRO(U(LCTL),END);
}; break;
case 3: //MAC3 - Hold for rctrl and ] on tap
if (record->event.pressed) {
key_timer = timer_read();
return MACRO(D(RCTL), END );
} else {
return checktime() ? MACRO(U(RCTL),D(RALT),T(9),U(RALT),END):MACRO(U(RCTL),END);
}; break;
case 4: //MAC4 reserved for later.
if (record->event.pressed) { } else { }; break;
case 5: //MAC5 reserved for later.
if (record->event.pressed) { } else { }; break;
case 6: //MAC6 reserved for later.
if (record->event.pressed) { } else { }; break;
} return MACRO_NONE;
};
/*
Later use:
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { }
enum function_id { };
const uint16_t PROGMEM fn_actions[] = { };
*/

@ -0,0 +1,13 @@
# Admiral Strokers keymap
## For the Satan GH60 PCB
The Admiral STN60 is a layout for users of the satan GH60, optimized with some nice features such as mod tap for brackets (Similar to Space Cadett), space mod for F-row/ layer with easy to access media and control keys. The layout below is just as an example and is ISO based, ANSI and JIS layouts will be included later.
``````
[ _tmp ] = KEYMAP( // Copy this to get started. SCAN is scandinavian layout specific.
XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX,\
XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, DEAD,\
XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, SCAN, XXXX,\
XXXX, SCAN, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, DEAD,\
XXXX, XXXX, XXXX, XXXX, SCAN, XXXX, XXXX, XXXX, XXXX),\
```

@ -0,0 +1,21 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
MIDI_ENABLE = yes # MIDI support (+2400 to 4200, depending on config)
AUDIO_ENABLE = no # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,29 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -0,0 +1,77 @@
#include "satan.h"
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _BL 0
#define _ML 1
// readability
#define _______ KC_TRNS
#define XXXXXXX KC_NO
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap _BL: (Base Layer) Default Layer
* ,-----------------------------------------------------------.
* |Esc | 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backsp |
* |-----------------------------------------------------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \ |
* |-----------------------------------------------------------|
* |CAPS | A| S| D| F| G| H| J| K| L| ;| '|Return |
* |-----------------------------------------------------------|
* |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |
* |-----------------------------------------------------------|
* |Ctrl|Gui |Alt | Space |Alt |Gui |Midi|Ctrl |
* `-----------------------------------------------------------'
*/
[_BL] = KEYMAP_ANSI(
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC,KC_BSLS, \
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT, KC_ENT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_RSFT, \
KC_LCTL, KC_LGUI,KC_LALT, KC_SPC, KC_RALT,KC_RGUI, TG(_ML), KC_RCTL),
#if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
/* Keymap _ML: MIDI Layer (Advanced)
* ,------------------------------------------------------------------------.
* | Exit | | | | | | | | | | | | | |
* |------------------------------------------------------------------------|
* | Ch+ | | C# | D# | | F# | G# | A# | | C# | D# | | | |
* |------------------------------------------------------------------------|
* | Mod | C | D | E | F | G | A | B | C | D | E | F | |
* |------------------------------------------------------------------------|
* | Sustain |Oct-|Oct+|Mod-|Mod+| | | |Tns-|Tns+|Tns0| Sustain |
* |------------------------------------------------------------------------|
* | | | | All notes off | | | | |
* `------------------------------------------------------------------------'
*/
[_ML] = KEYMAP_ANSI(
TG(_ML), MI_VEL_1, MI_VEL_2, MI_VEL_3, MI_VEL_4, MI_VEL_5, MI_VEL_6, MI_VEL_7, MI_VEL_8, MI_VEL_9, MI_VEL_10, XXXXXXX, XXXXXXX, XXXXXXX, \
MI_CHU, XXXXXXX, MI_Cs, MI_Ds, XXXXXXX, MI_Fs, MI_Gs, MI_As, XXXXXXX, MI_Cs_1, MI_Ds_1, XXXXXXX, XXXXXXX, XXXXXXX, \
MI_MOD, MI_C, MI_D, MI_E, MI_F, MI_G, MI_A, MI_B, MI_C_1, MI_D_1, MI_E_1, MI_F_1, _______, \
MI_SUS, MI_OCTD, MI_OCTU, MI_MODSD, MI_MODSU, XXXXXXX, XXXXXXX, XXXXXXX, MI_TRNSD, MI_TRNSU, MI_TRNS_0, MI_SUS, \
_______, _______, _______, MI_ALLOFF, _______, _______, _______, _______),
#elif defined(MIDI_ENABLE) && defined(MIDI_BASIC)
/* Keymap _ML: MIDI Layer (Advanced)
* ,------------------------------------------------------------------------.
* | Exit | | | | | | | | | | | | | |
* |------------------------------------------------------------------------|
* | | | | | | | | | | | | | | |
* |------------------------------------------------------------------------|
* | | | | | | | | | | | | | |
* |------------------------------------------------------------------------|
* | |MuOn|MuOf|MiOn|MiOf| | | | | | | |
* |------------------------------------------------------------------------|
* | | | | | | | | |
* `------------------------------------------------------------------------'
*/
[_ML] = KEYMAP_ANSI(
TG(_ML), _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
_______, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, _______, _______, _______, \
_______, _______, _______, _______, _______, _______, _______, _______),
#endif
};

@ -0,0 +1 @@
# Satan GH60 layout demonstrating MIDI key mapping

@ -0,0 +1,21 @@
# Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
AUDIO_ENABLE = no # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,141 @@
#include "satan.h"
// Used for SHIFT_ESC
#define MODS_CTRL_MASK (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT))
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _QWERTY 0
#define _COLEMAK 1
#define _DVORAK 2
#define _FUNC 3
enum planck_keycodes {
QWERTY = SAFE_RANGE,
COLEMAK,
DVORAK
};
#define _______ KC_TRNS
#define XXXXXXX KC_NO
// Custom macros
#define ALT_GRV ALT_T(KC_GRV) // Tap for Backtick, hold for Alt
#define CTL_ESC CTL_T(KC_ESC) // Tap for Esc, hold for Ctrl
#define HPR_TAB ALL_T(KC_TAB) // Tap for Tab, hold for Hyper (Super+Ctrl+Shift+Alt)
#define SFT_ENT SFT_T(KC_ENT) // Tap for Enter, hold for Shift
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap _QWERTY: (Base Layer) Default Layer
* ,-----------------------------------------------------------.
* |Esc~| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backsp |
* |-----------------------------------------------------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \ |
* |-----------------------------------------------------------|
* |CAPS | A| S| D| F| G| H| J| K| L| ;| '|Return |
* |-----------------------------------------------------------|
* |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |
* |-----------------------------------------------------------|
* |Ctrl|Gui |Alt | Space |Alt |Gui |Fn |Ctrl |
* `-----------------------------------------------------------'
*/
[_QWERTY] = KEYMAP_ANSI(
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, \
HPR_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC,KC_BSLS, \
CTL_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT, KC_ENT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, SFT_ENT, \
KC_LCTL, KC_LGUI,KC_LALT, KC_SPC, KC_RALT,KC_RGUI,MO(_FUNC),KC_RCTL),
/* Keymap _COLEMAK: (Base Layer) Default Layer
* ,-----------------------------------------------------------.
* |Esc~| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backsp |
* |-----------------------------------------------------------|
* |Tab | Q| W| F| P| G| J| L| U| Y| ;| [| ]| \ |
* |-----------------------------------------------------------|
* |CAPS | A| R| S| T| D| H| N| E| I| O| '|Return |
* |-----------------------------------------------------------|
* |Shift | Z| X| C| V| B| K| M| ,| .| /|Shift |
* |-----------------------------------------------------------|
* |Ctrl|Gui |Alt | Space |Alt |Gui |Fn |Ctrl |
* `-----------------------------------------------------------'
*/
[_COLEMAK] = KEYMAP_ANSI(
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, \
HPR_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN,KC_LBRC, KC_RBRC,KC_BSLS, \
CTL_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O ,KC_QUOT, KC_ENT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM,KC_DOT, KC_SLSH, SFT_ENT, \
KC_LCTL, KC_LGUI,KC_LALT, KC_SPC, KC_RALT,KC_RGUI,MO(_FUNC),KC_RCTL),
/* Keymap _DVORAK: (Base Layer) Default Layer
* ,-----------------------------------------------------------.
* |Esc~| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| [| ]|Backsp |
* |-----------------------------------------------------------|
* |HypTb| '| ,| .| P| Y| F| G| C| R| L| /| =| \ |
* |-----------------------------------------------------------|
* |CtrlEsc| A| O| E| U| I| D| H| T| N| S| -|Return |
* |-----------------------------------------------------------|
* |Shift | ;| Q| J| K| X| B| M| W| V| Z|ShiftEnter|
* |-----------------------------------------------------------|
* |Ctrl|Gui |Alt | Space |Alt |Gui |Fn |Ctrl |
* `-----------------------------------------------------------'
*/
[_DVORAK] = KEYMAP_ANSI(
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_LBRC, KC_RBRC,KC_BSPC, \
HPR_TAB, KC_QUOT,KC_COMM,KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_SLSH, KC_EQL, KC_BSLS, \
CTL_ESC, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_MINS, KC_ENT, \
KC_LSFT, KC_SCLN,KC_Q, KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, SFT_ENT, \
KC_LCTL, KC_LGUI,KC_LALT, KC_SPC, KC_RALT,KC_RGUI,MO(_FUNC),KC_RCTL),
/* Keymap _FUNC: Function Layer
* ,-----------------------------------------------------------.
* | | F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete |
* |-----------------------------------------------------------|
* | |Hom| UP|End| | | |Qwt|Cmk|Dvk| |BL-|BL+|BL |
* |-----------------------------------------------------------|
* | |LFT| DN| RT| | |LFT| DN| UP| RT|Vo+|Pg+| |
* |-----------------------------------------------------------|
* | | | |Prv|Ply|Nxt| | | |Vo-|Pg-| |
* |-----------------------------------------------------------|
* |RESET| | | | | | | |
* `-----------------------------------------------------------'
*/
[_FUNC] = KEYMAP_ANSI(
_______,KC_F1 ,KC_F2 ,KC_F3 ,KC_F4 ,KC_F5 ,KC_F6 ,KC_F7 ,KC_F8 ,KC_F9 ,KC_F10 ,KC_F11 ,KC_F12 ,KC_DEL, \
_______,KC_HOME,KC_UP ,KC_END ,_______,_______,_______,QWERTY ,COLEMAK,DVORAK ,_______,BL_DEC ,BL_INC ,BL_TOGG, \
_______,KC_LEFT,KC_DOWN,KC_RGHT,_______,_______,KC_LEFT,KC_DOWN,KC_UP ,KC_RGHT,KC_VOLU,KC_PGUP ,_______, \
_______ ,_______,_______,KC_MPRV,KC_MPLY,KC_MNXT,_______,_______,_______,KC_VOLD,KC_PGDN ,_______, \
RESET ,_______,_______ ,_______ ,_______,_______,_______,_______
)
};
void persistant_default_layer_set(uint16_t default_layer) {
eeconfig_update_default_layer(default_layer);
default_layer_set(default_layer);
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case QWERTY:
if (record->event.pressed) {
persistant_default_layer_set(1UL<<_QWERTY);
}
return false;
break;
case COLEMAK:
if (record->event.pressed) {
persistant_default_layer_set(1UL<<_COLEMAK);
}
return false;
break;
case DVORAK:
if (record->event.pressed) {
persistant_default_layer_set(1UL<<_DVORAK);
}
return false;
break;
}
return true;
}

@ -0,0 +1 @@
# smt's Satan GH60 layout

@ -0,0 +1,29 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
#endif

@ -1,9 +1,5 @@
#include "tada68.h"
// Used for SHIFT_ESC
#define MODS_CTRL_MASK (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT))
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
@ -36,63 +32,21 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap _FL: Function Layer
* ,----------------------------------------------------------------.
* | | | | | | | | | | | | | | RESET| |
* | | F1|F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|Del |Ins |
* |----------------------------------------------------------------|
* | | | | | | | | | | | |BL-|BL+|BL | |
* | | |Up | | | | | | | | | | | |Hme |
* |----------------------------------------------------------------|
* | | | | | | | | | | | | | |
* | |<- |Dn | ->| | | | | | | | | |End |
* |----------------------------------------------------------------|
* | | F1|F2 | F3|F4 | F5| F6| F7| F8| | | | | |
* | | | |Bl-|BL |BL+| |VU-|VU+|MUT| |MouseL|MsU|Rck |
* |----------------------------------------------------------------|
* | | | | | | | | | | |
* | | | | | | | |MsL|MsD|MsR |
* `----------------------------------------------------------------'
*/
[_FL] = KEYMAP_ANSI(
#ifdef RGBLIGHT_ENABLE
_______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,RESET,_______, \
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, BL_DEC,BL_INC, BL_TOGG,_______, \
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,_______, \
_______,RGB_TOG,RGB_MOD,RGB_HUI,RGB_HUD,RGB_SAI,RGB_SAD,RGB_VAI,RGB_VAD,_______,_______,_______,_______,_______, \
_______,_______,_______, _______, _______,_______,_______,_______,_______, _______),
#else
_______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,RESET,_______, \
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, BL_DEC,BL_INC, BL_TOGG,_______, \
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,_______, \
_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, \
_______,_______,_______, _______, _______,_______,_______,_______,_______, _______),
#endif
};
/*enum function_id {
//SHIFT_ESC,
_______, KC_F1 ,KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_INS , \
_______,_______,KC_UP, _______,_______,_______,_______,_______,_______,_______,_______, BL_DEC,BL_INC, BL_TOGG,KC_HOME, \
_______,KC_LEFT,KC_DOWN,KC_RIGHT,_______,_______,_______,_______,_______,_______,_______,_______, _______,KC_END, \
_______,_______,_______,BL_DEC, BL_TOGG,BL_INC, _______,KC_VOLD,KC_VOLU,KC_MUTE,_______,KC_BTN1, KC_MS_U, KC_BTN2, \
_______,_______,_______, _______, _______,_______,_______,KC_MS_L,KC_MS_D, KC_MS_R),
};
const uint16_t PROGMEM fn_actions[] = {
//[0] = ACTION_FUNCTION(SHIFT_ESC),
};
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
static uint8_t shift_esc_shift_mask;
switch (id) {
case SHIFT_ESC:
shift_esc_shift_mask = get_mods()&MODS_CTRL_MASK;
if (record->event.pressed) {
if (shift_esc_shift_mask) {
add_key(KC_GRV);
send_keyboard_report();
} else {
add_key(KC_ESC);
send_keyboard_report();
}
} else {
if (shift_esc_shift_mask) {
del_key(KC_GRV);
send_keyboard_report();
} else {
del_key(KC_ESC);
send_keyboard_report();
}
}
break;
}
}*/

@ -1 +1,3 @@
# default TADA68 layout
This layout replicates the default factory layout of the TADA68.

@ -1,4 +1,15 @@
TADA68 keyboard firmware
======================
========================
TODO: to be updated.
1) from the keyboards/tada68 directory run:
```
$ make flashbin
```
2) hit the reset button on the TADA, the lights will start flashing.
3) You'll see a new drive on your computer called TADA68. Backup the original factory `FLASH.BIN` file thats inside it.
4) Delete `FLASH.BIN` from the TADA drive and copy `tada68_default.bin` that was generated at the root of the qmk directory into the TADA drive.
5) Hit ESC on the keyboard. The lights will stop flashing and your firmware is loaded!

@ -32,8 +32,8 @@ enum planck_keycodes {
// Custom macros
#define CTL_ESC CTL_T(KC_ESC) // Tap for Esc, hold for Ctrl
#define SFT_ENT SFT_T(KC_ENT) // Tap for Enter, hold for Shift
#define HPR_TAB ALL_T(KC_TAB) // Tap for Tab, hold for Hyper
#define ALT_GRV ALT_T(KC_GRV) // Tap for Backtick, hold for Alt
#define HPR_TAB ALL_T(KC_TAB) // Tap for Tab, hold for Hyper (Super+Ctrl+Alt+Shift)
#define ALT_GRV ALT_T(KC_GRV) // Tap for Backtick, hold for Alt (Ctrl+Alt+Shift)
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
@ -117,13 +117,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[_LOWER] = KEYMAP_TV45(
/*,--------+-------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-----------------.*/
KC_0 , KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL ,
ALL_T(KC_0), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL ,
/*|--------`-------`--------`--------`--------`--------`--------`--------`--------`--------`--------`-----------------|*/
KC_DLR , KC_4, KC_5, KC_6, KC_DOT, KC_PLUS, KC_ASTR, KC_4, KC_5, KC_6, KC_DOT, KC_PGUP ,
CTL_T(KC_DLR), KC_4, KC_5, KC_6, KC_DOT, KC_PLUS, KC_ASTR, KC_4, KC_5, KC_6, KC_DOT, KC_PGUP ,
/*|---------`-------`--------`--------`--------`--------`--------`--------`--------`--------`--------`----------------|*/
KC_EQL , KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_SLSH, KC_1, KC_2, KC_3, KC_UP, KC_PGDN ,
SFT_T(KC_EQL), KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_SLSH, KC_1, KC_2, KC_3, KC_UP, SFT_T(KC_PGDN),
/*|----------`-------`--------`--------`--------`--------`--------`--------`--------`--------`--------`---------------|*/
BACKLIT , _______ , _______ , KC_HOME , KC_END , _______ , KC_LEFT, KC_DOWN, KC_RGHT ),
ALT_T(BACKLIT), _______ , _______ , KC_HOME , KC_END , _______ , KC_LEFT, KC_DOWN, KC_RGHT ),
/*`---------+---------------+---------+-------^^^------+-------^^^-------+----------+--------+--------+--------------'*/
/* Raise
@ -139,18 +139,18 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[_RAISE] = KEYMAP_TV45(
/*,--------+-------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-----------------.*/
KC_TILD,KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL ,
ALL_T(KC_TILD),KC_EXLM,KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL ,
/*|--------`-------`--------`--------`--------`--------`--------`--------`--------`--------`--------`-----------------|*/
KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_QUES, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE ,
CTL_T(KC_F1), KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_QUES, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE ,
/*|---------`-------`--------`--------`--------`--------`--------`--------`--------`--------`--------`----------------|*/
KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_MINS, KC_SLSH, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS ,
SFT_T(KC_F7), KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_MINS, KC_SLSH, KC_EQL, KC_LBRC, KC_RBRC, SFT_T(KC_BSLS),
/*|----------`-------`--------`--------`--------`--------`--------`--------`--------`--------`--------`---------------|*/
BACKLIT , _______ , _______ , KC_MPLY , KC_MNXT , _______ , KC_MUTE, KC_VOLD, KC_VOLU ),
ALT_T(BACKLIT), _______ , _______ , KC_MPLY , KC_MNXT , _______ , KC_MUTE, KC_VOLD, KC_VOLU ),
/*`---------+---------------+---------+-------^^^------+-------^^^-------+----------+--------+--------+--------------'*/
/* Adjust (Lower + Raise)
* ,---------+------+------+------+------+------+------+------+------+------+------+---------.
* | | Reset| | | | | | | | | | Del |
* | | Reset| | | | | | | | | | Reset |
* |---------`------`------`------`------`------`------`------`------`------`------`---------|
* | | | | | |AGnorm|AGswap|Qwerty|Colemk|Dvorak| | |
* |----------`------`------`------`------`------`------`------`------`------`------`--------|
@ -161,7 +161,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[_ADJUST] = KEYMAP_TV45(
/*,--------+-------+--------+--------+--------+--------+--------+--------+--------+--------+--------+-----------------.*/
_______, RESET , _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL ,
_______, RESET , _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET ,
/*|--------`-------`--------`--------`--------`--------`--------`--------`--------`--------`--------`-----------------|*/
_______ ,_______, _______, _______, _______, AG_NORM, AG_SWAP, QWERTY, COLEMAK, DVORAK, _______, _______ ,
/*|---------`-------`--------`--------`--------`--------`--------`--------`--------`--------`--------`----------------|*/

@ -0,0 +1,13 @@
# cheese's Layout
Customized xd60 keymap
![Base Layout](base_layout.png "Base Layout")
![Fn Layout](fn_layout.png "Fn Layout")
## Programming Instructions:
`cd` into keymap directory, `make dfu`
## Features
- Media keys and movement keys setup like on the pok3r
- Lower right movement keys setup like on the fc660m (fn+direction for home/end/page up and down)
- Caps lock can be triggered by pressing both shift keys at the same time (and deactivated the same way)

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

@ -0,0 +1,67 @@
#include "xd60.h"
#include "action_layer.h"
// Each layer gets a name for readability.
// The underscores don't mean anything - you can
// have a layer called STUFF or any other name.
// Layer names don't all need to be of the same
// length, and you can also skip them entirely
// and just use numbers.
#define _BL 0
#define _FL 1
#define _LS 2
#define _RS 3
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* (Base Layer) Default Layer
* ,-----------------------------------------------------------.
* |Esc~| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backsp |
* |-----------------------------------------------------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \ |
* |-----------------------------------------------------------|
* |FUNCTION| A| S| D| F| G| H| J| K| L| ;| '|Return|
* |-----------------------------------------------------------|
* |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |
* |-----------------------------------------------------------|
* |Ctrl|Gui |Alt | Space |FN|Left|Up|Down|Right|
* `-----------------------------------------------------------'
*/
[_BL] = KEYMAP(
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_BSPC, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, \
MO(_FL), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NO, KC_ENT, \
F(0), KC_NO, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, F(1), F(1), F(1), \
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(_FL), KC_LEFT, KC_UP, KC_DOWN, KC_RIGHT),
// Function Layer
[_FL] = KEYMAP(
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_DEL, \
KC_TRNS, KC_MPRV, KC_MPLY, KC_MNXT, KC_TRNS, KC_CALC, KC_INS, KC_PGUP, KC_UP, KC_PGDN, KC_PSCR, KC_SLCK, KC_PAUS, KC_TRNS, \
KC_TRNS, KC_VOLD, KC_MUTE, KC_VOLU, KC_TRNS, KC_TRNS, KC_HOME, KC_LEFT, KC_DOWN, KC_RGHT, KC_END, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_APP, KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGUP, KC_PGDN, KC_END),
// Left Shift Layer
[_LS] = KEYMAP(
KC_GRV, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_CAPS, KC_CAPS, KC_CAPS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
// Right Shift Layer
[_RS] = KEYMAP(
KC_GRV, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_CAPS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
};
// Custom Actions
const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_LAYER_MODS(_LS, MOD_LSFT),
[1] = ACTION_LAYER_MODS(_RS, MOD_RSFT),
};

@ -0,0 +1,264 @@
The GNU General Public License, Version 2, June 1991 (GPLv2)
============================================================
> Copyright (C) 1989, 1991 Free Software Foundation, Inc.
> 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
Preamble
--------
The licenses for most software are designed to take away your freedom to share
and change it. By contrast, the GNU General Public License is intended to
guarantee your freedom to share and change free software--to make sure the
software is free for all its users. This General Public License applies to most
of the Free Software Foundation's software and to any other program whose
authors commit to using it. (Some other Free Software Foundation software is
covered by the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not price. Our
General Public Licenses are designed to make sure that you have the freedom to
distribute copies of free software (and charge for this service if you wish),
that you receive source code or can get it if you want it, that you can change
the software or use pieces of it in new free programs; and that you know you can
do these things.
To protect your rights, we need to make restrictions that forbid anyone to deny
you these rights or to ask you to surrender the rights. These restrictions
translate to certain responsibilities for you if you distribute copies of the
software, or if you modify it.
For example, if you distribute copies of such a program, whether gratis or for a
fee, you must give the recipients all the rights that you have. You must make
sure that they, too, receive or can get the source code. And you must show them
these terms so they know their rights.
We protect your rights with two steps: (1) copyright the software, and (2) offer
you this license which gives you legal permission to copy, distribute and/or
modify the software.
Also, for each author's protection and ours, we want to make certain that
everyone understands that there is no warranty for this free software. If the
software is modified by someone else and passed on, we want its recipients to
know that what they have is not the original, so that any problems introduced by
others will not reflect on the original authors' reputations.
Finally, any free program is threatened constantly by software patents. We wish
to avoid the danger that redistributors of a free program will individually
obtain patent licenses, in effect making the program proprietary. To prevent
this, we have made it clear that any patent must be licensed for everyone's free
use or not licensed at all.
The precise terms and conditions for copying, distribution and modification
follow.
Terms And Conditions For Copying, Distribution And Modification
---------------------------------------------------------------
**0.** This License applies to any program or other work which contains a notice
placed by the copyright holder saying it may be distributed under the terms of
this General Public License. The "Program", below, refers to any such program or
work, and a "work based on the Program" means either the Program or any
derivative work under copyright law: that is to say, a work containing the
Program or a portion of it, either verbatim or with modifications and/or
translated into another language. (Hereinafter, translation is included without
limitation in the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not covered by
this License; they are outside its scope. The act of running the Program is not
restricted, and the output from the Program is covered only if its contents
constitute a work based on the Program (independent of having been made by
running the Program). Whether that is true depends on what the Program does.
**1.** You may copy and distribute verbatim copies of the Program's source code
as you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice and
disclaimer of warranty; keep intact all the notices that refer to this License
and to the absence of any warranty; and give any other recipients of the Program
a copy of this License along with the Program.
You may charge a fee for the physical act of transferring a copy, and you may at
your option offer warranty protection in exchange for a fee.
**2.** You may modify your copy or copies of the Program or any portion of it,
thus forming a work based on the Program, and copy and distribute such
modifications or work under the terms of Section 1 above, provided that you also
meet all of these conditions:
* **a)** You must cause the modified files to carry prominent notices stating
that you changed the files and the date of any change.
* **b)** You must cause any work that you distribute or publish, that in whole
or in part contains or is derived from the Program or any part thereof, to
be licensed as a whole at no charge to all third parties under the terms of
this License.
* **c)** If the modified program normally reads commands interactively when
run, you must cause it, when started running for such interactive use in the
most ordinary way, to print or display an announcement including an
appropriate copyright notice and a notice that there is no warranty (or
else, saying that you provide a warranty) and that users may redistribute
the program under these conditions, and telling the user how to view a copy
of this License. (Exception: if the Program itself is interactive but does
not normally print such an announcement, your work based on the Program is
not required to print an announcement.)
These requirements apply to the modified work as a whole. If identifiable
sections of that work are not derived from the Program, and can be reasonably
considered independent and separate works in themselves, then this License, and
its terms, do not apply to those sections when you distribute them as separate
works. But when you distribute the same sections as part of a whole which is a
work based on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the entire whole,
and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest your
rights to work written entirely by you; rather, the intent is to exercise the
right to control the distribution of derivative or collective works based on the
Program.
In addition, mere aggregation of another work not based on the Program with the
Program (or with a work based on the Program) on a volume of a storage or
distribution medium does not bring the other work under the scope of this
License.
**3.** You may copy and distribute the Program (or a work based on it, under
Section 2) in object code or executable form under the terms of Sections 1 and 2
above provided that you also do one of the following:
* **a)** Accompany it with the complete corresponding machine-readable source
code, which must be distributed under the terms of Sections 1 and 2 above on
a medium customarily used for software interchange; or,
* **b)** Accompany it with a written offer, valid for at least three years, to
give any third party, for a charge no more than your cost of physically
performing source distribution, a complete machine-readable copy of the
corresponding source code, to be distributed under the terms of Sections 1
and 2 above on a medium customarily used for software interchange; or,
* **c)** Accompany it with the information you received as to the offer to
distribute corresponding source code. (This alternative is allowed only for
noncommercial distribution and only if you received the program in object
code or executable form with such an offer, in accord with Subsection b
above.)
The source code for a work means the preferred form of the work for making
modifications to it. For an executable work, complete source code means all the
source code for all modules it contains, plus any associated interface
definition files, plus the scripts used to control compilation and installation
of the executable. However, as a special exception, the source code distributed
need not include anything that is normally distributed (in either source or
binary form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component itself
accompanies the executable.
If distribution of executable or object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the source code
from the same place counts as distribution of the source code, even though third
parties are not compelled to copy the source along with the object code.
**4.** You may not copy, modify, sublicense, or distribute the Program except as
expressly provided under this License. Any attempt otherwise to copy, modify,
sublicense or distribute the Program is void, and will automatically terminate
your rights under this License. However, parties who have received copies, or
rights, from you under this License will not have their licenses terminated so
long as such parties remain in full compliance.
**5.** You are not required to accept this License, since you have not signed
it. However, nothing else grants you permission to modify or distribute the
Program or its derivative works. These actions are prohibited by law if you do
not accept this License. Therefore, by modifying or distributing the Program (or
any work based on the Program), you indicate your acceptance of this License to
do so, and all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
**6.** Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the original
licensor to copy, distribute or modify the Program subject to these terms and
conditions. You may not impose any further restrictions on the recipients'
exercise of the rights granted herein. You are not responsible for enforcing
compliance by third parties to this License.
**7.** If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues), conditions
are imposed on you (whether by court order, agreement or otherwise) that
contradict the conditions of this License, they do not excuse you from the
conditions of this License. If you cannot distribute so as to satisfy
simultaneously your obligations under this License and any other pertinent
obligations, then as a consequence you may not distribute the Program at all.
For example, if a patent license would not permit royalty-free redistribution of
the Program by all those who receive copies directly or indirectly through you,
then the only way you could satisfy both it and this License would be to refrain
entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply and the
section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any patents or
other property right claims or to contest validity of any such claims; this
section has the sole purpose of protecting the integrity of the free software
distribution system, which is implemented by public license practices. Many
people have made generous contributions to the wide range of software
distributed through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing to
distribute software through any other system and a licensee cannot impose that
choice.
This section is intended to make thoroughly clear what is believed to be a
consequence of the rest of this License.
**8.** If the distribution and/or use of the Program is restricted in certain
countries either by patents or by copyrighted interfaces, the original copyright
holder who places the Program under this License may add an explicit
geographical distribution limitation excluding those countries, so that
distribution is permitted only in or among countries not thus excluded. In such
case, this License incorporates the limitation as if written in the body of this
License.
**9.** The Free Software Foundation may publish revised and/or new versions of
the General Public License from time to time. Such new versions will be similar
in spirit to the present version, but may differ in detail to address new
problems or concerns.
Each version is given a distinguishing version number. If the Program specifies
a version number of this License which applies to it and "any later version",
you have the option of following the terms and conditions either of that version
or of any later version published by the Free Software Foundation. If the
Program does not specify a version number of this License, you may choose any
version ever published by the Free Software Foundation.
**10.** If you wish to incorporate parts of the Program into other free programs
whose distribution conditions are different, write to the author to ask for
permission. For software which is copyrighted by the Free Software Foundation,
write to the Free Software Foundation; we sometimes make exceptions for this.
Our decision will be guided by the two goals of preserving the free status of
all derivatives of our free software and of promoting the sharing and reuse of
software generally.
No Warranty
-----------
**11.** BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM
"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
**12.** IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

@ -0,0 +1,656 @@
The GNU General Public License, Version 3, 29 June 2007 (GPLv3)
===============================================================
> Copyright &copy; 2007
> Free Software Foundation, Inc.
> <<http://fsf.org/>>
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
Preamble
--------
The GNU General Public License is a free, copyleft license for software and
other kinds of works.
The licenses for most software and other practical works are designed to take
away your freedom to share and change the works. By contrast, the GNU General
Public License is intended to guarantee your freedom to share and change all
versions of a program--to make sure it remains free software for all its users.
We, the Free Software Foundation, use the GNU General Public License for most of
our software; it applies also to any other work released this way by its
authors. You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our
General Public Licenses are designed to make sure that you have the freedom to
distribute copies of free software (and charge for them if you wish), that you
receive source code or can get it if you want it, that you can change the
software or use pieces of it in new free programs, and that you know you can do
these things.
To protect your rights, we need to prevent others from denying you these rights
or asking you to surrender the rights. Therefore, you have certain
responsibilities if you distribute copies of the software, or if you modify it:
responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether gratis or for a
fee, you must pass on to the recipients the same freedoms that you received. You
must make sure that they, too, receive or can get the source code. And you must
show them these terms so they know their rights.
Developers that use the GNU GPL protect your rights with two steps: (1) assert
copyright on the software, and (2) offer you this License giving you legal
permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains that there
is no warranty for this free software. For both users' and authors' sake, the
GPL requires that modified versions be marked as changed, so that their problems
will not be attributed erroneously to authors of previous versions.
Some devices are designed to deny users access to install or run modified
versions of the software inside them, although the manufacturer can do so. This
is fundamentally incompatible with the aim of protecting users' freedom to
change the software. The systematic pattern of such abuse occurs in the area of
products for individuals to use, which is precisely where it is most
unacceptable. Therefore, we have designed this version of the GPL to prohibit
the practice for those products. If such problems arise substantially in other
domains, we stand ready to extend this provision to those domains in future
versions of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents. States
should not allow patents to restrict development and use of software on
general-purpose computers, but in those that do, we wish to avoid the special
danger that patents applied to a free program could make it effectively
proprietary. To prevent this, the GPL assures that patents cannot be used to
render the program non-free.
The precise terms and conditions for copying, distribution and modification
follow.
TERMS AND CONDITIONS
--------------------
### 0. Definitions.
"This License refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of works,
such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this License. Each
licensee is addressed as "you". "Licensees" and "recipients" may be individuals
or organizations.
To "modify" a work means to copy from or adapt all or part of the work in a
fashion requiring copyright permission, other than the making of an exact copy.
The resulting work is called a "modified version" of the earlier work or a work
"based on" the earlier work.
A "covered work" means either the unmodified Program or a work based on the
Program.
To "propagate" a work means to do anything with it that, without permission,
would make you directly or secondarily liable for infringement under applicable
copyright law, except executing it on a computer or modifying a private copy.
Propagation includes copying, distribution (with or without modification),
making available to the public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other parties to
make or receive copies. Mere interaction with a user through a computer network,
with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices" to the extent
that it includes a convenient and prominently visible feature that (1) displays
an appropriate copyright notice, and (2) tells the user that there is no
warranty for the work (except to the extent that warranties are provided), that
licensees may convey the work under this License, and how to view a copy of this
License. If the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
### 1. Source Code.
The "source code" for a work means the preferred form of the work for making
modifications to it. "Object code" means any non-source form of a work.
A "Standard Interface" means an interface that either is an official standard
defined by a recognized standards body, or, in the case of interfaces specified
for a particular programming language, one that is widely used among developers
working in that language.
The "System Libraries" of an executable work include anything, other than the
work as a whole, that (a) is included in the normal form of packaging a Major
Component, but which is not part of that Major Component, and (b) serves only to
enable use of the work with that Major Component, or to implement a Standard
Interface for which an implementation is available to the public in source code
form. A "Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system (if any) on
which the executable work runs, or a compiler used to produce the work, or an
object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all the source
code needed to generate, install, and (for an executable work) run the object
code and to modify the work, including scripts to control those activities.
However, it does not include the work's System Libraries, or general-purpose
tools or generally available free programs which are used unmodified in
performing those activities but which are not part of the work. For example,
Corresponding Source includes interface definition files associated with source
files for the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require, such as by
intimate data communication or control flow between those subprograms and other
parts of the work.
The Corresponding Source need not include anything that users can regenerate
automatically from other parts of the Corresponding Source.
The Corresponding Source for a work in source code form is that same work.
### 2. Basic Permissions.
All rights granted under this License are granted for the term of copyright on
the Program, and are irrevocable provided the stated conditions are met. This
License explicitly affirms your unlimited permission to run the unmodified
Program. The output from running a covered work is covered by this License only
if the output, given its content, constitutes a covered work. This License
acknowledges your rights of fair use or other equivalent, as provided by
copyright law.
You may make, run and propagate covered works that you do not convey, without
conditions so long as your license otherwise remains in force. You may convey
covered works to others for the sole purpose of having them make modifications
exclusively for you, or provide you with facilities for running those works,
provided that you comply with the terms of this License in conveying all
material for which you do not control copyright. Those thus making or running
the covered works for you must do so exclusively on your behalf, under your
direction and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under the conditions
stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological measure under
any applicable law fulfilling obligations under article 11 of the WIPO copyright
treaty adopted on 20 December 1996, or similar laws prohibiting or restricting
circumvention of such measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention is
effected by exercising rights under this License with respect to the covered
work, and you disclaim any intention to limit operation or modification of the
work as a means of enforcing, against the work's users, your or third parties'
legal rights to forbid circumvention of technological measures.
### 4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you receive it,
in any medium, provided that you conspicuously and appropriately publish on each
copy an appropriate copyright notice; keep intact all notices stating that this
License and any non-permissive terms added in accord with section 7 apply to the
code; keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey, and you may
offer support or warranty protection for a fee.
### 5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to produce it
from the Program, in the form of source code under the terms of section 4,
provided that you also meet all of these conditions:
* **a)** The work must carry prominent notices stating that you modified it,
and giving a relevant date.
* **b)** The work must carry prominent notices stating that it is released
under this License and any conditions added under section 7. This
requirement modifies the requirement in section 4 to "keep intact all
notices".
* **c)** You must license the entire work, as a whole, under this License to
anyone who comes into possession of a copy. This License will therefore
apply, along with any applicable section 7 additional terms, to the whole of
the work, and all its parts, regardless of how they are packaged. This
License gives no permission to license the work in any other way, but it
does not invalidate such permission if you have separately received it.
* **d)** If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your work need not
make them do so.
A compilation of a covered work with other separate and independent works,
which are not by their nature extensions of the covered work, and which are
not combined with it such as to form a larger program, in or on a volume of
a storage or distribution medium, is called an "aggregate" if the
compilation and its resulting copyright are not used to limit the access or
legal rights of the compilation's users beyond what the individual works
permit. Inclusion of a covered work in an aggregate does not cause this
License to apply to the other parts of the aggregate.
### 6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms of sections 4
and 5, provided that you also convey the machine-readable Corresponding Source
under the terms of this License, in one of these ways:
* **a)** Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the Corresponding
Source fixed on a durable physical medium customarily used for software
interchange.
* **b)** Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a written offer,
valid for at least three years and valid for as long as you offer spare
parts or customer support for that product model, to give anyone who
possesses the object code either (1) a copy of the Corresponding Source for
all the software in the product that is covered by this License, on a
durable physical medium customarily used for software interchange, for a
price no more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the Corresponding Source from a
network server at no charge.
* **c)** Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This alternative is
allowed only occasionally and noncommercially, and only if you received the
object code with such an offer, in accord with subsection 6b.
* **d)** Convey the object code by offering access from a designated place
(gratis or for a charge), and offer equivalent access to the Corresponding
Source in the same way through the same place at no further charge. You need
not require recipients to copy the Corresponding Source along with the
object code. If the place to copy the object code is a network server, the
Corresponding Source may be on a different server (operated by you or a
third party) that supports equivalent copying facilities, provided you
maintain clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the Corresponding
Source, you remain obligated to ensure that it is available for as long as
needed to satisfy these requirements.
* **e)** Convey the object code using peer-to-peer transmission, provided you
inform other peers where the object code and Corresponding Source of the
work are being offered to the general public at no charge under subsection
6d.
A separable portion of the object code, whose source code is excluded from
the Corresponding Source as a System Library, need not be included in
conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family, or
household purposes, or (2) anything designed or sold for incorporation into
a dwelling. In determining whether a product is a consumer product, doubtful
cases shall be resolved in favor of coverage. For a particular product
received by a particular user, "normally used" refers to a typical or common
use of that class of product, regardless of the status of the particular
user or of the way in which the particular user actually uses, or expects or
is expected to use, the product. A product is a consumer product regardless
of whether the product has substantial commercial, industrial or non-
consumer uses, unless such uses represent the only significant mode of use
of the product.
"Installation Information" for a User Product means any methods, procedures,
authorization keys, or other information required to install and execute
modified versions of a covered work in that User Product from a modified
version of its Corresponding Source. The information must suffice to ensure
that the continued functioning of the modified object code is in no case
prevented or interfered with solely because modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as part of
a transaction in which the right of possession and use of the User Product
is transferred to the recipient in perpetuity or for a fixed term
(regardless of how the transaction is characterized), the Corresponding
Source conveyed under this section must be accompanied by the Installation
Information. But this requirement does not apply if neither you nor any
third party retains the ability to install modified object code on the User
Product (for example, the work has been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates for
a work that has been modified or installed by the recipient, or for the User
Product in which it has been modified or installed. Access to a network may
be denied when the modification itself materially and adversely affects the
operation of the network or violates the rules and protocols for
communication across the network.
Corresponding Source conveyed, and Installation Information provided, in
accord with this section must be in a format that is publicly documented
(and with an implementation available to the public in source code form),
and must require no special password or key for unpacking, reading or
copying.
### 7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this License by
making exceptions from one or more of its conditions. Additional permissions
that are applicable to the entire Program shall be treated as though they were
included in this License, to the extent that they are valid under applicable
law. If additional permissions apply only to part of the Program, that part may
be used separately under those permissions, but the entire Program remains
governed by this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option remove any
additional permissions from that copy, or from any part of it. (Additional
permissions may be written to require their own removal in certain cases when
you modify the work.) You may place additional permissions on material, added by
you to a covered work, for which you have or can give appropriate copyright
permission.
Notwithstanding any other provision of this License, for material you add to a
covered work, you may (if authorized by the copyright holders of that material)
supplement the terms of this License with terms:
* **a)** Disclaiming warranty or limiting liability differently from the terms
of sections 15 and 16 of this License; or
* **b)** Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal Notices
displayed by works containing it; or
* **c)** Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in reasonable
ways as different from the original version; or
* **d)** Limiting the use for publicity purposes of names of licensors or
authors of the material; or
* **e)** Declining to grant rights under trademark law for use of some trade
names, trademarks, or service marks; or
* **f)** Requiring indemnification of licensors and authors of that material
by anyone who conveys the material (or modified versions of it) with
contractual assumptions of liability to the recipient, for any liability
that these contractual assumptions directly impose on those licensors and
authors.
All other non-permissive additional terms are considered "further restrictions"
within the meaning of section 10. If the Program as you received it, or any part
of it, contains a notice stating that it is governed by this License along with
a term that is a further restriction, you may remove that term. If a license
document contains a further restriction but permits relicensing or conveying
under this License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does not survive
such relicensing or conveying.
If you add terms to a covered work in accord with this section, you must place,
in the relevant source files, a statement of the additional terms that apply to
those files, or a notice indicating where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the form of a
separately written license, or stated as exceptions; the above requirements
apply either way.
### 8. Termination.
You may not propagate or modify a covered work except as expressly provided
under this License. Any attempt otherwise to propagate or modify it is void, and
will automatically terminate your rights under this License (including any
patent licenses granted under the third paragraph of section 11).
However, if you cease all violation of this License, then your license from a
particular copyright holder is reinstated (a) provisionally, unless and until
the copyright holder explicitly and finally terminates your license, and (b)
permanently, if the copyright holder fails to notify you of the violation by
some reasonable means prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is reinstated
permanently if the copyright holder notifies you of the violation by some
reasonable means, this is the first time you have received notice of violation
of this License (for any work) from that copyright holder, and you cure the
violation prior to 30 days after your receipt of the notice.
Termination of your rights under this section does not terminate the licenses of
parties who have received copies or rights from you under this License. If your
rights have been terminated and not permanently reinstated, you do not qualify
to receive new licenses for the same material under section 10.
### 9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or run a copy of
the Program. Ancillary propagation of a covered work occurring solely as a
consequence of using peer-to-peer transmission to receive a copy likewise does
not require acceptance. However, nothing other than this License grants you
permission to propagate or modify any covered work. These actions infringe
copyright if you do not accept this License. Therefore, by modifying or
propagating a covered work, you indicate your acceptance of this License to do
so.
### 10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically receives a
license from the original licensors, to run, modify and propagate that work,
subject to this License. You are not responsible for enforcing compliance by
third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered work results
from an entity transaction, each party to that transaction who receives a copy
of the work also receives whatever licenses to the work the party's predecessor
in interest had or could give under the previous paragraph, plus a right to
possession of the Corresponding Source of the work from the predecessor in
interest, if the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the rights
granted or affirmed under this License. For example, you may not impose a
license fee, royalty, or other charge for exercise of rights granted under this
License, and you may not initiate litigation (including a cross-claim or
counterclaim in a lawsuit) alleging that any patent claim is infringed by
making, using, selling, offering for sale, or importing the Program or any
portion of it.
### 11. Patents.
A "contributor" is a copyright holder who authorizes use under this License of
the Program or a work on which the Program is based. The work thus licensed is
called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims owned or
controlled by the contributor, whether already acquired or hereafter acquired,
that would be infringed by some manner, permitted by this License, of making,
using, or selling its contributor version, but do not include claims that would
be infringed only as a consequence of further modification of the contributor
version. For purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free patent
license under the contributor's essential patent claims, to make, use, sell,
offer for sale, import and otherwise run, modify and propagate the contents of
its contributor version.
In the following three paragraphs, a "patent license" is any express agreement
or commitment, however denominated, not to enforce a patent (such as an express
permission to practice a patent or covenant not to sue for patent infringement).
To "grant" such a patent license to a party means to make such an agreement or
commitment not to enforce a patent against the party.
If you convey a covered work, knowingly relying on a patent license, and the
Corresponding Source of the work is not available for anyone to copy, free of
charge and under the terms of this License, through a publicly available network
server or other readily accessible means, then you must either (1) cause the
Corresponding Source to be so available, or (2) arrange to deprive yourself of
the benefit of the patent license for this particular work, or (3) arrange, in a
manner consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have actual
knowledge that, but for the patent license, your conveying the covered work in a
country, or your recipient's use of the covered work in a country, would
infringe one or more identifiable patents in that country that you have reason
to believe are valid.
If, pursuant to or in connection with a single transaction or arrangement, you
convey, or propagate by procuring conveyance of, a covered work, and grant a
patent license to some of the parties receiving the covered work authorizing
them to use, propagate, modify or convey a specific copy of the covered work,
then the patent license you grant is automatically extended to all recipients of
the covered work and works based on it.
A patent license is "discriminatory" if it does not include within the scope of
its coverage, prohibits the exercise of, or is conditioned on the non- exercise
of one or more of the rights that are specifically granted under this License.
You may not convey a covered work if you are a party to an arrangement with a
third party that is in the business of distributing software, under which you
make payment to the third party based on the extent of your activity of
conveying the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory patent
license (a) in connection with copies of the covered work conveyed by you (or
copies made from those copies), or (b) primarily for and in connection with
specific products or compilations that contain the covered work, unless you
entered into that arrangement, or that patent license was granted, prior to 28
March 2007.
Nothing in this License shall be construed as excluding or limiting any implied
license or other defenses to infringement that may otherwise be available to you
under applicable patent law.
### 12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not excuse
you from the conditions of this License. If you cannot convey a covered work so
as to satisfy simultaneously your obligations under this License and any other
pertinent obligations, then as a consequence you may not convey it at all. For
example, if you agree to terms that obligate you to collect a royalty for
further conveying from those to whom you convey the Program, the only way you
could satisfy both those terms and this License would be to refrain entirely
from conveying the Program.
### 13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have permission to link
or combine any covered work with a work licensed under version 3 of the GNU
Affero General Public License into a single combined work, and to convey the
resulting work. The terms of this License will continue to apply to the part
which is the covered work, but the special requirements of the GNU Affero
General Public License, section 13, concerning interaction through a network
will apply to the combination as such.
### 14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of the GNU
General Public License from time to time. Such new versions will be similar in
spirit to the present version, but may differ in detail to address new problems
or concerns.
Each version is given a distinguishing version number. If the Program specifies
that a certain numbered version of the GNU General Public License "or any later
version" applies to it, you have the option of following the terms and
conditions either of that numbered version or of any later version published by
the Free Software Foundation. If the Program does not specify a version number
of the GNU General Public License, you may choose any version ever published by
the Free Software Foundation.
If the Program specifies that a proxy can decide which future versions of the
GNU General Public License can be used, that proxy's public statement of
acceptance of a version permanently authorizes you to choose that version for
the Program.
Later license versions may give you additional or different permissions.
However, no additional obligations are imposed on any author or copyright holder
as a result of your choosing to follow a later version.
### 15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
### 16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY
COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS
PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY
HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
### 17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided above cannot
be given local legal effect according to their terms, reviewing courts shall
apply local law that most closely approximates an absolute waiver of all civil
liability in connection with the Program, unless a warranty or assumption of
liability accompanies a copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
---------------------------------------------
If you develop a new program, and you want it to be of the greatest possible use
to the public, the best way to achieve this is to make it free software which
everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach
them to the start of each source file to most effectively state the exclusion of
warranty; and each file should have at least the "copyright" line and a pointer
to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short notice like
this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'.
This is free software, and you are welcome to redistribute it under certain
conditions; type 'show c' for details.
The hypothetical commands 'show w' and 'show c' should show the appropriate
parts of the General Public License. Of course, your program's commands might be
different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school, if
any, to sign a "copyright disclaimer" for the program, if necessary. For more
information on this, and how to apply and follow the GNU GPL, see
<<http://www.gnu.org/licenses/>>.
The GNU General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may consider
it more useful to permit linking proprietary applications with the library. If
this is what you want to do, use the GNU Lesser General Public License instead
of this License. But first, please read
<<http://www.gnu.org/philosophy/why-not-lgpl.html>>.

@ -0,0 +1,32 @@
This software is licensed with a Modified BSD License.
All of this is supposed to be Free Software, Open Source, DFSG-free,
GPL-compatible, and OK to use in both free and proprietary applications.
Additions and corrections to this file are welcome.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

@ -1,3 +1,19 @@
/* Copyright 2015 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// Simple analog to digitial conversion
#include <avr/io.h>

@ -1,3 +1,19 @@
/* Copyright 2015 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _analog_h_included__
#define _analog_h_included__

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "api.h"
#include "quantum.h"
@ -176,4 +192,4 @@ void process_api(uint16_t length, uint8_t * data) {
// #endif
}
}
}

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _API_H_
#define _API_H_
@ -56,4 +72,4 @@ bool process_api_keyboard(uint8_t length, uint8_t * data);
__attribute__ ((weak))
bool process_api_user(uint8_t length, uint8_t * data);
#endif
#endif

@ -1,3 +1,18 @@
/* Copyright 2016 Jack Humbert, Fred Sundvik
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "api_sysex.h"
#include "sysex_tools.h"
#include "print.h"

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _API_SYSEX_H_
#define _API_SYSEX_H_
@ -7,4 +23,4 @@ void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes,
#define SEND_BYTES(mt, dt, b, l) send_bytes_sysex(mt, dt, b, l)
#endif
#endif

@ -1,3 +1,18 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <string.h>
//#include <math.h>
@ -89,15 +104,15 @@ void audio_init()
}
audio_config.raw = eeconfig_read_audio();
// Set port PC6 (OC3A and /OC4A) as output
// Set port PC6 (OC3A and /OC4A) as output
DDRC |= _BV(PORTC6);
DISABLE_AUDIO_COUNTER_3_ISR;
// TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
// Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
// Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A)
// Clock Select (CS3n) = 0b010 = Clock / 8
// TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
// Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
// Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A)
// Clock Select (CS3n) = 0b010 = Clock / 8
TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
@ -106,6 +121,8 @@ void audio_init()
void stop_all_notes()
{
dprintf("audio stop all notes");
if (!audio_initialized) {
audio_init();
}
@ -128,6 +145,8 @@ void stop_all_notes()
void stop_note(float freq)
{
dprintf("audio stop note freq=%d", (int)freq);
if (playing_note) {
if (!audio_initialized) {
audio_init();
@ -183,159 +202,161 @@ float vibrato(float average_freq) {
ISR(TIMER3_COMPA_vect)
{
float freq;
if (playing_note) {
if (voices > 0) {
if (polyphony_rate > 0) {
if (voices > 1) {
voice_place %= voices;
if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
voice_place = (voice_place + 1) % voices;
place = 0.0;
}
}
#ifdef VIBRATO_ENABLE
if (vibrato_strength > 0) {
freq = vibrato(frequencies[voice_place]);
} else {
freq = frequencies[voice_place];
}
#else
freq = frequencies[voice_place];
#endif
} else {
if (glissando) {
if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
frequency = frequency * pow(2, 440/frequency/12/2);
} else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
frequency = frequency * pow(2, -440/frequency/12/2);
} else {
frequency = frequencies[voices - 1];
}
} else {
frequency = frequencies[voices - 1];
}
#ifdef VIBRATO_ENABLE
if (vibrato_strength > 0) {
freq = vibrato(frequency);
} else {
freq = frequency;
}
#else
freq = frequency;
#endif
}
if (envelope_index < 65535) {
envelope_index++;
}
freq = voice_envelope(freq);
if (freq < 30.517578125) {
freq = 30.52;
}
TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
}
}
if (playing_notes) {
if (note_frequency > 0) {
#ifdef VIBRATO_ENABLE
if (vibrato_strength > 0) {
freq = vibrato(note_frequency);
} else {
freq = note_frequency;
}
#else
freq = note_frequency;
#endif
if (envelope_index < 65535) {
envelope_index++;
}
freq = voice_envelope(freq);
TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
} else {
TIMER_3_PERIOD = 0;
TIMER_3_DUTY_CYCLE = 0;
}
note_position++;
bool end_of_note = false;
if (TIMER_3_PERIOD > 0) {
end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF));
} else {
end_of_note = (note_position >= (note_length * 0x7FF));
}
if (end_of_note) {
current_note++;
if (current_note >= notes_count) {
if (notes_repeat) {
current_note = 0;
} else {
DISABLE_AUDIO_COUNTER_3_ISR;
DISABLE_AUDIO_COUNTER_3_OUTPUT;
playing_notes = false;
return;
}
}
if (!note_resting && (notes_rest > 0)) {
note_resting = true;
note_frequency = 0;
note_length = notes_rest;
current_note--;
} else {
note_resting = false;
envelope_index = 0;
note_frequency = (*notes_pointer)[current_note][0];
note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
}
note_position = 0;
}
}
if (!audio_config.enable) {
playing_notes = false;
playing_note = false;
}
float freq;
if (playing_note) {
if (voices > 0) {
if (polyphony_rate > 0) {
if (voices > 1) {
voice_place %= voices;
if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
voice_place = (voice_place + 1) % voices;
place = 0.0;
}
}
#ifdef VIBRATO_ENABLE
if (vibrato_strength > 0) {
freq = vibrato(frequencies[voice_place]);
} else {
freq = frequencies[voice_place];
}
#else
freq = frequencies[voice_place];
#endif
} else {
if (glissando) {
if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
frequency = frequency * pow(2, 440/frequency/12/2);
} else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
frequency = frequency * pow(2, -440/frequency/12/2);
} else {
frequency = frequencies[voices - 1];
}
} else {
frequency = frequencies[voices - 1];
}
#ifdef VIBRATO_ENABLE
if (vibrato_strength > 0) {
freq = vibrato(frequency);
} else {
freq = frequency;
}
#else
freq = frequency;
#endif
}
if (envelope_index < 65535) {
envelope_index++;
}
freq = voice_envelope(freq);
if (freq < 30.517578125) {
freq = 30.52;
}
TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
}
}
if (playing_notes) {
if (note_frequency > 0) {
#ifdef VIBRATO_ENABLE
if (vibrato_strength > 0) {
freq = vibrato(note_frequency);
} else {
freq = note_frequency;
}
#else
freq = note_frequency;
#endif
if (envelope_index < 65535) {
envelope_index++;
}
freq = voice_envelope(freq);
TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
} else {
TIMER_3_PERIOD = 0;
TIMER_3_DUTY_CYCLE = 0;
}
note_position++;
bool end_of_note = false;
if (TIMER_3_PERIOD > 0) {
end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF));
} else {
end_of_note = (note_position >= (note_length * 0x7FF));
}
if (end_of_note) {
current_note++;
if (current_note >= notes_count) {
if (notes_repeat) {
current_note = 0;
} else {
DISABLE_AUDIO_COUNTER_3_ISR;
DISABLE_AUDIO_COUNTER_3_OUTPUT;
playing_notes = false;
return;
}
}
if (!note_resting && (notes_rest > 0)) {
note_resting = true;
note_frequency = 0;
note_length = notes_rest;
current_note--;
} else {
note_resting = false;
envelope_index = 0;
note_frequency = (*notes_pointer)[current_note][0];
note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
}
note_position = 0;
}
}
if (!audio_config.enable) {
playing_notes = false;
playing_note = false;
}
}
void play_note(float freq, int vol) {
dprintf("audio play note freq=%d vol=%d", (int)freq, vol);
if (!audio_initialized) {
audio_init();
}
if (audio_config.enable && voices < 8) {
DISABLE_AUDIO_COUNTER_3_ISR;
if (audio_config.enable && voices < 8) {
DISABLE_AUDIO_COUNTER_3_ISR;
// Cancel notes if notes are playing
if (playing_notes)
stop_all_notes();
// Cancel notes if notes are playing
if (playing_notes)
stop_all_notes();
playing_note = true;
playing_note = true;
envelope_index = 0;
envelope_index = 0;
if (freq > 0) {
frequencies[voices] = freq;
volumes[voices] = vol;
voices++;
}
if (freq > 0) {
frequencies[voices] = freq;
volumes[voices] = vol;
voices++;
}
ENABLE_AUDIO_COUNTER_3_ISR;
ENABLE_AUDIO_COUNTER_3_OUTPUT;
}
}
}
@ -346,37 +367,37 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
audio_init();
}
if (audio_config.enable) {
if (audio_config.enable) {
DISABLE_AUDIO_COUNTER_3_ISR;
DISABLE_AUDIO_COUNTER_3_ISR;
// Cancel note if a note is playing
if (playing_note)
stop_all_notes();
// Cancel note if a note is playing
if (playing_note)
stop_all_notes();
playing_notes = true;
playing_notes = true;
notes_pointer = np;
notes_count = n_count;
notes_repeat = n_repeat;
notes_rest = n_rest;
notes_pointer = np;
notes_count = n_count;
notes_repeat = n_repeat;
notes_rest = n_rest;
place = 0;
current_note = 0;
place = 0;
current_note = 0;
note_frequency = (*notes_pointer)[current_note][0];
note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
note_position = 0;
note_position = 0;
ENABLE_AUDIO_COUNTER_3_ISR;
ENABLE_AUDIO_COUNTER_3_OUTPUT;
}
}
}
bool is_playing_notes(void) {
return playing_notes;
return playing_notes;
}
bool is_audio_on(void) {

@ -1,3 +1,18 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef AUDIO_H
#define AUDIO_H
@ -88,4 +103,4 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
bool is_playing_notes(void);
#endif
#endif

@ -1,3 +1,18 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <string.h>
//#include <math.h>

@ -1,3 +1,19 @@
/* Copyright 2016 IBNobody
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

@ -1,3 +1,19 @@
/* Copyright 2016 IBNobody
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
@ -12,4 +28,4 @@
extern const float vibrato_lut[VIBRATO_LUT_LENGTH];
extern const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH];
#endif /* LUTS_H */
#endif /* LUTS_H */

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MUSICAL_NOTES_H
#define MUSICAL_NOTES_H
@ -214,4 +230,4 @@
#define NOTE_BF8 NOTE_AS8
#endif
#endif

@ -1,8 +1,27 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "musical_notes.h"
#ifndef SONG_LIST_H
#define SONG_LIST_H
#define COIN_SOUND \
E__NOTE(_A5 ),\
HD_NOTE(_E6 ),
#define ODE_TO_JOY \
Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \
Q__NOTE(_G4), Q__NOTE(_F4), Q__NOTE(_E4), Q__NOTE(_D4), \
@ -122,4 +141,39 @@
E__NOTE(_E5), \
E__NOTE(_D5),
#define UNICODE_WINDOWS \
E__NOTE(_B5), \
S__NOTE(_E6),
#define UNICODE_LINUX \
E__NOTE(_E6), \
S__NOTE(_B5),
#define COIN_SOUND \
E__NOTE(_A5 ), \
HD_NOTE(_E6 ),
#define ONE_UP_SOUND \
Q__NOTE(_E6 ), \
Q__NOTE(_G6 ), \
Q__NOTE(_E7 ), \
Q__NOTE(_C7 ), \
Q__NOTE(_D7 ), \
Q__NOTE(_G7 ),
#define SONIC_RING \
E__NOTE(_E6), \
E__NOTE(_G6), \
HD_NOTE(_C7),
#define ZELDA_PUZZLE \
Q__NOTE(_G5), \
Q__NOTE(_FS5), \
Q__NOTE(_DS5), \
Q__NOTE(_A4), \
Q__NOTE(_GS4), \
Q__NOTE(_E5), \
Q__NOTE(_GS5), \
HD_NOTE(_C6),
#endif

@ -1,3 +1,18 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "voices.h"
#include "audio.h"
#include "stdlib.h"

@ -1,3 +1,18 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
@ -32,4 +47,4 @@ void set_voice(voice_type v);
void voice_iterate(void);
void voice_deiterate(void);
#endif
#endif

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
@ -262,4 +278,4 @@ const uint8_t sinewave[] PROGMEM= //2048 values
0x76,0x77,0x77,0x77,0x78,0x78,0x78,0x79,
0x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7c,0x7c,
0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f
};
};

@ -1,3 +1,19 @@
/* Copyright 2015-2017 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_DEFINITIONS_H
#define CONFIG_DEFINITIONS_H

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Author: Wojciech Siewierski < wojciech dot siewierski at onet dot pl > */
#ifndef DYNAMIC_MACROS_H
#define DYNAMIC_MACROS_H

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "keycode_config.h"
extern keymap_config_t keymap_config;
@ -71,4 +87,4 @@ uint16_t keycode_config(uint16_t keycode) {
default:
return keycode;
}
}
}

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "eeconfig.h"
#include "keycode.h"

@ -1,5 +1,5 @@
/*
Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
Copyright 2012-2016 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

@ -1,5 +1,5 @@
/*
Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
Copyright 2012-2017 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

@ -1,3 +1,18 @@
/* Copyright 2016 Didier Loiseau
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Keymap macros for the French BÉPO layout - http://bepo.fr */
#ifndef KEYMAP_BEPO_H
#define KEYMAP_BEPO_H

@ -1,3 +1,18 @@
/* Copyright 2016 Didier Loiseau
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_CANADIAN_MULTILINGUAG_H
#define KEYMAP_CANADIAN_MULTILINGUAG_H

@ -1,3 +1,18 @@
/* Copyright 2015-2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_COLEMAK_H
#define KEYMAP_COLEMAK_H

@ -1,3 +1,18 @@
/* Copyright 2015-2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_DVORAK_H
#define KEYMAP_DVORAK_H

@ -1,3 +1,19 @@
/* Copyright 2016 Artyom Mironov
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_DVP_H
#define KEYMAP_DVP_H

@ -1,3 +1,18 @@
/* Copyright 2016 Vincent Pochet
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_FR_CH
#define KEYMAP_FR_CH

@ -1,3 +1,18 @@
/* Copyright 2015-2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_FRENCH_H
#define KEYMAP_FRENCH_H

@ -1,3 +1,18 @@
/* Copyright 2016 Sébastien Pérochon
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_FRENCH_OSX_H
#define KEYMAP_FRENCH_OSX_H
@ -74,4 +89,4 @@
#define FR_PIPE LSFT(LALT(KC_L))
#define FR_BSLS LSFT(LALT(FR_COLN))
#endif
#endif

@ -1,3 +1,19 @@
/* Copyright 2015-2016 Matthias Schmidtt
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_GERMAN
#define KEYMAP_GERMAN

@ -1,3 +1,18 @@
/* Copyright 2016 heartsekai
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_SWISS_GERMAN
#define KEYMAP_SWISS_GERMAN

@ -1,3 +1,18 @@
/* Copyright 2016 Stephen Bösebeck
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_GERMAN_OSX
#define KEYMAP_GERMAN_OSX

@ -1,4 +1,19 @@
/* JP106-layout (Japanese Standard)
/* Copyright 2016 h-youhei
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* JP106-layout (Japanese Standard)
*
* For more information, see
* http://www2d.biglobe.ne.jp/~msyk/keyboard/layout/usbkeycode.html

@ -1,3 +1,18 @@
/* Copyright 2016 Matthias Schmitt
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_NEO2
#define KEYMAP_NEO2

@ -1,3 +1,18 @@
/* Copyright 2015-2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_NORDIC_H
#define KEYMAP_NORDIC_H

@ -1,3 +1,18 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_NORWEGIAN_H
#define KEYMAP_NORWEGIAN_H

@ -1,3 +1,18 @@
/* Copyright 2016 James Kay
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_PLOVER_H
#define KEYMAP_PLOVER_H

@ -1,77 +0,0 @@
#ifndef KEYMAP_RUSSIAN_H
#define KEYMAP_RUSSIAN_H
#include "keymap.h"
// Normal Chracters // reg SHIFT
#define RU_A KC_F // а and А
#define RU_BE KC_COMM // б and Б
#define RU_VE KC_D // в and В
#define RU_GHE KC_U // г and Г
#define RU_DE KC_L // д and Д
#define RU_IE KC_T // е and Е
#define RU_IO KC_GRV // ё and Ё
#define RU_ZHE KC_SCLN // ж and Ж
#define RU_ZE KC_P // з and З
#define RU_I KC_B // и and И
#define RU_SRT_I KC_Q // й and Й
#define RU_KA KC_R // к and К
#define RU_EL KC_K // л and Л
#define RU_EM KC_V // м and М
#define RU_EN KC_Y // н and Н
#define RU_O KC_J // о and О
#define RU_PE KC_G // п and П
#define RU_ER KC_H // р and Р
#define RU_ES KC_C // с and С
#define RU_TE KC_N // т and Т
#define RU_U KC_E // у and У
#define RU_EF KC_A // ф and Ф
#define RU_HA KC_LBRC // х and Х
#define RU_TSE KC_W // ц and Ц
#define RU_CHE KC_X // ч and Ч
#define RU_SHA KC_I // ш and Ш
#define RU_SHCHA KC_O // щ and Щ
#define RU_HSIGN KC_RBRC // ъ and Ъ
#define RU_YERU KC_S // ы and Ы
#define RU_SSIGN KC_M // ь and Ь
#define RU_E KC_QUOT // э and Э
#define RU_YU KC_DOT // ю and Ю
#define RU_YA KC_Z // я and Я
#define RU_1 KC_1 // 1 and !
#define RU_2 KC_2 // 2 and "
#define RU_3 KC_3 // 3 and №
#define RU_4 KC_4 // 4 and ;
#define RU_5 KC_5 // 5 and %
#define RU_6 KC_6 // 6 and :
#define RU_7 KC_7 // 7 and ?
#define RU_8 KC_8 // 8 and *
#define RU_9 KC_9 // 9 and (
#define RU_0 KC_0 // 0 and )
#define RU_MINS KC_MINS // - and _
#define RU_EQL KC_EQL // = and +
#define RU_BSLS KC_BSLS // \ and /
#define RU_DOT KC_SLSH // . and ,
// Shifted Chracters
#define RU_EXLM LSFT(RU_1) // !
#define RU_DQUT LSFT(RU_2) // "
#define RU_NMRO LSFT(RU_3) // №
#define RU_SCLN LSFT(RU_4) // ;
#define RU_PERC LSFT(RU_5) // %
#define RU_COLN LSFT(RU_6) // :
#define RU_QUES LSFT(RU_7) // ?
#define RU_ASTR LSFT(RU_8) // *
#define RU_LPRN LSFT(RU_9) // (
#define RU_RPRN LSFT(RU_0) // )
#define RU_UNDR LSFT(RU_MINS) // _
#define RU_PLUS LSFT(RU_EQL) // +
#define RU_SLSH LSFT(RU_BSLS) // /
#define RU_COMM LSFT(RU_DOT) // ,
// Alt Gr-ed characters
#define RU_RUBL RALT(RU_8) // ₽
#endif

@ -1,3 +1,18 @@
/* Copyright 2015-2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_SPANISH_H
#define KEYMAP_SPANISH_H

@ -1,3 +1,18 @@
/* Copyright 2015-2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYMAP_UK_H
#define KEYMAP_UK_H

@ -1,163 +0,0 @@
#ifndef KEYMAP_CYRILLIC_H
#define KEYMAP_CYRILLIC_H
#include "keymap.h"
/*
* This is based off of
* https://en.wikipedia.org/wiki/Cyrillic_script
*
* Unicode is iffy, a software implementation is preferred
*/
// Capital Char russian/ukrainian/bulgarian
#define CY_A UC(0x0410) // А rus ukr bul
#define CY_BE UC(0x0411) // Б rus ukr bul
#define CY_VE UC(0x0412) // В rus ukr bul
#define CY_GHE UC(0x0413) // Г rus ukr bul
#define CY_GHEUP UC(0x0490) // Ґ ukr
#define CY_DE UC(0x0414) // Д rus ukr bul
#define CY_DJE UC(0x0402) // Ђ
#define CY_GJE UC(0x0403) // Ѓ
#define CY_IE UC(0x0415) // Е rus ukr bul
#define CY_IO UC(0x0401) // Ё rus
#define CY_UIE UC(0x0404) // Є ukr
#define CY_ZHE UC(0x0416) // Ж rus ukr bul
#define CY_ZE UC(0x0417) // З rus ukr bul
#define CY_DZE UC(0x0405) // Ѕ
#define CY_I UC(0x0418) // И rus ukr bul
#define CY_B_U_I UC(0x0406) // І ukr
#define CY_YI UC(0x0407) // Ї ukr
#define CY_SRT_I UC(0x0419) // Й rus ukr bul
#define CY_JE UC(0x0408) // Ј
#define CY_KA UC(0x041a) // К rus ukr bul
#define CY_EL UC(0x041b) // Л rus ukr bul
#define CY_LJE UC(0x0409) // Љ
#define CY_EM UC(0x041c) // М rus ukr bul
#define CY_EN UC(0x041d) // Н rus ukr bul
#define CY_NJE UC(0x040a) // Њ
#define CY_O UC(0x041e) // О rus ukr bul
#define CY_PE UC(0x041f) // П rus ukr bul
#define CY_ER UC(0x0420) // Р rus ukr bul
#define CY_ES UC(0x0421) // С rus ukr bul
#define CY_TE UC(0x0422) // Т rus ukr bul
#define CY_TSHE UC(0x040b) // Ћ
#define CY_KJE UC(0x040c) // Ќ
#define CY_U UC(0x0423) // У rus ukr bul
#define CY_SRT_U UC(0x040e) // Ў
#define CY_EF UC(0x0424) // Ф rus ukr bul
#define CY_HA UC(0x0425) // Х rus bul
#define CY_TSE UC(0x0426) // Ц rus ukr bul
#define CY_CHE UC(0x0427) // Ч rus ukr bul
#define CY_DZHE UC(0x040f) // Џ
#define CY_SHA UC(0x0428) // Ш rus ukr bul
#define CY_SHCHA UC(0x0429) // Щ rus ukr bul
#define CY_HSIGN UC(0x042a) // Ъ rus bul
#define CY_YERU UC(0x042b) // Ы rus
#define CY_SSIGN UC(0x042c) // Ь rus ukr bul
#define CY_E UC(0x042d) // Э rus
#define CY_YU UC(0x042e) // Ю rus ukr bul
#define CY_YA UC(0x042f) // Я rus ukr bul
// Important Cyrillic non-Slavic letters
#define CY_PALOCHKA UC(0x04c0) // Ӏ
#define CY_SCHWA UC(0x04d8) // Ә
#define CY_GHE_S UC(0x0492) // Ғ
#define CY_ZE_D UC(0x0498) // Ҙ
#define CY_ES_D UC(0x04aa) // Ҫ
#define CY_BR_KA UC(0x04a0) // Ҡ
#define CY_ZHE_D UC(0x0496) // Җ
#define CY_KA_D UC(0x049a) // Қ
#define CY_EN_D UC(0x04a2) // Ң
#define CY_ENGHE UC(0x04a4) // Ҥ
#define CY_BRD_O UC(0x04e8) // Ө
#define CY_STR_U UC(0x04ae) // Ү
#define CY_S_U_S UC(0x04b0) // Ұ
#define CY_SHHA UC(0x04ba) // Һ
#define CY_HA_D UC(0x04b2) // Ҳ
// Small
#define CY_a UC(0x0430) // a rus ukr bul
#define CY_be UC(0x0431) // б rus ukr bul
#define CY_ve UC(0x0432) // в rus ukr bul
#define CY_ghe UC(0x0433) // г rus ukr bul
#define CY_gheup UC(0x0491) // ґ ukr
#define CY_de UC(0x0434) // д rus ukr bul
#define CY_dje UC(0x0452) // ђ
#define CY_gje UC(0x0453) // ѓ
#define CY_ie UC(0x0435) // е rus ukr bul
#define CY_io UC(0x0451) // ё rus
#define CY_uie UC(0x0454) // є ukr
#define CY_zhe UC(0x0436) // ж rus ukr bul
#define CY_ze UC(0x0437) // з rus ukr bul
#define CY_dze UC(0x0455) // ѕ
#define CY_i UC(0x0438) // и rus ukr bul
#define CY_b_u_i UC(0x0456) // і ukr
#define CY_yi UC(0x0457) // ї ukr
#define CY_srt_i UC(0x0439) // й rus ukr bul
#define CY_je UC(0x0458) // ј
#define CY_ka UC(0x043a) // к rus ukr bul
#define CY_el UC(0x043b) // л rus ukr bul
#define CY_lje UC(0x0459) // љ
#define CY_em UC(0x043c) // м rus ukr bul
#define CY_en UC(0x043d) // н rus ukr bul
#define CY_nje UC(0x045a) // њ
#define CY_o UC(0x043e) // о rus ukr bul
#define CY_pe UC(0x043f) // п rus ukr bul
#define CY_er UC(0x0440) // р rus ukr bul
#define CY_es UC(0x0441) // с rus ukr bul
#define CY_te UC(0x0442) // т rus ukr bul
#define CY_tshe UC(0x045b) // ћ
#define CY_kje UC(0x045c) // ќ
#define CY_u UC(0x0443) // у rus ukr bul
#define CY_srt_u UC(0x045e) // ў
#define CY_ef UC(0x0444) // ф rus ukr bul
#define CY_ha UC(0x0445) // х rus ukr bul
#define CY_tse UC(0x0446) // ц rus ukr bul
#define CY_che UC(0x0447) // ч rus ukr bul
#define CY_dzhe UC(0x045f) // џ
#define CY_sha UC(0x0448) // ш rus ukr bul
#define CY_shcha UC(0x0449) // щ rus ukr bul
#define CY_hsign UC(0x044a) // ъ rus bul
#define CY_yeru UC(0x044b) // ы rus
#define CY_ssign UC(0x044c) // ь rus ukr bul
#define CY_e UC(0x044d) // э rus
#define CY_yu UC(0x044e) // ю rus ukr bul
#define CY_ya UC(0x044f) // я rus ukr bul
// Important Cyrillic non-Slavic letters
#define CY_palochka UC(0x04cf) // ӏ
#define CY_schwa UC(0x04d9) // ә
#define CY_ghe_s UC(0x0493) // ғ
#define CY_ze_d UC(0x0499) // ҙ
#define CY_es_d UC(0x04ab) // ҫ
#define CY_br_ka UC(0x04a1) // ҡ
#define CY_zhe_d UC(0x0497) // җ
#define CY_ka_d UC(0x049b) // қ
#define CY_en_d UC(0x04a3) // ң
#define CY_enghe UC(0x04a5) // ҥ
#define CY_brd_o UC(0x04e9) // ө
#define CY_str_u UC(0x04af) // ү
#define CY_s_u_s UC(0x04b1) // ұ
#define CY_shha UC(0x04bb) // һ
#define CY_ha_d UC(0x04b3) // ҳ
// Extra
#define CY_slr_ve UC(0x1c80) // ᲀ CYRILLIC SMALL LETTER ROUNDED VE
#define CY_ll_de UC(0x1c81) // ᲁ CYRILLIC SMALL LETTER LONG-LEGGED DE
#define CY_ZEMLYA UC(0xa640) // Ꙁ CYRILLIC CAPITAL LETTER ZEMLYA
#define CY_zemlya UC(0xa641) // ꙁ CYRILLIC SMALL LETTER ZEMLYA
#define CY_RV_DZE UC(0xa644) // CYRILLIC CAPITAL LETTER REVERSED DZE
#define CY_rv_DZE UC(0xa645) // ꙅ CYRILLIC SMALL LETTER REVERSED DZE
#define CY_slw_es UC(0x1c83) // ᲃ CYRILLIC SMALL LETTER WIDE ES
#define CY_st_te UC(0x1c84) // ᲄ CYRILLIC SMALL LETTER TALL TE
#define CY_3l_te UC(0x1c85) // ᲅ CYRILLIC SMALL LETTER THREE-LEGGED TE
#define CY_thsign UC(0x1c86) // ᲆ CYRILLIC SMALL LETTER TALL HARD SIGN
#define CY_YERUBY UC(0xa650) // Ꙑ CYRILLIC CAPITAL LETTER YERU WITH BACK YER
#define CY_yeruby UC(0xa651) // ꙑ CYRILLIC SMALL LETTER YERU WITH BACK YER
#define CY_RUBL UC(0x20bd) // ₽
#define CY_NMRO UC(0x2116) // №
// The letters Zje and Sje are made for other letters and accent marks
#endif

@ -7,7 +7,18 @@
* Jan 18th, 2014 v2.0b Initial Version
* Nov 29th, 2015 v2.3 Added SK6812RGBW support
*
* License: GNU GPL v2 (see License.txt)
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "light_ws2812.h"

@ -6,8 +6,18 @@
*
* Please do not change this file! All configuration is handled in "ws2812_config.h"
*
* License: GNU GPL v2 (see License.txt)
+
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LIGHT_WS2812_H_

@ -1,6 +1,5 @@
/*
Copyright 2012 Jun Wako
Copyright 2014 Jack Humbert
Copyright 2012-2017 Jun Wako, Jack Humbert
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

@ -1,3 +1,18 @@
/* Copyright 2016 Wez Furlong
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// Some helpers for controlling gpio pins
#include <avr/io.h>

@ -0,0 +1,62 @@
#include "audio.h"
#include "process_audio.h"
static float compute_freq_for_midi_note(uint8_t note)
{
// https://en.wikipedia.org/wiki/MIDI_tuning_standard
return pow(2.0, (note - 69) / 12.0) * 440.0f;
}
bool process_audio(uint16_t keycode, keyrecord_t *record) {
if (keycode == AU_ON && record->event.pressed) {
audio_on();
return false;
}
if (keycode == AU_OFF && record->event.pressed) {
audio_off();
return false;
}
if (keycode == AU_TOG && record->event.pressed) {
if (is_audio_on())
{
audio_off();
}
else
{
audio_on();
}
return false;
}
if (keycode == MUV_IN && record->event.pressed) {
voice_iterate();
music_scale_user();
return false;
}
if (keycode == MUV_DE && record->event.pressed) {
voice_deiterate();
music_scale_user();
return false;
}
return true;
}
void process_audio_noteon(uint8_t note) {
play_note(compute_freq_for_midi_note(note), 0xF);
}
void process_audio_noteoff(uint8_t note) {
stop_note(compute_freq_for_midi_note(note));
}
void process_audio_all_notes_off(void) {
stop_all_notes();
}
__attribute__ ((weak))
void audio_on_user() {}

@ -0,0 +1,11 @@
#ifndef PROCESS_AUDIO_H
#define PROCESS_AUDIO_H
bool process_audio(uint16_t keycode, keyrecord_t *record);
void process_audio_noteon(uint8_t note);
void process_audio_noteoff(uint8_t note);
void process_audio_all_notes_off(void);
void audio_on_user(void);
#endif

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "process_chording.h"
bool keys_chord(uint8_t keys[]) {
@ -57,4 +73,4 @@ bool process_chording(uint16_t keycode, keyrecord_t *record) {
}
}
return true;
}
}

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROCESS_CHORDING_H
#define PROCESS_CHORDING_H
@ -13,4 +29,4 @@ uint8_t chord_key_down = 0;
bool process_chording(uint16_t keycode, keyrecord_t *record);
#endif
#endif

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "process_combo.h"
#include "print.h"

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROCESS_COMBO_H
#define PROCESS_COMBO_H

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "process_leader.h"
__attribute__ ((weak))
@ -35,4 +51,4 @@ bool process_leader(uint16_t keycode, keyrecord_t *record) {
}
}
return true;
}
}

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROCESS_LEADER_H
#define PROCESS_LEADER_H
@ -20,4 +36,4 @@ void leader_end(void);
#define LEADER_EXTERNS() extern bool leading; extern uint16_t leader_time; extern uint16_t leader_sequence[5]; extern uint8_t leader_sequence_size
#define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT)
#endif
#endif

@ -1,68 +1,253 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "process_midi.h"
bool midi_activated = false;
uint8_t midi_starting_note = 0x0C;
int midi_offset = 7;
bool process_midi(uint16_t keycode, keyrecord_t *record) {
if (keycode == MI_ON && record->event.pressed) {
midi_activated = true;
#ifdef AUDIO_ENABLE
music_scale_user();
#endif
return false;
}
#ifdef MIDI_ENABLE
#include "midi.h"
#ifdef MIDI_BASIC
void process_midi_basic_noteon(uint8_t note)
{
midi_send_noteon(&midi_device, 0, note, 128);
}
void process_midi_basic_noteoff(uint8_t note)
{
midi_send_noteoff(&midi_device, 0, note, 0);
}
void process_midi_all_notes_off(void)
{
midi_send_cc(&midi_device, 0, 0x7B, 0);
}
#endif // MIDI_BASIC
#ifdef MIDI_ADVANCED
#include "timer.h"
static uint8_t tone_status[MIDI_TONE_COUNT];
static uint8_t midi_modulation;
static int8_t midi_modulation_step;
static uint16_t midi_modulation_timer;
inline uint8_t compute_velocity(uint8_t setting)
{
return (setting + 1) * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN + 1));
}
if (keycode == MI_OFF && record->event.pressed) {
midi_activated = false;
midi_send_cc(&midi_device, 0, 0x7B, 0);
return false;
void midi_init(void)
{
midi_config.octave = MI_OCT_2 - MIDI_OCTAVE_MIN;
midi_config.transpose = 0;
midi_config.velocity = (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN);
midi_config.channel = 0;
midi_config.modulation_interval = 8;
for (uint8_t i = 0; i < MIDI_TONE_COUNT; i++)
{
tone_status[i] = MIDI_INVALID_NOTE;
}
if (midi_activated) {
if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) {
if (record->event.pressed) {
midi_starting_note++; // Change key
midi_send_cc(&midi_device, 0, 0x7B, 0);
}
return false;
}
if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) {
if (record->event.pressed) {
midi_starting_note--; // Change key
midi_send_cc(&midi_device, 0, 0x7B, 0);
}
return false;
}
if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
midi_offset++; // Change scale
midi_send_cc(&midi_device, 0, 0x7B, 0);
return false;
}
if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
midi_offset--; // Change scale
midi_send_cc(&midi_device, 0, 0x7B, 0);
return false;
}
// basic
// uint8_t note = (midi_starting_note + SCALE[record->event.key.col + midi_offset])+12*(MATRIX_ROWS - record->event.key.row);
// advanced
// uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+12*(MATRIX_ROWS - record->event.key.row);
// guitar
uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+5*(MATRIX_ROWS - record->event.key.row);
// violin
// uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+7*(MATRIX_ROWS - record->event.key.row);
if (record->event.pressed) {
// midi_send_noteon(&midi_device, record->event.key.row, midi_starting_note + SCALE[record->event.key.col], 127);
midi_send_noteon(&midi_device, 0, note, 127);
} else {
// midi_send_noteoff(&midi_device, record->event.key.row, midi_starting_note + SCALE[record->event.key.col], 127);
midi_send_noteoff(&midi_device, 0, note, 127);
}
if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
return false;
midi_modulation = 0;
midi_modulation_step = 0;
midi_modulation_timer = 0;
}
void midi_task(void)
{
if (timer_elapsed(midi_modulation_timer) < midi_config.modulation_interval)
return;
midi_modulation_timer = timer_read();
if (midi_modulation_step != 0)
{
dprintf("midi modulation %d\n", midi_modulation);
midi_send_cc(&midi_device, midi_config.channel, 0x1, midi_modulation);
if (midi_modulation_step < 0 && midi_modulation < -midi_modulation_step) {
midi_modulation = 0;
midi_modulation_step = 0;
return;
}
midi_modulation += midi_modulation_step;
if (midi_modulation > 127)
midi_modulation = 127;
}
return true;
}
uint8_t midi_compute_note(uint16_t keycode)
{
return 12 * midi_config.octave + (keycode - MIDI_TONE_MIN) + midi_config.transpose;
}
bool process_midi(uint16_t keycode, keyrecord_t *record)
{
switch (keycode) {
case MIDI_TONE_MIN ... MIDI_TONE_MAX:
{
uint8_t channel = midi_config.channel;
uint8_t tone = keycode - MIDI_TONE_MIN;
uint8_t velocity = compute_velocity(midi_config.velocity);
if (record->event.pressed) {
uint8_t note = midi_compute_note(keycode);
midi_send_noteon(&midi_device, channel, note, velocity);
dprintf("midi noteon channel:%d note:%d velocity:%d\n", channel, note, velocity);
tone_status[tone] = note;
}
else {
uint8_t note = tone_status[tone];
if (note != MIDI_INVALID_NOTE)
{
midi_send_noteoff(&midi_device, channel, note, velocity);
dprintf("midi noteoff channel:%d note:%d velocity:%d\n", channel, note, velocity);
}
tone_status[tone] = MIDI_INVALID_NOTE;
}
return false;
}
case MIDI_OCTAVE_MIN ... MIDI_OCTAVE_MAX:
if (record->event.pressed) {
midi_config.octave = keycode - MIDI_OCTAVE_MIN;
dprintf("midi octave %d\n", midi_config.octave);
}
return false;
case MI_OCTD:
if (record->event.pressed && midi_config.octave > 0) {
midi_config.octave--;
dprintf("midi octave %d\n", midi_config.octave);
}
return false;
case MI_OCTU:
if (record->event.pressed && midi_config.octave < (MIDI_OCTAVE_MAX - MIDI_OCTAVE_MIN)) {
midi_config.octave++;
dprintf("midi octave %d\n", midi_config.octave);
}
return false;
case MIDI_TRANSPOSE_MIN ... MIDI_TRANSPOSE_MAX:
if (record->event.pressed) {
midi_config.transpose = keycode - MI_TRNS_0;
dprintf("midi transpose %d\n", midi_config.transpose);
}
return false;
case MI_TRNSD:
if (record->event.pressed && midi_config.transpose > (MIDI_TRANSPOSE_MIN - MI_TRNS_0)) {
midi_config.transpose--;
dprintf("midi transpose %d\n", midi_config.transpose);
}
return false;
case MI_TRNSU:
if (record->event.pressed && midi_config.transpose < (MIDI_TRANSPOSE_MAX - MI_TRNS_0)) {
const bool positive = midi_config.transpose > 0;
midi_config.transpose++;
if (positive && midi_config.transpose < 0)
midi_config.transpose--;
dprintf("midi transpose %d\n", midi_config.transpose);
}
return false;
case MIDI_VELOCITY_MIN ... MIDI_VELOCITY_MAX:
if (record->event.pressed) {
midi_config.velocity = keycode - MIDI_VELOCITY_MIN;
dprintf("midi velocity %d\n", midi_config.velocity);
}
return false;
case MI_VELD:
if (record->event.pressed && midi_config.velocity > 0) {
midi_config.velocity--;
dprintf("midi velocity %d\n", midi_config.velocity);
}
return false;
case MI_VELU:
if (record->event.pressed) {
midi_config.velocity++;
dprintf("midi velocity %d\n", midi_config.velocity);
}
return false;
case MIDI_CHANNEL_MIN ... MIDI_CHANNEL_MAX:
if (record->event.pressed) {
midi_config.channel = keycode - MIDI_CHANNEL_MIN;
dprintf("midi channel %d\n", midi_config.channel);
}
return false;
case MI_CHD:
if (record->event.pressed) {
midi_config.channel--;
dprintf("midi channel %d\n", midi_config.channel);
}
return false;
case MI_CHU:
if (record->event.pressed) {
midi_config.channel++;
dprintf("midi channel %d\n", midi_config.channel);
}
return false;
case MI_ALLOFF:
if (record->event.pressed) {
midi_send_cc(&midi_device, midi_config.channel, 0x7B, 0);
dprintf("midi all notes off\n");
}
return false;
case MI_SUS:
midi_send_cc(&midi_device, midi_config.channel, 0x40, record->event.pressed ? 127 : 0);
dprintf("midi sustain %d\n", record->event.pressed);
return false;
case MI_PORT:
midi_send_cc(&midi_device, midi_config.channel, 0x41, record->event.pressed ? 127 : 0);
dprintf("midi portamento %d\n", record->event.pressed);
return false;
case MI_SOST:
midi_send_cc(&midi_device, midi_config.channel, 0x42, record->event.pressed ? 127 : 0);
dprintf("midi sostenuto %d\n", record->event.pressed);
return false;
case MI_SOFT:
midi_send_cc(&midi_device, midi_config.channel, 0x43, record->event.pressed ? 127 : 0);
dprintf("midi soft %d\n", record->event.pressed);
return false;
case MI_LEG:
midi_send_cc(&midi_device, midi_config.channel, 0x43, record->event.pressed ? 127 : 0);
dprintf("midi legato %d\n", record->event.pressed);
return false;
case MI_MOD:
midi_modulation_step = record->event.pressed ? 1 : -1;
return false;
case MI_MODSD:
if (record->event.pressed) {
midi_config.modulation_interval++;
// prevent overflow
if (midi_config.modulation_interval == 0)
midi_config.modulation_interval--;
dprintf("midi modulation interval %d\n", midi_config.modulation_interval);
}
return false;
case MI_MODSU:
if (record->event.pressed && midi_config.modulation_interval > 0) {
midi_config.modulation_interval--;
dprintf("midi modulation interval %d\n", midi_config.modulation_interval);
}
return false;
};
return true;
}
#endif // MIDI_ADVANCED
#endif // MIDI_ENABLE

@ -1,207 +1,56 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROCESS_MIDI_H
#define PROCESS_MIDI_H
#include "quantum.h"
bool process_midi(uint16_t keycode, keyrecord_t *record);
#ifdef MIDI_ENABLE
#ifdef MIDI_BASIC
void process_midi_basic_noteon(uint8_t note);
void process_midi_basic_noteoff(uint8_t note);
void process_midi_all_notes_off(void);
#endif
#define MIDI(n) ((n) | 0x6000)
#define MIDI12 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000
#ifdef MIDI_ADVANCED
typedef union {
uint32_t raw;
struct {
uint8_t octave :4;
int8_t transpose :4;
uint8_t velocity :4;
uint8_t channel :4;
uint8_t modulation_interval :4;
};
} midi_config_t;
midi_config_t midi_config;
void midi_init(void);
void midi_task(void);
bool process_midi(uint16_t keycode, keyrecord_t *record);
#define CHNL(note, channel) (note + (channel << 8))
#define MIDI_INVALID_NOTE 0xFF
#define MIDI_TONE_COUNT (MIDI_TONE_MAX - MIDI_TONE_MIN + 1)
#define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \
0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \
0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \
0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \
0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), }
uint8_t midi_compute_note(uint16_t keycode);
#endif // MIDI_ADVANCED
#define N_CN1 (0x600C + (12 * -1) + 0 )
#define N_CN1S (0x600C + (12 * -1) + 1 )
#define N_DN1F (0x600C + (12 * -1) + 1 )
#define N_DN1 (0x600C + (12 * -1) + 2 )
#define N_DN1S (0x600C + (12 * -1) + 3 )
#define N_EN1F (0x600C + (12 * -1) + 3 )
#define N_EN1 (0x600C + (12 * -1) + 4 )
#define N_FN1 (0x600C + (12 * -1) + 5 )
#define N_FN1S (0x600C + (12 * -1) + 6 )
#define N_GN1F (0x600C + (12 * -1) + 6 )
#define N_GN1 (0x600C + (12 * -1) + 7 )
#define N_GN1S (0x600C + (12 * -1) + 8 )
#define N_AN1F (0x600C + (12 * -1) + 8 )
#define N_AN1 (0x600C + (12 * -1) + 9 )
#define N_AN1S (0x600C + (12 * -1) + 10)
#define N_BN1F (0x600C + (12 * -1) + 10)
#define N_BN1 (0x600C + (12 * -1) + 11)
#define N_C0 (0x600C + (12 * 0) + 0 )
#define N_C0S (0x600C + (12 * 0) + 1 )
#define N_D0F (0x600C + (12 * 0) + 1 )
#define N_D0 (0x600C + (12 * 0) + 2 )
#define N_D0S (0x600C + (12 * 0) + 3 )
#define N_E0F (0x600C + (12 * 0) + 3 )
#define N_E0 (0x600C + (12 * 0) + 4 )
#define N_F0 (0x600C + (12 * 0) + 5 )
#define N_F0S (0x600C + (12 * 0) + 6 )
#define N_G0F (0x600C + (12 * 0) + 6 )
#define N_G0 (0x600C + (12 * 0) + 7 )
#define N_G0S (0x600C + (12 * 0) + 8 )
#define N_A0F (0x600C + (12 * 0) + 8 )
#define N_A0 (0x600C + (12 * 0) + 9 )
#define N_A0S (0x600C + (12 * 0) + 10)
#define N_B0F (0x600C + (12 * 0) + 10)
#define N_B0 (0x600C + (12 * 0) + 11)
#define N_C1 (0x600C + (12 * 1) + 0 )
#define N_C1S (0x600C + (12 * 1) + 1 )
#define N_D1F (0x600C + (12 * 1) + 1 )
#define N_D1 (0x600C + (12 * 1) + 2 )
#define N_D1S (0x600C + (12 * 1) + 3 )
#define N_E1F (0x600C + (12 * 1) + 3 )
#define N_E1 (0x600C + (12 * 1) + 4 )
#define N_F1 (0x600C + (12 * 1) + 5 )
#define N_F1S (0x600C + (12 * 1) + 6 )
#define N_G1F (0x600C + (12 * 1) + 6 )
#define N_G1 (0x600C + (12 * 1) + 7 )
#define N_G1S (0x600C + (12 * 1) + 8 )
#define N_A1F (0x600C + (12 * 1) + 8 )
#define N_A1 (0x600C + (12 * 1) + 9 )
#define N_A1S (0x600C + (12 * 1) + 10)
#define N_B1F (0x600C + (12 * 1) + 10)
#define N_B1 (0x600C + (12 * 1) + 11)
#define N_C2 (0x600C + (12 * 2) + 0 )
#define N_C2S (0x600C + (12 * 2) + 1 )
#define N_D2F (0x600C + (12 * 2) + 1 )
#define N_D2 (0x600C + (12 * 2) + 2 )
#define N_D2S (0x600C + (12 * 2) + 3 )
#define N_E2F (0x600C + (12 * 2) + 3 )
#define N_E2 (0x600C + (12 * 2) + 4 )
#define N_F2 (0x600C + (12 * 2) + 5 )
#define N_F2S (0x600C + (12 * 2) + 6 )
#define N_G2F (0x600C + (12 * 2) + 6 )
#define N_G2 (0x600C + (12 * 2) + 7 )
#define N_G2S (0x600C + (12 * 2) + 8 )
#define N_A2F (0x600C + (12 * 2) + 8 )
#define N_A2 (0x600C + (12 * 2) + 9 )
#define N_A2S (0x600C + (12 * 2) + 10)
#define N_B2F (0x600C + (12 * 2) + 10)
#define N_B2 (0x600C + (12 * 2) + 11)
#define N_C3 (0x600C + (12 * 3) + 0 )
#define N_C3S (0x600C + (12 * 3) + 1 )
#define N_D3F (0x600C + (12 * 3) + 1 )
#define N_D3 (0x600C + (12 * 3) + 2 )
#define N_D3S (0x600C + (12 * 3) + 3 )
#define N_E3F (0x600C + (12 * 3) + 3 )
#define N_E3 (0x600C + (12 * 3) + 4 )
#define N_F3 (0x600C + (12 * 3) + 5 )
#define N_F3S (0x600C + (12 * 3) + 6 )
#define N_G3F (0x600C + (12 * 3) + 6 )
#define N_G3 (0x600C + (12 * 3) + 7 )
#define N_G3S (0x600C + (12 * 3) + 8 )
#define N_A3F (0x600C + (12 * 3) + 8 )
#define N_A3 (0x600C + (12 * 3) + 9 )
#define N_A3S (0x600C + (12 * 3) + 10)
#define N_B3F (0x600C + (12 * 3) + 10)
#define N_B3 (0x600C + (12 * 3) + 11)
#define N_C4 (0x600C + (12 * 4) + 0 )
#define N_C4S (0x600C + (12 * 4) + 1 )
#define N_D4F (0x600C + (12 * 4) + 1 )
#define N_D4 (0x600C + (12 * 4) + 2 )
#define N_D4S (0x600C + (12 * 4) + 3 )
#define N_E4F (0x600C + (12 * 4) + 3 )
#define N_E4 (0x600C + (12 * 4) + 4 )
#define N_F4 (0x600C + (12 * 4) + 5 )
#define N_F4S (0x600C + (12 * 4) + 6 )
#define N_G4F (0x600C + (12 * 4) + 6 )
#define N_G4 (0x600C + (12 * 4) + 7 )
#define N_G4S (0x600C + (12 * 4) + 8 )
#define N_A4F (0x600C + (12 * 4) + 8 )
#define N_A4 (0x600C + (12 * 4) + 9 )
#define N_A4S (0x600C + (12 * 4) + 10)
#define N_B4F (0x600C + (12 * 4) + 10)
#define N_B4 (0x600C + (12 * 4) + 11)
#define N_C5 (0x600C + (12 * 5) + 0 )
#define N_C5S (0x600C + (12 * 5) + 1 )
#define N_D5F (0x600C + (12 * 5) + 1 )
#define N_D5 (0x600C + (12 * 5) + 2 )
#define N_D5S (0x600C + (12 * 5) + 3 )
#define N_E5F (0x600C + (12 * 5) + 3 )
#define N_E5 (0x600C + (12 * 5) + 4 )
#define N_F5 (0x600C + (12 * 5) + 5 )
#define N_F5S (0x600C + (12 * 5) + 6 )
#define N_G5F (0x600C + (12 * 5) + 6 )
#define N_G5 (0x600C + (12 * 5) + 7 )
#define N_G5S (0x600C + (12 * 5) + 8 )
#define N_A5F (0x600C + (12 * 5) + 8 )
#define N_A5 (0x600C + (12 * 5) + 9 )
#define N_A5S (0x600C + (12 * 5) + 10)
#define N_B5F (0x600C + (12 * 5) + 10)
#define N_B5 (0x600C + (12 * 5) + 11)
#define N_C6 (0x600C + (12 * 6) + 0 )
#define N_C6S (0x600C + (12 * 6) + 1 )
#define N_D6F (0x600C + (12 * 6) + 1 )
#define N_D6 (0x600C + (12 * 6) + 2 )
#define N_D6S (0x600C + (12 * 6) + 3 )
#define N_E6F (0x600C + (12 * 6) + 3 )
#define N_E6 (0x600C + (12 * 6) + 4 )
#define N_F6 (0x600C + (12 * 6) + 5 )
#define N_F6S (0x600C + (12 * 6) + 6 )
#define N_G6F (0x600C + (12 * 6) + 6 )
#define N_G6 (0x600C + (12 * 6) + 7 )
#define N_G6S (0x600C + (12 * 6) + 8 )
#define N_A6F (0x600C + (12 * 6) + 8 )
#define N_A6 (0x600C + (12 * 6) + 9 )
#define N_A6S (0x600C + (12 * 6) + 10)
#define N_B6F (0x600C + (12 * 6) + 10)
#define N_B6 (0x600C + (12 * 6) + 11)
#define N_C7 (0x600C + (12 * 7) + 0 )
#define N_C7S (0x600C + (12 * 7) + 1 )
#define N_D7F (0x600C + (12 * 7) + 1 )
#define N_D7 (0x600C + (12 * 7) + 2 )
#define N_D7S (0x600C + (12 * 7) + 3 )
#define N_E7F (0x600C + (12 * 7) + 3 )
#define N_E7 (0x600C + (12 * 7) + 4 )
#define N_F7 (0x600C + (12 * 7) + 5 )
#define N_F7S (0x600C + (12 * 7) + 6 )
#define N_G7F (0x600C + (12 * 7) + 6 )
#define N_G7 (0x600C + (12 * 7) + 7 )
#define N_G7S (0x600C + (12 * 7) + 8 )
#define N_A7F (0x600C + (12 * 7) + 8 )
#define N_A7 (0x600C + (12 * 7) + 9 )
#define N_A7S (0x600C + (12 * 7) + 10)
#define N_B7F (0x600C + (12 * 7) + 10)
#define N_B7 (0x600C + (12 * 7) + 11)
#define N_C8 (0x600C + (12 * 8) + 0 )
#define N_C8S (0x600C + (12 * 8) + 1 )
#define N_D8F (0x600C + (12 * 8) + 1 )
#define N_D8 (0x600C + (12 * 8) + 2 )
#define N_D8S (0x600C + (12 * 8) + 3 )
#define N_E8F (0x600C + (12 * 8) + 3 )
#define N_E8 (0x600C + (12 * 8) + 4 )
#define N_F8 (0x600C + (12 * 8) + 5 )
#define N_F8S (0x600C + (12 * 8) + 6 )
#define N_G8F (0x600C + (12 * 8) + 6 )
#define N_G8 (0x600C + (12 * 8) + 7 )
#define N_G8S (0x600C + (12 * 8) + 8 )
#define N_A8F (0x600C + (12 * 8) + 8 )
#define N_A8 (0x600C + (12 * 8) + 9 )
#define N_A8S (0x600C + (12 * 8) + 10)
#define N_B8F (0x600C + (12 * 8) + 10)
#define N_B8 (0x600C + (12 * 8) + 11)
#define N_C8 (0x600C + (12 * 8) + 0 )
#define N_C8S (0x600C + (12 * 8) + 1 )
#define N_D8F (0x600C + (12 * 8) + 1 )
#define N_D8 (0x600C + (12 * 8) + 2 )
#define N_D8S (0x600C + (12 * 8) + 3 )
#define N_E8F (0x600C + (12 * 8) + 3 )
#define N_E8 (0x600C + (12 * 8) + 4 )
#define N_F8 (0x600C + (12 * 8) + 5 )
#define N_F8S (0x600C + (12 * 8) + 6 )
#define N_G8F (0x600C + (12 * 8) + 6 )
#define N_G8 (0x600C + (12 * 8) + 7 )
#define N_G8S (0x600C + (12 * 8) + 8 )
#define N_A8F (0x600C + (12 * 8) + 8 )
#define N_A8 (0x600C + (12 * 8) + 9 )
#define N_A8S (0x600C + (12 * 8) + 10)
#define N_B8F (0x600C + (12 * 8) + 10)
#define N_B8 (0x600C + (12 * 8) + 11)
#endif // MIDI_ENABLE
#endif
#endif

@ -1,5 +1,29 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "process_music.h"
#ifdef AUDIO_ENABLE
#include "process_audio.h"
#endif
#if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
#include "process_midi.h"
#endif
#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
bool music_activated = false;
uint8_t music_starting_note = 0x0C;
int music_offset = 7;
@ -8,36 +32,41 @@ int music_offset = 7;
static bool music_sequence_recording = false;
static bool music_sequence_recorded = false;
static bool music_sequence_playing = false;
static float music_sequence[16] = {0};
static uint8_t music_sequence[16] = {0};
static uint8_t music_sequence_count = 0;
static uint8_t music_sequence_position = 0;
static uint16_t music_sequence_timer = 0;
static uint16_t music_sequence_interval = 100;
bool process_music(uint16_t keycode, keyrecord_t *record) {
static void music_noteon(uint8_t note) {
#ifdef AUDIO_ENABLE
process_audio_noteon(note);
#endif
#if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
process_midi_basic_noteon(note);
#endif
}
if (keycode == AU_ON && record->event.pressed) {
audio_on();
return false;
}
static void music_noteoff(uint8_t note) {
#ifdef AUDIO_ENABLE
process_audio_noteoff(note);
#endif
#if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
process_midi_basic_noteoff(note);
#endif
}
if (keycode == AU_OFF && record->event.pressed) {
audio_off();
return false;
}
void music_all_notes_off(void) {
#ifdef AUDIO_ENABLE
process_audio_all_notes_off();
#endif
#if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
process_midi_all_notes_off();
#endif
}
if (keycode == AU_TOG && record->event.pressed) {
if (is_audio_on())
{
audio_off();
}
else
{
audio_on();
}
return false;
}
bool process_music(uint16_t keycode, keyrecord_t *record) {
if (keycode == MU_ON && record->event.pressed) {
music_on();
@ -61,22 +90,10 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
return false;
}
if (keycode == MUV_IN && record->event.pressed) {
voice_iterate();
music_scale_user();
return false;
}
if (keycode == MUV_DE && record->event.pressed) {
voice_deiterate();
music_scale_user();
return false;
}
if (music_activated) {
if (keycode == KC_LCTL && record->event.pressed) { // Start recording
stop_all_notes();
music_all_notes_off();
music_sequence_recording = true;
music_sequence_recorded = false;
music_sequence_playing = false;
@ -85,7 +102,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
}
if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing
stop_all_notes();
music_all_notes_off();
if (music_sequence_recording) { // was recording
music_sequence_recorded = true;
}
@ -95,7 +112,7 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
}
if (keycode == KC_LGUI && record->event.pressed && music_sequence_recorded) { // Start playing
stop_all_notes();
music_all_notes_off();
music_sequence_recording = false;
music_sequence_playing = true;
music_sequence_position = 0;
@ -114,32 +131,34 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
music_sequence_interval+=10;
return false;
}
#define MUSIC_MODE_GUITAR
#ifdef MUSIC_MODE_CHROMATIC
float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + record->event.key.col + music_offset)/12.0+(MATRIX_ROWS - record->event.key.row));
uint8_t note = (music_starting_note + record->event.key.col + music_offset - 3)+12*(MATRIX_ROWS - record->event.key.row);
#elif defined(MUSIC_MODE_GUITAR)
float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + record->event.key.col + music_offset)/12.0+(float)(MATRIX_ROWS - record->event.key.row + 7)*5.0/12);
uint8_t note = (music_starting_note + record->event.key.col + music_offset + 32)+5*(MATRIX_ROWS - record->event.key.row);
#elif defined(MUSIC_MODE_VIOLIN)
float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + record->event.key.col + music_offset)/12.0+(float)(MATRIX_ROWS - record->event.key.row + 5)*7.0/12);
uint8_t note = (music_starting_note + record->event.key.col + music_offset + 32)+7*(MATRIX_ROWS - record->event.key.row);
#else
float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(music_starting_note + SCALE[record->event.key.col + music_offset])/12.0+(MATRIX_ROWS - record->event.key.row));
uint8_t note = (music_starting_note + SCALE[record->event.key.col + music_offset] - 3)+12*(MATRIX_ROWS - record->event.key.row);
#endif
if (record->event.pressed) {
play_note(freq, 0xF);
music_noteon(note);
if (music_sequence_recording) {
music_sequence[music_sequence_count] = freq;
music_sequence[music_sequence_count] = note;
music_sequence_count++;
}
} else {
stop_note(freq);
music_noteoff(note);
}
if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
return false;
}
return true;
return true;
}
bool is_music_on(void) {
@ -161,26 +180,26 @@ void music_on(void) {
void music_off(void) {
music_activated = 0;
stop_all_notes();
music_all_notes_off();
}
__attribute__ ((weak))
void music_on_user() {}
__attribute__ ((weak))
void audio_on_user() {}
__attribute__ ((weak))
void music_scale_user() {}
void matrix_scan_music(void) {
if (music_sequence_playing) {
if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) {
music_sequence_timer = timer_read();
stop_note(music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)]);
play_note(music_sequence[music_sequence_position], 0xF);
uint8_t prev_note = music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)];
uint8_t next_note = music_sequence[music_sequence_position];
music_noteoff(prev_note);
music_noteon(next_note);
music_sequence_position = (music_sequence_position + 1) % music_sequence_count;
}
}
}
__attribute__ ((weak))
void music_on_user() {}
__attribute__ ((weak))
void music_scale_user() {}
#endif // defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))

@ -1,8 +1,26 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROCESS_MUSIC_H
#define PROCESS_MUSIC_H
#include "quantum.h"
#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
bool process_music(uint16_t keycode, keyrecord_t *record);
bool is_music_on(void);
@ -10,9 +28,9 @@ void music_toggle(void);
void music_on(void);
void music_off(void);
void audio_on_user(void);
void music_on_user(void);
void music_scale_user(void);
void music_all_notes_off(void);
void matrix_scan_music(void);
@ -24,4 +42,6 @@ void matrix_scan_music(void);
0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), }
#endif
#endif
#endif // defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
#endif

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "process_printer.h"
#include "action_util.h"
@ -251,4 +267,4 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
}
return true;
}
}

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROCESS_PRINTER_H
#define PROCESS_PRINTER_H
@ -5,4 +21,4 @@
#include "protocol/serial.h"
#endif
#endif

@ -1,3 +1,19 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "process_printer.h"
#include "action_util.h"
@ -257,4 +273,4 @@ bool process_printer(uint16_t keycode, keyrecord_t *record) {
}
return true;
}
}

@ -1,6 +1,23 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "quantum.h"
#include "action_tapping.h"
uint8_t get_oneshot_mods(void);
static uint16_t last_td;
static int8_t highest_td = -1;

@ -1,3 +1,18 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROCESS_TAP_DANCE_H
#define PROCESS_TAP_DANCE_H

@ -1,3 +1,19 @@
/* Copyright 2017 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "process_ucis.h"
qk_ucis_state_t qk_ucis_state;
@ -130,4 +146,4 @@ bool process_ucis (uint16_t keycode, keyrecord_t *record) {
return false;
}
return true;
}
}

@ -1,3 +1,19 @@
/* Copyright 2017 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROCESS_UCIS_H
#define PROCESS_UCIS_H

@ -1,8 +1,29 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "process_unicode.h"
#include "action_util.h"
static uint8_t first_flag = 0;
bool process_unicode(uint16_t keycode, keyrecord_t *record) {
if (keycode > QK_UNICODE && record->event.pressed) {
if (first_flag == 0) {
set_unicode_input_mode(eeprom_read_byte(EECONFIG_UNICODEMODE));
first_flag = 1;
}
uint16_t unicode = keycode & 0x7FFF;
unicode_input_start();
register_hex(unicode);

@ -1,3 +1,18 @@
/* Copyright 2016 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROCESS_UNICODE_H
#define PROCESS_UNICODE_H

@ -1,10 +1,28 @@
/* Copyright 2017 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "process_unicode_common.h"
static uint8_t input_mode;
uint8_t mods;
void set_unicode_input_mode(uint8_t os_target)
{
input_mode = os_target;
eeprom_update_byte(EECONFIG_UNICODEMODE, os_target);
}
uint8_t get_unicode_input_mode(void) {
@ -76,10 +94,22 @@ void unicode_input_finish (void) {
if (mods & MOD_BIT(KC_RGUI)) register_code(KC_RGUI);
}
__attribute__((weak))
uint16_t hex_to_keycode(uint8_t hex)
{
if (hex == 0x0) {
return KC_0;
} else if (hex < 0xA) {
return KC_1 + (hex - 0x1);
} else {
return KC_A + (hex - 0xA);
}
}
void register_hex(uint16_t hex) {
for(int i = 3; i >= 0; i--) {
uint8_t digit = ((hex >> (i*4)) & 0xF);
register_code(hex_to_keycode(digit));
unregister_code(hex_to_keycode(digit));
}
}
}

@ -1,3 +1,19 @@
/* Copyright 2017 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROCESS_UNICODE_COMMON_H
#define PROCESS_UNICODE_COMMON_H
@ -129,4 +145,4 @@ void register_hex(uint16_t hex);
#define UC_TILD UC(0x007E)
#define UC_DEL UC(0x007F)
#endif
#endif

@ -1,3 +1,19 @@
/* Copyright 2017 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "process_unicodemap.h"
#include "process_unicode_common.h"
@ -53,4 +69,4 @@ bool process_unicode_map(uint16_t keycode, keyrecord_t *record) {
}
}
return true;
}
}

@ -1,3 +1,19 @@
/* Copyright 2017 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PROCESS_UNICODEMAP_H
#define PROCESS_UNICODEMAP_H
@ -6,4 +22,4 @@
void unicode_map_input_error(void);
bool process_unicode_map(uint16_t keycode, keyrecord_t *record);
#endif
#endif

@ -1,3 +1,19 @@
/* Copyright 2016-2017 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "quantum.h"
#ifdef PROTOCOL_LUFA
#include "outputselect.h"
@ -7,6 +23,9 @@
#define TAPPING_TERM 200
#endif
#include "backlight.h"
extern backlight_config_t backlight_config;
#ifdef FAUXCLICKY_ENABLE
#include "fauxclicky.h"
#endif
@ -95,8 +114,8 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
void reset_keyboard(void) {
clear_keyboard();
#ifdef AUDIO_ENABLE
stop_all_notes();
#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_ENABLE_BASIC))
music_all_notes_off();
shutdown_user();
#endif
wait_ms(250);
@ -150,10 +169,13 @@ bool process_record_quantum(keyrecord_t *record) {
if (!(
process_record_kb(keycode, record) &&
#ifdef MIDI_ENABLE
#if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
process_midi(keycode, record) &&
#endif
#ifdef AUDIO_ENABLE
process_audio(keycode, record) &&
#endif
#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
process_music(keycode, record) &&
#endif
#ifdef TAP_DANCE_ENABLE
@ -291,14 +313,6 @@ bool process_record_quantum(keyrecord_t *record) {
return false;
break;
#endif
#ifdef ADAFRUIT_BLE_ENABLE
case OUT_BLE:
if (record->event.pressed) {
set_output(OUTPUT_ADAFRUIT_BLE);
}
return false;
break;
#endif
#endif
case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
if (record->event.pressed) {
@ -601,6 +615,10 @@ void matrix_scan_quantum() {
matrix_scan_combo();
#endif
#if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
backlight_task();
#endif
matrix_scan_kb();
}
@ -668,13 +686,13 @@ __attribute__ ((weak))
void backlight_set(uint8_t level)
{
// Prevent backlight blink on lowest level
#if BACKLIGHT_ON_STATE == 0
// PORTx &= ~n
_SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
#else
// PORTx |= n
_SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
#endif
// #if BACKLIGHT_ON_STATE == 0
// // PORTx &= ~n
// _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
// #else
// // PORTx |= n
// _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
// #endif
if ( level == 0 ) {
#ifndef NO_BACKLIGHT_CLOCK
@ -682,13 +700,13 @@ void backlight_set(uint8_t level)
TCCR1A &= ~(_BV(COM1x1));
OCR1x = 0x0;
#else
#if BACKLIGHT_ON_STATE == 0
// PORTx |= n
_SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
#else
// PORTx &= ~n
_SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
#endif
// #if BACKLIGHT_ON_STATE == 0
// // PORTx |= n
// _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
// #else
// // PORTx &= ~n
// _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
// #endif
#endif
}
#ifndef NO_BACKLIGHT_CLOCK
@ -711,6 +729,30 @@ void backlight_set(uint8_t level)
#endif
}
uint8_t backlight_tick = 0;
void backlight_task(void) {
#ifdef NO_BACKLIGHT_CLOCK
if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
#if BACKLIGHT_ON_STATE == 0
// PORTx &= ~n
_SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
#else
// PORTx |= n
_SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
#endif
} else {
#if BACKLIGHT_ON_STATE == 0
// PORTx |= n
_SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
#else
// PORTx &= ~n
_SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
#endif
}
backlight_tick = (backlight_tick + 1) % 16;
#endif
}
#ifdef BACKLIGHT_BREATHING

@ -1,3 +1,18 @@
/* Copyright 2016-2017 Erez Zukerman, Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QUANTUM_H
#define QUANTUM_H
@ -35,11 +50,16 @@ extern uint32_t default_layer_state;
#ifdef MIDI_ENABLE
#include <lufa.h>
#ifdef MIDI_ADVANCED
#include "process_midi.h"
#endif
#endif // MIDI_ENABLE
#ifdef AUDIO_ENABLE
#include "audio.h"
#include "process_audio.h"
#endif
#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
#include "process_music.h"
#endif
@ -103,6 +123,7 @@ void unregister_code16 (uint16_t code);
#ifdef BACKLIGHT_ENABLE
void backlight_init_ports(void);
void backlight_task(void);
#ifdef BACKLIGHT_BREATHING
void breathing_enable(void);

@ -1,7 +1,31 @@
/* Copyright 2016-2017 Jack Humbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QUANTUM_KEYCODES_H
#define QUANTUM_KEYCODES_H
#ifndef MIDI_ENABLE_STRICT
#define MIDI_ENABLE_STRICT 0
#endif
#if !MIDI_ENABLE_STRICT || (defined(MIDI_ENABLE) && defined(MIDI_ADVANCED))
#ifndef MIDI_TONE_KEYCODE_OCTAVES
#define MIDI_TONE_KEYCODE_OCTAVES 3
#endif
#endif
enum quantum_keycodes {
// Ranges used in shortucuts - not to be used directly
QK_TMK = 0x0000,
@ -107,9 +131,230 @@ enum quantum_keycodes {
MUV_IN,
MUV_DE,
// Midi mode on/off
MIDI_ON,
MIDI_OFF,
// Midi
#if !MIDI_ENABLE_STRICT || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
MI_ON, // send midi notes when music mode is enabled
MI_OFF, // don't send midi notes when music mode is enabled
#endif
#if !MIDI_ENABLE_STRICT || (defined(MIDI_ENABLE) && defined(MIDI_ADVANCED))
MIDI_TONE_MIN,
#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 0
MI_C = MIDI_TONE_MIN,
MI_Cs,
MI_Db = MI_Cs,
MI_D,
MI_Ds,
MI_Eb = MI_Ds,
MI_E,
MI_F,
MI_Fs,
MI_Gb = MI_Fs,
MI_G,
MI_Gs,
MI_Ab = MI_Gs,
MI_A,
MI_As,
MI_Bb = MI_As,
MI_B,
#endif
#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 1
MI_C_1,
MI_Cs_1,
MI_Db_1 = MI_Cs_1,
MI_D_1,
MI_Ds_1,
MI_Eb_1 = MI_Ds_1,
MI_E_1,
MI_F_1,
MI_Fs_1,
MI_Gb_1 = MI_Fs_1,
MI_G_1,
MI_Gs_1,
MI_Ab_1 = MI_Gs_1,
MI_A_1,
MI_As_1,
MI_Bb_1 = MI_As_1,
MI_B_1,
#endif
#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 2
MI_C_2,
MI_Cs_2,
MI_Db_2 = MI_Cs_2,
MI_D_2,
MI_Ds_2,
MI_Eb_2 = MI_Ds_2,
MI_E_2,
MI_F_2,
MI_Fs_2,
MI_Gb_2 = MI_Fs_2,
MI_G_2,
MI_Gs_2,
MI_Ab_2 = MI_Gs_2,
MI_A_2,
MI_As_2,
MI_Bb_2 = MI_As_2,
MI_B_2,
#endif
#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 3
MI_C_3,
MI_Cs_3,
MI_Db_3 = MI_Cs_3,
MI_D_3,
MI_Ds_3,
MI_Eb_3 = MI_Ds_3,
MI_E_3,
MI_F_3,
MI_Fs_3,
MI_Gb_3 = MI_Fs_3,
MI_G_3,
MI_Gs_3,
MI_Ab_3 = MI_Gs_3,
MI_A_3,
MI_As_3,
MI_Bb_3 = MI_As_3,
MI_B_3,
#endif
#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 4
MI_C_4,
MI_Cs_4,
MI_Db_4 = MI_Cs_4,
MI_D_4,
MI_Ds_4,
MI_Eb_4 = MI_Ds_4,
MI_E_4,
MI_F_4,
MI_Fs_4,
MI_Gb_4 = MI_Fs_4,
MI_G_4,
MI_Gs_4,
MI_Ab_4 = MI_Gs_4,
MI_A_4,
MI_As_4,
MI_Bb_4 = MI_As_4,
MI_B_4,
#endif
#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 5
MI_C_5,
MI_Cs_5,
MI_Db_5 = MI_Cs_5,
MI_D_5,
MI_Ds_5,
MI_Eb_5 = MI_Ds_5,
MI_E_5,
MI_F_5,
MI_Fs_5,
MI_Gb_5 = MI_Fs_5,
MI_G_5,
MI_Gs_5,
MI_Ab_5 = MI_Gs_5,
MI_A_5,
MI_As_5,
MI_Bb_5 = MI_As_5,
MI_B_5,
#endif
#if !MIDI_ENABLE_STRICT || MIDI_TONE_KEYCODE_OCTAVES > 5
MIDI_TONE_MAX = MI_B_5,
#elif MIDI_TONE_KEYCODE_OCTAVES > 4
MIDI_TONE_MAX = MI_B_4,
#elif MIDI_TONE_KEYCODE_OCTAVES > 3
MIDI_TONE_MAX = MI_B_3,
#elif MIDI_TONE_KEYCODE_OCTAVES > 2
MIDI_TONE_MAX = MI_B_2,
#elif MIDI_TONE_KEYCODE_OCTAVES > 1
MIDI_TONE_MAX = MI_B_1,
#elif MIDI_TONE_KEYCODE_OCTAVES > 0
MIDI_TONE_MAX = MI_B,
#endif
MIDI_OCTAVE_MIN,
MI_OCT_N2 = MIDI_OCTAVE_MIN,
MI_OCT_N1,
MI_OCT_0,
MI_OCT_1,
MI_OCT_2,
MI_OCT_3,
MI_OCT_4,
MI_OCT_5,
MI_OCT_6,
MI_OCT_7,
MIDI_OCTAVE_MAX = MI_OCT_7,
MI_OCTD, // octave down
MI_OCTU, // octave up
MIDI_TRANSPOSE_MIN,
MI_TRNS_N6 = MIDI_TRANSPOSE_MIN,
MI_TRNS_N5,
MI_TRNS_N4,
MI_TRNS_N3,
MI_TRNS_N2,
MI_TRNS_N1,
MI_TRNS_0,
MI_TRNS_1,
MI_TRNS_2,
MI_TRNS_3,
MI_TRNS_4,
MI_TRNS_5,
MI_TRNS_6,
MIDI_TRANSPOSE_MAX = MI_TRNS_6,
MI_TRNSD, // transpose down
MI_TRNSU, // transpose up
MIDI_VELOCITY_MIN,
MI_VEL_1 = MIDI_VELOCITY_MIN,
MI_VEL_2,
MI_VEL_3,
MI_VEL_4,
MI_VEL_5,
MI_VEL_6,
MI_VEL_7,
MI_VEL_8,
MI_VEL_9,
MI_VEL_10,
MIDI_VELOCITY_MAX = MI_VEL_10,
MI_VELD, // velocity down
MI_VELU, // velocity up
MIDI_CHANNEL_MIN,
MI_CH1 = MIDI_CHANNEL_MIN,
MI_CH2,
MI_CH3,
MI_CH4,
MI_CH5,
MI_CH6,
MI_CH7,
MI_CH8,
MI_CH9,
MI_CH10,
MI_CH11,
MI_CH12,
MI_CH13,
MI_CH14,
MI_CH15,
MI_CH16,
MIDI_CHANNEL_MAX = MI_CH16,
MI_CHD, // previous channel
MI_CHU, // next channel
MI_ALLOFF, // all notes off
MI_SUS, // sustain
MI_PORT, // portamento
MI_SOST, // sostenuto
MI_SOFT, // soft pedal
MI_LEG, // legato
MI_MOD, // modulation
MI_MODSD, // decrease modulation speed
MI_MODSU, // increase modulation speed
#endif // MIDI_ADVANCED
// Backlight functionality
BL_0,
@ -159,9 +404,6 @@ enum quantum_keycodes {
#ifdef BLUETOOTH_ENABLE
OUT_BT,
#endif
#ifdef ADAFRUIT_BLE_ENABLE
OUT_BLE,
#endif
// always leave at the end
SAFE_RANGE
@ -183,6 +425,7 @@ enum quantum_keycodes {
#define ALTG(kc) (kc | QK_RCTL | QK_RALT)
#define SCMD(kc) (kc | QK_LGUI | QK_LSFT)
#define SWIN(kc) SCMD(kc)
#define LCA(kc) (kc | QK_LCTL | QK_LALT)
#define MOD_HYPR 0xf
#define MOD_MEH 0x7
@ -281,9 +524,6 @@ enum quantum_keycodes {
#define BL_ON BL_9
#define BL_OFF BL_0
#define MI_ON MIDI_ON
#define MI_OFF MIDI_OFF
// GOTO layer - 16 layers max
// when:
// ON_PRESS = 1
@ -339,6 +579,7 @@ enum quantum_keycodes {
#define ALL_T(kc) MT((MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI), kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/
#define SCMD_T(kc) MT((MOD_LGUI | MOD_LSFT), kc)
#define SWIN_T(kc) SCMD_T(kc)
#define LCA_T(kc) MT((MOD_LCTL | MOD_LALT), kc) // Left control and left alt
// Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap
#define KC_HYPR HYPR(KC_NO)

@ -1,3 +1,18 @@
/* Copyright 2016-2017 Yang Liu
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <util/delay.h>

@ -1,3 +1,18 @@
/* Copyright 2017 Yang Liu
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef RGBLIGHT_H
#define RGBLIGHT_H

@ -1,7 +1,5 @@
The MIT License (MIT)
Copyright (c) 2016 Fred Sundvik
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights

@ -1,3 +1,18 @@
# Copyright 2013 Jun Wako <wakojun@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
ifndef MAKEFILE_INCLUDED
include ../../Makefile
endif
endif

@ -1,5 +1,5 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
Copyright 2017 REPLACE_WITH_YOUR_NAME
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -159,4 +159,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
/*
* MIDI options
*/
/* Prevent use of disabled MIDI features in the keymap */
//#define MIDI_ENABLE_STRICT 1
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
//#define MIDI_BASIC
/* enable advanced MIDI features:
- MIDI notes can be added to the keymap
- Octave shift and transpose
- Virtual sustain, portamento, and modulation wheel
- etc.
*/
//#define MIDI_ADVANCED
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 1
#endif

@ -1,4 +1,20 @@
# Build Options
# Copyright 2013 Jun Wako <wakojun@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# QMK Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
@ -9,7 +25,7 @@ CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI controls
MIDI_ENABLE = no # MIDI support (+2400 to 4200, depending on config)
AUDIO_ENABLE = no # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
@ -18,4 +34,4 @@ SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
endif
endif

@ -1,3 +1,19 @@
/* Copyright 2017 REPLACE_WITH_YOUR_NAME
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
@ -5,4 +21,4 @@
// place overrides here
#endif
#endif

@ -1,3 +1,18 @@
/* Copyright 2017 REPLACE_WITH_YOUR_NAME
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "%KEYBOARD%.h"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
@ -41,4 +56,4 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
void led_set_user(uint8_t usb_led) {
}
}

@ -61,7 +61,7 @@ SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE ?= no # USB Nkey Rollover
BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality on B7 by default
MIDI_ENABLE ?= no # MIDI controls
MIDI_ENABLE ?= no # MIDI support (+2400 to 4200, depending on config)
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE ?= no # Audio output on port C6

@ -1,3 +1,18 @@
/* Copyright 2017 REPLACE_WITH_YOUR_NAME
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "%KEYBOARD%.h"
void matrix_init_kb(void) {

@ -1,3 +1,18 @@
/* Copyright 2017 REPLACE_WITH_YOUR_NAME
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef %KEYBOARD_UPPERCASE%_H
#define %KEYBOARD_UPPERCASE%_H
@ -5,7 +20,7 @@
// This a shortcut to help you visually see your layout.
// The following is an example using the Planck MIT layout
// The first section contains all of the arguements
// The first section contains all of the arguments
// The second converts the arguments into a two-dimensional array
#define KEYMAP( \
k00, k01, k02, \

@ -1,3 +1,19 @@
/* Copyright 2016 Fred Sundvik
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "variable_trace.h"
#include <stddef.h>
#include <string.h>

@ -1,3 +1,19 @@
/* Copyright 2016 Fred Sundvik
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef VARIABLE_TRACE_H
#define VARIABLE_TRACE_H

@ -1,6 +1,6 @@
# Quantum Mechanical Keyboard Firmware
[![Build Status](https://travis-ci.org/qmk/qmk_firmware.svg?branch=master)](https://travis-ci.org/jackhumbert/qmk_firmware) [![Gitter](https://badges.gitter.im/qmk/qmk_firmware.svg)](https://gitter.im/qmk/qmk_firmware?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
[![Build Status](https://travis-ci.org/qmk/qmk_firmware.svg?branch=master)](https://travis-ci.org/qmk/qmk_firmware) [![Gitter](https://badges.gitter.im/qmk/qmk_firmware.svg)](https://gitter.im/qmk/qmk_firmware?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
This is a keyboard firmware based on the [tmk_keyboard firmware](http://github.com/tmk/tmk_keyboard) with some useful features for Atmel AVR controllers, and more specifically, the [OLKB product line](http://olkb.com), the [ErgoDox EZ](http://www.ergodox-ez.com) keyboard, and the [Clueboard product line](http://clueboard.co/).
@ -35,5 +35,5 @@ This is not a tiny project. While this is the main readme, there are many other
* The readme for your own keyboard: This is found under `keyboards/<your keyboards's name>/`. So for the ErgoDox EZ, it's [here](keyboards/ergodox/ez/); for the Planck, it's [here](keyboards/planck/) and so on.
* The list of possible keycodes you can use in your keymap is actually spread out in a few different places:
* [doc/keycode.txt](doc/keycode.txt) - an explanation of those same keycodes.
* [quantum/keymap.h](quantum/keymap.h) - this is where the QMK-specific aliases are all set up. Things like the Hyper and Meh key, the Leader key, and all of the other QMK innovations. These are also explained and documented below, but `keymap.h` is where they're actually defined.
* [quantum/quantum_keycodes.h](quantum/quantum_keycodes.h) - this is where the QMK-specific aliases are all set up. Things like the Hyper and Meh key, the Leader key, and all of the other QMK innovations. These are also explained and documented below, but `quantum_keycodes.h` is where they're actually defined.
* The [TMK documentation](doc/TMK_README.md). QMK is based on TMK, and this explains how it works internally.

@ -143,8 +143,13 @@ MCUFLAGS = -mcpu=$(MCU)
DEBUG = gdb
DFU_ARGS =
ifneq ("$(SERIAL)","")
DFU_ARGS += -S $(SERIAL)
endif
# List any extra directories to look for libraries here.
EXTRALIBDIRS = $(RULESPATH)/ld
dfu-util: $(BUILD_DIR)/$(TARGET).bin sizeafter
dfu-util -D $(BUILD_DIR)/$(TARGET).bin
dfu-util $(DFU_ARGS) -D $(BUILD_DIR)/$(TARGET).bin

@ -93,14 +93,25 @@ ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
TMK_COMMON_DEFS += -DBACKLIGHT_ENABLE
endif
ifeq ($(strip $(ADAFRUIT_BLE_ENABLE)), yes)
TMK_COMMON_DEFS += -DADAFRUIT_BLE_ENABLE
endif
ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
endif
ifeq ($(strip $(BLUETOOTH)), AdafruitBLE)
TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
TMK_COMMON_DEFS += -DMODULE_ADAFRUIT_BLE
endif
ifeq ($(strip $(BLUETOOTH)), AdafruitEZKey)
TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
TMK_COMMON_DEFS += -DMODULE_ADAFRUIT_EZKEY
endif
ifeq ($(strip $(BLUETOOTH)), RN42)
TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE
TMK_COMMON_DEFS += -DMODULE_RN42
endif
ifeq ($(strip $(ONEHAND_ENABLE)), yes)
TMK_COMMON_DEFS += -DONEHAND_ENABLE
endif

@ -228,6 +228,7 @@ bool process_tapping(keyrecord_t *keyp)
if (WITHIN_TAPPING_TERM(event)) {
if (event.pressed) {
if (IS_TAPPING_KEY(event.key)) {
#ifndef TAPPING_FORCE_HOLD
if (!tapping_key.tap.interrupted && tapping_key.tap.count > 0) {
// sequential tap.
keyp->tap = tapping_key.tap;
@ -237,11 +238,11 @@ bool process_tapping(keyrecord_t *keyp)
tapping_key = *keyp;
debug_tapping_key();
return true;
} else {
// FIX: start new tap again
tapping_key = *keyp;
return true;
}
#endif
// FIX: start new tap again
tapping_key = *keyp;
return true;
} else if (is_tap_key(event.key)) {
// Sequential tap can be interfered with other tap key.
debug("Tapping: Start with interfering other tap.\n");

@ -33,6 +33,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define EECONFIG_BACKLIGHT (uint8_t *)6
#define EECONFIG_AUDIO (uint8_t *)7
#define EECONFIG_RGBLIGHT (uint32_t *)8
#define EECONFIG_UNICODEMODE (uint8_t *)12
/* debug bit */

@ -22,11 +22,21 @@ ifeq ($(strip $(MIDI_ENABLE)), yes)
include $(TMK_PATH)/protocol/midi.mk
endif
ifeq ($(strip $(ADAFRUIT_BLE_ENABLE)), yes)
LUFA_SRC += $(LUFA_DIR)/adafruit_ble.cpp
ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
LUFA_SRC += $(LUFA_DIR)/bluetooth.c \
$(TMK_DIR)/protocol/serial_uart.c
endif
ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
ifeq ($(strip $(BLUETOOTH)), AdafruitBLE)
LUFA_SRC += $(LUFA_DIR)/adafruit_ble.cpp
endif
ifeq ($(strip $(BLUETOOTH)), AdafruitEZKey)
LUFA_SRC += $(LUFA_DIR)/bluetooth.c \
$(TMK_DIR)/protocol/serial_uart.c
endif
ifeq ($(strip $(BLUETOOTH)), RN42)
LUFA_SRC += $(LUFA_DIR)/bluetooth.c \
$(TMK_DIR)/protocol/serial_uart.c
endif
@ -54,6 +64,7 @@ LUFA_OPTS += -DUSE_FLASH_DESCRIPTORS
LUFA_OPTS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
#LUFA_OPTS += -DINTERRUPT_CONTROL_ENDPOINT
LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8
LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1
# Remote wakeup fix for ATmega32U2 https://github.com/tmk/tmk_keyboard/issues/361

@ -3,7 +3,7 @@
* Supports the Adafruit BLE board built around the nRF51822 chip.
*/
#pragma once
#ifdef ADAFRUIT_BLE_ENABLE
#ifdef MODULE_ADAFRUIT_BLE
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
@ -57,4 +57,4 @@ extern bool adafruit_ble_set_power_level(int8_t level);
}
#endif
#endif // ADAFRUIT_BLE_ENABLE
#endif // MODULE_ADAFRUIT_BLE

@ -62,4 +62,18 @@ void bluefruit_serial_send(uint8_t data);
(usage == AC_REFRESH ? 0x0000 : \
(usage == AC_BOOKMARKS ? 0x0000 : 0)))))))))))))))))))
#endif
#define CONSUMER2RN42(usage) \
(usage == AUDIO_MUTE ? 0x0040 : \
(usage == AUDIO_VOL_UP ? 0x0010 : \
(usage == AUDIO_VOL_DOWN ? 0x0020 : \
(usage == TRANSPORT_NEXT_TRACK ? 0x0100 : \
(usage == TRANSPORT_PREV_TRACK ? 0x0200 : \
(usage == TRANSPORT_STOP ? 0x0400 : \
(usage == TRANSPORT_STOP_EJECT ? 0x0800 : \
(usage == TRANSPORT_PLAY_PAUSE ? 0x0080 : \
(usage == AL_EMAIL ? 0x0200 : \
(usage == AL_LOCAL_BROWSER ? 0x8000 : \
(usage == AC_SEARCH ? 0x0400 : \
(usage == AC_HOME ? 0x0100 : 0))))))))))))
#endif

@ -67,10 +67,11 @@
#endif
#ifdef BLUETOOTH_ENABLE
#include "bluetooth.h"
#endif
#ifdef ADAFRUIT_BLE_ENABLE
#ifdef MODULE_ADAFRUIT_BLE
#include "adafruit_ble.h"
#else
#include "bluetooth.h"
#endif
#endif
#ifdef VIRTSER_ENABLE
@ -602,18 +603,23 @@ static void send_keyboard(report_keyboard_t *report)
uint8_t where = where_to_send();
#ifdef BLUETOOTH_ENABLE
if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
bluefruit_serial_send(0xFD);
for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
bluefruit_serial_send(report->raw[i]);
}
}
#endif
#ifdef ADAFRUIT_BLE_ENABLE
if (where == OUTPUT_ADAFRUIT_BLE) {
if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
#ifdef MODULE_ADAFRUIT_BLE
adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
}
#elif MODULE_RN42
bluefruit_serial_send(0xFD);
bluefruit_serial_send(0x09);
bluefruit_serial_send(0x01);
for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
bluefruit_serial_send(report->raw[i]);
}
#else
bluefruit_serial_send(0xFD);
for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
bluefruit_serial_send(report->raw[i]);
}
#endif
}
#endif
if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
@ -660,24 +666,22 @@ static void send_mouse(report_mouse_t *report)
uint8_t where = where_to_send();
#ifdef BLUETOOTH_ENABLE
if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
bluefruit_serial_send(0xFD);
bluefruit_serial_send(0x00);
bluefruit_serial_send(0x03);
bluefruit_serial_send(report->buttons);
bluefruit_serial_send(report->x);
bluefruit_serial_send(report->y);
bluefruit_serial_send(report->v); // should try sending the wheel v here
bluefruit_serial_send(report->h); // should try sending the wheel h here
bluefruit_serial_send(0x00);
}
#endif
#ifdef ADAFRUIT_BLE_ENABLE
if (where == OUTPUT_ADAFRUIT_BLE) {
if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
#ifdef MODULE_ADAFRUIT_BLE
// FIXME: mouse buttons
adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h);
}
#else
bluefruit_serial_send(0xFD);
bluefruit_serial_send(0x00);
bluefruit_serial_send(0x03);
bluefruit_serial_send(report->buttons);
bluefruit_serial_send(report->x);
bluefruit_serial_send(report->y);
bluefruit_serial_send(report->v); // should try sending the wheel v here
bluefruit_serial_send(report->h); // should try sending the wheel h here
bluefruit_serial_send(0x00);
#endif
}
#endif
if (where != OUTPUT_USB && where != OUTPUT_USB_AND_BT) {
@ -727,6 +731,19 @@ static void send_consumer(uint16_t data)
#ifdef BLUETOOTH_ENABLE
if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) {
#ifdef MODULE_ADAFRUIT_BLE
adafruit_ble_send_consumer_key(data, 0);
#elif MODULE_RN42
static uint16_t last_data = 0;
if (data == last_data) return;
last_data = data;
uint16_t bitmap = CONSUMER2RN42(data);
bluefruit_serial_send(0xFD);
bluefruit_serial_send(0x03);
bluefruit_serial_send(0x03);
bluefruit_serial_send(bitmap&0xFF);
bluefruit_serial_send((bitmap>>8)&0xFF);
#else
static uint16_t last_data = 0;
if (data == last_data) return;
last_data = data;
@ -740,12 +757,7 @@ static void send_consumer(uint16_t data)
bluefruit_serial_send(0x00);
bluefruit_serial_send(0x00);
bluefruit_serial_send(0x00);
}
#endif
#ifdef ADAFRUIT_BLE_ENABLE
if (where == OUTPUT_ADAFRUIT_BLE) {
adafruit_ble_send_consumer_key(data, 0);
#endif
}
#endif
@ -1101,16 +1113,23 @@ void cc_callback(MidiDevice * device,
uint8_t chan, uint8_t num, uint8_t val);
void sysex_callback(MidiDevice * device,
uint16_t start, uint8_t length, uint8_t * data);
void setup_midi(void)
{
#ifdef MIDI_ADVANCED
midi_init();
#endif
midi_device_init(&midi_device);
midi_device_set_send_func(&midi_device, usb_send_func);
midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
}
#endif
int main(void) __attribute__ ((weak));
int main(void)
{
#ifdef MIDI_ENABLE
midi_device_init(&midi_device);
midi_device_set_send_func(&midi_device, usb_send_func);
midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
setup_midi();
#endif
setup_mcu();
@ -1130,7 +1149,7 @@ int main(void)
// midi_send_noteoff(&midi_device, 0, 64, 127);
#endif
#ifdef BLUETOOTH_ENABLE
#if defined(MODULE_ADAFRUIT_EZKEY) || defined(MODULE_RN42)
serial_init();
#endif
@ -1161,7 +1180,7 @@ int main(void)
print("Keyboard start.\n");
while (1) {
#if !defined(BLUETOOTH_ENABLE) && !defined(ADAFRUIT_BLE_ENABLE)
#if !defined(BLUETOOTH_ENABLE)
while (USB_DeviceState == DEVICE_STATE_Suspended) {
print("[s]");
suspend_power_down();
@ -1175,14 +1194,16 @@ int main(void)
#ifdef MIDI_ENABLE
midi_device_process(&midi_device);
// MIDI_Task();
#ifdef MIDI_ADVANCED
midi_task();
#endif
#endif
#if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE)
rgblight_task();
#endif
#ifdef ADAFRUIT_BLE_ENABLE
#ifdef MODULE_ADAFRUIT_BLE
adafruit_ble_task();
#endif

@ -49,7 +49,7 @@
#include <LUFA/Drivers/USB/USB.h>
#include "host.h"
#ifdef MIDI_ENABLE
#include "midi.h"
#include "process_midi.h"
#endif
#ifdef __cplusplus
extern "C" {

@ -14,7 +14,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "lufa.h"
#include "outputselect.h"
#ifdef ADAFRUIT_BLE_ENABLE
#ifdef MODULE_ADAFRUIT_BLE
#include "adafruit_ble.h"
#endif
@ -34,9 +34,9 @@ uint8_t auto_detect_output(void) {
return OUTPUT_USB;
}
#ifdef ADAFRUIT_BLE_ENABLE
#ifdef MODULE_ADAFRUIT_BLE
if (adafruit_ble_is_connected()) {
return OUTPUT_ADAFRUIT_BLE;
return OUTPUT_BLUETOOTH;
}
#endif

@ -18,7 +18,6 @@ enum outputs {
OUTPUT_NONE,
OUTPUT_USB,
OUTPUT_BLUETOOTH,
OUTPUT_ADAFRUIT_BLE,
// backward compatibility
OUTPUT_USB_AND_BT

@ -92,4 +92,23 @@ elif [[ -n "$(type -P zypper)" ]]; then
# TODO: The avr and eabi tools are not available as default packages, so we need
# another way to install them
elif [[ -n "$(type -P pkg)" ]]; then
# FreeBSD
pkg update
pkg install -y \
git \
wget \
gmake \
gcc \
zip \
unzip \
avr-binutils \
avr-gcc \
avr-libc \
dfu-programmer \
dfu-util \
arm-none-eabi-gcc \
arm-none-eabi-binutils \
arm-none-eabi-newlib \
diffutils
fi

Loading…
Cancel
Save