summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common.mk10
-rw-r--r--common/action.c151
-rw-r--r--common/action.h6
-rw-r--r--common/action_code.h14
-rw-r--r--common/action_oneshot.c21
-rw-r--r--common/action_oneshot.h52
-rw-r--r--common/action_tapping.c39
-rw-r--r--common/action_util.c213
-rw-r--r--common/action_util.h56
-rw-r--r--common/bootloader.c7
-rw-r--r--common/bootmagic.c4
-rw-r--r--common/bootmagic.h40
-rw-r--r--common/command.c47
-rw-r--r--common/host.c150
-rw-r--r--common/host.h17
-rw-r--r--common/keyboard.c3
-rw-r--r--common/keyboard.h19
-rw-r--r--common/keymap.c3
-rw-r--r--common/suspend.c3
-rw-r--r--converter/adb_usb/Makefile108
-rw-r--r--converter/adb_usb/Makefile.blargg (renamed from converter/adb_usb/Makefile.lufa)4
-rw-r--r--converter/adb_usb/Makefile.pjrc63
-rw-r--r--converter/adb_usb/adb_blargg.c216
-rw-r--r--converter/adb_usb/adb_blargg.h38
-rw-r--r--converter/adb_usb/config.h6
-rw-r--r--converter/adb_usb/led.c5
-rw-r--r--converter/adb_usb/matrix.c12
-rw-r--r--converter/m0110_usb/Makefile3
-rw-r--r--converter/m0110_usb/README.md128
-rw-r--r--converter/m0110_usb/config.h12
-rw-r--r--converter/m0110_usb/doc/m0110.jpgbin49360 -> 0 bytes
-rw-r--r--converter/m0110_usb/doc/teensy.jpgbin50081 -> 0 bytes
-rw-r--r--converter/m0110_usb/keymap.c139
-rw-r--r--converter/news_usb/config_pjrc.h6
-rw-r--r--converter/ps2_usb/config.h6
-rw-r--r--doc/keymap.md21
-rw-r--r--keyboard/IIgs/config.h6
-rw-r--r--keyboard/hhkb/Makefile18
-rw-r--r--keyboard/hhkb/config.h3
-rw-r--r--keyboard/hhkb/config_iwrap.h5
-rw-r--r--keyboard/hhkb/config_vusb.h6
-rw-r--r--keyboard/hhkb/keymap.c19
-rw-r--r--ldscript_keymap_avr5.x268
-rw-r--r--protocol/adb.c217
-rw-r--r--protocol/lufa/lufa.c9
-rw-r--r--protocol/m0110.c50
-rw-r--r--protocol/pjrc/main.c3
-rw-r--r--protocol/pjrc/usb.c1
48 files changed, 1516 insertions, 711 deletions
diff --git a/common.mk b/common.mk
index 47d5c852f3..5b70db9499 100644
--- a/common.mk
+++ b/common.mk
@@ -3,9 +3,9 @@ SRC += $(COMMON_DIR)/host.c \
$(COMMON_DIR)/keyboard.c \
$(COMMON_DIR)/action.c \
$(COMMON_DIR)/action_tapping.c \
- $(COMMON_DIR)/action_oneshot.c \
$(COMMON_DIR)/action_macro.c \
$(COMMON_DIR)/action_layer.c \
+ $(COMMON_DIR)/action_util.c \
$(COMMON_DIR)/keymap.c \
$(COMMON_DIR)/timer.c \
$(COMMON_DIR)/print.c \
@@ -68,6 +68,14 @@ ifdef BACKLIGHT_ENABLE
OPT_DEFS += -DBACKLIGHT_ENABLE
endif
+ifdef KEYMAP_SECTION_ENABLE
+ OPT_DEFS += -DKEYMAP_SECTION_ENABLE
+ EXTRALDFLAGS = -Wl,-L$(TOP_DIR),-Tldscript_keymap_avr5.x
+endif
+
+# Version string
+OPT_DEFS += -DVERSION=$(shell (git describe --always --dirty || echo 'unknown') 2> /dev/null)
+
# Search Path
VPATH += $(TOP_DIR)/common
diff --git a/common/action.c b/common/action.c
index 59c6f252dc..f7ae85b941 100644
--- a/common/action.c
+++ b/common/action.c
@@ -23,8 +23,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "backlight.h"
#include "action_layer.h"
#include "action_tapping.h"
-#include "action_oneshot.h"
#include "action_macro.h"
+#include "action_util.h"
#include "action.h"
#ifdef DEBUG_ACTION
@@ -79,15 +79,15 @@ void process_action(keyrecord_t *record)
action.key.mods<<4;
if (event.pressed) {
if (mods) {
- host_add_mods(mods);
- host_send_keyboard_report();
+ add_weak_mods(mods);
+ send_keyboard_report();
}
register_code(action.key.code);
} else {
unregister_code(action.key.code);
if (mods) {
- host_del_mods(mods);
- host_send_keyboard_report();
+ del_weak_mods(mods);
+ send_keyboard_report();
}
}
}
@@ -100,43 +100,30 @@ void process_action(keyrecord_t *record)
action.key.mods<<4;
switch (action.layer_tap.code) {
#ifndef NO_ACTION_ONESHOT
- case 0x00:
+ case MODS_ONESHOT:
// Oneshot modifier
if (event.pressed) {
if (tap_count == 0) {
- dprint("MODS_TAP: Oneshot: add_mods\n");
- add_mods(mods);
+ register_mods(mods);
}
else if (tap_count == 1) {
dprint("MODS_TAP: Oneshot: start\n");
- oneshot_start(mods);
- }
- else if (tap_count == TAPPING_TOGGLE) {
- dprint("MODS_TAP: Oneshot: toggle\n");
- oneshot_toggle();
+ set_oneshot_mods(mods);
}
else {
- dprint("MODS_TAP: Oneshot: cancel&add_mods\n");
- // double tap cancels oneshot and works as normal modifier.
- oneshot_cancel();
- add_mods(mods);
+ register_mods(mods);
}
} else {
if (tap_count == 0) {
- dprint("MODS_TAP: Oneshot: cancel/del_mods\n");
- // cancel oneshot on hold
- oneshot_cancel();
- del_mods(mods);
+ clear_oneshot_mods();
+ unregister_mods(mods);
}
else if (tap_count == 1) {
- dprint("MODS_TAP: Oneshot: del_mods\n");
- // retain Oneshot
- del_mods(mods);
+ // Retain Oneshot mods
}
else {
- dprint("MODS_TAP: Oneshot: del_mods\n");
- // cancel Mods
- del_mods(mods);
+ clear_oneshot_mods();
+ unregister_mods(mods);
}
}
break;
@@ -148,14 +135,14 @@ void process_action(keyrecord_t *record)
dprint("MODS_TAP: Tap: Cancel: add_mods\n");
// ad hoc: set 0 to cancel tap
record->tap.count = 0;
- add_mods(mods);
+ register_mods(mods);
} else {
dprint("MODS_TAP: Tap: register_code\n");
register_code(action.key.code);
}
} else {
dprint("MODS_TAP: No tap: add_mods\n");
- add_mods(mods);
+ register_mods(mods);
}
} else {
if (tap_count > 0) {
@@ -163,7 +150,7 @@ void process_action(keyrecord_t *record)
unregister_code(action.key.code);
} else {
dprint("MODS_TAP: No tap: add_mods\n");
- del_mods(mods);
+ unregister_mods(mods);
}
}
break;
@@ -343,30 +330,30 @@ void register_code(uint8_t code)
// Resync: ignore if caps lock already is on
if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) return;
#endif
- host_add_key(KC_CAPSLOCK);
- host_send_keyboard_report();
- host_del_key(KC_CAPSLOCK);
- host_send_keyboard_report();
+ add_key(KC_CAPSLOCK);
+ send_keyboard_report();
+ del_key(KC_CAPSLOCK);
+ send_keyboard_report();
}
else if (KC_LOCKING_NUM == code) {
#ifdef LOCKING_RESYNC_ENABLE
if (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) return;
#endif
- host_add_key(KC_NUMLOCK);
- host_send_keyboard_report();
- host_del_key(KC_NUMLOCK);
- host_send_keyboard_report();
+ add_key(KC_NUMLOCK);
+ send_keyboard_report();
+ del_key(KC_NUMLOCK);
+ send_keyboard_report();
}
else if (KC_LOCKING_SCROLL == code) {
#ifdef LOCKING_RESYNC_ENABLE
if (host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) return;
#endif
- host_add_key(KC_SCROLLLOCK);
- host_send_keyboard_report();
- host_del_key(KC_SCROLLLOCK);
- host_send_keyboard_report();
+ add_key(KC_SCROLLLOCK);
+ send_keyboard_report();
+ del_key(KC_SCROLLLOCK);
+ send_keyboard_report();
}
#endif
@@ -375,25 +362,28 @@ void register_code(uint8_t code)
if (command_proc(code)) return;
#ifndef NO_ACTION_ONESHOT
+/* TODO: remove
if (oneshot_state.mods && !oneshot_state.disabled) {
- uint8_t tmp_mods = host_get_mods();
- host_add_mods(oneshot_state.mods);
+ uint8_t tmp_mods = get_mods();
+ add_mods(oneshot_state.mods);
- host_add_key(code);
- host_send_keyboard_report();
+ add_key(code);
+ send_keyboard_report();
- host_set_mods(tmp_mods);
+ set_mods(tmp_mods);
+ send_keyboard_report();
oneshot_cancel();
} else
+*/
#endif
{
- host_add_key(code);
- host_send_keyboard_report();
+ add_key(code);
+ send_keyboard_report();
}
}
else if IS_MOD(code) {
- host_add_mods(MOD_BIT(code));
- host_send_keyboard_report();
+ add_mods(MOD_BIT(code));
+ send_keyboard_report();
}
else if IS_SYSTEM(code) {
host_system_send(KEYCODE2SYSTEM(code));
@@ -415,40 +405,40 @@ void unregister_code(uint8_t code)
// Resync: ignore if caps lock already is off
if (!(host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK))) return;
#endif
- host_add_key(KC_CAPSLOCK);
- host_send_keyboard_report();
- host_del_key(KC_CAPSLOCK);
- host_send_keyboard_report();
+ add_key(KC_CAPSLOCK);
+ send_keyboard_report();
+ del_key(KC_CAPSLOCK);
+ send_keyboard_report();
}
else if (KC_LOCKING_NUM == code) {
#ifdef LOCKING_RESYNC_ENABLE
if (!(host_keyboard_leds() & (1<<USB_LED_NUM_LOCK))) return;
#endif
- host_add_key(KC_NUMLOCK);
- host_send_keyboard_report();
- host_del_key(KC_NUMLOCK);
- host_send_keyboard_report();
+ add_key(KC_NUMLOCK);
+ send_keyboard_report();
+ del_key(KC_NUMLOCK);
+ send_keyboard_report();
}
else if (KC_LOCKING_SCROLL == code) {
#ifdef LOCKING_RESYNC_ENABLE
if (!(host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK))) return;
#endif
- host_add_key(KC_SCROLLLOCK);
- host_send_keyboard_report();
- host_del_key(KC_SCROLLLOCK);
- host_send_keyboard_report();
+ add_key(KC_SCROLLLOCK);
+ send_keyboard_report();
+ del_key(KC_SCROLLLOCK);
+ send_keyboard_report();
}
#endif
else if IS_KEY(code) {
- host_del_key(code);
- host_send_keyboard_report();
+ del_key(code);
+ send_keyboard_report();
}
else if IS_MOD(code) {
- host_del_mods(MOD_BIT(code));
- host_send_keyboard_report();
+ del_mods(MOD_BIT(code));
+ send_keyboard_report();
}
else if IS_SYSTEM(code) {
host_system_send(0);
@@ -458,38 +448,33 @@ void unregister_code(uint8_t code)
}
}
-void add_mods(uint8_t mods)
+void register_mods(uint8_t mods)
{
if (mods) {
- host_add_mods(mods);
- host_send_keyboard_report();
+ add_mods(mods);
+ send_keyboard_report();
}
}
-void del_mods(uint8_t mods)
+void unregister_mods(uint8_t mods)
{
if (mods) {
- host_del_mods(mods);
- host_send_keyboard_report();
+ del_mods(mods);
+ send_keyboard_report();
}
}
-void set_mods(uint8_t mods)
-{
- host_set_mods(mods);
- host_send_keyboard_report();
-}
-
void clear_keyboard(void)
{
- host_clear_mods();
+ clear_mods();
clear_keyboard_but_mods();
}
void clear_keyboard_but_mods(void)
{
- host_clear_keys();
- host_send_keyboard_report();
+ clear_weak_mods();
+ clear_keys();
+ send_keyboard_report();
#ifdef MOUSEKEY_ENABLE
mousekey_clear();
mousekey_send();
@@ -502,7 +487,7 @@ void clear_keyboard_but_mods(void)
bool sending_anykey(void)
{
- return (host_has_anykey() || host_mouse_in_use() ||
+ return (has_anykey() || host_mouse_in_use() ||
host_last_sysytem_report() || host_last_consumer_report());
}
diff --git a/common/action.h b/common/action.h
index 8f1f5b7986..d57f4a86ff 100644
--- a/common/action.h
+++ b/common/action.h
@@ -59,9 +59,9 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
void process_action(keyrecord_t *record);
void register_code(uint8_t code);
void unregister_code(uint8_t code);
-void add_mods(uint8_t mods);
-void del_mods(uint8_t mods);
-void set_mods(uint8_t mods);
+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);
bool sending_anykey(void);
diff --git a/common/action_code.h b/common/action_code.h
index 45e974a668..c153838f2b 100644
--- a/common/action_code.h
+++ b/common/action_code.h
@@ -29,13 +29,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* 000r|0000|0000 0001 Transparent code
* 000r|0000| keycode Key
* 000r|mods|0000 0000 Modifiers
- * 000r|mods| keycode Key and Modifiers
+ * 000r|mods| keycode Modifiers+Key(Modified key)
* r: Left/Right flag(Left:0, Right:1)
*
* ACT_MODS_TAP(001r):
* 001r|mods|0000 0000 Modifiers with OneShot
* 001r|mods|0000 00xx (reserved)
- * 001r|mods| keycode Modifiers with Tap Key
+ * 001r|mods| keycode Modifiers with Tap Key(Dual role)
*
*
* Other Keys(01xx)
@@ -69,7 +69,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* 1001|oopp|BBBB BBBB 8-bit Bitwise Operation???
*
* ACT_LAYER_TAP(101x):
- * 101E|LLLL| keycode Invert with tap key
+ * 101E|LLLL| keycode On/Off with tap key
* 101E|LLLL|1110 xxxx Reserved(0xE0-EF)
* 101E|LLLL|1111 0000 Invert with tap toggle(0xF0)
* 101E|LLLL|1111 0001 On/Off
@@ -207,10 +207,10 @@ enum mods_codes {
MODS_ONESHOT = 0x00,
};
#define ACTION_KEY(key) ACTION(ACT_MODS, (key))
-#define ACTION_MODS(mods) ACTION(ACT_MODS, (mods)<<8 | 0)
-#define ACTION_MODS_KEY(mods, key) ACTION(ACT_MODS, (mods)<<8 | (key))
-#define ACTION_MODS_TAP_KEY(mods, key) ACTION(ACT_MODS_TAP, (mods)<<8 | (key))
-#define ACTION_MODS_ONESHOT(mods) ACTION(ACT_MODS_TAP, (mods)<<8 | MODS_ONESHOT)
+#define ACTION_MODS(mods) ACTION(ACT_MODS, (mods&0x1f)<<8 | 0)
+#define ACTION_MODS_KEY(mods, key) ACTION(ACT_MODS, (mods&0x1f)<<8 | (key))
+#define ACTION_MODS_TAP_KEY(mods, key) ACTION(ACT_MODS_TAP, (mods&0x1f)<<8 | (key))
+#define ACTION_MODS_ONESHOT(mods) ACTION(ACT_MODS_TAP, (mods&0x1f)<<8 | MODS_ONESHOT)
/*
diff --git a/common/action_oneshot.c b/common/action_oneshot.c
deleted file mode 100644
index d34f44b5ab..0000000000
--- a/common/action_oneshot.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#include "action_oneshot.h"
-
-
-#ifndef NO_ACTION_ONESHOT
-oneshot_state_t oneshot_state;
-
-void oneshot_start(uint8_t mods)
-{
- oneshot_state.mods = mods;
-}
-
-void oneshot_cancel(void)
-{
- oneshot_state.mods = 0;
-}
-
-void oneshot_toggle(void)
-{
- oneshot_state.disabled = !oneshot_state.disabled;
-}
-#endif
diff --git a/common/action_oneshot.h b/common/action_oneshot.h
deleted file mode 100644
index 36ef9e9bce..0000000000
--- a/common/action_oneshot.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
-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_ONESHOT_H
-#define ACTION_ONESHOT_H
-
-#include <stdint.h>
-#include <stdbool.h>
-
-#ifdef NO_ACTION_TAPPING
- #define NO_ACTION_ONESHOT
-#endif
-
-#ifndef NO_ACTION_ONESHOT
-/* Oneshot modifier
- *
- * Problem: Want to capitalize like 'The' but the result tends to be 'THe'.
- * Solution: Oneshot modifier have its effect on only one key coming next.
- * Tap Shift, then type 't', 'h' and 'e'. Not need to hold Shift key.
- *
- * Hold: works as normal modifier.
- * Tap: one shot modifier.
- * 2 Tap: cancel one shot modifier.
- * 5-Tap: toggles enable/disable oneshot feature.
- */
-typedef struct {
- uint8_t mods;
- bool disabled;
-} oneshot_state_t;
-
-
-oneshot_state_t oneshot_state;
-
-void oneshot_start(uint8_t mods);
-void oneshot_cancel(void);
-void oneshot_toggle(void);
-#endif
-
-#endif
diff --git a/common/action_tapping.c b/common/action_tapping.c
index a6292535ed..826c233096 100644
--- a/common/action_tapping.c
+++ b/common/action_tapping.c
@@ -1,7 +1,9 @@
#include <stdint.h>
#include <stdbool.h>
#include "action.h"
+#include "action_layer.h"
#include "action_tapping.h"
+#include "keycode.h"
#include "timer.h"
#ifdef DEBUG_ACTION
@@ -27,9 +29,7 @@ static uint8_t waiting_buffer_tail = 0;
static bool process_tapping(keyrecord_t *record);
static bool waiting_buffer_enq(keyrecord_t record);
static void waiting_buffer_clear(void);
-#if TAPPING_TERM >= 500
static bool waiting_buffer_typed(keyevent_t event);
-#endif
static bool waiting_buffer_has_anykey_pressed(void);
static void waiting_buffer_scan_tap(void);
static void debug_tapping_key(void);
@@ -97,18 +97,43 @@ bool process_tapping(keyrecord_t *keyp)
return false;
}
#if TAPPING_TERM >= 500
- /* This can settle mod/fn state fast but may prevent from typing fast. */
- else if (!event.pressed && waiting_buffer_typed(event)) {
- // other key typed. not tap.
+ /* Process a key typed within TAPPING_TERM
+ * This can register the key before settlement of tapping,
+ * useful for long TAPPING_TERM but may prevent fast typing.
+ */
+ else if (IS_RELEASED(event) && waiting_buffer_typed(event)) {
debug("Tapping: End. No tap. Interfered by typing key\n");
process_action(&tapping_key);
tapping_key = (keyrecord_t){};
debug_tapping_key();
-
// enqueue
return false;
}
#endif
+ /* Process release event of a key pressed before tapping starts
+ * Without this unexpected repeating will occur with having fast repeating setting
+ * https://github.com/tmk/tmk_keyboard/issues/60
+ */
+ else if (IS_RELEASED(event) && !waiting_buffer_typed(event)) {
+ // Modifier should be retained till end of this tapping.
+ action_t action = layer_switch_get_action(event.key);
+ switch (action.kind.id) {
+ case ACT_LMODS:
+ case ACT_RMODS:
+ if (action.key.mods && !action.key.code) return false;
+ if (IS_MOD(action.key.code)) return false;
+ break;
+ case ACT_LMODS_TAP:
+ case ACT_RMODS_TAP:
+ if (action.key.mods && keyp->tap.count == 0) return false;
+ if (IS_MOD(action.key.code)) return false;
+ break;
+ }
+ // Release of key should be process immediately.
+ debug("Tapping: release event of a key pressed before tapping\n");
+ process_action(keyp);
+ return true;
+ }
else {
// set interrupted flag when other key preesed during tapping
if (event.pressed) {
@@ -289,7 +314,6 @@ void waiting_buffer_clear(void)
waiting_buffer_tail = 0;
}
-#if TAPPING_TERM >= 500
bool waiting_buffer_typed(keyevent_t event)
{
for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
@@ -299,7 +323,6 @@ bool waiting_buffer_typed(keyevent_t event)
}
return false;
}
-#endif
bool waiting_buffer_has_anykey_pressed(void)
{
diff --git a/common/action_util.c b/common/action_util.c
new file mode 100644
index 0000000000..99a3adaab6
--- /dev/null
+++ b/common/action_util.c
@@ -0,0 +1,213 @@
+/*
+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 "host.h"
+#include "report.h"
+#include "debug.h"
+#include "action_util.h"
+#include "timer.h"
+
+static inline void add_key_byte(uint8_t code);
+static inline void del_key_byte(uint8_t code);
+#ifdef NKRO_ENABLE
+static inline void add_key_bit(uint8_t code);
+static inline void del_key_bit(uint8_t code);
+#endif
+
+static uint8_t real_mods = 0;
+static uint8_t weak_mods = 0;
+
+
+// TODO: pointer variable is not needed
+//report_keyboard_t keyboard_report = {};
+report_keyboard_t *keyboard_report = &(report_keyboard_t){};
+
+#ifndef NO_ACTION_ONESHOT
+static int8_t oneshot_mods = 0;
+#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
+static int16_t oneshot_time = 0;
+#endif
+#endif
+
+
+void send_keyboard_report(void) {
+ keyboard_report->mods = real_mods;
+ keyboard_report->mods |= weak_mods;
+#ifndef NO_ACTION_ONESHOT
+ if (oneshot_mods) {
+#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
+ if (TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT) {
+ dprintf("Oneshot: timeout\n");
+ clear_oneshot_mods();
+ }
+#endif
+ keyboard_report->mods |= oneshot_mods;
+ if (has_anykey()) {
+ clear_oneshot_mods();
+ }
+ }
+#endif
+ host_keyboard_send(keyboard_report);
+}
+
+/* key */
+void add_key(uint8_t key)
+{
+#ifdef NKRO_ENABLE
+ if (keyboard_nkro) {
+ add_key_bit(key);
+ return;
+ }
+#endif
+ add_key_byte(key);
+}
+
+void del_key(uint8_t key)
+{
+#ifdef NKRO_ENABLE
+ if (keyboard_nkro) {
+ del_key_bit(key);
+ return;
+ }
+#endif
+ del_key_byte(key);
+}
+
+void clear_keys(void)
+{
+ // not clear mods
+ for (int8_t i = 1; i < REPORT_SIZE; i++) {
+ keyboard_report->raw[i] = 0;
+ }
+}
+
+
+/* modifier */
+uint8_t get_mods(void) { return real_mods; }
+void add_mods(uint8_t mods) { real_mods |= mods; }
+void del_mods(uint8_t mods) { real_mods &= ~mods; }
+void set_mods(uint8_t mods) { real_mods = mods; }
+void clear_mods(void) { real_mods = 0; }
+
+/* weak modifier */
+uint8_t get_weak_mods(void) { return weak_mods; }
+void add_weak_mods(uint8_t mods) { weak_mods |= mods; }
+void del_weak_mods(uint8_t mods) { weak_mods &= ~mods; }
+void set_weak_mods(uint8_t mods) { weak_mods = mods; }
+void clear_weak_mods(void) { weak_mods = 0; }
+
+/* Oneshot modifier */
+#ifndef NO_ACTION_ONESHOT
+void set_oneshot_mods(uint8_t mods)
+{
+ oneshot_mods = mods;
+#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
+ oneshot_time = timer_read();
+#endif
+}
+void clear_oneshot_mods(void)
+{
+ oneshot_mods = 0;
+#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
+ oneshot_time = 0;
+#endif
+}
+#endif
+
+
+
+
+/*
+ * inspect keyboard state
+ */
+uint8_t has_anykey(void)
+{
+ uint8_t cnt = 0;
+ for (uint8_t i = 1; i < REPORT_SIZE; i++) {
+ if (keyboard_report->raw[i])
+ cnt++;
+ }
+ return cnt;
+}
+
+uint8_t has_anymod(void)
+{
+ return bitpop(real_mods);
+}
+
+uint8_t get_first_key(void)
+{
+#ifdef NKRO_ENABLE
+ if (keyboard_nkro) {
+ uint8_t i = 0;
+ for (; i < REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
+ ;
+ return i<<3 | biton(keyboard_report->nkro.bits[i]);
+ }
+#endif
+ return keyboard_report->keys[0];
+}
+
+
+
+/* local functions */
+static inline void add_key_byte(uint8_t code)
+{
+ int8_t i = 0;
+ int8_t empty = -1;
+ for (; i < REPORT_KEYS; i++) {
+ if (keyboard_report->keys[i] == code) {
+ break;
+ }
+ if (empty == -1 && keyboard_report->keys[i] == 0) {
+ empty = i;
+ }
+ }
+ if (i == REPORT_KEYS) {
+ if (empty != -1) {
+ keyboard_report->keys[empty] = code;
+ }
+ }
+}
+
+static inline void del_key_byte(uint8_t code)
+{
+ for (uint8_t i = 0; i < REPORT_KEYS; i++) {
+ if (keyboard_report->keys[i] == code) {
+ keyboard_report->keys[i] = 0;
+ }
+ }
+}
+
+#ifdef NKRO_ENABLE
+static inline void add_key_bit(uint8_t code)
+{
+ if ((code>>3) < REPORT_BITS) {
+ keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
+ } else {
+ dprintf("add_key_bit: can't add: %02X\n", code);
+ }
+}
+
+static inline void del_key_bit(uint8_t code)
+{
+ if ((code>>3) < REPORT_BITS) {
+ keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
+ } else {
+ dprintf("del_key_bit: can't del: %02X\n", code);
+ }
+}
+#endif
diff --git a/common/action_util.h b/common/action_util.h
new file mode 100644
index 0000000000..939bc2b662
--- /dev/null
+++ b/common/action_util.h
@@ -0,0 +1,56 @@
+/*
+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>
+
+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);
+#endif
diff --git a/common/bootloader.c b/common/bootloader.c
index 43a7e47ce2..cda295b181 100644
--- a/common/bootloader.c
+++ b/common/bootloader.c
@@ -71,7 +71,8 @@ void bootloader_jump_after_watchdog_reset(void)
MCUSR &= ~(1<<WDRF);
wdt_disable();
- ((void (*)(void))BOOTLOADER_START)();
+ // This is compled into 'icall', address should be in word unit, not byte.
+ ((void (*)(void))(BOOTLOADER_START/2))();
}
}
@@ -141,7 +142,7 @@ void bootloader_jump(void) {
ADCSRA = 0; TWCR = 0; UCSR0B = 0;
#endif
- // start Bootloader
- ((void (*)(void))BOOTLOADER_START)();
+ // This is compled into 'icall', address should be in word unit, not byte.
+ ((void (*)(void))(BOOTLOADER_START/2))();
}
#endif
diff --git a/common/bootmagic.c b/common/bootmagic.c
index 410dc68364..036d490440 100644
--- a/common/bootmagic.c
+++ b/common/bootmagic.c
@@ -18,8 +18,10 @@ void bootmagic(void)
}
/* 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)) {
@@ -53,7 +55,7 @@ void bootmagic(void)
/* keymap config */
keymap_config.raw = eeconfig_read_keymap();
- if (bootmagic_scan_keycode(BOOTMAGIC_KEY_SWAP_CONTROL_CPASLOCK)) {
+ 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)) {
diff --git a/common/bootmagic.h b/common/bootmagic.h
index 2d14b3e763..7c19223973 100644
--- a/common/bootmagic.h
+++ b/common/bootmagic.h
@@ -23,34 +23,72 @@
#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
*/
-#define BOOTMAGIC_KEY_SWAP_CONTROL_CPASLOCK KC_LCTRL
+#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
/*
* 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);
diff --git a/common/command.c b/common/command.c
index 4649e00ab0..f6f2769513 100644
--- a/common/command.c
+++ b/common/command.c
@@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "keyboard.h"
#include "bootloader.h"
#include "action_layer.h"
+#include "action_util.h"
#include "eeconfig.h"
#include "sleep_led.h"
#include "led.h"
@@ -251,10 +252,48 @@ static bool command_common(uint8_t code)
break;
case KC_V: // print version & information
print("\n\n----- Version -----\n");
- print(STR(DESCRIPTION) "\n");
- print(STR(MANUFACTURER) "(" STR(VENDOR_ID) ")/");
- print(STR(PRODUCT) "(" STR(PRODUCT_ID) ") ");
- print("VERSION: " STR(DEVICE_VER) "\n");
+ print("DESC: " STR(DESCRIPTION) "\n");
+ print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") "
+ "PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
+ "VER: " STR(DEVICE_VER) "\n");
+ print("BUILD: " STR(VERSION) " (" __TIME__ " " __DATE__ ")\n");
+ /* build options */
+ print("OPTIONS:"
+#ifdef PROTOCOL_PJRC
+ " PJRC"
+#endif
+#ifdef PROTOCOL_LUFA
+ " LUFA"
+#endif
+#ifdef PROTOCOL_VUSB
+ " VUSB"
+#endif
+#ifdef BOOTMAGIC_ENABLE
+ " BOOTMAGIC"
+#endif
+#ifdef MOUSEKEY_ENABLE
+ " MOUSEKEY"
+#endif
+#ifdef EXTRAKEY_ENABLE
+ " EXTRAKEY"
+#endif
+#ifdef CONSOLE_ENABLE
+ " CONSOLE"
+#endif
+#ifdef COMMAND_ENABLE
+ " COMMAND"
+#endif
+#ifdef NKRO_ENABLE
+ " NKRO"
+#endif
+#ifdef KEYMAP_SECTION_ENABLE
+ " KEYMAP_SECTION"
+#endif
+ " " STR(BOOTLOADER_SIZE) "\n");
+
+ print("GCC: " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__)
+ " AVR-LIBC: " __AVR_LIBC_VERSION_STRING__
+ " AVR_ARCH: avr" STR(__AVR_ARCH__) "\n");
break;
case KC_T: // print timer
print_val_hex32(timer_count);
diff --git a/common/host.c b/common/host.c
index 5694516527..0703dba013 100644
--- a/common/host.c
+++ b/common/host.c
@@ -27,7 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
bool keyboard_nkro = false;
#endif
-report_keyboard_t *keyboard_report = &(report_keyboard_t){};
report_mouse_t mouse_report = {};
@@ -35,13 +34,6 @@ static host_driver_t *driver;
static uint16_t last_system_report = 0;
static uint16_t last_consumer_report = 0;
-static inline void add_key_byte(uint8_t code);
-static inline void del_key_byte(uint8_t code);
-#ifdef NKRO_ENABLE
-static inline void add_key_bit(uint8_t code);
-static inline void del_key_bit(uint8_t code);
-#endif
-
void host_set_driver(host_driver_t *d)
{
@@ -67,7 +59,7 @@ void host_keyboard_send(report_keyboard_t *report)
if (debug_keyboard) {
dprint("keyboard_report: ");
for (uint8_t i = 0; i < REPORT_SIZE; i++) {
- dprintf("%02X ", keyboard_report->raw[i]);
+ dprintf("%02X ", report->raw[i]);
}
dprint("\n");
}
@@ -97,98 +89,6 @@ void host_consumer_send(uint16_t report)
(*driver->send_consumer)(report);
}
-
-
-/* keyboard report utils */
-void host_add_key(uint8_t key)
-{
-#ifdef NKRO_ENABLE
- if (keyboard_nkro) {
- add_key_bit(key);
- return;
- }
-#endif
- add_key_byte(key);
-}
-
-void host_del_key(uint8_t key)
-{
-#ifdef NKRO_ENABLE
- if (keyboard_nkro) {
- del_key_bit(key);
- return;
- }
-#endif
- del_key_byte(key);
-}
-
-void host_clear_keys(void)
-{
- // not clea mods
- for (int8_t i = 1; i < REPORT_SIZE; i++) {
- keyboard_report->raw[i] = 0;
- }
-}
-
-uint8_t host_get_mods(void)
-{
- return keyboard_report->mods;
-}
-
-void host_add_mods(uint8_t mods)
-{
- keyboard_report->mods |= mods;
-}
-
-void host_del_mods(uint8_t mods)
-{
- keyboard_report->mods &= ~mods;
-}
-
-void host_set_mods(uint8_t mods)
-{
- keyboard_report->mods = mods;
-}
-
-void host_clear_mods(void)
-{
- keyboard_report->mods = 0;
-}
-
-uint8_t host_has_anykey(void)
-{
- uint8_t cnt = 0;
- for (uint8_t i = 1; i < REPORT_SIZE; i++) {
- if (keyboard_report->raw[i])
- cnt++;
- }
- return cnt;
-}
-
-uint8_t host_has_anymod(void)
-{
- return bitpop(keyboard_report->mods);
-}
-
-uint8_t host_get_first_key(void)
-{
-#ifdef NKRO_ENABLE
- if (keyboard_nkro) {
- uint8_t i = 0;
- for (; i < REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
- ;
- return i<<3 | biton(keyboard_report->nkro.bits[i]);
- }
-#endif
- return keyboard_report->keys[0];
-}
-
-void host_send_keyboard_report(void)
-{
- if (!driver) return;
- host_keyboard_send(keyboard_report);
-}
-
uint8_t host_mouse_in_use(void)
{
return (mouse_report.buttons | mouse_report.x | mouse_report.y | mouse_report.v | mouse_report.h);
@@ -203,51 +103,3 @@ uint16_t host_last_consumer_report(void)
{
return last_consumer_report;
}
-
-static inline void add_key_byte(uint8_t code)
-{
- int8_t i = 0;
- int8_t empty = -1;
- for (; i < REPORT_KEYS; i++) {
- if (keyboard_report->keys[i] == code) {
- break;
- }
- if (empty == -1 && keyboard_report->keys[i] == 0) {
- empty = i;
- }
- }
- if (i == REPORT_KEYS) {
- if (empty != -1) {
- keyboard_report->keys[empty] = code;
- }
- }
-}
-
-static inline void del_key_byte(uint8_t code)
-{
- for (uint8_t i = 0; i < REPORT_KEYS; i++) {
- if (keyboard_report->keys[i] == code) {
- keyboard_report->keys[i] = 0;
- }
- }
-}
-
-#ifdef NKRO_ENABLE
-static inline void add_key_bit(uint8_t code)
-{
- if ((code>>3) < REPORT_BITS) {
- keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
- } else {
- dprintf("add_key_bit: can't add: %02X\n", code);
- }
-}
-
-static inline void del_key_bit(uint8_t code)
-{
- if ((code>>3) < REPORT_BITS) {
- keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
- } else {
- dprintf("del_key_bit: can't del: %02X\n", code);
- }
-}
-#endif
diff --git a/common/host.h b/common/host.h
index 7c4f06601d..c1a0fbac40 100644
--- a/common/host.h
+++ b/common/host.h
@@ -33,7 +33,6 @@ extern bool keyboard_nkro;
#endif
/* report */
-extern report_keyboard_t *keyboard_report;
extern report_mouse_t mouse_report;
@@ -48,22 +47,6 @@ void host_mouse_send(report_mouse_t *report);
void host_system_send(uint16_t data);
void host_consumer_send(uint16_t data);
-/* keyboard report utils */
-void host_add_key(uint8_t key);
-void host_del_key(uint8_t key);
-void host_clear_keys(void);
-
-uint8_t host_get_mods(void);
-void host_add_mods(uint8_t mods);
-void host_del_mods(uint8_t mods);
-void host_set_mods(uint8_t mods);
-void host_clear_mods(void);
-
-uint8_t host_has_anykey(void);
-uint8_t host_has_anymod(void);
-uint8_t host_get_first_key(void);
-void host_send_keyboard_report(void);
-
/* mouse report utils */
uint8_t host_mouse_in_use(void);
diff --git a/common/keyboard.c b/common/keyboard.c
index d1821a099f..601e3abe17 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -54,9 +54,6 @@ static bool has_ghost_in_row(uint8_t row)
void keyboard_init(void)
{
- // TODO: configuration of sendchar impl
- print_set_sendchar(sendchar);
-
timer_init();
matrix_init();
#ifdef PS2_MOUSE_ENABLE
diff --git a/common/keyboard.h b/common/keyboard.h
index 78cb24034f..d1a922420b 100644
--- a/common/keyboard.h
+++ b/common/keyboard.h
@@ -42,16 +42,15 @@ typedef struct {
/* equivalent test of key_t */
#define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col)
-/* (time == 0) means no event and assumes matrix has no 255 line. */
-#define IS_NOEVENT(event) ((event).time == 0 || ((event).key.row == 255 && (event).key.col == 255))
-
-#define NOEVENT (keyevent_t){ \
- .key = (key_t){ .row = 255, .col = 255 }, \
- .pressed = false, \
- .time = 0 \
-}
-
-/* tick event */
+/* Rules for No Event:
+ * 1) (time == 0) to handle (keyevent_t){} as empty event
+ * 2) Matrix(255, 255) to make TICK event available
+ */
+static inline bool IS_NOEVENT(keyevent_t event) { return event.time == 0 || (event.key.row == 255 && event.key.col == 255); }
+static inline bool IS_PRESSED(keyevent_t event) { return (!IS_NOEVENT(event) && event.pressed); }
+static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) && !event.pressed); }
+
+/* Tick event */
#define TICK (keyevent_t){ \
.key = (key_t){ .row = 255, .col = 255 }, \
.pressed = false, \
diff --git a/common/keymap.c b/common/keymap.c
index cf4711bf66..bfb8ffac1a 100644
--- a/common/keymap.c
+++ b/common/keymap.c
@@ -36,10 +36,11 @@ action_t action_for_key(uint8_t layer, key_t key)
return keymap_fn_to_action(keycode);
#ifdef BOOTMAGIC_ENABLE
case KC_CAPSLOCK:
+ case KC_LOCKING_CAPS:
if (keymap_config.swap_control_capslock || keymap_config.capslock_to_control) {
return keycode_to_action(KC_LCTL);
}
- return keycode_to_action(KC_CAPS);
+ return keycode_to_action(keycode);
case KC_LCTL:
if (keymap_config.swap_control_capslock) {
return keycode_to_action(KC_CAPSLOCK);
diff --git a/common/suspend.c b/common/suspend.c
index 146b96d5cc..5b378892f3 100644
--- a/common/suspend.c
+++ b/common/suspend.c
@@ -51,8 +51,7 @@ bool suspend_wakeup_condition(void)
// run immediately after wakeup
void suspend_wakeup_init(void)
{
- // clear matrix and keyboard state
- matrix_init();
+ // clear keyboard state
clear_keyboard();
#ifdef BACKLIGHT_ENABLE
backlight_init();
diff --git a/converter/adb_usb/Makefile b/converter/adb_usb/Makefile
index 09f30180a8..372ef6c09a 100644
--- a/converter/adb_usb/Makefile
+++ b/converter/adb_usb/Makefile
@@ -1,5 +1,45 @@
+#----------------------------------------------------------------------------
+# On command line:
+#
+# make all = Make software.
+#
+# make clean = Clean out built project files.
+#
+# make coff = Convert ELF to AVR COFF.
+#
+# make extcoff = Convert ELF to AVR Extended COFF.
+#
+# make program = Download the hex file to the device.
+# Please customize your programmer settings(PROGRAM_CMD)
+#
+# make teensy = Download the hex file to the device, using teensy_loader_cli.
+# (must have teensy_loader_cli installed).
+#
+# make dfu = Download the hex file to the device, using dfu-programmer (must
+# have dfu-programmer installed).
+#
+# make flip = Download the hex file to the device, using Atmel FLIP (must
+# have Atmel FLIP installed).
+#
+# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
+# (must have dfu-programmer installed).
+#
+# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
+# (must have Atmel FLIP installed).
+#
+# make debug = Start either simulavr or avarice as specified for debugging,
+# with avr-gdb or avr-insight as the front end for debugging.
+#
+# make filename.s = Just compile filename.c into the assembler code only.
+#
+# make filename.i = Create a preprocessed source file for use in submitting
+# bug reports to the GCC project.
+#
+# To rebuild project do "make clean" then "make all".
+#----------------------------------------------------------------------------
+
# Target file name (without extension).
-TARGET = adb_usb
+TARGET = adb_usb_lufa
# Directory common source filess exist
TOP_DIR = ../..
@@ -7,7 +47,7 @@ TOP_DIR = ../..
# Directory keyboard dependent files exist
TARGET_DIR = .
-# keyboard dependent files
+# project specific files
SRC = keymap.c \
matrix.c \
led.c \
@@ -16,22 +56,47 @@ SRC = keymap.c \
CONFIG_H = config.h
-# MCU name, you MUST set this to match the board you are using
-# type "make clean" after changing this, so all files will be rebuilt
-#MCU = at90usb162 # Teensy 1.0
-MCU = atmega32u4 # Teensy 2.0
-#MCU = at90usb646 # Teensy++ 1.0
-#MCU = at90usb1286 # Teensy++ 2.0
-
+# MCU name
+#MCU = at90usb1287
+MCU = atmega32u4
# Processor frequency.
-# Normally the first thing your program should do is set the clock prescaler,
-# so your program will run at the correct speed. You should also set this
-# variable to same clock speed. The _delay_ms() macro uses this, and many
-# examples use this variable to calculate timings. Do not add a "UL" here.
+# This will define a symbol, F_CPU, in all source code files equal to the
+# processor frequency in Hz. You can then use this symbol in your source code to
+# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
+# automatically to create a 32-bit value in your source code.
+#
+# This will be an integer division of F_USB below, as it is sourced by
+# F_USB after it has run through any CPU prescalers. Note that this value
+# does not *change* the processor frequency - it should merely be updated to
+# reflect the processor speed set externally so that the code can use accurate
+# software delays.
F_CPU = 16000000
+#
+# LUFA specific
+#
+# Target architecture (see library "Board Types" documentation).
+ARCH = AVR8
+
+# Input clock frequency.
+# This will define a symbol, F_USB, in all source code files equal to the
+# input clock frequency (before any prescaling is performed) in Hz. This value may
+# differ from F_CPU if prescaling is used on the latter, and is required as the
+# raw input clock is fed directly to the PLL sections of the AVR for high speed
+# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
+# at the end, this will be done automatically to create a 32-bit value in your
+# source code.
+#
+# If no clock division is performed on the input clock inside the AVR (via the
+# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
+F_USB = $(F_CPU)
+
+# Interrupt driven control endpoint task(+60)
+#OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
+
+
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
@@ -44,20 +109,23 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# comment out to disable the options.
#
-#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
-#MOUSEKEY_ENABLE = yes # Mouse keys(+5000)
-#EXTRAKEY_ENABLE = yes # Audio control and System control(+600)
-#CONSOLE_ENABLE = yes # Console for debug
-#COMMAND_ENABLE = yes # Commands for debug and configuration
+BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
+MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
+EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
+CONSOLE_ENABLE = yes # Console for debug(+400)
+COMMAND_ENABLE = yes # Commands for debug and configuration
#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
-#NKRO_ENABLE = yes # USB Nkey Rollover(+500)
+#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
+
+# Optimize size but this may cause error "relocation truncated to fit"
+#EXTRALDFLAGS = -Wl,--relax
# Search Path
VPATH += $(TARGET_DIR)
VPATH += $(TOP_DIR)
-include $(TOP_DIR)/protocol/pjrc.mk
+include $(TOP_DIR)/protocol/lufa.mk
include $(TOP_DIR)/protocol.mk
include $(TOP_DIR)/common.mk
include $(TOP_DIR)/rules.mk
diff --git a/converter/adb_usb/Makefile.lufa b/converter/adb_usb/Makefile.blargg
index 372ef6c09a..edce82d695 100644
--- a/converter/adb_usb/Makefile.lufa
+++ b/converter/adb_usb/Makefile.blargg
@@ -39,7 +39,7 @@
#----------------------------------------------------------------------------
# Target file name (without extension).
-TARGET = adb_usb_lufa
+TARGET = adb_usb_blargg
# Directory common source filess exist
TOP_DIR = ../..
@@ -51,7 +51,7 @@ TARGET_DIR = .
SRC = keymap.c \
matrix.c \
led.c \
- adb.c
+ adb_blargg.c
CONFIG_H = config.h
diff --git a/converter/adb_usb/Makefile.pjrc b/converter/adb_usb/Makefile.pjrc
new file mode 100644
index 0000000000..c3a5d8f553
--- /dev/null
+++ b/converter/adb_usb/Makefile.pjrc
@@ -0,0 +1,63 @@
+# Target file name (without extension).
+TARGET = adb_usb_pjrc
+
+# Directory common source filess exist
+TOP_DIR = ../..
+
+# Directory keyboard dependent files exist
+TARGET_DIR = .
+
+# keyboard dependent files
+SRC = keymap.c \
+ matrix.c \
+ led.c \
+ adb.c
+
+CONFIG_H = config.h
+
+
+# MCU name, you MUST set this to match the board you are using
+# type "make clean" after changing this, so all files will be rebuilt
+#MCU = at90usb162 # Teensy 1.0
+MCU = atmega32u4 # Teensy 2.0
+#MCU = at90usb646 # Teensy++ 1.0
+#MCU = at90usb1286 # Teensy++ 2.0
+
+
+# Processor frequency.
+# Normally the first thing your program should do is set the clock prescaler,
+# so your program will run at the correct speed. You should also set this
+# variable to same clock speed. The _delay_ms() macro uses this, and many
+# examples use this variable to calculate timings. Do not add a "UL" here.
+F_CPU = 16000000
+
+
+# Boot Section Size in *bytes*
+# Teensy halfKay 512
+# Teensy++ halfKay 1024
+# Atmel DFU loader 4096
+# LUFA bootloader 4096
+# USBaspLoader 2048
+OPT_DEFS += -DBOOTLOADER_SIZE=4096
+
+
+# Build Options
+# comment out to disable the options.
+#
+BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
+MOUSEKEY_ENABLE = yes # Mouse keys(+5000)
+EXTRAKEY_ENABLE = yes # Audio control and System control(+600)
+CONSOLE_ENABLE = yes # Console for debug
+COMMAND_ENABLE = yes # Commands for debug and configuration
+#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
+#NKRO_ENABLE = yes # USB Nkey Rollover(+500)
+
+
+# Search Path
+VPATH += $(TARGET_DIR)
+VPATH += $(TOP_DIR)
+
+include $(TOP_DIR)/protocol/pjrc.mk
+include $(TOP_DIR)/protocol.mk
+include $(TOP_DIR)/common.mk
+include $(TOP_DIR)/rules.mk
diff --git a/converter/adb_usb/adb_blargg.c b/converter/adb_usb/adb_blargg.c
new file mode 100644
index 0000000000..963758c533
--- /dev/null
+++ b/converter/adb_usb/adb_blargg.c
@@ -0,0 +1,216 @@
+// Bit-banged implementation without any use of interrupts.
+// Data pin must have external 1K pull-up resistor.
+// Operates data pin as open-collector output.
+
+#include "adb_blargg.h"
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <util/delay.h>
+
+// Copyright 2011 Jun WAKO <wakojun@gmail.com>
+// Copyright 2013 Shay Green <gblargg@gmail.com>
+// See bottom of file for license
+
+typedef uint8_t byte;
+
+// Make loop iteration take us total, including cyc overhead of loop logic
+#define delay_loop_usec( us, cyc ) \
+ __builtin_avr_delay_cycles( (unsigned long) (F_CPU / 1e6 * (us) + 0.5) - (cyc) )
+
+#if !defined(ADB_PORT) || \
+ !defined(ADB_PIN) || \
+ !defined(ADB_DDR) || \
+ !defined(ADB_DATA_BIT)
+ #error
+#endif
+
+enum { data_mask = 1<<ADB_DATA_BIT };
+
+enum { adb_cmd_read = 0x2C };
+enum { adb_cmd_write = 0x28 };
+
+// gcc is very unreliable for inlining, so use macros
+#define data_lo() (ADB_DDR |= data_mask)
+#define data_hi() (ADB_DDR &= ~data_mask)
+#define data_in() (ADB_PIN & data_mask)
+
+static void place_bit( byte bit )
+{
+ // 100 us bit cell time
+ data_lo();
+ _delay_us( 35 );
+
+ // Difference between a 0 and 1 bit is just this 30us portion in the middle
+ if ( bit )
+ data_hi();
+ _delay_us( 30 );
+
+ data_hi();
+ _delay_us( 35 );
+}
+
+static void place_bit0( void ) { place_bit( 0 ); }
+static void place_bit1( void ) { place_bit( 1 ); }
+
+static void send_byte( byte data )
+{
+ for ( byte n = 8; n; n-- )
+ {
+ place_bit( data & 0x80 );
+ data <<= 1;
+ }
+}
+
+static void command( byte cmd )
+{
+ data_lo();
+ _delay_us( 800 );
+ place_bit1();
+ send_byte( cmd );
+ place_bit0();
+}
+
+void adb_host_init( void )
+{
+ // Always keep port output 0, then just toggle DDR to be GND or leave it floating (high).
+ ADB_DDR &= ~data_mask;
+ ADB_PORT &= ~data_mask;
+
+ #ifdef ADB_PSW_BIT
+ // Weak pull-up
+ ADB_PORT |= (1<<ADB_PSW_BIT);
+ ADB_DDR &= ~(1<<ADB_PSW_BIT);
+ #endif
+}
+
+bool adb_host_psw( void )
+{
+ #ifdef ADB_PSW_BIT
+ return (ADB_PIN & (1<<ADB_PSW_BIT)) != 0;
+ #else
+ return true;
+ #endif
+}
+
+// Waits while data == val, or until us timeout expires. Returns remaining time,
+// zero if timed out.
+static byte while_data( byte us, byte data )
+{
+ while ( data_in() == data )
+ {
+ delay_loop_usec( 1 /* us period */, 7 /* cycles loop overhead */ );
+ if ( !--us )
+ break;
+ }
+ return us;
+}
+
+static byte while_lo( byte us ) { return while_data( us, 0 ); }
+static byte while_hi( byte us ) { return while_data( us, data_mask ); }
+
+static uint16_t adb_host_talk( byte cmd )
+{
+ command( cmd );
+ _delay_us( 5 );
+ if ( !while_hi( 260 - 5 ) ) // avg 160
+ return adb_host_nothing;
+
+ // Receive start bit and 16 data bits.
+ // Doing them all in loop allows consistent error checking
+ uint16_t data = 0;
+ byte n = 17;
+ do
+ {
+ data <<= 1;
+ enum { timeout = 130 }; // maximum bit cell time
+
+ byte lo = while_lo( timeout );
+ if ( !lo )
+ goto error; // timeout
+
+ byte hi = while_hi( lo );
+ if ( !hi )
+ goto error; // timeout
+
+ if ( timeout-lo < lo-hi )
+ data |= 1;
+ else if ( n == 17 )
+ goto error; // start bit is wrong
+ }
+ while ( --n );
+
+ // duration must be split in two due to 255 limit
+ if ( !while_lo( 255 ) && !while_lo( 351 - 255 ) )
+ goto error;
+
+ if ( while_hi( 91 ) )
+ goto error;
+
+ return data;
+
+error:
+ return adb_host_error;
+}
+
+uint16_t adb_host_kbd_recv( void )
+{
+ return adb_host_talk( adb_cmd_read + 0 );
+}
+
+uint16_t adb_host_kbd_modifiers( void )
+{
+ return adb_host_talk( adb_cmd_read + 2 );
+}
+
+void adb_host_listen( byte cmd, byte data_h, byte data_l )
+{
+ command( cmd );
+ _delay_us( 200 );
+
+ place_bit1();
+ send_byte( data_h );
+ send_byte( data_l );
+ place_bit0();
+}
+
+void adb_host_kbd_led( byte led )
+{
+ adb_host_listen( adb_cmd_write + 2, 0, led & 0x07 );
+}
+
+/* This software is licensed with a Modified BSD License.
+All of this is supposed to be Free Software, Open Source, DFSG-free,
+GPL-compatible, and OK to use in both free and proprietary applications.
+Additions and corrections to this file are welcome.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+* Neither the name of the copyright holders nor the names of
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE. */
diff --git a/converter/adb_usb/adb_blargg.h b/converter/adb_usb/adb_blargg.h
new file mode 100644
index 0000000000..2542cb5496
--- /dev/null
+++ b/converter/adb_usb/adb_blargg.h
@@ -0,0 +1,38 @@
+// Basic support for ADB keyboard
+
+#ifndef ADB_BLARGG_H
+#define ADB_BLARGG_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+// Sets up ADB bus. Doesn't send anything to keyboard.
+void adb_host_init( void );
+
+// Receives key press event from keyboard.
+// 0xKKFF: one key changed state
+// 0xKKKK: two keys changed state
+enum { adb_host_nothing = 0 }; // no keys changed state
+enum { adb_host_error = 0xFFFE }; // receive error
+uint16_t adb_host_kbd_recv( void );
+
+// Current state of keyboard modifiers and a few other keys
+// Returns adb_host_nothing if keyboard didn't respond.
+// Returns adb_host_error if error receiving.
+uint16_t adb_host_kbd_modifiers( void );
+
+// Sends command and two bytes of data to keyboard
+void adb_host_listen( uint8_t cmd, uint8_t data_h, uint8_t data_l );
+
+// Sets keyboard LEDs. Note that bits are inverted here, so 1 means off, 0 means on.
+void adb_host_kbd_led( uint8_t led );
+
+// State of power switch (false = pressed), or true if unsupported
+bool adb_host_psw( void );
+
+
+// Legacy support
+#define ADB_POWER 0x7F
+#define ADB_CAPS 0x39
+
+#endif
diff --git a/converter/adb_usb/config.h b/converter/adb_usb/config.h
index 4ce27bbfeb..5ce5c22159 100644
--- a/converter/adb_usb/config.h
+++ b/converter/adb_usb/config.h
@@ -44,12 +44,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define USE_LEGACY_KEYMAP
-/* mouse keys */
-#ifdef MOUSEKEY_ENABLE
-# define MOUSEKEY_DELAY_TIME 192
-#endif
-
-
/* ADB port setting */
#define ADB_PORT PORTD
#define ADB_PIN PIND
diff --git a/converter/adb_usb/led.c b/converter/adb_usb/led.c
index 0e162f379b..1e7911f942 100644
--- a/converter/adb_usb/led.c
+++ b/converter/adb_usb/led.c
@@ -15,12 +15,15 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "stdint.h"
+#include <stdint.h>
+#include <util/delay.h>
#include "adb.h"
#include "led.h"
void led_set(uint8_t usb_led)
{
+ // need a wait to send command without miss
+ _delay_ms(100);
adb_host_kbd_led(~usb_led);
}
diff --git a/converter/adb_usb/matrix.c b/converter/adb_usb/matrix.c
index a616d10e40..54be2b0f57 100644
--- a/converter/adb_usb/matrix.c
+++ b/converter/adb_usb/matrix.c
@@ -67,6 +67,13 @@ uint8_t matrix_cols(void)
void matrix_init(void)
{
adb_host_init();
+ // wait for keyboard to boot up and receive command
+ _delay_ms(1000);
+ // Enable keyboard left/right modifier distinction
+ // Addr:Keyboard(0010), Cmd:Listen(10), Register3(11)
+ // upper byte: reserved bits 0000, device address 0010
+ // lower byte: device handler 00000011
+ adb_host_listen(0x2B,0x02,0x03);
// initialize matrix state: all keys off
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
@@ -85,6 +92,7 @@ uint8_t matrix_scan(void)
uint8_t key0, key1;
is_modified = false;
+ _delay_ms(12); // delay for preventing overload of poor ADB keyboard controller
codes = adb_host_kbd_recv();
key0 = codes>>8;
key1 = codes&0xFF;
@@ -100,9 +108,7 @@ uint8_t matrix_scan(void)
} else if (codes == 0xFFFF) { // power key release
register_key(0xFF);
} else if (key0 == 0xFF) { // error
- if (debug_matrix) print("adb_host_kbd_recv: ERROR(matrix cleared.)\n");
- // clear matrix to unregister all keys
- for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
+ xprintf("adb_host_kbd_recv: ERROR(%02X)\n", codes);
return key1;
} else {
register_key(key0);
diff --git a/converter/m0110_usb/Makefile b/converter/m0110_usb/Makefile
index 66eae880f4..7791527e43 100644
--- a/converter/m0110_usb/Makefile
+++ b/converter/m0110_usb/Makefile
@@ -71,13 +71,14 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# *Comment out* to disable the options.
#
-#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
+BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = yes # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
+KEYMAP_SECTION_ENABLE = yes # fixed address keymap for keymap editor
diff --git a/converter/m0110_usb/README.md b/converter/m0110_usb/README.md
index bd8bef9f21..b3fb8f7e97 100644
--- a/converter/m0110_usb/README.md
+++ b/converter/m0110_usb/README.md
@@ -1,10 +1,12 @@
M0110/M0110A to USB keyboard converter
======================================
-This firmware converts the protocol of Apple Macintosh keyboard M0110/M0110A into USB.
-Target board of this project is [PJRC Teensy](http://www.pjrc.com/teensy/), though,
-you can use other board with USB AVR like `ATmega32U4` and `AT90USB`.
+This firmware converts the protocol of Apple Macintosh keyboard **M0110**, **M0110A** and **M0120** into USB. Target of this project is USB AVR controller **ATmega32U4**. Using this converter you can revive these retro keyboards with modern computer.
+
+Pics of **M0110 + M0120** and **M0110A**.
+
+![M0110+M0120](http://i.imgur.com/dyvXb2Tm.jpg)
+![M0110A](http://i.imgur.com/HuHOEoHm.jpg)
-![M0110](https://raw.github.com/tmk/tmk_keyboard/master/converter/m0110_usb/doc/m0110.jpg)
- M0110A support was contributed by [skagon@github](https://github.com/skagon).
- M0120 also is supported. keys(+ * / and ,) on M0120 are recognized as cursor keys.
@@ -13,49 +15,42 @@ you can use other board with USB AVR like `ATmega32U4` and `AT90USB`.
Update
------
-- 2013/08 Change port for signals PF to PD
+- 2013/08: Change port for signals `PF` to `PD`
+- 2013/09: Change port again, it uses inversely `PD0` for data and `PD1` for clock line now.
-Connection
-----------
-You need 4P4C plug and cable to connect Teensy or other AVR dev board into the keyboard.
-Teensy port `PD0` is assigned for `CLOCK` line and `PD1` for `DATA` by default,
-you can change pin configuration with editing *config.h*.
+Building Hardware
+-----------------
+You need **4P4C** cable and **ATMega32U4** board like PJRC [Teensy]. Port of the MCU `PD1` is assigned to `CLOCK` line and `PD0` to `DATA` by default, you can change pin configuration with editing `config.h`.
-You can find 4P4C plugs on telephone handset cable. Note that it is *crossover* connection
-while Macintosh keyboard cable is *straight*.
+[![M0110 Converter](http://i.imgur.com/4G2ZOegm.jpg)](http://i.imgur.com/4G2ZOeg.jpg)
-[![Conection](https://raw.github.com/tmk/tmk_keyboard/master/converter/m0110_usb/doc/teensy.jpg)]
+### 4P4C phone handset cable
+Note that original cable used with Mac is **straight** while phone handset cable is **crossover**.
-In this pic:
+<http://en.wikipedia.org/wiki/Modular_connector#4P4C>
-1. `GND`(Black)
-2. `CLOCK`(Red)
-3. `DATA`(Green)
-4. `+5V`(Yellow)
+Close-up pic of handset cable. You can see one end of plug has reverse color codes against the other. Click to enlarge.
+[![4P4C cable](http://i.imgur.com/3S9P1mYm.jpg?1)](http://i.imgur.com/3S9P1mY.jpg?1)
-Note that wire colors may vary in your cable.
+[Teensy]: http://www.pjrc.com/teensy/
-### Pinout
+### Socket Pinout
- <http://pinouts.ru/Inputs/MacKeyboard_pinout.shtml>
-- <http://en.wikipedia.org/wiki/Modular_connector#4P4C>
![Jack fig](http://www.kbdbabel.org/conn/kbd_connector_macplus.png)
### Pull-up Registor
-You may need pull-up registors on signal lines(`CLOCK`, `DATA`) in particular
-when you have long or coiled cable. 1k-10k Ohm will be OK for this purpose.
-In some cases MCU can't read signal from keyboard correctly without pull-up resistors.
+You may need pull-up registors on signal lines(`CLOCK`, `DATA`) in particular when you have long or coiled cable. **1k-10k Ohm** will be OK for this purpose. In that case the converter may not read signal from keyboard correctly without pull-up resistors.
Building Frimware
-----------------
-To compile firmware you need AVR GCC. You can use [WinAVR](http://winavr.sourceforge.net/) on Windows.
-You can edit *Makefile* and *config.h* to change compile options and pin configuration.
+To compile firmware you need AVR GCC. You can edit *Makefile* and *config.h* to change compile options and pin configuration.
$ git clone git://github.com/tmk/tmk_keyboard.git (or download source)
$ cd m0110_usb
@@ -71,64 +66,69 @@ Keymap
You can change keymaps by editing *keymap.c*.
### M0110 & M0120
-#### *Default*
- ,---------------------------------------------------------. ,---------------.
- | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Ctl| -|Lft|Rgt|
- |---------------------------------------------------------| |---------------|
- |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | 7| 8| 9| Up|
- |---------------------------------------------------------| |---------------|
- |Fn0 | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| Dn|
- |---------------------------------------------------------| |---------------|
- |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | | 1| 2| 3| |
- `---------------------------------------------------------' |-----------|Ent|
- |Ctl|Alt | Space |Gui |Ctl| | 0| .| |
- `-----------------------------------------------' `---------------'
-#### *HHKB/WASD Layer(WASD/IJKL)*
- ,---------------------------------------------------------. ,---------------.
- |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk| -|Lft|Rgt|
- |---------------------------------------------------------| |---------------|
- |Caps |Hom| Up|PgU| | | |PgU| Up|Hom|Psc|Slk|Pau|Ins| | 7| 8| 9| Up|
- |---------------------------------------------------------| |---------------|
- |Fn0 |Lef|Dow|Rig| | | |Lef|Dow|Rig| | |Return| | 4| 5| 6| Dn|
- |---------------------------------------------------------| |---------------|
- |Shift |End| |PgD| | | |PgD| |End| |Shift | | 1| 2| 3| |
- `---------------------------------------------------------' |-----------|Ent|
- |Ctl|Alt | Space |Gui |Ctl| | 0| .| |
- `-----------------------------------------------' `---------------'
+#### *Default Layer*
+ ,---------------------------------------------------------. ,---------------.
+ | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Clr| -|Lft|Rgt|
+ |---------------------------------------------------------| |---------------|
+ |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | 7| 8| 9| Up|
+ |---------------------------------------------------------| |---------------|
+ |Caps | A| S| D| F| G| H| J| K| L| ;| '|Enter | | 4| 5| 6| Dn|
+ |---------------------------------------------------------| |---------------|
+ |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | | 1| 2| 3| |
+ `---------------------------------------------------------' |-----------|Ent|
+ |Ctl|Gui | Space |Alt |Ctl| | 0| .| |
+ `-----------------------------------------------' `---------------'
+
+- `Space` and `Enter` also work as `Fn` layer switch key when holding down.
+
+#### *Function Layer(WASD/HHKB)*
+ ,---------------------------------------------------------. ,---------------.
+ |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk| -|Lft|Rgt|
+ |---------------------------------------------------------| |---------------|
+ |Caps |Hom| Up|PgU| | | | |Psc|Slk|Pau|Up |Ins| \| | 7| 8| 9| Up|
+ |---------------------------------------------------------| |---------------|
+ |Caps |Lef|Dow|Rig| | | | |Hom|PgU|Lef|Rig|Enter | | 4| 5| 6| Dn|
+ |---------------------------------------------------------| |---------------|
+ |Shift |End| |PgD| | | | |End|PgD|Dow|Shift | | 1| 2| 3| |
+ `---------------------------------------------------------' |-----------|Ent|
+ |Ctl|Gui | Space |Alt |Ctl| | 0| .| |
+ `-----------------------------------------------' `---------------'
+
### M0110A
-#### *Default*
+#### *Default Layer*
,---------------------------------------------------------. ,---------------.
- | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Ctl| =| /| *|
+ | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Clr| =| /| *|
|---------------------------------------------------------| |---------------|
|Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -|
|-----------------------------------------------------' | |---------------|
- |Fn0 | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +|
+ |Caps | A| S| D| F| G| H| J| K| L| ;| '|Enter | | 4| 5| 6| +|
|---------------------------------------------------------| |---------------|
|Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft| Up| | 1| 2| 3| |
|---------------------------------------------------------| |-----------|Ent|
- |Alt |Gui | Space | \|Lft|Rgt| Dn| | 0| .| |
+ |Ctrl |Gui | Space | \|Lft|Rgt|Dwn| | 0| .| |
`---------------------------------------------------------' `---------------'
-#### *Cursor Layer(WASD/IJKL)*
+
+- `Space` and `Enter` also work as `Fn` layer switch key when holding down.
+- `Backslash(\)` also works as `Alt` when holding down.
+
+#### *Function Layer(WASD/HHKB)*
,---------------------------------------------------------. ,---------------.
|Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk| =| /| *|
|---------------------------------------------------------| |---------------|
- |Caps |Hom| Up|PgU| | | |PgU| Up|Hom|Psc|Slk|Pau| | | 7| 8| 9| -|
+ |Caps |Hom| Up|PgU| | | | |Psc|Slk|Pau|Up |Ins| | | 7| 8| 9| -|
|-----------------------------------------------------' | |---------------|
- |Fn0 |Lef|Dow|Rig| | | |Lef|Dow|Rig| | |Return| | 4| 5| 6| +|
+ |Caps |Lef|Dow|Rig| | | | |Hom|PgU|Lef|Rig|Enter | | 4| 5| 6| +|
|---------------------------------------------------------| |---------------|
- |Shift |End| |PgD| | | |PgD| |End| |Shif|PgU| | 1| 2| 3| |
+ |Shift |End| |PgD| | | | |End|PgD|Dow|Shif|PgU| | 1| 2| 3| |
|---------------------------------------------------------| |-----------|Ent|
- |Alt |Gui | Space |Ins|Hom|End|PgD| | 0| .| |
+ |Ctrl |Gui | Space | \|Hom|End|PgD| | 0| .| |
`---------------------------------------------------------' `---------------'
Debug
-----
-You can use [PJRC HID listen](http://www.pjrc.com/teensy/hid_listen.html) to see debug output.
-
-The converter has some functions for debug, press `<magickey>+H` simultaneously to get help.
-These function is totally undocumented, tentative, inconsistent and buggy.
+You can use [PJRC HID listen](http://www.pjrc.com/teensy/hid_listen.html) to see debug output. The converter has some functions for debug, press `<Command>+H` simultaneously to get help.
-magickey: Shift+Option+Command(Shift+Alt+Gui or Shift+Alt+Control)
+- Command: `Shift+Option+Command`(`Shift+Alt+Gui` or `Shift+Alt+Control`)
diff --git a/converter/m0110_usb/config.h b/converter/m0110_usb/config.h
index 2f63a3a490..801bc4ebfa 100644
--- a/converter/m0110_usb/config.h
+++ b/converter/m0110_usb/config.h
@@ -32,10 +32,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define MATRIX_COLS 8
-/* legacy keymap support */
-#define USE_LEGACY_KEYMAP
-
-
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
@@ -48,15 +44,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_LALT) | MOD_BIT(KC_LCTL)) \
)
+/* boot magic key */
+#define BOOTMAGIC_KEY_SALT KC_FN0
+#define BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL KC_LCAP
+
/* ports */
#define M0110_CLOCK_PORT PORTD
#define M0110_CLOCK_PIN PIND
#define M0110_CLOCK_DDR DDRD
-#define M0110_CLOCK_BIT 0
+#define M0110_CLOCK_BIT 1
#define M0110_DATA_PORT PORTD
#define M0110_DATA_PIN PIND
#define M0110_DATA_DDR DDRD
-#define M0110_DATA_BIT 1
+#define M0110_DATA_BIT 0
#endif
diff --git a/converter/m0110_usb/doc/m0110.jpg b/converter/m0110_usb/doc/m0110.jpg
deleted file mode 100644
index ef9a123abc..0000000000
--- a/converter/m0110_usb/doc/m0110.jpg
+++ /dev/null
Binary files differ
diff --git a/converter/m0110_usb/doc/teensy.jpg b/converter/m0110_usb/doc/teensy.jpg
deleted file mode 100644
index 96e93e7e24..0000000000
--- a/converter/m0110_usb/doc/teensy.jpg
+++ /dev/null
Binary files differ
diff --git a/converter/m0110_usb/keymap.c b/converter/m0110_usb/keymap.c
index 7a3bc35856..031c881b72 100644
--- a/converter/m0110_usb/keymap.c
+++ b/converter/m0110_usb/keymap.c
@@ -44,7 +44,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* |---------------------------------------------------------| |---------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -|
* |-----------------------------------------------------' | |---------------|
- * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +|
+ * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Enter | | 4| 5| 6| +|
* |---------------------------------------------------------| |---------------|
* |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| |
* |---------------------------------------------------------' |-----------|Ent|
@@ -57,7 +57,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* |---------------------------------------------------------| |---------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | 7| 8| 9| /|
* |---------------------------------------------------------| |---------------|
- * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| ,|
+ * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Enter | | 4| 5| 6| ,|
* |---------------------------------------------------------| |---------------|
* |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | | 1| 2| 3| |
* `---------------------------------------------------------' |-----------|Ent|
@@ -77,7 +77,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* |---------------------------------------------------------| |---------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -|
* |-----------------------------------------------------' | |---------------|
- * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +|
+ * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Enter | | 4| 5| 6| +|
* |---------------------------------------------------------| |---------------|
* |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| |
* |---------------------------------------------------------| |-----------|Ent|
@@ -108,89 +108,116 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
{ KC_##K68, KC_NO, KC_NO, KC_NO, KC_NO, KC_##K6D, KC_NO, KC_NO }, \
}
-#define KEYCODE(layer, row, col) (pgm_read_byte(&keymaps[(layer)][(row)][(col)]))
-
-
-// Assign Fn key(0-7) to a layer to which switch with the Fn key pressed.
-static const uint8_t PROGMEM fn_layer[] = {
- 1, // Fn0
- 0, // Fn1
- 0, // Fn2
- 0, // Fn3
- 0, // Fn4
- 0, // Fn5
- 0, // Fn6
- 0 // Fn7
-};
-
-// Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer.
-// See layer.c for details.
-static const uint8_t PROGMEM fn_keycode[] = {
- KC_NO, // Fn0
- KC_NO, // Fn1
- KC_NO, // Fn2
- KC_NO, // Fn3
- KC_NO, // Fn4
- KC_NO, // Fn5
- KC_NO, // Fn6
- KC_NO // Fn7
-};
-
-static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+#ifdef KEYMAP_SECTION_ENABLE
+const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS] __attribute__ ((section (".keymap.keymaps"))) = {
+#else
+static const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
+#endif
/* Default:
* ,---------------------------------------------------------. ,---------------.
- * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Ctl| =| /| *|
+ * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Clr| =| /| *|
* |---------------------------------------------------------| |---------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -|
* |-----------------------------------------------------' | |---------------|
- * |Fn0 | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +|
+ * |Caps | A| S| D| F| G| H| J| K| L| ;| '|Enter | | 4| 5| 6| +|
* |---------------------------------------------------------| |---------------|
* |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| |
* |---------------------------------------------------------| |-----------|Ent|
- * |Ctl |Alt | Space |Gui| \|Lft|Rgt|Dn | | 0| .| |
+ * |Ctl |Gui | Space |Alt| \|Lft|Rgt|Dn | | 0| .| |
* `---------------------------------------------------------' `---------------'
*/
- KEYMAP(
- GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, LCTL,EQL, PSLS,PAST,
+ [0] = KEYMAP(
+ GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, CLR, EQL, PSLS,PAST,
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, P7, P8, P9, PMNS,
- FN0, A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS,
+ LCAP,A, S, D, F, G, H, J, K, L, SCLN,QUOT, FN15, P4, P5, P6, PPLS,
LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, UP, P1, P2, P3, PENT,
- LCTL,LALT, SPC, LGUI,BSLS,LEFT,RGHT,DOWN, P0, PDOT
+ LCTL,LGUI, FN16, LALT,FN31,LEFT,RGHT,DOWN, P0, PDOT
),
/* Cursor Layer(WASD, IJKL)
* ,---------------------------------------------------------. ,---------------.
* |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk| =| /| *|
* |---------------------------------------------------------| |---------------|
- * |Caps |Hom| Up|PgU| | | |PgU| Up|Hom|Psc|Slk|Pau| | | 7| 8| 9| -|
+ * |Caps |Hom| Up|PgU| | | | |Psc|Slk|Pau|Up |Ins| | | 7| 8| 9| -|
* |-----------------------------------------------------' | |---------------|
- * |Fn0 |Lef|Dow|Rig| | | |Lef|Dow|Rig| | |Return| | 4| 5| 6| +|
+ * |Caps |Lef|Dow|Rig| | | | |Hom|PgU|Lef|Rig|Enter | | 4| 5| 6| +|
* |---------------------------------------------------------| |---------------|
- * |Shift |End| |PgD| | | |PgD| |End| |Shif|PgU| | 1| 2| 3| |
+ * |Shift |End| |PgD| | | | |End|PgD|Dow|Shif|PgU| | 1| 2| 3| |
* |---------------------------------------------------------| |-----------|Ent|
- * |Ctl |Alt | Space |Gui |Ins|Hom|End|PgD| | 0| .| |
+ * |Ctl |Gui | Space |Alt | \|Hom|End|PgD| | 0| .| |
* `---------------------------------------------------------' `---------------'
*/
- KEYMAP(
+ [3] = KEYMAP(
+ ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,EQL, PSLS,PAST,
+ CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,PAUS,UP, INS, P7, P8, P9, PMNS,
+ LCAP,LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, FN15, P4, P5, P6, PPLS,
+ LSFT,END, NO, PGDN,NO, NO, NO, NO, END, PGDN,DOWN, PGUP, P1, P2, P3, PENT,
+ LCTL,LGUI, FN16, LALT,FN31,HOME,END, PGDN, P0, PDOT
+ ),
+ [4] = KEYMAP(
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,EQL, PSLS,PAST,
- CAPS,HOME,UP, PGUP,NO, NO, NO, PGUP,UP, HOME,PSCR,SLCK,PAUS, P7, P8, P9, PMNS,
- FN0, LEFT,DOWN,RGHT,NO, NO, NO, LEFT,DOWN,RGHT,NO, NO, ENT, P4, P5, P6, PPLS,
- LSFT,END, NO, PGDN,NO, NO, NO, PGDN,NO, END, NO, PGUP, P1, P2, P3, PENT,
- LCTL,LALT, SPC, LGUI,INS, HOME,END, PGDN, P0, PDOT
+ CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,PAUS,UP, INS, P7, P8, P9, PMNS,
+ LCAP,LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, FN15, P4, P5, P6, PPLS,
+ LSFT,END, NO, PGDN,NO, NO, NO, NO, END, PGDN,DOWN, PGUP, P1, P2, P3, PENT,
+ LCTL,LGUI, FN16, LALT,FN31,HOME,END, PGDN, P0, PDOT
),
+ [7] = {},
+};
+
+
+/*
+ * Fn action definition
+ */
+#ifdef KEYMAP_SECTION_ENABLE
+const uint16_t fn_actions[] __attribute__ ((section (".keymap.fn_actions"))) = {
+#else
+static const uint16_t fn_actions[] PROGMEM = {
+#endif
+ [0] = ACTION_LAYER_MOMENTARY(1),
+ [1] = ACTION_LAYER_MOMENTARY(2),
+ [2] = ACTION_LAYER_MOMENTARY(3),
+ [3] = ACTION_LAYER_MOMENTARY(4),
+ [4] = ACTION_LAYER_MOMENTARY(5),
+ [5] = ACTION_LAYER_MOMENTARY(6),
+ [6] = ACTION_LAYER_MOMENTARY(7),
+ [7] = ACTION_LAYER_TOGGLE(1),
+ [8] = ACTION_LAYER_TOGGLE(2),
+ [9] = ACTION_LAYER_TOGGLE(3),
+ [10] = ACTION_LAYER_TAP_TOGGLE(1),
+ [11] = ACTION_LAYER_TAP_TOGGLE(2),
+ [12] = ACTION_LAYER_TAP_TOGGLE(3),
+ [13] = ACTION_LAYER_TAP_KEY(1, KC_F),
+ [14] = ACTION_LAYER_TAP_KEY(2, KC_J),
+ [15] = ACTION_LAYER_TAP_KEY(3, KC_ENTER),
+ [16] = ACTION_LAYER_TAP_KEY(4, KC_SPACE),
+ [17] = ACTION_LAYER_TAP_KEY(5, KC_SCOLON),
+ [18] = ACTION_LAYER_TAP_KEY(6, KC_QUOTE),
+ [19] = ACTION_LAYER_TAP_KEY(7, KC_SLASH),
+ [20] = ACTION_MODS_TAP_KEY(MOD_LSFT, KC_SPACE),
+ [21] = ACTION_MODS_TAP_KEY(MOD_LCTL, KC_SPACE),
+ [22] = ACTION_MODS_TAP_KEY(MOD_RCTL, KC_QUOTE),
+ [23] = ACTION_MODS_TAP_KEY(MOD_RCTL, KC_ENTER),
+ [24] = ACTION_MODS_TAP_KEY(MOD_LCTL, KC_ESC),
+ [25] = ACTION_MODS_TAP_KEY(MOD_LCTL, KC_BSPACE),
+ [26] = ACTION_MODS_ONESHOT(MOD_LCTL),
+ [27] = ACTION_MODS_TAP_KEY(MOD_LSFT, KC_ESC),
+ [28] = ACTION_MODS_TAP_KEY(MOD_LSFT, KC_BSPACE),
+ [29] = ACTION_MODS_ONESHOT(MOD_LSFT),
+ [30] = ACTION_MODS_TAP_KEY(MOD_RSFT, KC_GRAVE),
+ [31] = ACTION_MODS_TAP_KEY(MOD_RALT, KC_BSLASH),
};
-uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col)
-{
- return KEYCODE(layer, row, col);
-}
-uint8_t keymap_fn_layer(uint8_t index)
+/* translates key to keycode */
+uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
{
- return pgm_read_byte(&fn_layer[index]);
+ return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]);
}
-uint8_t keymap_fn_keycode(uint8_t index)
+/* translates Fn index to action */
+action_t keymap_fn_to_action(uint8_t keycode)
{
- return pgm_read_byte(&fn_keycode[index]);
+ action_t action;
+ action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]);
+ return action;
}
diff --git a/converter/news_usb/config_pjrc.h b/converter/news_usb/config_pjrc.h
index 92751d1eea..adce014c9e 100644
--- a/converter/news_usb/config_pjrc.h
+++ b/converter/news_usb/config_pjrc.h
@@ -42,12 +42,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
)
-/* mouse keys */
-#ifdef MOUSEKEY_ENABLE
-# define MOUSEKEY_DELAY_TIME 255
-#endif
-
-
/* Asynchronous USART
* 8-data bit, non parity, 1-stop bit, no flow control
*/
diff --git a/converter/ps2_usb/config.h b/converter/ps2_usb/config.h
index 4a2d1fc47b..51cd271d78 100644
--- a/converter/ps2_usb/config.h
+++ b/converter/ps2_usb/config.h
@@ -39,10 +39,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
)
-/* mouse keys */
-#ifdef MOUSEKEY_ENABLE
-# define MOUSEKEY_DELAY_TIME 255
-#endif
+/* legacy keymap support */
+#define USE_LEGACY_KEYMAP
#ifdef PS2_USE_USART
diff --git a/doc/keymap.md b/doc/keymap.md
index e4728b507d..11e80a9c31 100644
--- a/doc/keymap.md
+++ b/doc/keymap.md
@@ -227,7 +227,7 @@ You can define these actions on *'A'* key and *'left shift'* modifier with:
ACTION_KEY(KC_A)
ACTION_KEY(KC_LSFT)
-#### 2.1.2 Key with modifiers
+#### 2.1.2 Modified key
This action is comprised of strokes of modifiers and a key. `Macro` action is needed if you want more complex key strokes.
Say you want to assign a key to `Shift + 1` to get charactor *'!'* or `Alt + Tab` to switch application windows.
@@ -244,7 +244,7 @@ Registers multiple modifiers with pressing a key. To specify multiple modifiers
ACTION_MODS(MOD_ALT | MOD_LSFT)
-#### 2.1.3 Modifier with tap key
+#### 2.1.3 Modifier with Tap key([Dual role][dual_role])
Works as a modifier key while holding, but registers a key on tap(press and release quickly).
@@ -497,7 +497,7 @@ Number of taps can be configured with `TAPPING_TOGGLE` in `config.h`, `5` by def
Tapping is to press and release a key quickly. Tapping speed is determined with setting of `TAPPING_TERM`, which can be defined in `config.h`, 200ms by default.
### 4.1 Tap Key
-This is a feature to assign normal key action and modifier including layer switching to just same one physical key. This is a kind of [Dual role modifier][dual_role]. It works as modifier when holding the key but registers normal key when tapping.
+This is a feature to assign normal key action and modifier including layer switching to just same one physical key. This is a kind of [Dual role key][dual_role]. It works as modifier when holding the key but registers normal key when tapping.
Modifier with tap key:
@@ -507,7 +507,7 @@ Layer switching with tap key:
ACTION_LAYER_TAP_KEY(2, KC_SCLN)
-[dual_role]: http://en.wikipedia.org/wiki/Modifier_key#Dual-role_modifier_keys
+[dual_role]: http://en.wikipedia.org/wiki/Modifier_key#Dual-role_keys
### 4.2 Tap Toggle
@@ -516,13 +516,14 @@ This is a feature to assign both toggle layer and momentary switch layer action
ACTION_LAYER_TAP_TOGGLE(1)
-### 4.3 One Shot Modifier
-This adds oneshot feature to modifier key. 'One Shot Modifier' is one time modifier which has effect only on following just one key.
-It works as normal modifier key when holding but oneshot modifier when tapping.
+### 4.3 Oneshot Modifier
+This runs onetime effect swhich modify only on just one following key. It works as normal modifier key when holding down while oneshot modifier when tapping.
ACTION_MODS_ONESHOT(MOD_LSFT)
-Say you want to type 'The', you have to push and hold Shift before type 't' then release Shift before type 'h' and 'e' or you'll get 'THe'. With One Shot Modifier you can tap Shift then type 't', 'h' and 'e' normally, you don't need to holding Shift key properly here.
+Say you want to type 'The', you have to push and hold Shift key before type 't' then release it before type 'h' and 'e', otherwise you'll get 'THe' or 'the' unintentionally. With Oneshot Modifier you can tap Shift then type 't', 'h' and 'e' normally, you don't need to holding Shift key properly here. This mean you can realease Shift before 't' is pressed down.
+
+Oneshot effect is cancel unless following key is pressed down within `ONESHOT_TIMEOUT` of `config.h`. No timeout when it is `0` or not defined.
@@ -571,5 +572,5 @@ Top layer has higher precedence than lower layers.
is to press and release a key quickly.
### Fn key
is key which executes a special action like layer switching, mouse key, macro or etc.
-### dual role modifier
-<http://en.wikipedia.org/wiki/Modifier_key#Dual-role_modifier_keys>
+### dual role key
+<http://en.wikipedia.org/wiki/Modifier_key#Dual-role_keys>
diff --git a/keyboard/IIgs/config.h b/keyboard/IIgs/config.h
index 0039cb48b5..bc8bf75f94 100644
--- a/keyboard/IIgs/config.h
+++ b/keyboard/IIgs/config.h
@@ -56,10 +56,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define LAYER_SEND_FN_TERM 300
-/* mouse keys */
-#ifdef MOUSEKEY_ENABLE
-# define MOUSEKEY_DELAY_TIME 192
-#endif
+/* legacy keymap support */
+#define USE_LEGACY_KEYMAP
#endif
diff --git a/keyboard/hhkb/Makefile b/keyboard/hhkb/Makefile
index 1ef0a0187a..94078702c4 100644
--- a/keyboard/hhkb/Makefile
+++ b/keyboard/hhkb/Makefile
@@ -111,12 +111,13 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# comment out to disable the options.
#
-BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration
-MOUSEKEY_ENABLE = yes # Mouse keys
-EXTRAKEY_ENABLE = yes # Audio control and System control
-CONSOLE_ENABLE = yes # Console for debug
-COMMAND_ENABLE = yes # Commands for debug and configuration
-NKRO_ENABLE = yes # USB Nkey Rollover
+BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = yes # Console for debug
+COMMAND_ENABLE = yes # Commands for debug and configuration
+NKRO_ENABLE = yes # USB Nkey Rollover
+KEYMAP_SECTION_ENABLE = yes # fixed address keymap for keymap editor
# Search Path
@@ -127,5 +128,8 @@ include $(TOP_DIR)/protocol/lufa.mk
include $(TOP_DIR)/common.mk
include $(TOP_DIR)/rules.mk
-debug-on: EXTRAFLAGS += -DDEBUG
+debug-on: EXTRAFLAGS += -DDEBUG -DDEBUG_ACTION
debug-on: all
+
+debug-off: EXTRAFLAGS += -DNO_DEBUG -DNO_PRINT
+debug-off: all
diff --git a/keyboard/hhkb/config.h b/keyboard/hhkb/config.h
index 83a911beab..a8f76ae6b0 100644
--- a/keyboard/hhkb/config.h
+++ b/keyboard/hhkb/config.h
@@ -40,7 +40,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define TAPPING_TERM 300
/* tap count needed for toggling a feature */
#define TAPPING_TOGGLE 5
-
+/* Oneshot timeout(ms) */
+#define ONESHOT_TIMEOUT 300
/* Boot Magic salt key: Space */
#define BOOTMAGIC_KEY_SALT KC_FN6
diff --git a/keyboard/hhkb/config_iwrap.h b/keyboard/hhkb/config_iwrap.h
index 80a608882d..747c755132 100644
--- a/keyboard/hhkb/config_iwrap.h
+++ b/keyboard/hhkb/config_iwrap.h
@@ -34,11 +34,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* key combination for command */
#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)))
-/* mouse keys */
-#ifdef MOUSEKEY_ENABLE
-# define MOUSEKEY_DELAY_TIME 255
-#endif
-
/* pins for Software UART */
#define SUART_IN_PIN PINC
#define SUART_IN_BIT 5
diff --git a/keyboard/hhkb/config_vusb.h b/keyboard/hhkb/config_vusb.h
index 37d3e4f228..44f7acd6cd 100644
--- a/keyboard/hhkb/config_vusb.h
+++ b/keyboard/hhkb/config_vusb.h
@@ -35,10 +35,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* key combination for command */
#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)))
-/* mouse keys */
-#ifdef MOUSEKEY_ENABLE
-# define MOUSEKEY_DELAY_TIME 100
-#endif
-
-
#endif
diff --git a/keyboard/hhkb/keymap.c b/keyboard/hhkb/keymap.c
index faa62dd7e1..f2c6caf480 100644
--- a/keyboard/hhkb/keymap.c
+++ b/keyboard/hhkb/keymap.c
@@ -48,8 +48,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
{ KC_##K70, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_NO } \
}
-
-static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+#ifdef KEYMAP_SECTION_ENABLE
+const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS] __attribute__ ((section (".keymap.keymaps"))) = {
+#else
+static const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
+#endif
/* Layer 0: Default Layer
* ,-----------------------------------------------------------.
* |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| `|
@@ -186,7 +189,11 @@ enum macro_id {
/*
* Fn action definition
*/
-static const uint16_t PROGMEM fn_actions[] = {
+#ifdef KEYMAP_SECTION_ENABLE
+const uint16_t fn_actions[] __attribute__ ((section (".keymap.fn_actions"))) = {
+#else
+static const uint16_t fn_actions[] PROGMEM = {
+#endif
[0] = ACTION_DEFAULT_LAYER_SET(0), // Default layer(not used)
[1] = ACTION_LAYER_TAP_TOGGLE(1), // HHKB layer(toggle with 5 taps)
[2] = ACTION_LAYER_TAP_KEY(2, KC_SLASH), // Cursor layer with Slash*
@@ -310,10 +317,6 @@ uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
action_t keymap_fn_to_action(uint8_t keycode)
{
action_t action;
- if (FN_INDEX(keycode) < sizeof(fn_actions) / sizeof(fn_actions[0])) {
- action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]);
- } else {
- action.code = ACTION_NO;
- }
+ action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]);
return action;
}
diff --git a/ldscript_keymap_avr5.x b/ldscript_keymap_avr5.x
new file mode 100644
index 0000000000..c09693e514
--- /dev/null
+++ b/ldscript_keymap_avr5.x
@@ -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:5)
+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 = 128K
+ 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) }
+}
diff --git a/protocol/adb.c b/protocol/adb.c
index 2baad32340..750f4b9650 100644
--- a/protocol/adb.c
+++ b/protocol/adb.c
@@ -1,5 +1,6 @@
/*
Copyright 2011 Jun WAKO <wakojun@gmail.com>
+Copyright 2013 Shay Green <gblargg@gmail.com>
This software is licensed with a Modified BSD License.
All of this is supposed to be Free Software, Open Source, DFSG-free,
@@ -40,11 +41,14 @@ POSSIBILITY OF SUCH DAMAGE.
#include <avr/io.h>
#include <avr/interrupt.h>
#include "adb.h"
+#include "debug.h"
-static inline void data_lo(void);
-static inline void data_hi(void);
-static inline bool data_in(void);
+// GCC doesn't inline functions normally
+#define data_lo() (ADB_DDR |= (1<<ADB_DATA_BIT))
+#define data_hi() (ADB_DDR &= ~(1<<ADB_DATA_BIT))
+#define data_in() (ADB_PIN & (1<<ADB_DATA_BIT))
+
#ifdef ADB_PSW_BIT
static inline void psw_lo(void);
static inline void psw_hi(void);
@@ -55,24 +59,17 @@ static inline void attention(void);
static inline void place_bit0(void);
static inline void place_bit1(void);
static inline void send_byte(uint8_t data);
-static inline bool read_bit(void);
-static inline uint8_t read_byte(void);
-static inline uint8_t wait_data_lo(uint16_t us);
-static inline uint8_t wait_data_hi(uint8_t us);
+static inline uint16_t wait_data_lo(uint16_t us);
+static inline uint16_t wait_data_hi(uint16_t us);
void adb_host_init(void)
{
+ ADB_PORT &= ~(1<<ADB_DATA_BIT);
data_hi();
#ifdef ADB_PSW_BIT
psw_hi();
#endif
-
- // Enable keyboard left/right modifier distinction
- // Addr:Keyboard(0010), Cmd:Listen(10), Register3(11)
- // upper byte: reserved bits 0000, device address 0010
- // lower byte: device handler 00000011
- adb_host_listen(0x2B,0x02,0x03);
}
#ifdef ADB_PSW_BIT
@@ -82,6 +79,49 @@ bool adb_host_psw(void)
}
#endif
+/*
+ * Don't call this in a row without the delay, otherwise it makes some of poor controllers
+ * overloaded and misses strokes. Recommended interval is 12ms.
+ *
+ * Thanks a lot, blargg!
+ * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919>
+ * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139>
+ */
+
+// ADB Bit Cells
+//
+// bit cell time: 70-130us
+// low part of bit0: 60-70% of bit cell
+// low part of bit1: 30-40% of bit cell
+//
+// bit cell time 70us 130us
+// --------------------------------------------
+// low part of bit0 42-49 78-91
+// high part of bit0 21-28 39-52
+// low part of bit1 21-28 39-52
+// high part of bit1 42-49 78-91
+//
+//
+// bit0:
+// 70us bit cell:
+// ____________~~~~~~
+// 42-49 21-28
+//
+// 130us bit cell:
+// ____________~~~~~~
+// 78-91 39-52
+//
+// bit1:
+// 70us bit cell:
+// ______~~~~~~~~~~~~
+// 21-28 42-49
+//
+// 130us bit cell:
+// ______~~~~~~~~~~~~
+// 39-52 78-91
+//
+// [from Apple IIgs Hardware Reference Second Edition]
+
uint16_t adb_host_kbd_recv(void)
{
uint16_t data = 0;
@@ -91,22 +131,50 @@ uint16_t adb_host_kbd_recv(void)
if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us)
return 0; // No data to send
}
- if (!read_bit()) { // Startbit(1)
- // Service Request
- return -2;
- }
-
+
// ad hoc fix: without block inerrupt read wrong bit occasionally and get keys stuck
- cli();
- data = read_byte();
- data = (data<<8) | read_byte();
- uint8_t stop = read_bit(); // Stopbit(0)
- sei();
+ // TODO: is this needed anymore with improved timing?
+ //cli();
+ uint8_t n = 17; // start bit + 16 data bits
+ do {
+ uint8_t lo = (uint8_t) wait_data_hi(130);
+ if (!lo)
+ goto error;
+
+ uint8_t hi = (uint8_t) wait_data_lo(lo);
+ if (!hi)
+ goto error;
+
+ hi = lo - hi;
+ lo = 130 - lo;
+
+ data <<= 1;
+ if (lo < hi) {
+ data |= 1;
+ }
+ else if (n == 17) {
+ // Service Request
+ dprintf("Startbit ERROR\n");
+ sei();
+ return -2;
+ }
+ }
+ while ( --n );
- if (stop) {
+ // Stop bit can't be checked normally since it could have service request lenghtening
+ // and its high state never goes low.
+ if (!wait_data_hi(351) || wait_data_lo(91)) {
+ dprintf("Stopbit ERROR\n");
+ sei();
return -3;
}
+ sei();
return data;
+
+error:
+ dprintf("Bit ERROR\n");
+ sei();
+ return -4;
}
void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l)
@@ -131,23 +199,6 @@ void adb_host_kbd_led(uint8_t led)
}
-static inline void data_lo()
-{
- ADB_DDR |= (1<<ADB_DATA_BIT);
- ADB_PORT &= ~(1<<ADB_DATA_BIT);
-}
-static inline void data_hi()
-{
- ADB_PORT |= (1<<ADB_DATA_BIT);
- ADB_DDR &= ~(1<<ADB_DATA_BIT);
-}
-static inline bool data_in()
-{
- ADB_PORT |= (1<<ADB_DATA_BIT);
- ADB_DDR &= ~(1<<ADB_DATA_BIT);
- return ADB_PIN&(1<<ADB_DATA_BIT);
-}
-
#ifdef ADB_PSW_BIT
static inline void psw_lo()
{
@@ -170,7 +221,7 @@ static inline bool psw_in()
static inline void attention(void)
{
data_lo();
- _delay_us(700);
+ _delay_us(800-35); // bit1 holds lo for 35 more
place_bit1();
}
@@ -200,81 +251,27 @@ static inline void send_byte(uint8_t data)
}
}
-static inline bool read_bit(void)
-{
- // ADB Bit Cells
- //
- // bit cell time: 70-130us
- // low part of bit0: 60-70% of bit cell
- // low part of bit1: 30-40% of bit cell
- //
- // bit cell time 70us 130us
- // --------------------------------------------
- // low part of bit0 42-49 78-91
- // high part of bit0 21-28 39-52
- // low part of bit1 21-28 39-52
- // high part of bit1 42-49 78-91
- //
- //
- // bit0:
- // 70us bit cell:
- // ____________~~~~~~
- // 42-49 21-28
- //
- // 130us bit cell:
- // ____________~~~~~~
- // 78-91 39-52
- //
- // bit1:
- // 70us bit cell:
- // ______~~~~~~~~~~~~
- // 21-28 42-49
- //
- // 130us bit cell:
- // ______~~~~~~~~~~~~
- // 39-52 78-91
- //
- // read:
- // ________|~~~~~~~~~
- // 55us
- // Read data line after 55us. If data line is low/high then bit is 0/1.
- // This method might not work at <90us bit cell time.
- //
- // [from Apple IIgs Hardware Reference Second Edition]
- bool bit;
- wait_data_lo(75); // wait the start of bit cell at least 130ms(55+0+75)
- _delay_us(55);
- bit = data_in();
- wait_data_hi(36); // wait high part of bit cell at least 91ms(55+36)
- return bit;
-}
-
-static inline uint8_t read_byte(void)
-{
- uint8_t data = 0;
- for (int i = 0; i < 8; i++) {
- data <<= 1;
- if (read_bit())
- data = data | 1;
- }
- return data;
-}
-
-static inline uint8_t wait_data_lo(uint16_t us)
+// These are carefully coded to take 6 cycles of overhead.
+// inline asm approach became too convoluted
+static inline uint16_t wait_data_lo(uint16_t us)
{
- while (data_in() && us) {
- _delay_us(1);
- us--;
+ do {
+ if ( !data_in() )
+ break;
+ _delay_us(1 - (6 * 1000000.0 / F_CPU));
}
+ while ( --us );
return us;
}
-static inline uint8_t wait_data_hi(uint8_t us)
+static inline uint16_t wait_data_hi(uint16_t us)
{
- while (!data_in() && us) {
- _delay_us(1);
- us--;
+ do {
+ if ( data_in() )
+ break;
+ _delay_us(1 - (6 * 1000000.0 / F_CPU));
}
+ while ( --us );
return us;
}
diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c
index c1617cd05a..a230d5ba20 100644
--- a/protocol/lufa/lufa.c
+++ b/protocol/lufa/lufa.c
@@ -531,19 +531,26 @@ static void SetupHardware(void)
// for Console_Task
USB_Device_EnableSOFEvents();
+ print_set_sendchar(sendchar);
}
int main(void) __attribute__ ((weak));
int main(void)
{
SetupHardware();
+ sei();
+#if defined(INTERRUPT_CONTROL_ENDPOINT)
+ while (USB_DeviceState != DEVICE_STATE_Configured) ;
+#endif
+ print("USB configured.\n");
+
keyboard_init();
host_set_driver(&lufa_driver);
#ifdef SLEEP_LED_ENABLE
sleep_led_init();
#endif
- sei();
+ print("Keyboard start.\n");
while (1) {
while (USB_DeviceState == DEVICE_STATE_Suspended) {
suspend_power_down();
diff --git a/protocol/m0110.c b/protocol/m0110.c
index 8bf7cfe4fe..924ec316b8 100644
--- a/protocol/m0110.c
+++ b/protocol/m0110.c
@@ -91,10 +91,11 @@ uint8_t m0110_error = 0;
void m0110_init(void)
{
- uint8_t data;
idle();
_delay_ms(1000);
+/* Not needed to initialize in fact.
+ uint8_t data;
m0110_send(M0110_MODEL);
data = m0110_recv();
print("m0110_init model: "); phex(data); print("\n");
@@ -102,6 +103,7 @@ void m0110_init(void)
m0110_send(M0110_TEST);
data = m0110_recv();
print("m0110_init test: "); phex(data); print("\n");
+*/
}
uint8_t m0110_send(uint8_t data)
@@ -503,29 +505,29 @@ Scan Code
m0110_recv_key() function returns following scan codes instead of raw key events.
Scan codes are 1 byte long and MSB(bit7) is set when key is released.
- M0110
- ,---------------------------------------------------------.
- | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs|
- |---------------------------------------------------------|
- |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \|
- |---------------------------------------------------------|
- |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return|
- |---------------------------------------------------------|
- |Shift | Z| X| C| V| B| N| M| ,| ,| /| |
- `---------------------------------------------------------'
- |Opt|Mac | Space |Enter|Opt|
- `------------------------------------------------'
- ,---------------------------------------------------------.
- | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33|
- |---------------------------------------------------------|
- | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A|
- |---------------------------------------------------------|
- | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24|
- |---------------------------------------------------------|
- | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38|
- `---------------------------------------------------------'
- | 3A| 37| 31 | 34| 3A|
- `------------------------------------------------'
+ M0110 M0120
+ ,---------------------------------------------------------. ,---------------.
+ | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Clr| -|Lft|Rgt|
+ |---------------------------------------------------------| |---------------|
+ |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | 7| 8| 9|Up |
+ |---------------------------------------------------------| |---------------|
+ |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6|Dn |
+ |---------------------------------------------------------| |---------------|
+ |Shift | Z| X| C| V| B| N| M| ,| ,| /| | | 1| 2| 3| |
+ `---------------------------------------------------------' |-----------|Ent|
+ |Opt|Mac | Space |Enter|Opt| | 0| .| |
+ `------------------------------------------------' `---------------'
+ ,---------------------------------------------------------. ,---------------.
+ | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | 47| 4E| 46| 42|
+ |---------------------------------------------------------| |---------------|
+ | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A| | 59| 5B| 5C| 4D|
+ |---------------------------------------------------------| |---------------|
+ | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | 56| 57| 58| 48|
+ |---------------------------------------------------------| |---------------|
+ | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| | 53| 54| 55| |
+ `---------------------------------------------------------' |-----------| 4C|
+ | 3A| 37| 31 | 34| 3A| | 52| 41| |
+ `------------------------------------------------' `---------------'
M0110A
,---------------------------------------------------------. ,---------------.
diff --git a/protocol/pjrc/main.c b/protocol/pjrc/main.c
index 5f15dbf892..1ef87f8651 100644
--- a/protocol/pjrc/main.c
+++ b/protocol/pjrc/main.c
@@ -30,6 +30,7 @@
#include "matrix.h"
#include "print.h"
#include "debug.h"
+#include "sendchar.h"
#include "util.h"
#include "suspend.h"
#include "host.h"
@@ -50,6 +51,8 @@ int main(void)
usb_init();
while (!usb_configured()) /* wait */ ;
+ print_set_sendchar(sendchar);
+
keyboard_init();
host_set_driver(pjrc_driver());
#ifdef SLEEP_LED_ENABLE
diff --git a/protocol/pjrc/usb.c b/protocol/pjrc/usb.c
index 902f9f7f77..84c99972f2 100644
--- a/protocol/pjrc/usb.c
+++ b/protocol/pjrc/usb.c
@@ -38,6 +38,7 @@
#include "sleep_led.h"
#endif
#include "suspend.h"
+#include "action_util.h"
/**************************************************************************