Squashed 'tmk_core/' changes from dc0e46e..57d27a8

57d27a8 Merge branch 'core_update_150924' into core
024abe3 core: Fix NKRO ifdef
7aa2d30 core: Fix for disabling NKRO in Boot protocol
95651fd core: Fix message print of debug command
c20cd29 lufa: Fix endpoint bank mode for ATMega32u2
82ac21f next_usb: Fix next_kbd_set_leds()
537d9c7 Change to KC_BOOTLOADER(KC_BTLD)
f2b3772 Add an assignable RESET key
fc99257 Fix parenthesis
e852582 Fix weak modifier clear in action macro
c2a6c5c core: Fix lufa suspend callback(#234)
fa548c5 usb_usb: Ignore error usage(0x01-03) report
513d95c usb_usb: Support locking key indicator LED
cd78802 core: Add keymap section ldscript for ATMega32U2
70c9abd Add description for non-US keys on keycode.h
538c192 lufa: Fix console flush #223
87628c9 Revert "Make action_for_key a weak symbol"
3c0a1ba Make action_for_key a weak symbol
6bb0d7d ibm4704_usb: Fix protocol handling
b6ef5cf Add keyboard_setup() and matrix_setup()
f4bb8b2 ibm4704_usb: Fix interrupt of clock(rising edge)
0c1fcc1 usb_usb: Change debug LED pin config
595710d Reduce code size of magic commands
6bed174 Add description of AVR bootloader and boot section
54c6a01 Merge commit 'f6d56675f9f981c5464f0ca7a1fbb0162154e8c5'
d18d42e Merge branch 'core-update2' into core
febec88 Add compile options '-fdata-sections'

git-subtree-dir: tmk_core
git-subtree-split: 57d27a8e39173a589b4abae74851f95c39940174
pull/33/head
Jun Wako 9 years ago
parent f6d56675f9
commit fdc38ef3f9

@ -66,7 +66,14 @@ endif
ifdef KEYMAP_SECTION_ENABLE ifdef KEYMAP_SECTION_ENABLE
OPT_DEFS += -DKEYMAP_SECTION_ENABLE OPT_DEFS += -DKEYMAP_SECTION_ENABLE
EXTRALDFLAGS = -Wl,-L$(TMK_DIR),-Tldscript_keymap_avr5.x
ifeq ($(strip $(MCU)),atmega32u2)
EXTRALDFLAGS = -Wl,-L$(TMK_DIR),-Tldscript_keymap_avr35.x
else ifeq ($(strip $(MCU)),atmega32u4)
EXTRALDFLAGS = -Wl,-L$(TMK_DIR),-Tldscript_keymap_avr5.x
else
EXTRALDFLAGS = $(error no ldscript for keymap section)
endif
endif endif
# Version string # Version string

@ -266,7 +266,7 @@ enum layer_pram_tap_op {
#define ACTION_LAYER_ON_OFF(layer) ACTION_LAYER_TAP((layer), OP_ON_OFF) #define ACTION_LAYER_ON_OFF(layer) ACTION_LAYER_TAP((layer), OP_ON_OFF)
#define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON) #define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON)
#define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR) #define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR)
#define ACTION_LAYER_MODS(layer, mods) ACTION_LAYER_TAP((layer), 0xe0 | (mods)&0x0f) #define ACTION_LAYER_MODS(layer, mods) ACTION_LAYER_TAP((layer), 0xe0 | ((mods)&0x0f))
/* With Tapping */ /* With Tapping */
#define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key)) #define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key))
#define ACTION_LAYER_TAP_TOGGLE(layer) ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE) #define ACTION_LAYER_TAP_TOGGLE(layer) ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE)

@ -42,6 +42,7 @@ void action_macro_play(const macro_t *macro_p)
dprintf("KEY_DOWN(%02X)\n", macro); dprintf("KEY_DOWN(%02X)\n", macro);
if (IS_MOD(macro)) { if (IS_MOD(macro)) {
add_weak_mods(MOD_BIT(macro)); add_weak_mods(MOD_BIT(macro));
send_keyboard_report();
} else { } else {
register_code(macro); register_code(macro);
} }
@ -51,6 +52,7 @@ void action_macro_play(const macro_t *macro_p)
dprintf("KEY_UP(%02X)\n", macro); dprintf("KEY_UP(%02X)\n", macro);
if (IS_MOD(macro)) { if (IS_MOD(macro)) {
del_weak_mods(MOD_BIT(macro)); del_weak_mods(MOD_BIT(macro));
send_keyboard_report();
} else { } else {
unregister_code(macro); unregister_code(macro);
} }

@ -76,7 +76,7 @@ void send_keyboard_report(void) {
void add_key(uint8_t key) void add_key(uint8_t key)
{ {
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
if (keyboard_nkro) { if (keyboard_protocol && keyboard_nkro) {
add_key_bit(key); add_key_bit(key);
return; return;
} }
@ -87,7 +87,7 @@ void add_key(uint8_t key)
void del_key(uint8_t key) void del_key(uint8_t key)
{ {
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
if (keyboard_nkro) { if (keyboard_protocol && keyboard_nkro) {
del_key_bit(key); del_key_bit(key);
return; return;
} }
@ -160,7 +160,7 @@ uint8_t has_anymod(void)
uint8_t get_first_key(void) uint8_t get_first_key(void)
{ {
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
if (keyboard_nkro) { if (keyboard_protocol && keyboard_nkro) {
uint8_t i = 0; uint8_t i = 0;
for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++) for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
; ;

@ -11,12 +11,49 @@
#endif #endif
/* Boot Section Size in *BYTEs* /* Bootloader Size in *bytes*
* Teensy halfKay 512 *
* Teensy++ halfKay 1024 * AVR Boot section size are defined by setting BOOTSZ fuse in fact. Consult with your MCU datasheet.
* Atmel DFU loader 4096 * Note that 'Word'(2 bytes) size and address are used in datasheet while TMK uses 'Byte'.
* LUFA bootloader 4096 *
* USBaspLoader 2048 *
* Size of Bootloaders in bytes:
* Atmel DFU loader(ATmega32U4) 4096
* Atmel DFU loader(AT90USB128) 8192
* LUFA bootloader(ATmega32U4) 4096
* Arduino Caterina(ATmega32U4) 4096
* USBaspLoader(ATmega***) 2048
* Teensy halfKay(ATmega32U4) 512
* Teensy++ halfKay(AT90USB128) 1024
*
*
* AVR Boot section is located at the end of Flash memory like the followings.
*
*
* byte Atmel/LUFA(ATMega32u4) byte Atmel(AT90SUB128)
* 0x0000 +---------------+ 0x00000 +---------------+
* | | | |
* | | | |
* | Application | | Application |
* | | | |
* = = = =
* | | 32KB-4KB | | 128KB-8KB
* 0x6000 +---------------+ 0x1FC00 +---------------+
* | Bootloader | 4KB | Bootloader | 8KB
* 0x7FFF +---------------+ 0x1FFFF +---------------+
*
*
* byte Teensy(ATMega32u4) byte Teensy++(AT90SUB128)
* 0x0000 +---------------+ 0x00000 +---------------+
* | | | |
* | | | |
* | Application | | Application |
* | | | |
* = = = =
* | | 32KB-512B | | 128KB-1KB
* 0x7E00 +---------------+ 0x1FC00 +---------------+
* | Bootloader | 512B | Bootloader | 1KB
* 0x7FFF +---------------+ 0x1FFFF +---------------+
*/ */
#ifndef BOOTLOADER_SIZE #ifndef BOOTLOADER_SIZE
#warning To use bootloader_jump() you need to define BOOTLOADER_SIZE in config.h. #warning To use bootloader_jump() you need to define BOOTLOADER_SIZE in config.h.

@ -85,6 +85,8 @@ void suspend_power_down(void)
power_down(WDTO_15MS); power_down(WDTO_15MS);
} }
__attribute__ ((weak)) void matrix_power_up(void) {}
__attribute__ ((weak)) void matrix_power_down(void) {}
bool suspend_wakeup_condition(void) bool suspend_wakeup_condition(void)
{ {
matrix_power_up(); matrix_power_up();

@ -112,30 +112,33 @@ bool command_console_extra(uint8_t code)
***********************************************************/ ***********************************************************/
static void command_common_help(void) static void command_common_help(void)
{ {
print("\n\n----- Command Help -----\n"); print("\n\t- Magic -\n"
print("c: enter console mode\n"); "d: debug\n"
print("d: toggle debug enable\n"); "x: debug matrix\n"
print("x: toggle matrix debug\n"); "k: debug keyboard\n"
print("k: toggle keyboard debug\n"); "m: debug mouse\n"
print("m: toggle mouse debug\n"); "v: version\n"
#ifdef SLEEP_LED_ENABLE "s: status\n"
print("z: toggle sleep LED test\n"); "c: console mode\n"
"0-4: layer0-4(F10-F4)\n"
"Paus: bootloader\n"
#ifdef KEYBOARD_LOCK_ENABLE
"Caps: Lock\n"
#endif
#ifdef BOOTMAGIC_ENABLE
"e: eeprom\n"
#endif #endif
print("v: print device version & info\n");
print("t: print timer count\n");
print("s: print status\n");
print("e: print eeprom config\n");
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
print("n: toggle NKRO\n"); "n: NKRO\n"
#endif
#ifdef SLEEP_LED_ENABLE
"z: sleep LED test\n"
#endif #endif
print("0/F10: switch to Layer0 \n"); );
print("1/F1: switch to Layer1 \n");
print("2/F2: switch to Layer2 \n");
print("3/F3: switch to Layer3 \n");
print("4/F4: switch to Layer4 \n");
print("PScr: power down/remote wake-up\n");
print("Caps: Lock Keyboard(Child Proof)\n");
print("Paus: jump to bootloader\n");
} }
#ifdef BOOTMAGIC_ENABLE #ifdef BOOTMAGIC_ENABLE
@ -191,6 +194,7 @@ static bool command_common(uint8_t code)
print_eeconfig(); print_eeconfig();
break; break;
#endif #endif
#ifdef KEYBOARD_LOCK_ENABLE
case KC_CAPSLOCK: case KC_CAPSLOCK:
if (host_get_driver()) { if (host_get_driver()) {
host_driver = host_get_driver(); host_driver = host_get_driver();
@ -202,6 +206,7 @@ static bool command_common(uint8_t code)
print("Unlocked.\n"); print("Unlocked.\n");
} }
break; break;
#endif
case KC_H: case KC_H:
case KC_SLASH: /* ? */ case KC_SLASH: /* ? */
command_common_help(); command_common_help();
@ -212,58 +217,56 @@ static bool command_common(uint8_t code)
debug_mouse = false; debug_mouse = false;
debug_enable = false; debug_enable = false;
command_console_help(); command_console_help();
print("\nEnter Console Mode\n");
print("C> "); print("C> ");
command_state = CONSOLE; command_state = CONSOLE;
break; break;
case KC_PAUSE: case KC_PAUSE:
clear_keyboard(); clear_keyboard();
print("\n\nJump to bootloader... "); print("\n\nbootloader... ");
_delay_ms(1000); _delay_ms(1000);
bootloader_jump(); // not return bootloader_jump(); // not return
print("not supported.\n");
break; break;
case KC_D: case KC_D:
if (debug_enable) { if (debug_enable) {
print("\nDEBUG: disabled.\n"); print("\ndebug: off\n");
debug_matrix = false; debug_matrix = false;
debug_keyboard = false; debug_keyboard = false;
debug_mouse = false; debug_mouse = false;
debug_enable = false; debug_enable = false;
} else { } else {
print("\nDEBUG: enabled.\n"); print("\ndebug: on\n");
debug_enable = true; debug_enable = true;
} }
break; break;
case KC_X: // debug matrix toggle case KC_X: // debug matrix toggle
debug_matrix = !debug_matrix; debug_matrix = !debug_matrix;
if (debug_matrix) { if (debug_matrix) {
print("\nDEBUG: matrix enabled.\n"); print("\nmatrix: on\n");
debug_enable = true; debug_enable = true;
} else { } else {
print("\nDEBUG: matrix disabled.\n"); print("\nmatrix: off\n");
} }
break; break;
case KC_K: // debug keyboard toggle case KC_K: // debug keyboard toggle
debug_keyboard = !debug_keyboard; debug_keyboard = !debug_keyboard;
if (debug_keyboard) { if (debug_keyboard) {
print("\nDEBUG: keyboard enabled.\n"); print("\nkeyboard: on\n");
debug_enable = true; debug_enable = true;
} else { } else {
print("\nDEBUG: keyboard disabled.\n"); print("\nkeyboard: off\n");
} }
break; break;
case KC_M: // debug mouse toggle case KC_M: // debug mouse toggle
debug_mouse = !debug_mouse; debug_mouse = !debug_mouse;
if (debug_mouse) { if (debug_mouse) {
print("\nDEBUG: mouse enabled.\n"); print("\nmouse: on\n");
debug_enable = true; debug_enable = true;
} else { } else {
print("\nDEBUG: mouse disabled.\n"); print("\nmouse: off\n");
} }
break; break;
case KC_V: // print version & information case KC_V: // print version & information
print("\n\n----- Version -----\n"); print("\n\t- Version -\n");
print("DESC: " STR(DESCRIPTION) "\n"); print("DESC: " STR(DESCRIPTION) "\n");
print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") " print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") "
"PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") " "PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
@ -307,14 +310,16 @@ static bool command_common(uint8_t code)
" AVR-LIBC: " __AVR_LIBC_VERSION_STRING__ " AVR-LIBC: " __AVR_LIBC_VERSION_STRING__
" AVR_ARCH: avr" STR(__AVR_ARCH__) "\n"); " AVR_ARCH: avr" STR(__AVR_ARCH__) "\n");
break; break;
case KC_T: // print timer
print_val_hex32(timer_count);
break;
case KC_S: case KC_S:
print("\n\n----- Status -----\n"); print("\n\t- Status -\n");
print_val_hex8(host_keyboard_leds()); print_val_hex8(host_keyboard_leds());
print_val_hex8(keyboard_protocol); print_val_hex8(keyboard_protocol);
print_val_hex8(keyboard_idle); print_val_hex8(keyboard_idle);
#ifdef NKRO_ENABLE
print_val_hex8(keyboard_nkro);
#endif
print_val_hex32(timer_count);
#ifdef PROTOCOL_PJRC #ifdef PROTOCOL_PJRC
print_val_hex8(UDCON); print_val_hex8(UDCON);
print_val_hex8(UDIEN); print_val_hex8(UDIEN);
@ -334,39 +339,21 @@ static bool command_common(uint8_t code)
clear_keyboard(); //Prevents stuck keys. clear_keyboard(); //Prevents stuck keys.
keyboard_nkro = !keyboard_nkro; keyboard_nkro = !keyboard_nkro;
if (keyboard_nkro) if (keyboard_nkro)
print("NKRO: enabled\n"); print("NKRO: on\n");
else else
print("NKRO: disabled\n"); print("NKRO: off\n");
break;
#endif
#ifdef EXTRAKEY_ENABLE
case KC_PSCREEN:
// TODO: Power key should take this feature? otherwise any key during suspend.
#ifdef PROTOCOL_PJRC
if (suspend && remote_wakeup) {
usb_remote_wakeup();
} else {
host_system_send(SYSTEM_POWER_DOWN);
host_system_send(0);
_delay_ms(500);
}
#else
host_system_send(SYSTEM_POWER_DOWN);
_delay_ms(100);
host_system_send(0);
_delay_ms(500);
#endif
break; break;
#endif #endif
case KC_ESC: case KC_ESC:
case KC_GRV: case KC_GRV:
case KC_0: case KC_0:
case KC_F10:
switch_default_layer(0); switch_default_layer(0);
break; break;
case KC_1 ... KC_9: case KC_1 ... KC_9:
switch_default_layer((code - KC_1) + 1); switch_default_layer((code - KC_1) + 1);
break; break;
case KC_F1 ... KC_F12: case KC_F1 ... KC_F9:
switch_default_layer((code - KC_F1) + 1); switch_default_layer((code - KC_F1) + 1);
break; break;
default: default:
@ -382,11 +369,12 @@ static bool command_common(uint8_t code)
***********************************************************/ ***********************************************************/
static void command_console_help(void) static void command_console_help(void)
{ {
print("\n\n----- Console Help -----\n"); print("\n\t- Console -\n"
print("ESC/q: quit\n"); "ESC/q: quit\n"
#ifdef MOUSEKEY_ENABLE #ifdef MOUSEKEY_ENABLE
print("m: mousekey\n"); "m: mousekey\n"
#endif #endif
);
} }
static bool command_console(uint8_t code) static bool command_console(uint8_t code)
@ -398,14 +386,12 @@ static bool command_console(uint8_t code)
break; break;
case KC_Q: case KC_Q:
case KC_ESC: case KC_ESC:
print("\nQuit Console Mode\n");
command_state = ONESHOT; command_state = ONESHOT;
return false; return false;
#ifdef MOUSEKEY_ENABLE #ifdef MOUSEKEY_ENABLE
case KC_M: case KC_M:
mousekey_console_help(); mousekey_console_help();
print("\nEnter Mousekey Console\n"); print("M> ");
print("M0>");
command_state = MOUSEKEY; command_state = MOUSEKEY;
return true; return true;
#endif #endif
@ -426,16 +412,17 @@ static uint8_t mousekey_param = 0;
static void mousekey_param_print(void) static void mousekey_param_print(void)
{ {
print("\n\n----- Mousekey Parameters -----\n"); print("\n\t- Values -\n");
print("1: mk_delay(*10ms): "); pdec(mk_delay); print("\n"); print("1: delay(*10ms): "); pdec(mk_delay); print("\n");
print("2: mk_interval(ms): "); pdec(mk_interval); print("\n"); print("2: interval(ms): "); pdec(mk_interval); print("\n");
print("3: mk_max_speed: "); pdec(mk_max_speed); print("\n"); print("3: max_speed: "); pdec(mk_max_speed); print("\n");
print("4: mk_time_to_max: "); pdec(mk_time_to_max); print("\n"); print("4: time_to_max: "); pdec(mk_time_to_max); print("\n");
print("5: mk_wheel_max_speed: "); pdec(mk_wheel_max_speed); print("\n"); print("5: wheel_max_speed: "); pdec(mk_wheel_max_speed); print("\n");
print("6: mk_wheel_time_to_max: "); pdec(mk_wheel_time_to_max); print("\n"); print("6: wheel_time_to_max: "); pdec(mk_wheel_time_to_max); print("\n");
} }
#define PRINT_SET_VAL(v) print(#v " = "); print_dec(v); print("\n"); //#define PRINT_SET_VAL(v) print(#v " = "); print_dec(v); print("\n");
#define PRINT_SET_VAL(v) xprintf(#v " = %d\n", (v))
static void mousekey_param_inc(uint8_t param, uint8_t inc) static void mousekey_param_inc(uint8_t param, uint8_t inc)
{ {
switch (param) { switch (param) {
@ -534,24 +521,25 @@ static void mousekey_param_dec(uint8_t param, uint8_t dec)
static void mousekey_console_help(void) static void mousekey_console_help(void)
{ {
print("\n\n----- Mousekey Parameters Help -----\n"); print("\n\t- Mousekey -\n"
print("ESC/q: quit\n"); "ESC/q: quit\n"
print("1: select mk_delay(*10ms)\n"); "1: delay(*10ms)\n"
print("2: select mk_interval(ms)\n"); "2: interval(ms)\n"
print("3: select mk_max_speed\n"); "3: max_speed\n"
print("4: select mk_time_to_max\n"); "4: time_to_max\n"
print("5: select mk_wheel_max_speed\n"); "5: wheel_max_speed\n"
print("6: select mk_wheel_time_to_max\n"); "6: wheel_time_to_max\n"
print("p: print parameters\n"); "\n"
print("d: set default values\n"); "p: print values\n"
print("up: increase parameters(+1)\n"); "d: set defaults\n"
print("down: decrease parameters(-1)\n"); "up: +1\n"
print("pgup: increase parameters(+10)\n"); "down: -1\n"
print("pgdown: decrease parameters(-10)\n"); "pgup: +10\n"
print("\nspeed = delta * max_speed * (repeat / time_to_max)\n"); "pgdown: -10\n"
print("where delta: cursor="); pdec(MOUSEKEY_MOVE_DELTA); "\n"
print(", wheel="); pdec(MOUSEKEY_WHEEL_DELTA); print("\n"); "speed = delta * max_speed * (repeat / time_to_max)\n");
print("See http://en.wikipedia.org/wiki/Mouse_keys\n"); xprintf("where delta: cursor=%d, wheel=%d\n"
"See http://en.wikipedia.org/wiki/Mouse_keys\n", MOUSEKEY_MOVE_DELTA, MOUSEKEY_WHEEL_DELTA);
} }
static bool mousekey_console(uint8_t code) static bool mousekey_console(uint8_t code)
@ -563,11 +551,14 @@ static bool mousekey_console(uint8_t code)
break; break;
case KC_Q: case KC_Q:
case KC_ESC: case KC_ESC:
mousekey_param = 0; if (mousekey_param) {
print("\nQuit Mousekey Console\n"); mousekey_param = 0;
print("C> "); } else {
command_state = CONSOLE; print("C> ");
return false; command_state = CONSOLE;
return false;
}
break;
case KC_P: case KC_P:
mousekey_param_print(); mousekey_param_print();
break; break;
@ -577,12 +568,7 @@ static bool mousekey_console(uint8_t code)
case KC_4: case KC_4:
case KC_5: case KC_5:
case KC_6: case KC_6:
case KC_7:
case KC_8:
case KC_9:
case KC_0:
mousekey_param = numkey2num(code); mousekey_param = numkey2num(code);
print("selected parameter: "); pdec(mousekey_param); print("\n");
break; break;
case KC_UP: case KC_UP:
mousekey_param_inc(mousekey_param, 1); mousekey_param_inc(mousekey_param, 1);
@ -603,13 +589,16 @@ static bool mousekey_console(uint8_t code)
mk_time_to_max = MOUSEKEY_TIME_TO_MAX; mk_time_to_max = MOUSEKEY_TIME_TO_MAX;
mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED; mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED;
mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX; mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX;
print("set default values.\n"); print("set default\n");
break; break;
default: default:
print("?"); print("?");
return false; return false;
} }
print("M"); pdec(mousekey_param); print("> "); if (mousekey_param)
xprintf("M%d> ", mousekey_param);
else
print("M>" );
return true; return true;
} }
#endif #endif
@ -637,8 +626,7 @@ static uint8_t numkey2num(uint8_t code)
static void switch_default_layer(uint8_t layer) static void switch_default_layer(uint8_t layer)
{ {
print("switch_default_layer: "); print_dec(biton32(default_layer_state)); xprintf("L%d\n", layer);
print(" to "); print_dec(layer); print("\n");
default_layer_set(1UL<<layer); default_layer_set(1UL<<layer);
clear_keyboard(); clear_keyboard();
} }

@ -62,6 +62,12 @@ static bool has_ghost_in_row(uint8_t row)
#endif #endif
__attribute__ ((weak)) void matrix_setup(void) {}
void keyboard_setup(void)
{
matrix_setup();
}
void keyboard_init(void) void keyboard_init(void)
{ {
timer_init(); timer_init();

@ -58,13 +58,15 @@ static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) &&
} }
/* it runs once at early stage of startup before keyboard_init. */
void keyboard_setup(void);
/* it runs once after initializing host side protocol, debug and MCU peripherals. */
void keyboard_init(void); void keyboard_init(void);
/* it runs repeatedly in main loop */
void keyboard_task(void); void keyboard_task(void);
/* it runs when host LED status is updated */
void keyboard_set_leds(uint8_t leds); void keyboard_set_leds(uint8_t leds);
__attribute__ ((weak)) void matrix_power_up(void) {}
__attribute__ ((weak)) void matrix_power_down(void) {}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

@ -156,6 +156,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define KC_WSTP KC_WWW_STOP #define KC_WSTP KC_WWW_STOP
#define KC_WREF KC_WWW_REFRESH #define KC_WREF KC_WWW_REFRESH
#define KC_WFAV KC_WWW_FAVORITES #define KC_WFAV KC_WWW_FAVORITES
/* Jump to bootloader */
#define KC_BTLD KC_BOOTLOADER
/* Transparent */ /* Transparent */
#define KC_TRANSPARENT 1 #define KC_TRANSPARENT 1
#define KC_TRNS KC_TRANSPARENT #define KC_TRNS KC_TRANSPARENT
@ -214,7 +216,7 @@ enum hid_keyboard_keypad_usage {
KC_LBRACKET, KC_LBRACKET,
KC_RBRACKET, /* 0x30 */ KC_RBRACKET, /* 0x30 */
KC_BSLASH, /* \ (and |) */ KC_BSLASH, /* \ (and |) */
KC_NONUS_HASH, /* Non-US # and ~ */ KC_NONUS_HASH, /* Non-US # and ~ (Typically near the Enter key) */
KC_SCOLON, /* ; (and :) */ KC_SCOLON, /* ; (and :) */
KC_QUOTE, /* ' and " */ KC_QUOTE, /* ' and " */
KC_GRAVE, /* Grave accent and tilde */ KC_GRAVE, /* Grave accent and tilde */
@ -264,7 +266,7 @@ enum hid_keyboard_keypad_usage {
KC_KP_9, KC_KP_9,
KC_KP_0, KC_KP_0,
KC_KP_DOT, KC_KP_DOT,
KC_NONUS_BSLASH, /* Non-US \ and | */ KC_NONUS_BSLASH, /* Non-US \ and | (Typically near the Left-Shift key) */
KC_APPLICATION, KC_APPLICATION,
KC_POWER, KC_POWER,
KC_KP_EQUAL, KC_KP_EQUAL,
@ -426,6 +428,9 @@ enum internal_special_keycodes {
KC_MEDIA_FAST_FORWARD, KC_MEDIA_FAST_FORWARD,
KC_MEDIA_REWIND, /* 0xBC */ KC_MEDIA_REWIND, /* 0xBC */
/* Jump to bootloader */
KC_BOOTLOADER = 0xBF,
/* Fn key */ /* Fn key */
KC_FN0 = 0xC0, KC_FN0 = 0xC0,
KC_FN1, KC_FN1,

@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "action_layer.h" #include "action_layer.h"
#include "action.h" #include "action.h"
#include "action_macro.h" #include "action_macro.h"
#include "wait.h"
#include "debug.h" #include "debug.h"
@ -140,6 +141,11 @@ static action_t keycode_to_action(uint8_t keycode)
case KC_TRNS: case KC_TRNS:
action.code = ACTION_TRANSPARENT; action.code = ACTION_TRANSPARENT;
break; break;
case KC_BOOTLOADER:
clear_keyboard();
wait_ms(50);
bootloader_jump(); // not return
break;
default: default:
action.code = ACTION_NO; action.code = ACTION_NO;
break; break;

@ -28,6 +28,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define USB_LED_KANA 4 #define USB_LED_KANA 4
#ifdef __cplusplus
extern "C" {
#endif
void led_set(uint8_t usb_led); void led_set(uint8_t usb_led);
#ifdef __cplusplus
}
#endif
#endif #endif

@ -43,7 +43,9 @@ extern "C" {
uint8_t matrix_rows(void); uint8_t matrix_rows(void);
/* number of matrix columns */ /* number of matrix columns */
uint8_t matrix_cols(void); uint8_t matrix_cols(void);
/* intialize matrix for scaning. should be called once. */ /* should be called at early stage of startup before matrix_init.(optional) */
void matrix_setup(void);
/* intialize matrix for scaning. */
void matrix_init(void); void matrix_init(void);
/* scan all key states on matrix */ /* scan all key states on matrix */
uint8_t matrix_scan(void); uint8_t matrix_scan(void);

@ -0,0 +1,268 @@
/*
* linker script for configurable keymap
*
* This adds keymap section which places keymap at fixed address and
* is based on binutils-avr ldscripts(/usr/lib/ldscripts/avr5.x).
*/
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:35)
MEMORY
{
/* With keymap section
*
* Flash Map of ATMega32U4(32KB)
* +------------+ 0x0000
* | .vectors |
* | .progmem |
* | .init0-9 | > text region
* | .text |
* | .fini9-0 |
* | |
* |------------| _etext
* | .data |
* | .bss | > data region
* | .noinit |
* | |
* |------------| 0x6800
* | .keymap | > keymap region(2KB)
* |------------| 0x7000
* | bootloader | 4KB
* +------------+ 0x7FFF
*/
text (rx) : ORIGIN = 0, LENGTH = 64K
keymap (rw!x) : ORIGIN = 0x6800, LENGTH = 2K
data (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K
fuse (rw!x) : ORIGIN = 0x820000, LENGTH = 1K
lock (rw!x) : ORIGIN = 0x830000, LENGTH = 1K
signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K
}
SECTIONS
{
/* Read-only sections, merged into text segment: */
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.text :
{
*(.rel.text)
*(.rel.text.*)
*(.rel.gnu.linkonce.t*)
}
.rela.text :
{
*(.rela.text)
*(.rela.text.*)
*(.rela.gnu.linkonce.t*)
}
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.rodata :
{
*(.rel.rodata)
*(.rel.rodata.*)
*(.rel.gnu.linkonce.r*)
}
.rela.rodata :
{
*(.rela.rodata)
*(.rela.rodata.*)
*(.rela.gnu.linkonce.r*)
}
.rel.data :
{
*(.rel.data)
*(.rel.data.*)
*(.rel.gnu.linkonce.d*)
}
.rela.data :
{
*(.rela.data)
*(.rela.data.*)
*(.rela.gnu.linkonce.d*)
}
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
/* Internal text space or external memory. */
.text :
{
*(.vectors)
KEEP(*(.vectors))
/* For data that needs to reside in the lower 64k of progmem. */
*(.progmem.gcc*)
*(.progmem*)
. = ALIGN(2);
__trampolines_start = . ;
/* The jump trampolines for the 16-bit limited relocs will reside here. */
*(.trampolines)
*(.trampolines*)
__trampolines_end = . ;
/* For future tablejump instruction arrays for 3 byte pc devices.
We don't relax jump/call instructions within these sections. */
*(.jumptables)
*(.jumptables*)
/* For code that needs to reside in the lower 128k progmem. */
*(.lowtext)
*(.lowtext*)
__ctors_start = . ;
*(.ctors)
__ctors_end = . ;
__dtors_start = . ;
*(.dtors)
__dtors_end = . ;
KEEP(SORT(*)(.ctors))
KEEP(SORT(*)(.dtors))
/* From this point on, we don't bother about wether the insns are
below or above the 16 bits boundary. */
*(.init0) /* Start here after reset. */
KEEP (*(.init0))
*(.init1)
KEEP (*(.init1))
*(.init2) /* Clear __zero_reg__, set up stack pointer. */
KEEP (*(.init2))
*(.init3)
KEEP (*(.init3))
*(.init4) /* Initialize data and BSS. */
KEEP (*(.init4))
*(.init5)
KEEP (*(.init5))
*(.init6) /* C++ constructors. */
KEEP (*(.init6))
*(.init7)
KEEP (*(.init7))
*(.init8)
KEEP (*(.init8))
*(.init9) /* Call main(). */
KEEP (*(.init9))
*(.text)
. = ALIGN(2);
*(.text.*)
. = ALIGN(2);
*(.fini9) /* _exit() starts here. */
KEEP (*(.fini9))
*(.fini8)
KEEP (*(.fini8))
*(.fini7)
KEEP (*(.fini7))
*(.fini6) /* C++ destructors. */
KEEP (*(.fini6))
*(.fini5)
KEEP (*(.fini5))
*(.fini4)
KEEP (*(.fini4))
*(.fini3)
KEEP (*(.fini3))
*(.fini2)
KEEP (*(.fini2))
*(.fini1)
KEEP (*(.fini1))
*(.fini0) /* Infinite loop after program termination. */
KEEP (*(.fini0))
_etext = . ;
} > text
.data : AT (ADDR (.text) + SIZEOF (.text))
{
PROVIDE (__data_start = .) ;
*(.data)
*(.data*)
*(.rodata) /* We need to include .rodata here if gcc is used */
*(.rodata*) /* with -fdata-sections. */
*(.gnu.linkonce.d*)
. = ALIGN(2);
_edata = . ;
PROVIDE (__data_end = .) ;
} > data
.bss : AT (ADDR (.bss))
{
PROVIDE (__bss_start = .) ;
*(.bss)
*(.bss*)
*(COMMON)
PROVIDE (__bss_end = .) ;
} > data
__data_load_start = LOADADDR(.data);
__data_load_end = __data_load_start + SIZEOF(.data);
/* Global data not cleared after reset. */
.noinit :
{
PROVIDE (__noinit_start = .) ;
*(.noinit*)
PROVIDE (__noinit_end = .) ;
_end = . ;
PROVIDE (__heap_start = .) ;
} > data
/* keymap region is located at end of flash
* .fn_actions Fn actions definitions
* .keymaps Mapping layers
*/
.keymap :
{
PROVIDE(__keymap_start = .) ;
*(.keymap.fn_actions) /* 32*actions = 64bytes */
. = ALIGN(0x40);
*(.keymap.keymaps) /* rest of .keymap section */
*(.keymap*)
/* . = ALIGN(0x800); */ /* keymap section takes 2KB- */
} > keymap = 0x00 /* zero fill */
.eeprom :
{
*(.eeprom*)
__eeprom_end = . ;
} > eeprom
.fuse :
{
KEEP(*(.fuse))
KEEP(*(.lfuse))
KEEP(*(.hfuse))
KEEP(*(.efuse))
} > fuse
.lock :
{
KEEP(*(.lock*))
} > lock
.signature :
{
KEEP(*(.signature*))
} > signature
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
}

@ -1,4 +1,4 @@
/* /*
* linker script for configurable keymap * linker script for configurable keymap
* *
* This adds keymap section which places keymap at fixed address and * This adds keymap section which places keymap at fixed address and
@ -8,7 +8,7 @@ OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:5) OUTPUT_ARCH(avr:5)
MEMORY MEMORY
{ {
/* With keymap section /* With keymap section
* *
* Flash Map of ATMega32U4(32KB) * Flash Map of ATMega32U4(32KB)
* +------------+ 0x0000 * +------------+ 0x0000
@ -212,7 +212,7 @@ SECTIONS
{ {
PROVIDE(__keymap_start = .) ; PROVIDE(__keymap_start = .) ;
*(.keymap.fn_actions) /* 32*actions = 64bytes */ *(.keymap.fn_actions) /* 32*actions = 64bytes */
. = ALIGN(0x40); . = ALIGN(0x40);
*(.keymap.keymaps) /* rest of .keymap section */ *(.keymap.keymaps) /* rest of .keymap section */
*(.keymap*) *(.keymap*)
/* . = ALIGN(0x800); */ /* keymap section takes 2KB- */ /* . = ALIGN(0x800); */ /* keymap section takes 2KB- */

@ -21,9 +21,10 @@ uint8_t ibm4704_error = 0;
void ibm4704_init(void) void ibm4704_init(void)
{ {
inhibit(); // keep keyboard from sending
IBM4704_INT_INIT(); IBM4704_INT_INIT();
IBM4704_INT_ON(); IBM4704_INT_ON();
idle(); idle(); // allow keyboard sending
} }
/* /*
@ -104,51 +105,44 @@ uint8_t ibm4704_recv_response(void)
return rbuf_dequeue(); return rbuf_dequeue();
} }
uint8_t ibm4704_recv(void)
{
if (rbuf_has_data()) {
return rbuf_dequeue();
} else {
return -1;
}
}
/* /*
Keyboard to Host Keyboard to Host
---------------- ----------------
Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part. Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part.
____ __ __ __ __ __ __ __ __ __ ________ ____ __ __ __ __ __ __ __ __ __ _______
Clock \____/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ Clock \_____/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____
Data ____/ X____X____X____X____X____X____X____X____X____X________ Data ____/ X____X____X____X____X____X____X____X____X____X________
Start 0 1 2 3 4 5 6 7 P Stop Start 0 1 2 3 4 5 6 7 P Stop
Start bit: can be long as 300-350us. Start bit: can be long as 300-350us.
Inhibit: Pull Data line down to inhibit keyboard to send. Inhibit: Pull Data line down to inhibit keyboard to send.
Timing: Host reads bit while Clock is hi. Timing: Host reads bit while Clock is hi.(rising edge)
Stop bit: Keyboard pulls down Data line to lo after 9th clock. Stop bit: Keyboard pulls down Data line to lo after 9th clock.
*/ */
uint8_t ibm4704_recv(void)
{
if (rbuf_has_data()) {
return rbuf_dequeue();
} else {
return -1;
}
}
ISR(IBM4704_INT_VECT) ISR(IBM4704_INT_VECT)
{ {
static enum { static enum {
INIT, START, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, PARITY, BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, PARITY, STOP
} state = INIT; } state = BIT0;
// LSB first // LSB first
static uint8_t data = 0; static uint8_t data = 0;
// Odd parity // Odd parity
static uint8_t parity = false; static uint8_t parity = false;
ibm4704_error = 0; ibm4704_error = 0;
// return unless falling edge
if (clock_in()) { goto RETURN; } // why this occurs?
state++;
switch (state) { switch (state) {
case START:
// Data:Low
WAIT(data_hi, 10, state);
break;
case BIT0: case BIT0:
case BIT1: case BIT1:
case BIT2: case BIT2:
@ -169,6 +163,10 @@ ISR(IBM4704_INT_VECT)
} }
if (!parity) if (!parity)
goto ERROR; goto ERROR;
break;
case STOP:
// Data:Low
WAIT(data_lo, 100, state);
rbuf_enqueue(data); rbuf_enqueue(data);
ibm4704_error = IBM4704_ERR_NONE; ibm4704_error = IBM4704_ERR_NONE;
goto DONE; goto DONE;
@ -176,13 +174,14 @@ ISR(IBM4704_INT_VECT)
default: default:
goto ERROR; goto ERROR;
} }
state++;
goto RETURN; goto RETURN;
ERROR: ERROR:
ibm4704_error = state; ibm4704_error = state;
while (ibm4704_send(0xFE)) _delay_ms(1); // resend while (ibm4704_send(0xFE)) _delay_ms(1); // resend
xprintf("R:%02X%02X\n", state, data); xprintf("R:%02X%02X\n", state, data);
DONE: DONE:
state = INIT; state = BIT0;
data = 0; data = 0;
parity = false; parity = false;
RETURN: RETURN:

@ -53,6 +53,7 @@
#include "lufa.h" #include "lufa.h"
uint8_t keyboard_idle = 0; uint8_t keyboard_idle = 0;
/* 0: Boot Protocol, 1: Report Protocol(default) */
uint8_t keyboard_protocol = 1; uint8_t keyboard_protocol = 1;
static uint8_t keyboard_led_stats = 0; static uint8_t keyboard_led_stats = 0;
@ -179,7 +180,6 @@ void EVENT_USB_Device_Reset(void)
void EVENT_USB_Device_Suspend() void EVENT_USB_Device_Suspend()
{ {
print("[S]"); print("[S]");
matrix_power_down();
#ifdef SLEEP_LED_ENABLE #ifdef SLEEP_LED_ENABLE
sleep_led_enable(); sleep_led_enable();
#endif #endif
@ -197,13 +197,30 @@ void EVENT_USB_Device_WakeUp()
#endif #endif
} }
#ifdef CONSOLE_ENABLE
static bool console_flush = false;
#define CONSOLE_FLUSH_SET(b) do { \
uint8_t sreg = SREG; cli(); console_flush = b; SREG = sreg; \
} while (0)
// called every 1ms
void EVENT_USB_Device_StartOfFrame(void) void EVENT_USB_Device_StartOfFrame(void)
{ {
static uint8_t count;
if (++count % 50) return;
count = 0;
if (!console_flush) return;
Console_Task(); Console_Task();
console_flush = false;
} }
#endif
/** Event handler for the USB_ConfigurationChanged event. /** Event handler for the USB_ConfigurationChanged event.
* This is fired when the host sets the current configuration of the USB device after enumeration. * This is fired when the host sets the current configuration of the USB device after enumeration.
*
* ATMega32u2 supports dual bank(ping-pong mode) only on endpoint 3 and 4,
* it is safe to use singl bank for all endpoints.
*/ */
void EVENT_USB_Device_ConfigurationChanged(void) void EVENT_USB_Device_ConfigurationChanged(void)
{ {
@ -228,7 +245,7 @@ void EVENT_USB_Device_ConfigurationChanged(void)
#ifdef CONSOLE_ENABLE #ifdef CONSOLE_ENABLE
/* Setup Console HID Report Endpoints */ /* Setup Console HID Report Endpoints */
ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
CONSOLE_EPSIZE, ENDPOINT_BANK_DOUBLE); CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
#if 0 #if 0
ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT, ConfigSuccess &= ENDPOINT_CONFIG(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT,
CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE); CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE);
@ -333,10 +350,7 @@ void EVENT_USB_Device_ControlRequest(void)
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
keyboard_protocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00); keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
#ifdef NKRO_ENABLE
keyboard_nkro = !!keyboard_protocol;
#endif
clear_keyboard(); clear_keyboard();
} }
} }
@ -383,7 +397,7 @@ static void send_keyboard(report_keyboard_t *report)
/* Select the Keyboard Report Endpoint */ /* Select the Keyboard Report Endpoint */
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
if (keyboard_nkro) { if (keyboard_protocol && keyboard_nkro) {
/* Report protocol - NKRO */ /* Report protocol - NKRO */
Endpoint_SelectEndpoint(NKRO_IN_EPNUM); Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
@ -491,6 +505,10 @@ int8_t sendchar(uint8_t c)
// Because sendchar() is called so many times, waiting each call causes big lag. // Because sendchar() is called so many times, waiting each call causes big lag.
static bool timeouted = false; static bool timeouted = false;
// prevents Console_Task() from running during sendchar() runs.
// or char will be lost. These two function is mutually exclusive.
CONSOLE_FLUSH_SET(false);
if (USB_DeviceState != DEVICE_STATE_Configured) if (USB_DeviceState != DEVICE_STATE_Configured)
return -1; return -1;
@ -524,8 +542,12 @@ int8_t sendchar(uint8_t c)
Endpoint_Write_8(c); Endpoint_Write_8(c);
// send when bank is full // send when bank is full
if (!Endpoint_IsReadWriteAllowed()) if (!Endpoint_IsReadWriteAllowed()) {
while (!(Endpoint_IsINReady()));
Endpoint_ClearIN(); Endpoint_ClearIN();
} else {
CONSOLE_FLUSH_SET(true);
}
Endpoint_SelectEndpoint(ep); Endpoint_SelectEndpoint(ep);
return 0; return 0;
@ -544,7 +566,7 @@ int8_t sendchar(uint8_t c)
/******************************************************************************* /*******************************************************************************
* main * main
******************************************************************************/ ******************************************************************************/
static void SetupHardware(void) static void setup_mcu(void)
{ {
/* Disable watchdog if enabled by bootloader/fuses */ /* Disable watchdog if enabled by bootloader/fuses */
MCUSR &= ~(1 << WDRF); MCUSR &= ~(1 << WDRF);
@ -552,7 +574,10 @@ static void SetupHardware(void)
/* Disable clock division */ /* Disable clock division */
clock_prescale_set(clock_div_1); clock_prescale_set(clock_div_1);
}
static void setup_usb(void)
{
// Leonardo needs. Without this USB device is not recognized. // Leonardo needs. Without this USB device is not recognized.
USB_Disable(); USB_Disable();
@ -566,7 +591,9 @@ static void SetupHardware(void)
int main(void) __attribute__ ((weak)); int main(void) __attribute__ ((weak));
int main(void) int main(void)
{ {
SetupHardware(); setup_mcu();
keyboard_setup();
setup_usb();
sei(); sei();
/* wait for USB startup & debug output */ /* wait for USB startup & debug output */

@ -59,10 +59,16 @@ static inline void query(void);
static inline void reset(void); static inline void reset(void);
static inline uint32_t response(void); static inline uint32_t response(void);
#define out_hi_delay(intervals) do { out_hi(); _delay_us(NEXT_KBD_TIMING * intervals); } while (0); /* The keyboard sends signal with 50us pulse width on OUT line
#define out_lo_delay(intervals) do { out_lo(); _delay_us(NEXT_KBD_TIMING * intervals); } while (0); * while it seems to miss the 50us pulse on In line.
#define query_delay(intervals) do { query(); _delay_us(NEXT_KBD_TIMING * intervals); } while (0); * next_kbd_set_leds() often fails to sync LED status with 50us
#define reset_delay(intervals) do { reset(); _delay_us(NEXT_KBD_TIMING * intervals); } while (0); * but it works well with 51us(+1us) on TMK converter(ATMeaga32u2) at least.
* TODO: test on Teensy and Pro Micro configuration
*/
#define out_hi_delay(intervals) do { out_hi(); _delay_us((NEXT_KBD_TIMING+1) * intervals); } while (0);
#define out_lo_delay(intervals) do { out_lo(); _delay_us((NEXT_KBD_TIMING+1) * intervals); } while (0);
#define query_delay(intervals) do { query(); _delay_us((NEXT_KBD_TIMING+1) * intervals); } while (0);
#define reset_delay(intervals) do { reset(); _delay_us((NEXT_KBD_TIMING+1) * intervals); } while (0);
void next_kbd_init(void) void next_kbd_init(void)
{ {
@ -79,6 +85,7 @@ void next_kbd_init(void)
void next_kbd_set_leds(bool left, bool right) void next_kbd_set_leds(bool left, bool right)
{ {
cli();
out_lo_delay(9); out_lo_delay(9);
out_hi_delay(3); out_hi_delay(3);
@ -98,6 +105,7 @@ void next_kbd_set_leds(bool left, bool right)
out_lo_delay(7); out_lo_delay(7);
out_hi(); out_hi();
sei();
} }
#define NEXT_KBD_READ (NEXT_KBD_IN_PIN&(1<<NEXT_KBD_IN_BIT)) #define NEXT_KBD_READ (NEXT_KBD_IN_PIN&(1<<NEXT_KBD_IN_BIT))

@ -46,6 +46,8 @@ int main(void)
// set for 16 MHz clock // set for 16 MHz clock
CPU_PRESCALE(0); CPU_PRESCALE(0);
keyboard_setup();
// Initialize the USB, and then wait for the host to set configuration. // Initialize the USB, and then wait for the host to set configuration.
// If the Teensy is powered without a PC connected to the USB port, // If the Teensy is powered without a PC connected to the USB port,
// this will wait forever. // this will wait forever.

@ -1 +0,0 @@
Subproject commit 94c560c854c7a1dfc35e9de9db05de1b202de6c6

@ -1 +0,0 @@
Subproject commit c30fcdf1f112de581de7b145a97630539e5cff44

@ -1 +0,0 @@
Subproject commit 77762338286535dabb9c94b87060e33e487ff0f3

@ -1 +0,0 @@
Subproject commit 77b033420485f7d3d35430c0e8d4d844aa894834

@ -1,10 +0,0 @@
#ifndef LEONARDO_LED_H
#define LEONARDO_LED_H
// Leonardo "TX" LED for debug
#define LED_TX_INIT (DDRD |= (1<<5))
#define LED_TX_ON (PORTD &= ~(1<<5))
#define LED_TX_OFF (PORTD |= (1<<5))
#define LED_TX_TOGGLE (PORTD ^= (1<<5))
#endif

@ -10,15 +10,24 @@ uint16_t usb_hid_time_stamp;
void KBDReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) void KBDReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
{ {
::memcpy(&usb_hid_keyboard_report, buf, sizeof(report_keyboard_t)); bool is_error = false;
usb_hid_time_stamp = millis(); report_keyboard_t *report = (report_keyboard_t *)buf;
dprintf("KBDReport: %02X %02X", report->mods, report->reserved);
for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
if (IS_ERROR(report->keys[i])) {
is_error = true;
}
dprintf(" %02X", report->keys[i]);
}
dprint("\r\n");
debug("KBDReport: "); // ignore error and not send report to computer
debug_hex(usb_hid_keyboard_report.mods); if (is_error) {
debug(" --"); dprint("Error usage! \r\n");
for (uint8_t i = 0; i < 6; i++) { return;
debug(" ");
debug_hex(usb_hid_keyboard_report.keys[i]);
} }
debug("\r\n");
::memcpy(&usb_hid_keyboard_report, buf, sizeof(report_keyboard_t));
usb_hid_time_stamp = millis();
} }

@ -124,6 +124,7 @@ CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char CFLAGS += -funsigned-char
CFLAGS += -funsigned-bitfields CFLAGS += -funsigned-bitfields
CFLAGS += -ffunction-sections CFLAGS += -ffunction-sections
CFLAGS += -fdata-sections
CFLAGS += -fno-inline-small-functions CFLAGS += -fno-inline-small-functions
CFLAGS += -fpack-struct CFLAGS += -fpack-struct
CFLAGS += -fshort-enums CFLAGS += -fshort-enums

Loading…
Cancel
Save