diff --git a/README.md b/README.md
index d4793e9b..aae350d0 100644
--- a/README.md
+++ b/README.md
@@ -23,6 +23,7 @@ These features can be used in your keyboard.
* Virtual DIP Switch - Configurations stored EEPROM(Boot Magic)
* Locking CapsLock - Mechanical switch support for CapsLock
* Breathing Sleep LED - Sleep indicator with charm during USB suspend
+* Backlight - Control backlight levels
Projects
@@ -48,6 +49,7 @@ You can find some keyboard specific projects under `converter` and `keyboard` di
* [phantom](keyboard/phantom/) - [Phantom] keyboard (by Tranquilite)
* [IIgs_Standard](keyboard/IIgs/) - Apple [IIGS] keyboard mod(by JeffreySung)
* [macway](keyboard/macway/) - [Compact keyboard mod][GH_macway] [retired]
+* [KMAC](keyboard/kmac/) - Korean custom keyboard
[GH_macway]: http://geekhack.org/showwiki.php?title=Island:11930
[GH_hhkb]: http://geekhack.org/showwiki.php?title=Island:12047
diff --git a/common.mk b/common.mk
index 5f47e5c1..47d5c852 100644
--- a/common.mk
+++ b/common.mk
@@ -63,6 +63,11 @@ ifdef SLEEP_LED_ENABLE
OPT_DEFS += -DNO_SUSPEND_POWER_DOWN
endif
+ifdef BACKLIGHT_ENABLE
+ SRC += $(COMMON_DIR)/backlight.c
+ OPT_DEFS += -DBACKLIGHT_ENABLE
+endif
+
# Search Path
VPATH += $(TOP_DIR)/common
diff --git a/common/action.c b/common/action.c
index c7c8f71f..b1fa0e31 100644
--- a/common/action.c
+++ b/common/action.c
@@ -20,6 +20,7 @@ along with this program. If not, see .
#include "mousekey.h"
#include "command.h"
#include "led.h"
+#include "backlight.h"
#include "action_layer.h"
#include "action_tapping.h"
#include "action_oneshot.h"
@@ -291,6 +292,26 @@ void process_action(keyrecord_t *record)
case ACT_MACRO:
action_macro_play(action_get_macro(record, action.func.id, action.func.opt));
break;
+#endif
+#ifdef BACKLIGHT_ENABLE
+ case ACT_BACKLIGHT:
+ if (!event.pressed) {
+ switch (action.backlight.id) {
+ case BACKLIGHT_INCREASE:
+ backlight_increase();
+ break;
+ case BACKLIGHT_DECREASE:
+ backlight_decrease();
+ break;
+ case BACKLIGHT_TOGGLE:
+ backlight_toggle();
+ break;
+ case BACKLIGHT_STEP:
+ backlight_step();
+ break;
+ }
+ }
+ break;
#endif
case ACT_COMMAND:
break;
diff --git a/common/action_code.h b/common/action_code.h
index 0933dce1..2272091c 100644
--- a/common/action_code.h
+++ b/common/action_code.h
@@ -85,6 +85,9 @@ along with this program. If not, see .
* 1100|opt | id(8) Macro play?
* 1100|1111| id(8) Macro record?
*
+ * ACT_BACKLIGHT(1101):
+ * 1101|xxxx| id(8) Backlight commands
+ *
* ACT_COMMAND(1110):
* 1110|opt | id(8) Built-in Command exec
*
@@ -109,6 +112,7 @@ enum action_kind_id {
ACT_LAYER_TAP1 = 0b1011,
/* Extensions */
ACT_MACRO = 0b1100,
+ ACT_BACKLIGHT = 0b1101,
ACT_COMMAND = 0b1110,
ACT_FUNCTION = 0b1111
};
@@ -157,6 +161,9 @@ typedef union {
uint8_t page :2;
uint8_t kind :4;
} usage;
+ struct action_backlight {
+ uint8_t id :8;
+ } backlight;
struct action_command {
uint8_t id :8;
uint8_t opt :4;
@@ -272,10 +279,21 @@ enum layer_pram_tap_op {
/*
* Extensions
*/
+enum backlight_id {
+ BACKLIGHT_INCREASE = 0,
+ BACKLIGHT_DECREASE = 1,
+ BACKLIGHT_TOGGLE = 2,
+ BACKLIGHT_STEP = 3,
+};
/* Macro */
#define ACTION_MACRO(id) ACTION(ACT_MACRO, (id))
#define ACTION_MACRO_TAP(id) ACTION(ACT_MACRO, FUNC_TAP<<8 | (id))
#define ACTION_MACRO_OPT(id, opt) ACTION(ACT_MACRO, (opt)<<8 | (id))
+/* Backlight */
+#define ACTION_BACKLIGHT_INCREASE() ACTION(ACT_BACKLIGHT, BACKLIGHT_INCREASE)
+#define ACTION_BACKLIGHT_DECREASE() ACTION(ACT_BACKLIGHT, BACKLIGHT_DECREASE)
+#define ACTION_BACKLIGHT_TOGGLE() ACTION(ACT_BACKLIGHT, BACKLIGHT_TOGGLE)
+#define ACTION_BACKLIGHT_STEP() ACTION(ACT_BACKLIGHT, BACKLIGHT_STEP)
/* Command */
#define ACTION_COMMAND(id, opt) ACTION(ACT_COMMAND, (opt)<<8 | (addr))
/* Function */
diff --git a/common/backlight.c b/common/backlight.c
new file mode 100644
index 00000000..00dc04a0
--- /dev/null
+++ b/common/backlight.c
@@ -0,0 +1,77 @@
+/*
+Copyright 2013 Mathias Andersson
+
+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 .
+*/
+
+#include "backlight.h"
+#include "eeconfig.h"
+#include "debug.h"
+
+backlight_config_t backlight_config;
+
+void backlight_init(void)
+{
+ /* check signature */
+ if (!eeconfig_is_enabled()) {
+ eeconfig_init();
+ }
+ backlight_config.raw = eeconfig_read_backlight();
+ backlight_set(backlight_config.enable ? backlight_config.level : 0);
+}
+
+void backlight_increase(void)
+{
+ if(backlight_config.level < BACKLIGHT_LEVELS)
+ {
+ backlight_config.level++;
+ backlight_config.enable = 1;
+ eeconfig_write_backlight(backlight_config.raw);
+ }
+ dprintf("backlight increase: %u\n", backlight_config.level);
+ backlight_set(backlight_config.level);
+}
+
+void backlight_decrease(void)
+{
+ if(backlight_config.level > 0)
+ {
+ backlight_config.level--;
+ backlight_config.enable = !!backlight_config.level;
+ eeconfig_write_backlight(backlight_config.raw);
+ }
+ dprintf("backlight decrease: %u\n", backlight_config.level);
+ backlight_set(backlight_config.level);
+}
+
+void backlight_toggle(void)
+{
+ backlight_config.enable ^= 1;
+ eeconfig_write_backlight(backlight_config.raw);
+ dprintf("backlight toggle: %u\n", backlight_config.enable);
+ backlight_set(backlight_config.enable ? backlight_config.level : 0);
+}
+
+void backlight_step(void)
+{
+ backlight_config.level++;
+ if(backlight_config.level > BACKLIGHT_LEVELS)
+ {
+ backlight_config.level = 0;
+ }
+ backlight_config.enable = !!backlight_config.level;
+ eeconfig_write_backlight(backlight_config.raw);
+ dprintf("backlight step: %u\n", backlight_config.level);
+ backlight_set(backlight_config.level);
+}
diff --git a/common/backlight.h b/common/backlight.h
new file mode 100644
index 00000000..685c422a
--- /dev/null
+++ b/common/backlight.h
@@ -0,0 +1,41 @@
+/*
+Copyright 2013 Mathias Andersson
+
+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 .
+*/
+
+#ifndef BACKLIGHT_H
+#define BACKLIGHT_H
+
+#include
+#include
+
+typedef union {
+ uint8_t raw;
+ struct {
+ bool enable:1;
+ uint8_t level:7;
+ };
+} backlight_config_t;
+
+void backlight_init(void);
+
+void backlight_increase(void);
+void backlight_decrease(void);
+void backlight_toggle(void);
+void backlight_step(void);
+
+void backlight_set(uint8_t level);
+
+#endif
diff --git a/common/command.c b/common/command.c
index 73a72b4a..4649e00a 100644
--- a/common/command.c
+++ b/common/command.c
@@ -31,6 +31,7 @@ along with this program. If not, see .
#include "sleep_led.h"
#include "led.h"
#include "command.h"
+#include "backlight.h"
#ifdef MOUSEKEY_ENABLE
#include "mousekey.h"
@@ -149,6 +150,14 @@ static void print_eeconfig(void)
print(".no_gui: "); print_dec(kc.no_gui); print("\n");
print(".swap_grave_esc: "); print_dec(kc.swap_grave_esc); print("\n");
print(".swap_backslash_backspace: "); print_dec(kc.swap_backslash_backspace); print("\n");
+
+#ifdef BACKLIGHT_ENABLE
+ backlight_config_t bc;
+ bc.raw = eeconfig_read_backlight();
+ print("backlight_config.raw: "); print_hex8(bc.raw); print("\n");
+ print(".enable: "); print_dec(bc.enable); print("\n");
+ print(".level: "); print_dec(bc.level); print("\n");
+#endif
}
#endif
diff --git a/common/eeconfig.c b/common/eeconfig.c
index a833f4db..5bd47dc6 100644
--- a/common/eeconfig.c
+++ b/common/eeconfig.c
@@ -10,6 +10,9 @@ void eeconfig_init(void)
eeprom_write_byte(EECONFIG_DEFAULT_LAYER, 0);
eeprom_write_byte(EECONFIG_KEYMAP, 0);
eeprom_write_byte(EECONFIG_MOUSEKEY_ACCEL, 0);
+#ifdef BACKLIGHT_ENABLE
+ eeprom_write_byte(EECONFIG_BACKLIGHT, 0);
+#endif
}
void eeconfig_enable(void)
@@ -35,3 +38,8 @@ void eeconfig_write_default_layer(uint8_t val) { eeprom_write_byte(EECONFIG_DEFA
uint8_t eeconfig_read_keymap(void) { return eeprom_read_byte(EECONFIG_KEYMAP); }
void eeconfig_write_keymap(uint8_t val) { eeprom_write_byte(EECONFIG_KEYMAP, val); }
+
+#ifdef BACKLIGHT_ENABLE
+uint8_t eeconfig_read_backlight(void) { return eeprom_read_byte(EECONFIG_BACKLIGHT); }
+void eeconfig_write_backlight(uint8_t val) { eeprom_write_byte(EECONFIG_BACKLIGHT, val); }
+#endif
diff --git a/common/eeconfig.h b/common/eeconfig.h
index 0b605fc7..e1b5ae28 100644
--- a/common/eeconfig.h
+++ b/common/eeconfig.h
@@ -19,6 +19,7 @@ along with this program. If not, see .
#define EECONFIG_H
#include
+#include
#define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEED
@@ -29,6 +30,7 @@ along with this program. If not, see .
#define EECONFIG_DEFAULT_LAYER (uint8_t *)3
#define EECONFIG_KEYMAP (uint8_t *)4
#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)5
+#define EECONFIG_BACKLIGHT (uint8_t *)6
/* debug bit */
@@ -64,4 +66,9 @@ void eeconfig_write_default_layer(uint8_t val);
uint8_t eeconfig_read_keymap(void);
void eeconfig_write_keymap(uint8_t val);
+#ifdef BACKLIGHT_ENABLE
+uint8_t eeconfig_read_backlight(void);
+void eeconfig_write_backlight(uint8_t val);
+#endif
+
#endif
diff --git a/common/keyboard.c b/common/keyboard.c
index 6bc6fae6..d1821a09 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -31,6 +31,7 @@ along with this program. If not, see .
#include "bootmagic.h"
#include "eeconfig.h"
#include "mousekey.h"
+#include "backlight.h"
#ifdef MATRIX_HAS_GHOST
@@ -65,6 +66,10 @@ void keyboard_init(void)
#ifdef BOOTMAGIC_ENABLE
bootmagic();
#endif
+
+#ifdef BACKLIGHT_ENABLE
+ backlight_init();
+#endif
}
/*
diff --git a/common/suspend.c b/common/suspend.c
index 6029fe7f..146b96d5 100644
--- a/common/suspend.c
+++ b/common/suspend.c
@@ -1,10 +1,14 @@
#include "suspend.h"
#include "matrix.h"
#include "action.h"
+#include "backlight.h"
void suspend_power_down(void)
{
+#ifdef BACKLIGHT_ENABLE
+ backlight_set(0);
+#endif
#ifndef NO_SUSPEND_POWER_DOWN
// Enable watchdog to wake from MCU sleep
cli();
@@ -50,6 +54,9 @@ void suspend_wakeup_init(void)
// clear matrix and keyboard state
matrix_init();
clear_keyboard();
+#ifdef BACKLIGHT_ENABLE
+ backlight_init();
+#endif
}
#ifndef NO_SUSPEND_POWER_DOWN
diff --git a/doc/build.md b/doc/build.md
index 88504f09..ae856501 100644
--- a/doc/build.md
+++ b/doc/build.md
@@ -132,6 +132,7 @@ Optional. Note that ***comment out*** to disable them.
COMMAND_ENABLE = yes # Commands for debug and configuration
SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
+ #BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
### 3. Programmer
Optional. Set proper command for your controller, bootloader and programmer. This command can be used with `make program`. Not needed if you use `FLIP`, `dfu-programmer` or `Teesy Loader`.
diff --git a/doc/keymap.md b/doc/keymap.md
index 474a706e..7d979eb7 100644
--- a/doc/keymap.md
+++ b/doc/keymap.md
@@ -430,6 +430,27 @@ See `keyboard/hhkb/keymap.c` for sample.
+### 2.5 Backlight Action
+These actions control the backlight.
+
+#### 2.5.1 Change backlight level
+Increase backlight level.
+
+ ACTION_BACKLIGHT_INCREASE()
+
+Decrease backlight level.
+
+ ACTION_BACKLIGHT_DECREASE()
+
+Step through backlight levels.
+
+ ACTION_BACKLIGHT_STEP()
+
+#### 2.5.2 Turn on / off backlight
+Turn the backlight on and off without changing level.
+
+ ACTION_BACKLIGHT_TOGGLE()
+
## 3. Layer switching Example
diff --git a/keyboard/kmac/Makefile.lufa b/keyboard/kmac/Makefile.lufa
new file mode 100644
index 00000000..09343d4b
--- /dev/null
+++ b/keyboard/kmac/Makefile.lufa
@@ -0,0 +1,130 @@
+#----------------------------------------------------------------------------
+# On command line:
+#
+# make all = Make software.
+#
+# make clean = Clean out built project files.
+#
+# make coff = Convert ELF to AVR COFF.
+#
+# make extcoff = Convert ELF to AVR Extended COFF.
+#
+# make program = Download the hex file to the device.
+# Please customize your programmer settings(PROGRAM_CMD)
+#
+# make teensy = Download the hex file to the device, using teensy_loader_cli.
+# (must have teensy_loader_cli installed).
+#
+# make dfu = Download the hex file to the device, using dfu-programmer (must
+# have dfu-programmer installed).
+#
+# make flip = Download the hex file to the device, using Atmel FLIP (must
+# have Atmel FLIP installed).
+#
+# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
+# (must have dfu-programmer installed).
+#
+# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
+# (must have Atmel FLIP installed).
+#
+# make debug = Start either simulavr or avarice as specified for debugging,
+# with avr-gdb or avr-insight as the front end for debugging.
+#
+# make filename.s = Just compile filename.c into the assembler code only.
+#
+# make filename.i = Create a preprocessed source file for use in submitting
+# bug reports to the GCC project.
+#
+# To rebuild project do "make clean" then "make all".
+#----------------------------------------------------------------------------
+
+# Target file name (without extension).
+TARGET = kmac_lufa
+
+# Directory common source filess exist
+TOP_DIR = ../..
+
+# Directory keyboard dependent files exist
+TARGET_DIR = .
+
+
+# List C source files here. (C dependencies are automatically generated.)
+SRC += keymap.c \
+ matrix.c \
+ led.c \
+ backlight.c
+
+CONFIG_H = config.h
+
+
+# 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 = 8000000
+
+
+#
+# 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)
+
+
+# Build Options
+# comment out to disable the options.
+#
+BOOTMAGIC_ENABLE = yes # 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
+#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
+#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
+BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
+
+
+# Boot Section Size in bytes
+# Teensy halfKay 512
+# Atmel DFU loader 4096
+# LUFA bootloader 4096
+OPT_DEFS += -DBOOTLOADER_SIZE=4096
+
+
+# Search Path
+VPATH += $(TARGET_DIR)
+VPATH += $(TOP_DIR)
+
+include $(TOP_DIR)/protocol/lufa.mk
+include $(TOP_DIR)/common.mk
+include $(TOP_DIR)/rules.mk
+
+winkey: OPT_DEFS += -DLAYOUT_WINKEY
+winkey: all
+
+winkeyless: OPT_DEFS += -DLAYOUT_WINKEYLESS
+winkeyless: all
diff --git a/keyboard/kmac/Makefile.pjrc b/keyboard/kmac/Makefile.pjrc
new file mode 100644
index 00000000..22ee8de4
--- /dev/null
+++ b/keyboard/kmac/Makefile.pjrc
@@ -0,0 +1,101 @@
+#----------------------------------------------------------------------------
+# On command line:
+#
+# make all = Make software.
+#
+# make clean = Clean out built project files.
+#
+# make coff = Convert ELF to AVR COFF.
+#
+# make extcoff = Convert ELF to AVR Extended COFF.
+#
+# make program = Download the hex file to the device.
+# Please customize your programmer settings(PROGRAM_CMD)
+#
+# make teensy = Download the hex file to the device, using teensy_loader_cli.
+# (must have teensy_loader_cli installed).
+#
+# make dfu = Download the hex file to the device, using dfu-programmer (must
+# have dfu-programmer installed).
+#
+# make flip = Download the hex file to the device, using Atmel FLIP (must
+# have Atmel FLIP installed).
+#
+# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
+# (must have dfu-programmer installed).
+#
+# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
+# (must have Atmel FLIP installed).
+#
+# make debug = Start either simulavr or avarice as specified for debugging,
+# with avr-gdb or avr-insight as the front end for debugging.
+#
+# make filename.s = Just compile filename.c into the assembler code only.
+#
+# make filename.i = Create a preprocessed source file for use in submitting
+# bug reports to the GCC project.
+#
+# To rebuild project do "make clean" then "make all".
+#----------------------------------------------------------------------------
+
+# Target file name (without extension).
+TARGET = kmac_pjrc
+
+# Directory common source filess exist
+TOP_DIR = ../..
+
+# Directory keyboard dependent files exist
+TARGET_DIR = .
+
+# keyboard dependent files
+SRC = keymap.c \
+ matrix.c \
+ led.c \
+ backlight.c
+
+CONFIG_H = config.h
+
+
+# MCU name, you MUST set this to match the board you are using
+# type "make clean" after changing this, so all files will be rebuilt
+#MCU = at90usb162 # Teensy 1.0
+MCU = atmega32u4 # Teensy 2.0
+#MCU = at90usb646 # Teensy++ 1.0
+#MCU = at90usb1286 # Teensy++ 2.0
+
+
+# Processor frequency.
+# Normally the first thing your program should do is set the clock prescaler,
+# so your program will run at the correct speed. You should also set this
+# variable to same clock speed. The _delay_ms() macro uses this, and many
+# examples use this variable to calculate timings. Do not add a "UL" here.
+F_CPU = 8000000
+
+
+# Build Options
+# comment out to disable the options.
+#
+BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
+#MOUSEKEY_ENABLE = yes # Mouse keys(+5000)
+EXTRAKEY_ENABLE = yes # Audio control and System control(+600)
+CONSOLE_ENABLE = yes # Console for debug
+COMMAND_ENABLE = yes # Commands for debug and configuration
+#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
+#NKRO_ENABLE = yes # USB Nkey Rollover(+500)
+#PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support
+BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
+
+
+# Search Path
+VPATH += $(TARGET_DIR)
+VPATH += $(TOP_DIR)
+
+include $(TOP_DIR)/protocol/pjrc.mk
+include $(TOP_DIR)/common.mk
+include $(TOP_DIR)/rules.mk
+
+winkey: OPT_DEFS += -DLAYOUT_WINKEY
+winkey: all
+
+winkeyless: OPT_DEFS += -DLAYOUT_WINKEYLESS
+winkeyless: all
diff --git a/keyboard/kmac/README.md b/keyboard/kmac/README.md
new file mode 100644
index 00000000..8cfe0971
--- /dev/null
+++ b/keyboard/kmac/README.md
@@ -0,0 +1,110 @@
+KMAC keyboard firmware
+======================
+Korean custom keyboard designed by Byungho Kim and KBDMania community.
+
+*Note that this is not the official firmware*
+
+Supported models
+----------------
+At the moment only the TKL models is supported.
+
+
+Build
+-----
+Move to this directory then just run `make` like:
+
+ $ make -f Makefile.[pjrc|lufa] [winkey|winkeyless]
+
+Use `Makefile.pjrc` if you want to use PJRC stack or use `Makefile.lufa` for LUFA stack.
+
+
+Booloader
+---------
+The PCB is hardwired to run the bootloader if the key at the `Caps Lock` position is held down when connecting the keyboard.
+
+It is still possible to use Boot Magic and Command to access the bootloader though.
+
+
+Keymap
+------
+There are 2 different types of PCB.
+They each have their own keymap file.
+
+To customize a keymap:
+ 1. Edit the file that corresponds to your PCB.
+ 2. Specify your layout when building.
+
+### 1. Winkey
+This is the default keymap.
+
+See [keymap_winkey.h](keymap_winkey.h) for detail.
+
+#### 1.0. Winkey Default Layer
+ ,---. ,---------------. ,---------------. ,---------------. ,-----------.
+ |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau|
+ `---' `---------------' `---------------' `---------------' `-----------'
+ ,-----------------------------------------------------------. ,-----------.
+ |~ | 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backsp | |Ins|Hom|PgU|
+ |-----------------------------------------------------------| |-----------|
+ |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD|
+ |-----------------------------------------------------------| '-----------'
+ |Fn0 | A| S| D| F| G| H| J| K| L| ;| '|Return |
+ |-----------------------------------------------------------| ,---.
+ |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift | |Up |
+ |-----------------------------------------------------------| ,-----------.
+ |Ctl|Gui|Alt| Space |Alt|Gui|App|Ctl| |Lef|Dow|Rig|
+ `-----------------------------------------------------------' `-----------'
+
+#### 1.1. Winkey Media Layer
+ ,---. ,---------------. ,---------------. ,---------------. ,-----------.
+ |Led| | | | | | | | | | | | | | | | | | |Slp|
+ `---' `---------------' `---------------' `---------------' `-----------'
+ ,-----------------------------------------------------------. ,-----------.
+ | | | | | | | | | | |Mut|V- |V+ | | | | | |
+ |-----------------------------------------------------------| |-----------|
+ | | | | | | | | | |Stp|Ply|Prv|Nxt|Media| | | | |
+ |-----------------------------------------------------------| '-----------'
+ | | | | | | | | | | | | | |
+ |-----------------------------------------------------------| ,---.
+ | | | |Clc| | | | | | | |Caps | | |
+ |-----------------------------------------------------------| ,-----------.
+ | | | | | | | | | | | | |
+ `-----------------------------------------------------------' `-----------'
+
+
+### 2. Winkeyless
+Layout with 1.5 unit modifiers.
+
+See [keymap_winkeyless.h](keymap_winkeyless.h) for detail.
+
+#### 2.0. Winkeyless Default Layer
+ ,---. ,---------------. ,---------------. ,---------------. ,-----------.
+ |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau|
+ `---' `---------------' `---------------' `---------------' `-----------'
+ ,-----------------------------------------------------------. ,-----------.
+ |~ | 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backsp | |Ins|Hom|PgU|
+ |-----------------------------------------------------------| |-----------|
+ |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD|
+ |-----------------------------------------------------------| '-----------'
+ |Fn0 | A| S| D| F| G| H| J| K| L| ;| '|Return |
+ |-----------------------------------------------------------| ,---.
+ |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift | |Up |
+ |-----------------------------------------------------------| ,-----------.
+ |Ctl |Gui|Alt | Space |Alt |Gui|Ctl | |Lef|Dow|Rig|
+ `-----------------------------------------------------------' `-----------'
+
+#### 2.1. Winkeyless Media Layer
+ ,---. ,---------------. ,---------------. ,---------------. ,-----------.
+ |Led| | | | | | | | | | | | | | | | | | |Slp|
+ `---' `---------------' `---------------' `---------------' `-----------'
+ ,-----------------------------------------------------------. ,-----------.
+ | | | | | | | | | | |Mut|V- |V+ | | | | | |
+ |-----------------------------------------------------------| |-----------|
+ | | | | | | | | | |Stp|Ply|Prv|Nxt|Media| | | | |
+ |-----------------------------------------------------------| '-----------'
+ | | | | | | | | | | | | | |
+ |-----------------------------------------------------------| ,---.
+ | | | |Clc| | | | | | | |Caps | | |
+ |-----------------------------------------------------------| ,-----------.
+ | | | | | | | | | | | |
+ `-----------------------------------------------------------' `-----------'
diff --git a/keyboard/kmac/backlight.c b/keyboard/kmac/backlight.c
new file mode 100644
index 00000000..af38f658
--- /dev/null
+++ b/keyboard/kmac/backlight.c
@@ -0,0 +1,58 @@
+/*
+Copyright 2013 Mathias Andersson
+
+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 .
+*/
+
+#include
+#include "backlight.h"
+
+/* Backlight pin configuration
+ * F-row: High PB1
+ * W: Low PB4
+ * A: Low PB2
+ * S: Low PB3
+ * D: Low PD7
+ */
+void backlight_set(uint8_t level)
+{
+ // Set as output.
+ DDRB |= (1<<1) | (1<<2) | (1<<3) | (1<<4);
+ DDRD |= (1<<7);
+
+ // F-row
+ if(level & (1<<0))
+ {
+ PORTB |= (1<<1);
+ }
+ else
+ {
+ PORTB &= ~(1<<1);
+ }
+ // WASD
+ if(level & (1<<1))
+ {
+ PORTB &= ~(1<<4);
+ PORTB &= ~(1<<2);
+ PORTB &= ~(1<<3);
+ PORTD &= ~(1<<7);
+ }
+ else
+ {
+ PORTB |= (1<<4);
+ PORTB |= (1<<2);
+ PORTB |= (1<<3);
+ PORTD |= (1<<7);
+ }
+}
diff --git a/keyboard/kmac/config.h b/keyboard/kmac/config.h
new file mode 100644
index 00000000..c88df945
--- /dev/null
+++ b/keyboard/kmac/config.h
@@ -0,0 +1,50 @@
+/*
+Copyright 2013 Mathias Andersson
+
+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 .
+*/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0xFEED
+#define PRODUCT_ID 0x6050
+#define DEVICE_VER 0x0104
+#define MANUFACTURER KBDMania
+#define PRODUCT KMAC
+
+/* message strings */
+#define DESCRIPTION t.m.k. keyboard firmware for KMAC
+
+/* matrix size */
+#define MATRIX_ROWS 6
+#define MATRIX_COLS 17
+
+/* number of backlight levels */
+#define BACKLIGHT_LEVELS 3
+
+/* define if matrix has ghost */
+//#define MATRIX_HAS_GHOST
+
+/* Set 0 if need no debouncing */
+#define DEBOUNCE 5
+
+/* key combination for command */
+#define IS_COMMAND() ( \
+ keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
+)
+
+#endif
diff --git a/keyboard/kmac/keymap.c b/keyboard/kmac/keymap.c
new file mode 100644
index 00000000..5474b1b6
--- /dev/null
+++ b/keyboard/kmac/keymap.c
@@ -0,0 +1,97 @@
+/*
+Copyright 2013 Mathias Andersson
+
+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 .
+*/
+
+/*
+ * Keymap for KMAC controller
+ */
+#include
+#include
+#include
+#include "keycode.h"
+#include "action.h"
+#include "action_macro.h"
+#include "report.h"
+#include "host.h"
+#include "debug.h"
+#include "keymap.h"
+
+// Convert physical keyboard layout to matrix array.
+// This is a macro to define keymap easily in keyboard layout form.
+#define KEYMAP( \
+ K5A, K5C, K5D, K5E, K5F, K5G, K5H, K5I, K5J, K5K, K5L, K5M, K5N, K5O, K5P, K5Q, \
+ K4A, K4B, K4C, K4D, K4E, K4F, K4G, K4H, K4I, K4J, K4K, K4L, K4M, K4N, K4O, K4P, K4Q, \
+ K3A, K3B, K3C, K3D, K3E, K3F, K3G, K3H, K3I, K3J, K3K, K3L, K3M, K3N, K3O, K3P, K3Q, \
+ K2A, K2B, K2C, K2D, K2E, K2F, K2G, K2H, K2I, K2J, K2K, K2L, K2N, \
+ K1A, K1C, K1D, K1E, K1F, K1G, K1H, K1I, K1J, K1K, K1L, K1N, K1P, \
+ K0A, K0B, K0C, K0G, K0K, K0L, K0M, K0N, K0O, K0P, K0Q \
+) { \
+/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */ \
+/* 5 */ { KC_##K5A, KC_NO, KC_##K5C, KC_##K5D, KC_##K5E, KC_##K5F, KC_##K5G, KC_##K5H, KC_##K5I, KC_##K5J, KC_##K5K, KC_##K5L, KC_##K5M, KC_##K5N, KC_##K5O, KC_##K5P, KC_##K5Q}, \
+/* 4 */ { KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E, KC_##K4F, KC_##K4G, KC_##K4H, KC_##K4I, KC_##K4J, KC_##K4K, KC_##K4L, KC_##K4M, KC_##K4N, KC_##K4O, KC_##K4P, KC_##K4Q}, \
+/* 3 */ { KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_##K3F, KC_##K3G, KC_##K3H, KC_##K3I, KC_##K3J, KC_##K3K, KC_##K3L, KC_##K3M, KC_##K3N, KC_##K3O, KC_##K3P, KC_##K3Q}, \
+/* 2 */ { KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_##K2F, KC_##K2G, KC_##K2H, KC_##K2I, KC_##K2J, KC_##K2K, KC_##K2L, KC_NO, KC_##K2N, KC_NO, KC_NO, KC_NO }, \
+/* 1 */ { KC_##K1A, KC_##K1C, KC_##K1D, KC_##K1E, KC_##K1F, KC_##K1G, KC_##K1H, KC_##K1I, KC_##K1J, KC_##K1K, KC_##K1L, KC_NO, KC_NO, KC_##K1N, KC_NO, KC_##K1P, KC_NO }, \
+/* 0 */ { KC_##K0A, KC_##K0B, KC_##K0C, KC_NO, KC_NO, KC_##K0G, KC_NO, KC_NO, KC_##K0K, KC_NO, KC_##K0L, KC_NO, KC_##K0M, KC_##K0N, KC_##K0O, KC_##K0P, KC_##K0Q} \
+}
+
+#define KEYMAP_WINKEYLESS( \
+ K5A, K5C, K5D, K5E, K5F, K5G, K5H, K5I, K5J, K5K, K5L, K5M, K5N, K5O, K5P, K5Q, \
+ K4A, K4B, K4C, K4D, K4E, K4F, K4G, K4H, K4I, K4J, K4K, K4L, K4M, K4N, K4O, K4P, K4Q, \
+ K3A, K3B, K3C, K3D, K3E, K3F, K3G, K3H, K3I, K3J, K3K, K3L, K3M, K3N, K3O, K3P, K3Q, \
+ K2A, K2B, K2C, K2D, K2E, K2F, K2G, K2H, K2I, K2J, K2K, K2L, K2N, \
+ K1A, K1C, K1D, K1E, K1F, K1G, K1H, K1I, K1J, K1K, K1L, K1N, K1P, \
+ K0A, K0B, K0C, K0G, K0L, K0M, K0N, K0O, K0P, K0Q \
+) KEYMAP( \
+ K5A, K5C, K5D, K5E, K5F, K5G, K5H, K5I, K5J, K5K, K5L, K5M, K5N, K5O, K5P, K5Q, \
+ K4A, K4B, K4C, K4D, K4E, K4F, K4G, K4H, K4I, K4J, K4K, K4L, K4M, K4N, K4O, K4P, K4Q, \
+ K3A, K3B, K3C, K3D, K3E, K3F, K3G, K3H, K3I, K3J, K3K, K3L, K3M, K3N, K3O, K3P, K3Q, \
+ K2A, K2B, K2C, K2D, K2E, K2F, K2G, K2H, K2I, K2J, K2K, K2L, K2N, \
+ K1A, K1C, K1D, K1E, K1F, K1G, K1H, K1I, K1J, K1K, K1L, K1N, K1P, \
+ K0A, K0B, K0C, K0G, K0L, K0M, NO, K0N, K0O, K0P, K0Q \
+)
+
+#if defined(LAYOUT_WINKEYLESS)
+ #include "keymap_winkeyless.h"
+#else
+ #include "keymap_winkey.h"
+#endif
+
+#define KEYMAPS_SIZE (sizeof(keymaps) / sizeof(keymaps[0]))
+#define FN_ACTIONS_SIZE (sizeof(fn_actions) / sizeof(fn_actions[0]))
+
+/* translates key to keycode */
+uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
+{
+ if (layer < KEYMAPS_SIZE) {
+ return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]);
+ } else {
+ // fall back to layer 0
+ return pgm_read_byte(&keymaps[0][(key.row)][(key.col)]);
+ }
+}
+
+/* translates Fn keycode to action */
+action_t keymap_fn_to_action(uint8_t keycode)
+{
+ action_t action;
+ if (FN_INDEX(keycode) < FN_ACTIONS_SIZE) {
+ action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]);
+ } else {
+ action.code = ACTION_NO;
+ }
+ return action;
+}
diff --git a/keyboard/kmac/keymap_winkey.h b/keyboard/kmac/keymap_winkey.h
new file mode 100644
index 00000000..3379789e
--- /dev/null
+++ b/keyboard/kmac/keymap_winkey.h
@@ -0,0 +1,24 @@
+// KMAC Winkey
+static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /* 0: qwerty */
+ KEYMAP(\
+ ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, \
+ GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, \
+ TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, DEL, END, PGDN, \
+ FN0, A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, \
+ LSFT, Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT, UP, \
+ LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT),
+ /* 1: media keys */
+ KEYMAP(\
+ FN1, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,SLEP, \
+ TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,MUTE,VOLD,VOLU,TRNS, TRNS,TRNS,TRNS, \
+ TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,MSTP,MPLY,MPRV,MNXT,MSEL, TRNS,TRNS,TRNS, \
+ TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS, \
+ TRNS, TRNS,TRNS,CALC,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, CAPS, TRNS, \
+ TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,TRNS)
+};
+static const uint16_t PROGMEM fn_actions[] = {
+ [0] = ACTION_LAYER_MOMENTARY(1),
+ [1] = ACTION_BACKLIGHT_STEP()
+};
+
diff --git a/keyboard/kmac/keymap_winkeyless.h b/keyboard/kmac/keymap_winkeyless.h
new file mode 100644
index 00000000..939ee379
--- /dev/null
+++ b/keyboard/kmac/keymap_winkeyless.h
@@ -0,0 +1,24 @@
+// KMAC Winkeyless
+static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /* 0: qwerty */
+ KEYMAP_WINKEYLESS(\
+ ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, \
+ GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, \
+ TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, DEL, END, PGDN, \
+ FN0, A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, \
+ LSFT, Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT, UP, \
+ LCTL,LGUI,LALT, SPC, RALT,RGUI,RCTL, LEFT,DOWN,RGHT),
+ /* 1: media keys */
+ KEYMAP_WINKEYLESS(\
+ FN1, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,SLEP, \
+ TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,MUTE,VOLD,VOLU,TRNS, TRNS,TRNS,TRNS, \
+ TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,MSTP,MPLY,MPRV,MNXT,MSEL, TRNS,TRNS,TRNS, \
+ TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS, \
+ TRNS, TRNS,TRNS,CALC,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, CAPS, TRNS, \
+ TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS)
+};
+static const uint16_t PROGMEM fn_actions[] = {
+ [0] = ACTION_LAYER_MOMENTARY(1),
+ [1] = ACTION_BACKLIGHT_STEP()
+};
+
diff --git a/keyboard/kmac/led.c b/keyboard/kmac/led.c
new file mode 100644
index 00000000..7fa008a4
--- /dev/null
+++ b/keyboard/kmac/led.c
@@ -0,0 +1,54 @@
+/*
+Copyright 2012 Jun Wako
+
+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 .
+*/
+
+#include
+#include "stdint.h"
+#include "led.h"
+
+
+/* LED pin configuration
+ * Scroll Lock: Low PE6
+ * Caps Lock: Low PB0
+ */
+void led_set(uint8_t usb_led)
+{
+ // Set as output.
+ DDRB |= (1<<0);
+ DDRE |= (1<<6);
+
+ if (usb_led & (1<
+
+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 .
+*/
+
+#include
+#include
+#include
+#include
+#include "print.h"
+#include "debug.h"
+#include "util.h"
+#include "matrix.h"
+
+
+#ifndef DEBOUNCE
+# define DEBOUNCE 0
+#endif
+static uint8_t debouncing = DEBOUNCE;
+
+/* matrix state(1:on, 0:off) */
+static matrix_row_t matrix[MATRIX_ROWS];
+static matrix_row_t matrix_debouncing[MATRIX_ROWS];
+
+static uint8_t read_rows(void);
+static uint8_t read_caps(void);
+static void init_rows(void);
+static void unselect_cols(void);
+static void select_col(uint8_t col);
+
+inline
+uint8_t matrix_rows(void)
+{
+ return MATRIX_ROWS;
+}
+
+inline
+uint8_t matrix_cols(void)
+{
+ return MATRIX_COLS;
+}
+
+void matrix_init(void)
+{
+ unselect_cols();
+ init_rows();
+ // initialize matrix state: all keys off
+ for (uint8_t i=0; i < MATRIX_ROWS; i++) {
+ matrix[i] = 0;
+ matrix_debouncing[i] = 0;
+ }
+}
+
+uint8_t matrix_scan(void)
+{
+ for (uint8_t col = 0; col < MATRIX_COLS; col++) { // 0-16
+ select_col(col);
+ _delay_us(3); // TODO: Determine the correct value needed here.
+ uint8_t rows = read_rows();
+ // Use the otherwise unused col: 0 row: 3 for caps lock.
+ if(col == 0) {
+ rows |= read_caps();
+ }
+ for (uint8_t row = 0; row < MATRIX_ROWS; row++) { // 0-5
+ bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<