Squashed 'tmk_core/' content from commit 05caacc

git-subtree-dir: tmk_core
git-subtree-split: 05caaccec92694bb24c8c3c3a9940b96efd4605c
This commit is contained in:
tmk
2015-04-10 01:32:04 +09:00
commit a074364c37
533 changed files with 102049 additions and 0 deletions

13
.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
.dep
*.o
*.eep
*.elf
*.hex
*.lss
*.lst
*.map
*.sym
tags
*~
build/
*.bak

6
.gitmodules vendored Normal file
View File

@ -0,0 +1,6 @@
[submodule "protocol/lufa/LUFA-git"]
path = protocol/lufa/LUFA-git
url = https://github.com/abcminiuser/lufa.git
[submodule "protocol/usb_hid/USB_Host_Shield_2.0"]
path = protocol/usb_hid/USB_Host_Shield_2.0
url = https://github.com/felis/USB_Host_Shield_2.0.git

296
README.md Normal file
View File

@ -0,0 +1,296 @@
TMK Keyboard Firmware Collection
================================
This is a keyboard firmware with some useful features for Atmel AVR controller.
Source code is available here: <http://github.com/tmk/tmk_keyboard>
Features
--------
These features can be used in your keyboard.
* Multi-layer Keymap - Multiple keyboard layouts with layer switching
* Mouse key - Mouse control with keyboard
* System Control Key - Power Down, Sleep, Wake Up and USB Remote Wake up
* Media Control Key - Volume Down/Up, Mute, Next/Prev track, Play, Stop and etc
* USB NKRO - 120 keys(+ 8 modifiers) simultaneously
* PS/2 mouse support - PS/2 mouse(TrackPoint) as composite device
* Keyboard protocols - PS/2, ADB, M0110, Sun and other old keyboard protocols
* User Function - Customizable function of key with writing code
* Macro - Very primitive at this time
* Keyboard Tricks - Oneshot modifier and modifier with tapping feature
* Debug Console - Messages for debug and interaction with firmware
* 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
--------
You can find some keyboard specific projects under `converter` and `keyboard` directory.
### converter
* [ps2_usb](converter/ps2_usb/) - [PS/2 keyboard to USB][GH_ps2]
* [adb_usb](converter/adb_usb/) - [ADB keyboard to USB][GH_adb]
* [m0110_usb](converter/m0110_usb) - [Macintosh 128K/512K/Plus keyboard to USB][GH_m0110]
* [terminal_usb](converter/terminal_usb/) - [IBM Model M terminal keyboard(PS/2 scancode set3) to USB][GH_terminal]
* [news_usb](converter/news_usb/) - [Sony NEWS keyboard to USB][GH_news]
* [x68k_usb](converter/x68k_usb/) - [Sharp X68000 keyboard to USB][GH_x68k]
* [sun_usb](converter/sun_usb/) - [Sun] to USB(type4, 5 and 3?)
* [pc98_usb](converter/pc98_usb/) - [PC98] to USB
* [usb_usb](converter/usb_usb/) - USB to USB(experimental)
* [ascii_usb](converter/ascii_usb/) - ASCII(Serial console terminal) to USB
* [ibm4704_usb](converter/ibm4704_usb) - [IBM 4704 keyboard Converter][GH_ibm4704]
### keyboard
* [hhkb](keyboard/hhkb/) - [Happy Hacking Keyboard pro][GH_hhkb] **my main board**
* [gh60](keyboard/gh60/) - [GH60] DIY 60% keyboard [prototype][GH60_proto] **my second board**
* [hbkb](keyboard/hbkb/) - [Happy Buckling spring keyboard][GH_hbkb](IBM Model M 60% mod)
* [hid_liber](keyboard/hid_liber/) - [HID liberation][HID_liber] controller (by alaricljs)
* [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
* [Lightsaber](keyboard/lightsaber/) - Korean custom keyboard
* [Infinity](keyboard/infinity/) - Massdrop [Infinity keyboard][Infinity]
* [NerD](keyboard/nerd/) - Korean custom keyboard
* [KittenPaw](keyboard/kitten_paw) - Custom Majestouch controller
* [Lightpad](keyboard/lightpad) - Korean custom keypad
* [ghost_squid](keyboard/ghost_squid/) - [The Ghost Squid][ghost_squid] controller for [Cooler Master QuickFire XT][cmxt]
### Extenal projects using tmk_keyboard
* [ErgoDox_cub-uanic][cub-uanic] - Split Ergonomic Keyboard [ErgoDox][ergodox_org]
* [mcdox][mcdox_tmk] - [mcdox][mcdox]
[GH_macway]: http://geekhack.org/showwiki.php?title=Island:11930
[GH_hhkb]: http://geekhack.org/showwiki.php?title=Island:12047
[GH_ps2]: http://geekhack.org/showwiki.php?title=Island:14618
[GH_adb]: http://geekhack.org/showwiki.php?title=Island:14290
[GH_hhkb_bt]: http://geekhack.org/showwiki.php?title=Island:20851
[GH_m0110]: http://geekhack.org/showwiki.php?title=Island:24965
[GH_news]: http://geekhack.org/showwiki.php?title=Island:25759
[GH_terminal]: http://geekhack.org/showwiki.php?title=Island:27272
[GH_x68k]: http://geekhack.org/showwiki.php?title=Island:29060
[GH_hbkb]: http://geekhack.org/showwiki.php?title=Island:29483
[GH_ibm4704]: http://geekhack.org/index.php?topic=54706.0
[HID_liber]: http://deskthority.net/wiki/HID_Liberation_Device_-_DIY_Instructions
[Phantom]: http://geekhack.org/index.php?topic=26742
[GH60]: http://geekhack.org/index.php?topic=34959
[GH60_proto]: http://geekhack.org/index.php?topic=37570.0
[PC98]: http://en.wikipedia.org/wiki/NEC_PC-9801
[Sun]: http://en.wikipedia.org/wiki/Sun-3
[IIGS]: http://en.wikipedia.org/wiki/Apple_IIGS
[Infinity]: https://www.massdrop.com/buy/infinity-keyboard-kit
[ghost_squid]: http://deskthority.net/wiki/Costar_replacement_controllers#The_Ghost_Squid
[cmxt]: http://gaming.coolermaster.com/en/products/keyboards/quickfirext/
[ergodox_org]: http://ergodox.org/
[cub-uanic]: https://github.com/cub-uanic/tmk_keyboard/tree/master/keyboard/ergodox
[mcdox]: https://github.com/DavidMcEwan/mcdox
[mcdox_tmk]: https://github.com/DavidMcEwan/tmk_keyboard/tree/master/keyboard/mcdox
License
-------
**GPLv2** or later. Some protocol files are under **Modified BSD License**.
LUFA, PJRC and V-USB stack have their own license respectively.
Build Firmware and Program Controller
-------------------------------------
See [doc/build.md](doc/build.md).
Change your keymap
------------------
See [doc/keymap.md](doc/keymap.md).
Magic Commands
--------------
To see help press `Magic` + `H`.
`Magic` key bind may be `LShift` + `RShift` in many project, but `Power` key on ADB converter. `Magic` keybind can be vary on each project, check `config.h` in project directory.
Following commands can be also executed with `Magic` + key. In console mode `Magic` keybind is not needed.
----- Command Help -----
c: enter console mode
d: toggle debug enable
x: toggle matrix debug
k: toggle keyboard debug
m: toggle mouse debug
v: print device version & info
t: print timer count
s: print status
e: print eeprom config
n: toggle NKRO
0/F10: switch to Layer0
1/F1: switch to Layer1
2/F2: switch to Layer2
3/F3: switch to Layer3
4/F4: switch to Layer4
PScr: power down/remote wake-up
Caps: Lock Keyboard(Child Proof)
Paus: jump to bootloader
**TBD**
### Boot Magic Configuration - Virtual DIP Switch
Boot Magic are executed during boot up time. Press Magic key below then plug in keyboard cable.
Note that you must use keys of **Layer 0** as Magic keys. These settings are stored in EEPROM so that retain your configure over power cycles.
To avoid configuring accidentally additive salt key `KC_SPACE` also needs to be pressed along with the following configuration keys. The salt key is configurable in `config.h`. See [common/bootmagic.h](common/bootmagic.h).
#### General
- Skip reading EEPROM to start with default configuration(`ESC`)
- Clear configuration stored in EEPROM to reset configuration(`Backspace`)
#### Bootloader
- Kick up Bootloader(`B`)
#### Debug
- Debug enable(`D`)
- Debug matrix enable(`D`+`X`)
- Debug keyboard enable(`D`+`K`)
- Debug mouse enable(`D`+`M`)
#### Keymap
- Swap Control and CapsLock(`Left Control`)
- Change CapsLock to Control(`Caps Lock`)
- Swap LeftAlt and Gui(`Left Alt`)
- Swap RightAlt and Gui(`Right Alt`)
- Disable Gui(`Left Gui`)
- Swap Grave and Escape(`Grave`)
- Swap BackSlash and BackSpace(`Back Slash`)
- Enable NKRO on boot(`N`)
#### Default Layer
- Set Default Layer to 0(`0`)
- Set Default Layer to 1(`1`)
- Set Default Layer to 2(`2`)
- Set Default Layer to 3(`3`)
- Set Default Layer to 4(`4`)
- Set Default Layer to 5(`5`)
- Set Default Layer to 6(`6`)
- Set Default Layer to 7(`7`)
#### Caution
Unintentional use of this feature will cause user confusion.
TODO: Magic key combination to avoid unintentional press during plug in
**TBD**
Mechanical Locking support
--------------------------
This feature makes it possible for you to use mechanical switch for `CapsLock`, `NumLock` or `ScrollLock`. To enable this feature define these macros in `config.h` and use `KC_LCAP`, `KC_LNUM` or `KC_LSCR` in keymap for locking key instead of normal `KC_CAPS`, `KC_NLCK` or `KC_SLCK`. Resync option tries to keep lock switch state consistent with keyboard LED state.
#define LOCKING_SUPPORT_ENABLE
#define LOCKING_RESYNC_ENABLE
Start Your Own Project
-----------------------
**TBD**
### Config.h Options
#### 1. USB vendor/product ID and device description
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0xBEEF
#define MANUFACTURER t.m.k.
#define PRODUCT Macway mod
#define DESCRIPTION t.m.k. keyboard firmware for Macway mod
#### 2. Keyboard matrix configuration
#define MATRIX_ROWS 8
#define MATRIX_COLS 8
#define MATRIX_HAS_GHOST
Architecture
------------
Architecture Diagram
+---------------+---------------+-------------+
| Host | Keyboard | Matrix, LED |
___________ |-----------+-+ +-------------+ | +-----------|
/ /| Keys/Mouse | Protocol |d| | Action | | | Protocol |
/__________/ |<-----------| LUFA |r| | Layer, Tap | | | Matrix |
|.--------.| | LED | V-USB |i| |-------------| | | PS/2,IBM | __________________
|| || |----------->| PJRC |v| | Keymap | | | ADB,M0110| Keys / /_/_/_/_/_/_/_/ /|
|| Host || | Console | iWRAP(BT)|e| | Mousekey | | | SUN/NEWS |<----------/ /_/_/_/_/_/_/_/ / /
||________||/.<-----------| UART |r| | Report | | | X68K/PC98| Control / /_/_/_/_/_/_/_/ / /
`_========_'/| |---------------------------------------------|-------->/___ /_______/ ___/ /
|_o______o_|/ | Sendchar, Print, Debug, Command, ... | |_________________|/
+---------------------------------------------+ Keyboard
Debugging
--------
Use PJRC's `hid_listen` to see debug messages. You can use the tool for debug even if firmware use LUFA stack.
You can use xprintf() to display debug info on `hid_listen`, see `common/xprintf.h`.
Files and Directories
-------------------
### Top
* common/ - common codes
* protocol/ - keyboard protocol support
* keyboard/ - keyboard projects
* converter/ - protocol converter projects
* doc/ - documents
* common.mk - Makefile for common
* protocol.mk - Makefile for protocol
* rules.mk - Makefile for build rules
### Common
* host.h
* host_driver.h
* keyboard.h
* command.h
* keymap.h
* action.h
* keycode.h
* matrix.h
* led.h
* mousekey.h
* report.h
* debug.h
* print.h
* bootloader.h
* sendchar.h
* timer.h
* util.h
### Keyboard Protocols
* lufa/ - LUFA USB stack
* pjrc/ - PJRC USB stack
* vusb/ - Objective Development V-USB
* iwrap/ - Bluetooth HID for Bluegiga iWRAP
* ps2.c - PS/2 protocol
* adb.c - Apple Desktop Bus protocol
* m0110.c - Macintosh 128K/512K/Plus keyboard protocol
* news.c - Sony NEWS keyboard protocol
* x68k.c - Sharp X68000 keyboard protocol
* serial_soft.c - Asynchronous Serial protocol implemented by software
Coding Style
-------------
- Doesn't use Tab to indent, use 4-spaces instead.
Other Keyboard Firmware Projects
------------------
You can learn a lot about keyboard firmware from these. See [doc/other_projects.md](doc/other_projects.md).

77
common.mk Normal file
View File

@ -0,0 +1,77 @@
COMMON_DIR = common
SRC += $(COMMON_DIR)/host.c \
$(COMMON_DIR)/keyboard.c \
$(COMMON_DIR)/action.c \
$(COMMON_DIR)/action_tapping.c \
$(COMMON_DIR)/action_macro.c \
$(COMMON_DIR)/action_layer.c \
$(COMMON_DIR)/action_util.c \
$(COMMON_DIR)/keymap.c \
$(COMMON_DIR)/print.c \
$(COMMON_DIR)/debug.c \
$(COMMON_DIR)/util.c \
$(COMMON_DIR)/avr/suspend.c \
$(COMMON_DIR)/avr/xprintf.S \
$(COMMON_DIR)/avr/timer.c \
$(COMMON_DIR)/avr/bootloader.c
# Option modules
ifdef BOOTMAGIC_ENABLE
SRC += $(COMMON_DIR)/bootmagic.c
SRC += $(COMMON_DIR)/avr/eeconfig.c
OPT_DEFS += -DBOOTMAGIC_ENABLE
endif
ifdef MOUSEKEY_ENABLE
SRC += $(COMMON_DIR)/mousekey.c
OPT_DEFS += -DMOUSEKEY_ENABLE
OPT_DEFS += -DMOUSE_ENABLE
endif
ifdef EXTRAKEY_ENABLE
OPT_DEFS += -DEXTRAKEY_ENABLE
endif
ifdef CONSOLE_ENABLE
OPT_DEFS += -DCONSOLE_ENABLE
else
OPT_DEFS += -DNO_PRINT
OPT_DEFS += -DNO_DEBUG
endif
ifdef COMMAND_ENABLE
SRC += $(COMMON_DIR)/command.c
OPT_DEFS += -DCOMMAND_ENABLE
endif
ifdef NKRO_ENABLE
OPT_DEFS += -DNKRO_ENABLE
endif
ifdef USB_6KRO_ENABLE
OPT_DEFS += -DUSB_6KRO_ENABLE
endif
ifdef SLEEP_LED_ENABLE
SRC += $(COMMON_DIR)/sleep_led.c
OPT_DEFS += -DSLEEP_LED_ENABLE
OPT_DEFS += -DNO_SUSPEND_POWER_DOWN
endif
ifdef BACKLIGHT_ENABLE
SRC += $(COMMON_DIR)/backlight.c
OPT_DEFS += -DBACKLIGHT_ENABLE
endif
ifdef KEYMAP_SECTION_ENABLE
OPT_DEFS += -DKEYMAP_SECTION_ENABLE
EXTRALDFLAGS = -Wl,-L$(TMK_DIR),-Tldscript_keymap_avr5.x
endif
# Version string
OPT_DEFS += -DVERSION=$(shell (git describe --always --dirty || echo 'unknown') 2> /dev/null)
# Search Path
VPATH += $(TMK_DIR)/common

565
common/action.c Normal file

File diff suppressed because it is too large Load Diff

82
common/action.h Normal file
View File

@ -0,0 +1,82 @@
/*
Copyright 2012,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 ACTION_H
#define ACTION_H
#include <stdint.h>
#include <stdbool.h>
#include "keyboard.h"
#include "keycode.h"
#include "action_code.h"
#include "action_macro.h"
#ifdef __cplusplus
extern "C" {
#endif
/* tapping count and state */
typedef struct {
bool interrupted :1;
bool reserved2 :1;
bool reserved1 :1;
bool reserved0 :1;
uint8_t count :4;
} tap_t;
/* Key event container for recording */
typedef struct {
keyevent_t event;
#ifndef NO_ACTION_TAPPING
tap_t tap;
#endif
} keyrecord_t;
/* Execute action per keyevent */
void action_exec(keyevent_t event);
/* action for key */
action_t action_for_key(uint8_t layer, keypos_t key);
/* macro */
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt);
/* user defined special function */
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
/* Utilities for actions. */
void process_action(keyrecord_t *record);
void register_code(uint8_t code);
void unregister_code(uint8_t code);
void register_mods(uint8_t mods);
void unregister_mods(uint8_t mods);
//void set_mods(uint8_t mods);
void clear_keyboard(void);
void clear_keyboard_but_mods(void);
void layer_switch(uint8_t new_layer);
bool is_tap_key(keypos_t key);
/* debug */
void debug_event(keyevent_t event);
void debug_record(keyrecord_t record);
void debug_action(action_t action);
#ifdef __cplusplus
}
#endif
#endif /* ACTION_H */

315
common/action_code.h Normal file

File diff suppressed because it is too large Load Diff

138
common/action_layer.c Normal file
View File

@ -0,0 +1,138 @@
#include <stdint.h>
#include "keyboard.h"
#include "action.h"
#include "util.h"
#include "action_layer.h"
#ifdef DEBUG_ACTION
#include "debug.h"
#else
#include "nodebug.h"
#endif
/*
* Default Layer State
*/
uint32_t default_layer_state = 0;
static void default_layer_state_set(uint32_t state)
{
debug("default_layer_state: ");
default_layer_debug(); debug(" to ");
default_layer_state = state;
default_layer_debug(); debug("\n");
clear_keyboard_but_mods(); // To avoid stuck keys
}
void default_layer_debug(void)
{
dprintf("%08lX(%u)", default_layer_state, biton32(default_layer_state));
}
void default_layer_set(uint32_t state)
{
default_layer_state_set(state);
}
#ifndef NO_ACTION_LAYER
void default_layer_or(uint32_t state)
{
default_layer_state_set(default_layer_state | state);
}
void default_layer_and(uint32_t state)
{
default_layer_state_set(default_layer_state & state);
}
void default_layer_xor(uint32_t state)
{
default_layer_state_set(default_layer_state ^ state);
}
#endif
#ifndef NO_ACTION_LAYER
/*
* Keymap Layer State
*/
uint32_t layer_state = 0;
static void layer_state_set(uint32_t state)
{
dprint("layer_state: ");
layer_debug(); dprint(" to ");
layer_state = state;
layer_debug(); dprintln();
clear_keyboard_but_mods(); // To avoid stuck keys
}
void layer_clear(void)
{
layer_state_set(0);
}
void layer_move(uint8_t layer)
{
layer_state_set(1UL<<layer);
}
void layer_on(uint8_t layer)
{
layer_state_set(layer_state | (1UL<<layer));
}
void layer_off(uint8_t layer)
{
layer_state_set(layer_state & ~(1UL<<layer));
}
void layer_invert(uint8_t layer)
{
layer_state_set(layer_state ^ (1UL<<layer));
}
void layer_or(uint32_t state)
{
layer_state_set(layer_state | state);
}
void layer_and(uint32_t state)
{
layer_state_set(layer_state & state);
}
void layer_xor(uint32_t state)
{
layer_state_set(layer_state ^ state);
}
void layer_debug(void)
{
dprintf("%08lX(%u)", layer_state, biton32(layer_state));
}
#endif
action_t layer_switch_get_action(keypos_t key)
{
action_t action;
action.code = ACTION_TRANSPARENT;
#ifndef NO_ACTION_LAYER
uint32_t layers = layer_state | default_layer_state;
/* check top layer first */
for (int8_t i = 31; i >= 0; i--) {
if (layers & (1UL<<i)) {
action = action_for_key(i, key);
if (action.code != ACTION_TRANSPARENT) {
return action;
}
}
}
/* fall back to layer 0 */
action = action_for_key(0, key);
return action;
#else
action = action_for_key(biton32(default_layer_state), key);
return action;
#endif
}

77
common/action_layer.h Normal file
View File

@ -0,0 +1,77 @@
/*
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 ACTION_LAYER_H
#define ACTION_LAYER_H
#include <stdint.h>
#include "keyboard.h"
#include "action.h"
/*
* Default Layer
*/
extern uint32_t default_layer_state;
void default_layer_debug(void);
void default_layer_set(uint32_t state);
#ifndef NO_ACTION_LAYER
/* bitwise operation */
void default_layer_or(uint32_t state);
void default_layer_and(uint32_t state);
void default_layer_xor(uint32_t state);
#else
#define default_layer_or(state)
#define default_layer_and(state)
#define default_layer_xor(state)
#endif
/*
* Keymap Layer
*/
#ifndef NO_ACTION_LAYER
extern uint32_t layer_state;
void layer_debug(void);
void layer_clear(void);
void layer_move(uint8_t layer);
void layer_on(uint8_t layer);
void layer_off(uint8_t layer);
void layer_invert(uint8_t layer);
/* bitwise operation */
void layer_or(uint32_t state);
void layer_and(uint32_t state);
void layer_xor(uint32_t state);
#else
#define layer_state 0
#define layer_clear()
#define layer_move(layer)
#define layer_on(layer)
#define layer_off(layer)
#define layer_invert(layer)
#define layer_or(state)
#define layer_and(state)
#define layer_xor(state)
#define layer_debug()
#endif
/* return action depending on current layer status */
action_t layer_switch_get_action(keypos_t key);
#endif

83
common/action_macro.c Normal file
View File

@ -0,0 +1,83 @@
/*
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/>.
*/
#include "action.h"
#include "action_util.h"
#include "action_macro.h"
#include "wait.h"
#ifdef DEBUG_ACTION
#include "debug.h"
#else
#include "nodebug.h"
#endif
#ifndef NO_ACTION_MACRO
#define MACRO_READ() (macro = MACRO_GET(macro_p++))
void action_macro_play(const macro_t *macro_p)
{
macro_t macro = END;
uint8_t interval = 0;
if (!macro_p) return;
while (true) {
switch (MACRO_READ()) {
case KEY_DOWN:
MACRO_READ();
dprintf("KEY_DOWN(%02X)\n", macro);
if (IS_MOD(macro)) {
add_weak_mods(MOD_BIT(macro));
} else {
register_code(macro);
}
break;
case KEY_UP:
MACRO_READ();
dprintf("KEY_UP(%02X)\n", macro);
if (IS_MOD(macro)) {
del_weak_mods(MOD_BIT(macro));
} else {
unregister_code(macro);
}
break;
case WAIT:
MACRO_READ();
dprintf("WAIT(%u)\n", macro);
{ uint8_t ms = macro; while (ms--) wait_ms(1); }
break;
case INTERVAL:
interval = MACRO_READ();
dprintf("INTERVAL(%u)\n", interval);
break;
case 0x04 ... 0x73:
dprintf("DOWN(%02X)\n", macro);
register_code(macro);
break;
case 0x84 ... 0xF3:
dprintf("UP(%02X)\n", macro);
unregister_code(macro&0x7F);
break;
case END:
default:
return;
}
// interval
{ uint8_t ms = interval; while (ms--) wait_ms(1); }
}
}
#endif

102
common/action_macro.h Normal file
View File

@ -0,0 +1,102 @@
/*
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 ACTION_MACRO_H
#define ACTION_MACRO_H
#include <stdint.h>
#include "progmem.h"
#define MACRO_NONE 0
#define MACRO(...) ({ static const macro_t __m[] PROGMEM = { __VA_ARGS__ }; &__m[0]; })
#define MACRO_GET(p) pgm_read_byte(p)
typedef uint8_t macro_t;
#ifndef NO_ACTION_MACRO
void action_macro_play(const macro_t *macro_p);
#else
#define action_macro_play(macro)
#endif
/* Macro commands
* code(0x04-73) // key down(1byte)
* code(0x04-73) | 0x80 // key up(1byte)
* { KEY_DOWN, code(0x04-0xff) } // key down(2bytes)
* { KEY_UP, code(0x04-0xff) } // key up(2bytes)
* WAIT // wait milli-seconds
* INTERVAL // set interval between macro commands
* END // stop macro execution
*
* Ideas(Not implemented):
* modifiers
* system usage
* consumer usage
* unicode usage
* function call
* conditionals
* loop
*/
enum macro_command_id{
/* 0x00 - 0x03 */
END = 0x00,
KEY_DOWN,
KEY_UP,
/* 0x04 - 0x73 (reserved for keycode down) */
/* 0x74 - 0x83 */
WAIT = 0x74,
INTERVAL,
/* 0x84 - 0xf3 (reserved for keycode up) */
/* 0xf4 - 0xff */
};
/* TODO: keycode:0x04-0x73 can be handled by 1byte command else 2bytes are needed
* if keycode between 0x04 and 0x73
* keycode / (keycode|0x80)
* else
* {KEY_DOWN, keycode} / {KEY_UP, keycode}
*/
#define DOWN(key) KEY_DOWN, (key)
#define UP(key) KEY_UP, (key)
#define TYPE(key) DOWN(key), UP(key)
#define WAIT(ms) WAIT, (ms)
#define INTERVAL(ms) INTERVAL, (ms)
/* key down */
#define D(key) DOWN(KC_##key)
/* key up */
#define U(key) UP(KC_##key)
/* key type */
#define T(key) TYPE(KC_##key)
/* wait */
#define W(ms) WAIT(ms)
/* interval */
#define I(ms) INTERVAL(ms)
/* for backward comaptibility */
#define MD(key) DOWN(KC_##key)
#define MU(key) UP(KC_##key)
#endif /* ACTION_MACRO_H */

376
common/action_tapping.c Normal file

File diff suppressed because it is too large Load Diff

39
common/action_tapping.h Normal file
View File

@ -0,0 +1,39 @@
/*
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 ACTION_TAPPING_H
#define ACTION_TAPPING_H
/* period of tapping(ms) */
#ifndef TAPPING_TERM
#define TAPPING_TERM 200
#endif
/* tap count needed for toggling a feature */
#ifndef TAPPING_TOGGLE
#define TAPPING_TOGGLE 5
#endif
#define WAITING_BUFFER_SIZE 8
#ifndef NO_ACTION_TAPPING
void action_tapping_process(keyrecord_t record);
#endif
#endif

307
common/action_util.c Normal file

File diff suppressed because it is too large Load Diff

66
common/action_util.h Normal file
View File

@ -0,0 +1,66 @@
/*
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 ACTION_UTIL_H
#define ACTION_UTIL_H
#include <stdint.h>
#include "report.h"
#ifdef __cplusplus
extern "C" {
#endif
extern report_keyboard_t *keyboard_report;
void send_keyboard_report(void);
/* key */
void add_key(uint8_t key);
void del_key(uint8_t key);
void clear_keys(void);
/* modifier */
uint8_t get_mods(void);
void add_mods(uint8_t mods);
void del_mods(uint8_t mods);
void set_mods(uint8_t mods);
void clear_mods(void);
/* weak modifier */
uint8_t get_weak_mods(void);
void add_weak_mods(uint8_t mods);
void del_weak_mods(uint8_t mods);
void set_weak_mods(uint8_t mods);
void clear_weak_mods(void);
/* oneshot modifier */
void set_oneshot_mods(uint8_t mods);
void clear_oneshot_mods(void);
void oneshot_toggle(void);
void oneshot_enable(void);
void oneshot_disable(void);
/* inspect */
uint8_t has_anykey(void);
uint8_t has_anymod(void);
uint8_t get_first_key(void);
#ifdef __cplusplus
}
#endif
#endif

148
common/avr/bootloader.c Normal file
View File

@ -0,0 +1,148 @@
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <util/delay.h>
#include "bootloader.h"
#ifdef PROTOCOL_LUFA
#include <LUFA/Drivers/USB/USB.h>
#endif
/* Boot Section Size in *BYTEs*
* Teensy halfKay 512
* Teensy++ halfKay 1024
* Atmel DFU loader 4096
* LUFA bootloader 4096
* USBaspLoader 2048
*/
#ifndef BOOTLOADER_SIZE
#warning To use bootloader_jump() you need to define BOOTLOADER_SIZE in config.h.
#define BOOTLOADER_SIZE 4096
#endif
#define FLASH_SIZE (FLASHEND + 1L)
#define BOOTLOADER_START (FLASH_SIZE - BOOTLOADER_SIZE)
/*
* Entering the Bootloader via Software
* http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html
*/
#define BOOTLOADER_RESET_KEY 0xB007B007
uint32_t reset_key __attribute__ ((section (".noinit")));
/* initialize MCU status by watchdog reset */
void bootloader_jump(void) {
#ifdef PROTOCOL_LUFA
USB_Disable();
cli();
_delay_ms(2000);
#endif
#ifdef PROTOCOL_PJRC
cli();
UDCON = 1;
USBCON = (1<<FRZCLK);
UCSR1B = 0;
_delay_ms(5);
#endif
// watchdog reset
reset_key = BOOTLOADER_RESET_KEY;
wdt_enable(WDTO_250MS);
for (;;);
}
/* this runs before main() */
void bootloader_jump_after_watchdog_reset(void) __attribute__ ((used, naked, section (".init3")));
void bootloader_jump_after_watchdog_reset(void)
{
if ((MCUSR & (1<<WDRF)) && reset_key == BOOTLOADER_RESET_KEY) {
reset_key = 0;
// My custom USBasploader requires this to come up.
MCUSR = 0;
// Seems like Teensy halfkay loader requires clearing WDRF and disabling watchdog.
MCUSR &= ~(1<<WDRF);
wdt_disable();
// This is compled into 'icall', address should be in word unit, not byte.
((void (*)(void))(BOOTLOADER_START/2))();
}
}
#if 0
/* Jumping To The Bootloader
* http://www.pjrc.com/teensy/jump_to_bootloader.html
*
* This method doen't work when using LUFA. idk why.
* - needs to initialize more regisers or interrupt setting?
*/
void bootloader_jump(void) {
#ifdef PROTOCOL_LUFA
USB_Disable();
cli();
_delay_ms(2000);
#endif
#ifdef PROTOCOL_PJRC
cli();
UDCON = 1;
USBCON = (1<<FRZCLK);
UCSR1B = 0;
_delay_ms(5);
#endif
/*
* Initialize
*/
#if defined(__AVR_AT90USB162__)
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0;
TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0;
DDRB = 0; DDRC = 0; DDRD = 0;
PORTB = 0; PORTC = 0; PORTD = 0;
#elif defined(__AVR_ATmega32U4__)
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0;
DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0;
PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
#elif defined(__AVR_AT90USB646__)
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0;
DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;
PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
#elif defined(__AVR_AT90USB1286__)
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0;
DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;
PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
#endif
/*
* USBaspLoader
*/
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
// This makes custom USBasploader come up.
MCUSR = 0;
// initialize ports
PORTB = 0; PORTC= 0; PORTD = 0;
DDRB = 0; DDRC= 0; DDRD = 0;
// disable interrupts
EIMSK = 0; EECR = 0; SPCR = 0;
ACSR = 0; SPMCSR = 0; WDTCSR = 0; PCICR = 0;
TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0;
ADCSRA = 0; TWCR = 0; UCSR0B = 0;
#endif
// This is compled into 'icall', address should be in word unit, not byte.
((void (*)(void))(BOOTLOADER_START/2))();
}
#endif

45
common/avr/eeconfig.c Normal file
View File

@ -0,0 +1,45 @@
#include <stdint.h>
#include <stdbool.h>
#include <avr/eeprom.h>
#include "eeconfig.h"
void eeconfig_init(void)
{
eeprom_write_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
eeprom_write_byte(EECONFIG_DEBUG, 0);
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)
{
eeprom_write_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
}
void eeconfig_disable(void)
{
eeprom_write_word(EECONFIG_MAGIC, 0xFFFF);
}
bool eeconfig_is_enabled(void)
{
return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER);
}
uint8_t eeconfig_read_debug(void) { return eeprom_read_byte(EECONFIG_DEBUG); }
void eeconfig_write_debug(uint8_t val) { eeprom_write_byte(EECONFIG_DEBUG, val); }
uint8_t eeconfig_read_default_layer(void) { return eeprom_read_byte(EECONFIG_DEFAULT_LAYER); }
void eeconfig_write_default_layer(uint8_t val) { eeprom_write_byte(EECONFIG_DEFAULT_LAYER, val); }
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

122
common/avr/suspend.c Normal file
View File

@ -0,0 +1,122 @@
#include <stdbool.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include "matrix.h"
#include "action.h"
#include "backlight.h"
#include "suspend_avr.h"
#include "suspend.h"
#include "timer.h"
#ifdef PROTOCOL_LUFA
#include "lufa.h"
#endif
#define wdt_intr_enable(value) \
__asm__ __volatile__ ( \
"in __tmp_reg__,__SREG__" "\n\t" \
"cli" "\n\t" \
"wdr" "\n\t" \
"sts %0,%1" "\n\t" \
"out __SREG__,__tmp_reg__" "\n\t" \
"sts %0,%2" "\n\t" \
: /* no outputs */ \
: "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
"r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
"r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
_BV(WDIE) | (value & 0x07)) ) \
: "r0" \
)
void suspend_idle(uint8_t time)
{
cli();
set_sleep_mode(SLEEP_MODE_IDLE);
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
}
/* Power down MCU with watchdog timer
* wdto: watchdog timer timeout defined in <avr/wdt.h>
* WDTO_15MS
* WDTO_30MS
* WDTO_60MS
* WDTO_120MS
* WDTO_250MS
* WDTO_500MS
* WDTO_1S
* WDTO_2S
* WDTO_4S
* WDTO_8S
*/
static uint8_t wdt_timeout = 0;
static void power_down(uint8_t wdto)
{
#ifdef PROTOCOL_LUFA
if (USB_DeviceState == DEVICE_STATE_Configured) return;
#endif
wdt_timeout = wdto;
// Watchdog Interrupt Mode
wdt_intr_enable(wdto);
// TODO: more power saving
// See PicoPower application note
// - I/O port input with pullup
// - prescale clock
// - BOD disable
// - Power Reduction Register PRR
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
// Disable watchdog after sleep
wdt_disable();
}
void suspend_power_down(void)
{
power_down(WDTO_15MS);
}
bool suspend_wakeup_condition(void)
{
matrix_power_up();
matrix_scan();
matrix_power_down();
for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
if (matrix_get_row(r)) return true;
}
return false;
}
// run immediately after wakeup
void suspend_wakeup_init(void)
{
// clear keyboard state
clear_keyboard();
#ifdef BACKLIGHT_ENABLE
backlight_init();
#endif
}
#ifndef NO_SUSPEND_POWER_DOWN
/* watchdog timeout */
ISR(WDT_vect)
{
// compensate timer for sleep
switch (wdt_timeout) {
case WDTO_15MS:
timer_count += 15 + 2; // WDTO_15MS + 2(from observation)
break;
default:
;
}
}
#endif

27
common/avr/suspend_avr.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef SUSPEND_AVR_H
#define SUSPEND_AVR_H
#include <stdint.h>
#include <stdbool.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#define wdt_intr_enable(value) \
__asm__ __volatile__ ( \
"in __tmp_reg__,__SREG__" "\n\t" \
"cli" "\n\t" \
"wdr" "\n\t" \
"sts %0,%1" "\n\t" \
"out __SREG__,__tmp_reg__" "\n\t" \
"sts %0,%2" "\n\t" \
: /* no outputs */ \
: "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
"r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
"r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
_BV(WDIE) | (value & 0x07)) ) \
: "r0" \
)
#endif

117
common/avr/timer.c Normal file
View File

@ -0,0 +1,117 @@
/*
Copyright 2011 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/>.
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include "timer_avr.h"
#include "timer.h"
// counter resolution 1ms
// NOTE: union { uint32_t timer32; struct { uint16_t dummy; uint16_t timer16; }}
volatile uint32_t timer_count = 0;
void timer_init(void)
{
// Timer0 CTC mode
TCCR0A = 0x02;
#if TIMER_PRESCALER == 1
TCCR0B = 0x01;
#elif TIMER_PRESCALER == 8
TCCR0B = 0x02;
#elif TIMER_PRESCALER == 64
TCCR0B = 0x03;
#elif TIMER_PRESCALER == 256
TCCR0B = 0x04;
#elif TIMER_PRESCALER == 1024
TCCR0B = 0x05;
#else
# error "Timer prescaler value is NOT vaild."
#endif
OCR0A = TIMER_RAW_TOP;
TIMSK0 = (1<<OCIE0A);
}
inline
void timer_clear(void)
{
uint8_t sreg = SREG;
cli();
timer_count = 0;
SREG = sreg;
}
inline
uint16_t timer_read(void)
{
uint32_t t;
uint8_t sreg = SREG;
cli();
t = timer_count;
SREG = sreg;
return (t & 0xFFFF);
}
inline
uint32_t timer_read32(void)
{
uint32_t t;
uint8_t sreg = SREG;
cli();
t = timer_count;
SREG = sreg;
return t;
}
inline
uint16_t timer_elapsed(uint16_t last)
{
uint32_t t;
uint8_t sreg = SREG;
cli();
t = timer_count;
SREG = sreg;
return TIMER_DIFF_16((t & 0xFFFF), last);
}
inline
uint32_t timer_elapsed32(uint32_t last)
{
uint32_t t;
uint8_t sreg = SREG;
cli();
t = timer_count;
SREG = sreg;
return TIMER_DIFF_32(t, last);
}
// excecuted once per 1ms.(excess for just timer count?)
ISR(TIMER0_COMPA_vect)
{
timer_count++;
}

42
common/avr/timer_avr.h Normal file
View File

@ -0,0 +1,42 @@
/*
Copyright 2011 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 TIMER_AVR_H
#define TIMER_AVR_H 1
#include <stdint.h>
#ifndef TIMER_PRESCALER
# if F_CPU > 16000000
# define TIMER_PRESCALER 256
# elif F_CPU > 2000000
# define TIMER_PRESCALER 64
# elif F_CPU > 250000
# define TIMER_PRESCALER 8
# else
# define TIMER_PRESCALER 1
# endif
#endif
#define TIMER_RAW_FREQ (F_CPU/TIMER_PRESCALER)
#define TIMER_RAW TCNT0
#define TIMER_RAW_TOP (TIMER_RAW_FREQ/1000)
#if (TIMER_RAW_TOP > 255)
# error "Timer0 can't count 1ms at this clock freq. Use larger prescaler."
#endif
#endif

500
common/avr/xprintf.S Normal file

File diff suppressed because it is too large Load Diff

111
common/avr/xprintf.h Normal file
View File

@ -0,0 +1,111 @@
/*---------------------------------------------------------------------------
Extended itoa, puts and printf (C)ChaN, 2011
-----------------------------------------------------------------------------*/
#ifndef XPRINTF_H
#define XPRINTF_H
#include <inttypes.h>
#include <avr/pgmspace.h>
#ifdef __cplusplus
extern "C" {
#endif
extern void (*xfunc_out)(uint8_t);
#define xdev_out(func) xfunc_out = (void(*)(uint8_t))(func)
/* This is a pointer to user defined output function. It must be initialized
before using this modle.
*/
void xputc(char chr);
/* This is a stub function to forward outputs to user defined output function.
All outputs from this module are output via this function.
*/
/*-----------------------------------------------------------------------------*/
void xputs(const char *string_p);
/* The string placed in the ROM is forwarded to xputc() directly.
*/
/*-----------------------------------------------------------------------------*/
void xitoa(long value, char radix, char width);
/* Extended itoa().
value radix width output
100 10 6 " 100"
100 10 -6 "000100"
100 10 0 "100"
4294967295 10 0 "4294967295"
4294967295 -10 0 "-1"
655360 16 -8 "000A0000"
1024 16 0 "400"
0x55 2 -8 "01010101"
*/
/*-----------------------------------------------------------------------------*/
#define xprintf(format, ...) __xprintf(PSTR(format), ##__VA_ARGS__)
#define xsprintf(str, format, ...) __xsprintf(str, PSTR(format), ##__VA_ARGS__)
#define xfprintf(func, format, ...) __xfprintf(func, PSTR(format), ##__VA_ARGS__)
void __xprintf(const char *format_p, ...); /* Send formatted string to the registered device */
void __xsprintf(char*, const char *format_p, ...); /* Put formatted string to the memory */
void __xfprintf(void(*func)(uint8_t), const char *format_p, ...); /* Send formatted string to the specified device */
/* Format string is placed in the ROM. The format flags is similar to printf().
%[flag][width][size]type
flag
A '0' means filled with '0' when output is shorter than width.
' ' is used in default. This is effective only numeral type.
width
Minimum width in decimal number. This is effective only numeral type.
Default width is zero.
size
A 'l' means the argument is long(32bit). Default is short(16bit).
This is effective only numeral type.
type
'c' : Character, argument is the value
's' : String placed on the RAM, argument is the pointer
'S' : String placed on the ROM, argument is the pointer
'd' : Signed decimal, argument is the value
'u' : Unsigned decimal, argument is the value
'X' : Hexdecimal, argument is the value
'b' : Binary, argument is the value
'%' : '%'
*/
/*-----------------------------------------------------------------------------*/
char xatoi(char **str, long *ret);
/* Get value of the numeral string.
str
Pointer to pointer to source string
"0b11001010" binary
"0377" octal
"0xff800" hexdecimal
"1250000" decimal
"-25000" decimal
ret
Pointer to return value
*/
#ifdef __cplusplus
}
#endif
#endif

85
common/backlight.c Normal file
View File

@ -0,0 +1,85 @@
/*
Copyright 2013 Mathias Andersson <wraul@dbox.se>
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 "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);
}
void backlight_level(uint8_t level)
{
backlight_config.level ^= level;
backlight_config.enable = !!backlight_config.level;
eeconfig_write_backlight(backlight_config.raw);
backlight_set(backlight_config.level);
}

40
common/backlight.h Normal file
View File

@ -0,0 +1,40 @@
/*
Copyright 2013 Mathias Andersson <wraul@dbox.se>
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 BACKLIGHT_H
#define BACKLIGHT_H
#include <stdint.h>
#include <stdbool.h>
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);
void backlight_level(uint8_t level);
#endif

25
common/bootloader.h Normal file
View File

@ -0,0 +1,25 @@
/*
Copyright 2011 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 BOOTLOADER_H
#define BOOTLOADER_H
/* give code for your bootloader to come up if needed */
void bootloader_jump(void);
#endif

128
common/bootmagic.c Normal file
View File

@ -0,0 +1,128 @@
#include <stdint.h>
#include <stdbool.h>
#include <util/delay.h>
#include "matrix.h"
#include "bootloader.h"
#include "debug.h"
#include "keymap.h"
#include "host.h"
#include "action_layer.h"
#include "eeconfig.h"
#include "bootmagic.h"
void bootmagic(void)
{
/* check signature */
if (!eeconfig_is_enabled()) {
eeconfig_init();
}
/* do scans in case of bounce */
print("boogmagic scan: ... ");
uint8_t scan = 100;
while (scan--) { matrix_scan(); _delay_ms(10); }
print("done.\n");
/* bootmagic skip */
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SKIP)) {
return;
}
/* eeconfig clear */
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_EEPROM_CLEAR)) {
eeconfig_init();
}
/* bootloader */
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_BOOTLOADER)) {
bootloader_jump();
}
/* debug enable */
debug_config.raw = eeconfig_read_debug();
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_ENABLE)) {
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_MATRIX)) {
debug_config.matrix = !debug_config.matrix;
} else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_KEYBOARD)) {
debug_config.keyboard = !debug_config.keyboard;
} else if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEBUG_MOUSE)) {
debug_config.mouse = !debug_config.mouse;
} else {
debug_config.enable = !debug_config.enable;
}
}
eeconfig_write_debug(debug_config.raw);
/* keymap config */
keymap_config.raw = eeconfig_read_keymap();
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK)) {
keymap_config.swap_control_capslock = !keymap_config.swap_control_capslock;
}
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL)) {
keymap_config.capslock_to_control = !keymap_config.capslock_to_control;
}
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_LALT_LGUI)) {
keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui;
}
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_RALT_RGUI)) {
keymap_config.swap_ralt_rgui = !keymap_config.swap_ralt_rgui;
}
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_NO_GUI)) {
keymap_config.no_gui = !keymap_config.no_gui;
}
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_GRAVE_ESC)) {
keymap_config.swap_grave_esc = !keymap_config.swap_grave_esc;
}
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE)) {
keymap_config.swap_backslash_backspace = !keymap_config.swap_backslash_backspace;
}
if (bootmagic_scan_keycode(BOOTMAGIC_HOST_NKRO)) {
keymap_config.nkro = !keymap_config.nkro;
}
eeconfig_write_keymap(keymap_config.raw);
#ifdef NKRO_ENABLE
keyboard_nkro = keymap_config.nkro;
#endif
/* default layer */
uint8_t default_layer = 0;
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_0)) { default_layer |= (1<<0); }
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_1)) { default_layer |= (1<<1); }
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_2)) { default_layer |= (1<<2); }
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_3)) { default_layer |= (1<<3); }
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_4)) { default_layer |= (1<<4); }
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_5)) { default_layer |= (1<<5); }
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_6)) { default_layer |= (1<<6); }
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_7)) { default_layer |= (1<<7); }
if (default_layer) {
eeconfig_write_default_layer(default_layer);
default_layer_set((uint32_t)default_layer);
} else {
default_layer = eeconfig_read_default_layer();
default_layer_set((uint32_t)default_layer);
}
}
static bool scan_keycode(uint8_t keycode)
{
for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
matrix_row_t matrix_row = matrix_get_row(r);
for (uint8_t c = 0; c < MATRIX_COLS; c++) {
if (matrix_row & ((matrix_row_t)1<<c)) {
if (keycode == keymap_key_to_keycode(0, (keypos_t){ .row = r, .col = c })) {
return true;
}
}
}
}
return false;
}
bool bootmagic_scan_keycode(uint8_t keycode)
{
if (!scan_keycode(BOOTMAGIC_KEY_SALT)) return false;
return scan_keycode(keycode);
}

100
common/bootmagic.h Normal file
View File

@ -0,0 +1,100 @@
#ifndef BOOTMAGIC_H
#define BOOTMAGIC_H
/* bootmagic salt key */
#ifndef BOOTMAGIC_KEY_SALT
#define BOOTMAGIC_KEY_SALT KC_SPACE
#endif
/* skip bootmagic and eeconfig */
#ifndef BOOTMAGIC_KEY_SKIP
#define BOOTMAGIC_KEY_SKIP KC_ESC
#endif
/* eeprom clear */
#ifndef BOOTMAGIC_KEY_EEPROM_CLEAR
#define BOOTMAGIC_KEY_EEPROM_CLEAR KC_BSPACE
#endif
/* kick up bootloader */
#ifndef BOOTMAGIC_KEY_BOOTLOADER
#define BOOTMAGIC_KEY_BOOTLOADER KC_B
#endif
/* debug enable */
#ifndef BOOTMAGIC_KEY_DEBUG_ENABLE
#define BOOTMAGIC_KEY_DEBUG_ENABLE KC_D
#endif
#ifndef BOOTMAGIC_KEY_DEBUG_MATRIX
#define BOOTMAGIC_KEY_DEBUG_MATRIX KC_X
#endif
#ifndef BOOTMAGIC_KEY_DEBUG_KEYBOARD
#define BOOTMAGIC_KEY_DEBUG_KEYBOARD KC_K
#endif
#ifndef BOOTMAGIC_KEY_DEBUG_MOUSE
#define BOOTMAGIC_KEY_DEBUG_MOUSE KC_M
#endif
/*
* keymap config
*/
#ifndef BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK
#define BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK KC_LCTRL
#endif
#ifndef BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL
#define BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL KC_CAPSLOCK
#endif
#ifndef BOOTMAGIC_KEY_SWAP_LALT_LGUI
#define BOOTMAGIC_KEY_SWAP_LALT_LGUI KC_LALT
#endif
#ifndef BOOTMAGIC_KEY_SWAP_RALT_RGUI
#define BOOTMAGIC_KEY_SWAP_RALT_RGUI KC_RALT
#endif
#ifndef BOOTMAGIC_KEY_NO_GUI
#define BOOTMAGIC_KEY_NO_GUI KC_LGUI
#endif
#ifndef BOOTMAGIC_KEY_SWAP_GRAVE_ESC
#define BOOTMAGIC_KEY_SWAP_GRAVE_ESC KC_GRAVE
#endif
#ifndef BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE
#define BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE KC_BSLASH
#endif
#ifndef BOOTMAGIC_HOST_NKRO
#define BOOTMAGIC_HOST_NKRO KC_N
#endif
/*
* change default layer
*/
#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_0
#define BOOTMAGIC_KEY_DEFAULT_LAYER_0 KC_0
#endif
#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_1
#define BOOTMAGIC_KEY_DEFAULT_LAYER_1 KC_1
#endif
#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_2
#define BOOTMAGIC_KEY_DEFAULT_LAYER_2 KC_2
#endif
#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_3
#define BOOTMAGIC_KEY_DEFAULT_LAYER_3 KC_3
#endif
#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_4
#define BOOTMAGIC_KEY_DEFAULT_LAYER_4 KC_4
#endif
#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_5
#define BOOTMAGIC_KEY_DEFAULT_LAYER_5 KC_5
#endif
#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_6
#define BOOTMAGIC_KEY_DEFAULT_LAYER_6 KC_6
#endif
#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_7
#define BOOTMAGIC_KEY_DEFAULT_LAYER_7 KC_7
#endif
void bootmagic(void);
bool bootmagic_scan_keycode(uint8_t keycode);
#endif

644
common/command.c Normal file

File diff suppressed because it is too large Load Diff

35
common/command.h Normal file
View File

@ -0,0 +1,35 @@
/*
Copyright 2011 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 COMMAND_H
#define COMMAND
/* TODO: Refactoring */
typedef enum { ONESHOT, CONSOLE, MOUSEKEY } command_state_t;
extern command_state_t command_state;
/* This allows to extend commands. Return false when command is not processed. */
bool command_extra(uint8_t code);
bool command_console_extra(uint8_t code);
#ifdef COMMAND_ENABLE
bool command_proc(uint8_t code);
#else
#define command_proc(code) false
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More