summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/action.c11
-rw-r--r--common/action_code.h3
-rw-r--r--converter/ps2_usb/Makefile111
-rw-r--r--converter/ps2_usb/Makefile.pjrc75
-rw-r--r--converter/ps2_usb/config.h87
-rw-r--r--converter/ps2_usb/keymap.c379
-rw-r--r--converter/ps2_usb/keymap_common.c30
-rw-r--r--converter/ps2_usb/keymap_common.h174
-rw-r--r--converter/ps2_usb/keymap_plain.c50
-rw-r--r--converter/ps2_usb/matrix.c49
-rw-r--r--converter/terminal_bluefruit/Makefile113
-rw-r--r--converter/terminal_bluefruit/README37
-rw-r--r--converter/terminal_bluefruit/config.h112
-rw-r--r--converter/terminal_bluefruit/keymap.c227
-rw-r--r--converter/terminal_bluefruit/led.c35
-rw-r--r--converter/terminal_bluefruit/matrix.c262
-rw-r--r--doc/keymap.md6
-rw-r--r--keyboard/onekey/Makefile (renamed from keyboard/onekey/Makefile.lufa)4
-rw-r--r--keyboard/onekey/README.md2
-rw-r--r--keyboard/onekey/config.h4
-rw-r--r--keyboard/onekey/matrix.c18
-rw-r--r--protocol.mk4
-rw-r--r--protocol/bluefruit.mk27
-rw-r--r--protocol/bluefruit/bluefruit.c202
-rw-r--r--protocol/bluefruit/bluefruit.h28
-rw-r--r--protocol/bluefruit/main.c116
-rw-r--r--protocol/lufa/lufa.c4
-rw-r--r--protocol/pjrc/usb.c3
-rw-r--r--protocol/ps2.h146
-rw-r--r--protocol/ps2_busywait.c185
-rw-r--r--protocol/ps2_interrupt.c (renamed from protocol/ps2.c)334
-rw-r--r--protocol/ps2_usart.c174
32 files changed, 2111 insertions, 901 deletions
diff --git a/common/action.c b/common/action.c
index 485abf81e..e6938f5a2 100644
--- a/common/action.c
+++ b/common/action.c
@@ -128,6 +128,17 @@ void process_action(keyrecord_t *record)
}
break;
#endif
+ case MODS_TAP_TOGGLE:
+ if (event.pressed) {
+ if (tap_count <= TAPPING_TOGGLE) {
+ register_mods(mods);
+ }
+ } else {
+ if (tap_count < TAPPING_TOGGLE) {
+ unregister_mods(mods);
+ }
+ }
+ break;
default:
if (event.pressed) {
if (tap_count > 0) {
diff --git a/common/action_code.h b/common/action_code.h
index b08d36124..8df86b119 100644
--- a/common/action_code.h
+++ b/common/action_code.h
@@ -34,6 +34,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ACT_MODS_TAP(001r):
* 001r|mods|0000 0000 Modifiers with OneShot
+ * 001r|mods|0000 0001 Modifiers with tap toggle
* 001r|mods|0000 00xx (reserved)
* 001r|mods| keycode Modifiers with Tap Key(Dual role)
*
@@ -205,12 +206,14 @@ enum mods_bit {
};
enum mods_codes {
MODS_ONESHOT = 0x00,
+ MODS_TAP_TOGGLE = 0x01,
};
#define ACTION_KEY(key) ACTION(ACT_MODS, (key))
#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)
+#define ACTION_MODS_TAP_TOGGLE(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f)<<8 | MODS_TAP_TOGGLE)
/*
diff --git a/converter/ps2_usb/Makefile b/converter/ps2_usb/Makefile
index 0c6442374..04bf28a00 100644
--- a/converter/ps2_usb/Makefile
+++ b/converter/ps2_usb/Makefile
@@ -1,5 +1,5 @@
# Target file name (without extension).
-TARGET = ps2_usb
+TARGET = ps2_usb_lufa
# Directory common source filess exist
TOP_DIR = ../..
@@ -7,69 +7,96 @@ TOP_DIR = ../..
# Directory keyboard dependent files exist
TARGET_DIR = .
+# project specific files
+SRC = keymap_common.c \
+ matrix.c \
+ led.c
+
+ifdef KEYMAP
+ SRC := keymap_$(KEYMAP).c $(SRC)
+else
+ SRC := keymap_plain.c $(SRC)
+endif
+
+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
-# Build Options
-# *Comment out* to disable the options.
#
-MOUSEKEY_ENABLE = yes # Mouse keys
-EXTRAKEY_ENABLE = yes # Audio control and System control
-NKRO_ENABLE = yes # USB Nkey Rollover
+# 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)
-PS2_USE_USART = yes # uses hardware USART engine for PS/2 signal receive(recomened)
-#PS2_USE_INT = yes # uses external interrupt for falling edge of PS/2 clock pin
-#PS2_USE_BUSYWAIT = yes # uses primitive reference code
+# Interrupt driven control endpoint task(+60)
+OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
-# keyboard dependent files
-SRC = keymap.c \
- matrix.c \
- led.c
-
+# 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
-ifdef PS2_USE_USART
- SRC += protocol/ps2_usart.c
- OPT_DEFS += -DPS2_USE_USART
-endif
-ifdef PS2_USE_INT
- SRC += protocol/ps2.c
- OPT_DEFS += -DPS2_USE_INT
-endif
-ifdef PS2_USE_BUSYWAIT
- SRC += protocol/ps2.c
- OPT_DEFS += -DPS2_USE_BUSYWAIT
-endif
+# Build Options
+# comment out to disable the options.
+#
+#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
+MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
+EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
+CONSOLE_ENABLE = yes # Console for debug(+400)
+COMMAND_ENABLE = yes # Commands for debug and configuration
+NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
-#CONFIG_H = config_pjrc_usart.h
-CONFIG_H = config.h
+# PS/2 Options
+#
+#PS2_USE_USART = yes # uses hardware USART engine for PS/2 signal receive(recomened)
+#PS2_USE_INT = yes # uses external interrupt for falling edge of PS/2 clock pin
+PS2_USE_BUSYWAIT = yes # uses primitive reference code
-#---------------- Programming Options --------------------------
-PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex
+# 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.mk
+include $(TOP_DIR)/protocol/lufa.mk
include $(TOP_DIR)/common.mk
include $(TOP_DIR)/rules.mk
diff --git a/converter/ps2_usb/Makefile.pjrc b/converter/ps2_usb/Makefile.pjrc
new file mode 100644
index 000000000..0e175f8b4
--- /dev/null
+++ b/converter/ps2_usb/Makefile.pjrc
@@ -0,0 +1,75 @@
+# Target file name (without extension).
+TARGET = ps2_usb_pjrc
+
+# Directory common source filess exist
+TOP_DIR = ../..
+
+# Directory keyboard dependent files exist
+TARGET_DIR = .
+
+# keyboard dependent files
+SRC = keymap_common.c \
+ matrix.c \
+ led.c
+
+ifdef KEYMAP
+ SRC := keymap_$(KEYMAP).c $(SRC)
+else
+ SRC := keymap_plain.c $(SRC)
+endif
+
+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
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = yes # Console for debug(+400)
+COMMAND_ENABLE = yes # Commands for debug and configuration
+NKRO_ENABLE = yes # USB Nkey Rollover
+
+
+# PS/2 Options
+#
+#PS2_USE_USART = yes # uses hardware USART engine for PS/2 signal receive(recomened)
+#PS2_USE_INT = yes # uses external interrupt for falling edge of PS/2 clock pin
+PS2_USE_BUSYWAIT = yes # uses primitive reference code
+
+
+# Search Path
+VPATH += $(TARGET_DIR)
+VPATH += $(TOP_DIR)
+
+
+include $(TOP_DIR)/protocol.mk
+include $(TOP_DIR)/protocol/pjrc.mk
+include $(TOP_DIR)/common.mk
+include $(TOP_DIR)/rules.mk
diff --git a/converter/ps2_usb/config.h b/converter/ps2_usb/config.h
index 51cd271d7..c9bab1b07 100644
--- a/converter/ps2_usb/config.h
+++ b/converter/ps2_usb/config.h
@@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6512
+#define DEVICE_VER 0x0001
#define MANUFACTURER t.m.k.
#define PRODUCT PS/2 keyboard converter
#define DESCRIPTION convert PS/2 keyboard to USB
@@ -39,10 +40,52 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
)
-/* legacy keymap support */
-#define USE_LEGACY_KEYMAP
+//#define NO_SUSPEND_POWER_DOWN
+/*
+ * PS/2 Busywait
+ */
+#ifdef PS2_USE_BUSYWAIT
+#define PS2_CLOCK_PORT PORTD
+#define PS2_CLOCK_PIN PIND
+#define PS2_CLOCK_DDR DDRD
+#define PS2_CLOCK_BIT 5
+#define PS2_DATA_PORT PORTD
+#define PS2_DATA_PIN PIND
+#define PS2_DATA_DDR DDRD
+#define PS2_DATA_BIT 2
+#endif
+
+/*
+ * PS/2 Pin interrupt
+ */
+#ifdef PS2_USE_INT
+/* uses INT1 for clock line(ATMega32U4) */
+#define PS2_CLOCK_PORT PORTD
+#define PS2_CLOCK_PIN PIND
+#define PS2_CLOCK_DDR DDRD
+#define PS2_CLOCK_BIT 1
+#define PS2_DATA_PORT PORTD
+#define PS2_DATA_PIN PIND
+#define PS2_DATA_DDR DDRD
+#define PS2_DATA_BIT 2
+#define PS2_INT_INIT() do { \
+ EICRA |= ((1<<ISC11) | \
+ (0<<ISC10)); \
+} while (0)
+#define PS2_INT_ON() do { \
+ EIMSK |= (1<<INT1); \
+} while (0)
+#define PS2_INT_OFF() do { \
+ EIMSK &= ~(1<<INT1); \
+} while (0)
+#define PS2_INT_VECT INT1_vect
+#endif
+
+/*
+ * PS/2 USART
+ */
#ifdef PS2_USE_USART
#if defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)
/* XCK for clock line and RXD for data line */
@@ -54,7 +97,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define PS2_DATA_PIN PIND
#define PS2_DATA_DDR DDRD
#define PS2_DATA_BIT 2
-
/* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */
/* set DDR of CLOCK as input to be slave */
#define PS2_USART_INIT() do { \
@@ -85,7 +127,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define PS2_USART_RX_DATA UDR1
#define PS2_USART_ERROR (UCSR1A & ((1<<FE1) | (1<<DOR1) | (1<<UPE1)))
#define PS2_USART_RX_VECT USART1_RX_vect
-
#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
/* XCK for clock line and RXD for data line */
#define PS2_CLOCK_PORT PORTD
@@ -96,7 +137,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define PS2_DATA_PIN PIND
#define PS2_DATA_DDR DDRD
#define PS2_DATA_BIT 0
-
/* synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge */
/* set DDR of CLOCK as input to be slave */
#define PS2_USART_INIT() do { \
@@ -130,41 +170,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#endif
#endif
-
-#ifdef PS2_USE_INT
-/* uses INT1 for clock line(ATMega32U4) */
-#define PS2_CLOCK_PORT PORTD
-#define PS2_CLOCK_PIN PIND
-#define PS2_CLOCK_DDR DDRD
-#define PS2_CLOCK_BIT 1
-#define PS2_DATA_PORT PORTD
-#define PS2_DATA_PIN PIND
-#define PS2_DATA_DDR DDRD
-#define PS2_DATA_BIT 2
-
-#define PS2_INT_INIT() do { \
- EICRA |= ((1<<ISC11) | \
- (0<<ISC10)); \
-} while (0)
-#define PS2_INT_ON() do { \
- EIMSK |= (1<<INT1); \
-} while (0)
-#define PS2_INT_OFF() do { \
- EIMSK &= ~(1<<INT1); \
-} while (0)
-#define PS2_INT_VECT INT1_vect
-#endif
-
-
-#ifdef PS2_USE_BUSYWAIT
-#define PS2_CLOCK_PORT PORTF
-#define PS2_CLOCK_PIN PINF
-#define PS2_CLOCK_DDR DDRF
-#define PS2_CLOCK_BIT 0
-#define PS2_DATA_PORT PORTF
-#define PS2_DATA_PIN PINF
-#define PS2_DATA_DDR DDRF
-#define PS2_DATA_BIT 1
-#endif
-
#endif
diff --git a/converter/ps2_usb/keymap.c b/converter/ps2_usb/keymap.c
deleted file mode 100644
index c97783fa5..000000000
--- a/converter/ps2_usb/keymap.c
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
-Copyright 2011 Jun Wako <wakojun@gmail.com>
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Keymap for PS/2 keyboard
- */
-#include <stdint.h>
-#include <stdbool.h>
-#include <avr/pgmspace.h>
-#include "keycode.h"
-#include "print.h"
-#include "debug.h"
-#include "util.h"
-#include "keymap.h"
-
-
-
-
-// Following macros help you to define a keymap with the form of actual keyboard layout.
-
-/* US layout plus all other various keys */
-#define KEYMAP_ALL( \
- K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
- K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
- K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \
- K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \
- K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
- K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \
- \
- K61, /* for European ISO */ \
- K51, K13, K6A, K64, K67, /* for Japanese JIS */ \
- K08, K10, K18, K20, K28, K30, K38, K40, K48, K50, K57, K5F, /* F13-24 */ \
- KB7, KBF, KDE, /* System Power, Sleep, Wake */ \
- KA3, KB2, KA1, /* Mute, Volume Up, Volume Down */ \
- KCD, K95, KBB, KB4, KD0, /* Next, Previous, Stop, Pause, Media Select */ \
- KC8, KAB, KC0, /* Mail, Calculator, My Computer */ \
- K90, KBA, KB8, KB0, /* WWW Search, Home, Back, Forward */ \
- KA8, KA0, K98 /* WWW Stop, Refresh, Favorites */ \
-) { \
- { KC_NO, KC_##K01, KC_NO, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \
- { KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K0D, KC_##K0E, KC_NO }, \
- { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_NO }, \
- { KC_##K18, KC_NO, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_##K1E, KC_NO }, \
- { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_NO }, \
- { KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_NO }, \
- { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_NO }, \
- { KC_##K38, KC_NO, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_NO }, \
- { KC_##K40, KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_##K45, KC_##K46, KC_NO }, \
- { KC_##K48, KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E, KC_NO }, \
- { KC_##K50, KC_##K51, KC_##K52, KC_NO, KC_##K54, KC_##K55, KC_NO, KC_##K57 }, \
- { KC_##K58, KC_##K59, KC_##K5A, KC_##K5B, KC_NO, KC_##K5D, KC_NO, KC_##K5F }, \
- { KC_NO, KC_##K61, KC_NO, KC_NO, KC_##K64, KC_NO, KC_##K66, KC_##K67 }, \
- { KC_NO, KC_##K69, KC_##K6A, KC_##K6B, KC_##K6C, KC_NO, KC_NO, KC_NO }, \
- { KC_##K70, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_##K77 }, \
- { KC_##K78, KC_##K79, KC_##K7A, KC_##K7B, KC_##K7C, KC_##K7D, KC_##K7E, KC_NO }, \
- { KC_NO, KC_NO, KC_NO, KC_##K83, KC_NO, KC_NO, KC_NO, KC_NO }, \
- { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
- { KC_##K90, KC_##K91, KC_NO, KC_NO, KC_##K94, KC_##K95, KC_NO, KC_NO }, \
- { KC_##K98, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_##K9F }, \
- { KC_##KA0, KC_##KA1, KC_NO, KC_##KA3, KC_NO, KC_NO, KC_NO, KC_##KA7 }, \
- { KC_##KA8, KC_NO, KC_NO, KC_##KAB, KC_NO, KC_NO, KC_NO, KC_##KAF }, \
- { KC_##KB0, KC_NO, KC_##KB2, KC_NO, KC_##KB4, KC_NO, KC_NO, KC_##KB7 }, \
- { KC_##KB8, KC_NO, KC_##KBA, KC_##KBB, KC_NO, KC_NO, KC_NO, KC_##KBF }, \
- { KC_##KC0, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
- { KC_##KC8, KC_NO, KC_##KCA, KC_NO, KC_NO, KC_##KCD, KC_NO, KC_NO }, \
- { KC_##KD0, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
- { KC_NO, KC_NO, KC_##KDA, KC_NO, KC_NO, KC_NO, KC_##KDE, KC_NO }, \
- { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
- { KC_NO, KC_##KE9, KC_NO, KC_##KEB, KC_##KEC, KC_NO, KC_NO, KC_NO }, \
- { KC_##KF0, KC_##KF1, KC_##KF2, KC_NO, KC_##KF4, KC_##KF5, KC_NO, KC_NO }, \
- { KC_NO, KC_NO, KC_##KFA, KC_NO, KC_##KFC, KC_##KFD, KC_##KFE, KC_NO }, \
-}
-
-/* US layout */
-#define KEYMAP( \
- K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
- K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
- K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \
- K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \
- K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
- K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA \
-) \
-KEYMAP_ALL( \
- K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
- K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
- K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \
- K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \
- K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
- K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \
- \
- NUBS, \
- RO, KANA, JYEN, HENK, MHEN, \
- F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, \
- SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE, \
- AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN, \
- MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT, \
- MAIL, CALCULATOR, MY_COMPUTER, \
- WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD, \
- WWW_STOP, WWW_REFRESH, WWW_FAVORITES \
-)
-
-/* ISO layout */
-#define KEYMAP_ISO( \
- K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
- K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
- K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B, KF1,KE9,KFA, K6C,K75,K7D, \
- K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,K5D,K5A, K6B,K73,K74,K79, \
- K12,K61,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
- K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA \
-) \
-KEYMAP_ALL( \
- K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
- K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
- K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \
- K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \
- K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
- K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \
- \
- K61, \
- RO, KANA, JYEN, HENK, MHEN, \
- F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, \
- SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE, \
- AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN, \
- MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT, \
- MAIL, CALCULATOR, MY_COMPUTER, \
- WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD, \
- WWW_STOP, WWW_REFRESH, WWW_FAVORITES \
-)
-
-/* JIS layout */
-#define KEYMAP_JIS( \
- K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
- K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K6A,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
- K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B, KF1,KE9,KFA, K6C,K75,K7D, \
- K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,K5D, K5A, K6B,K73,K74,K79, \
- K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,K51, K59, KF5, K69,K72,K7A, \
- K14,K9F,K11, K67,K29,K64,K13, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA \
-) \
-KEYMAP_ALL( \
- K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
- K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
- K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \
- K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \
- K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
- K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \
- \
- NUBS, \
- K51, K13, K6A, K64, K67, \
- F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, \
- SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE, \
- AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN, \
- MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT, \
- MAIL, CALCULATOR, MY_COMPUTER, \
- WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD, \
- WWW_STOP, WWW_REFRESH, WWW_FAVORITES \
-)
-
-
-// Assign Fn key(0-7) to a layer to which switch with the Fn key pressed.
-static const uint8_t PROGMEM fn_layer[] = {
- 5, // Fn0
- 6, // 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_SCLN, // Fn0
- KC_SLSH, // Fn1
- KC_NO, // Fn2
- KC_NO, // Fn3
- KC_NO, // Fn4
- KC_NO, // Fn5
- KC_NO, // Fn6
- KC_NO // Fn7
-};
-
-
-// The keymap is a 32*8 byte array which convert a PS/2 scan code into a USB keycode.
-// See keycode.h for USB keycodes. You should omit a 'KC_' prefix of USB keycodes in keymap macro.
-// Use KEYMAP_ISO() or KEYMAP_JIS() instead of KEYMAP() if your keyboard is ISO or JIS.
-static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- /* 0: default
- * ,---. ,---------------. ,---------------. ,---------------. ,-----------. ,-----------.
- * |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |Pwr|Slp|Wak|
- * `---' `---------------' `---------------' `---------------' `-----------' `-----------'
- * ,-----------------------------------------------------------. ,-----------. ,---------------.
- * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| |Ins|Hom|PgU| |NmL| /| *| -|
- * |-----------------------------------------------------------| |-----------| |---------------|
- * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| |
- * |-----------------------------------------------------------| `-----------' |-----------| +|
- * |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return | | 4| 5| 6| |
- * |-----------------------------------------------------------| ,---. |---------------|
- * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| |
- * |-----------------------------------------------------------| ,-----------. |-----------|Ent|
- * |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl| |Lef|Dow|Rig| | 0| .| |
- * `-----------------------------------------------------------' `-----------' `---------------'
- * ; = Fn0(to Layer 5)
- * / = Fn1(to Layer 6)
- */
- KEYMAP(
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
- GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
- TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9,
- CAPS,A, S, D, F, G, H, J, K, L, FN0, QUOT, ENT, P4, P5, P6, PPLS,
- LSFT,Z, X, C, V, B, N, M, COMM,DOT, FN1, RSFT, UP, P1, P2, P3,
- LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
- ),
-
- /* 1: plain Qwerty without layer switching
- * ,-----------------------------------------------------------.
- * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa|
- * |-----------------------------------------------------------|
- * |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| ,| ,| /|Shift |
- * |-----------------------------------------------------------|
- * |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl|
- * `-----------------------------------------------------------'
- */
- KEYMAP(
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
- GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
- TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9,
- CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS,
- LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3,
- LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
- ),
-
- /* 2: Colemak http://colemak.com
- * ,-----------------------------------------------------------.
- * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa|
- * |-----------------------------------------------------------|
- * |Tab | Q| W| F| P| G| J| L| U| Y| ;| [| ]| \|
- * |-----------------------------------------------------------|
- * |BackSp| A| R| S| T| D| H| N| E| I| O| '|Return |
- * |-----------------------------------------------------------|
- * |Shift | Z| X| C| V| B| K| M| ,| ,| /|Shift |
- * |-----------------------------------------------------------|
- * |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl|
- * `----------------------------------------------------------'
- */
- KEYMAP(
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
- GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
- TAB, Q, W, F, P, G, J, L, U, Y, SCLN,LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9,
- BSPC,A, R, S, T, D, H, N, E, I, O, QUOT, ENT, P4, P5, P6, PPLS,
- LSFT,Z, X, C, V, B, K, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3,
- LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
- ),
-
- /* 3: Dvorak http://en.wikipedia.org/wiki/Dvorak_Simplified_Keyboard
- * ,-----------------------------------------------------------.
- * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| [| ]|Backspa|
- * |-----------------------------------------------------------|
- * |Tab | '| ,| .| P| Y| F| G| C| R| L| /| =| \|
- * |-----------------------------------------------------------|
- * |BackSp| A| O| E| U| I| D| H| T| N| S| -|Return |
- * |-----------------------------------------------------------|
- * |Shift | ;| Q| J| K| X| B| M| Wl V| Z|Shift |
- * |-----------------------------------------------------------|
- * |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl|
- * `-----------------------------------------------------------'
- */
- KEYMAP(
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
- GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, LBRC,RBRC,BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
- TAB, QUOT,COMM,DOT, P, Y, F, G, C, R, L, SLSH,EQL, BSLS, DEL, END, PGDN, P7, P8, P9,
- CAPS,A, O, E, U, I, D, H, T, N, S, MINS, ENT, P4, P5, P6, PPLS,
- LSFT,SCLN,Q, J, K, X, B, M, W, V, Z, RSFT, UP, P1, P2, P3,
- LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
- ),
-
- /* 4: Workman http://viralintrospection.wordpress.com/2010/09/06/a-different-philosophy-in-designing-keyboard-layouts/
- * ,-----------------------------------------------------------.
- * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa|
- * |-----------------------------------------------------------|
- * |Tab | Q| D| R| W| B| J| F| U| P| ;| [| ]| \|
- * |-----------------------------------------------------------|
- * |CapsLo| A| S| H| T| G| Y| N| E| O| I| '|Return |
- * |-----------------------------------------------------------|
- * |Shift | Z| X| M| C| V| K| L| ,| ,| /|Shift |
- * |-----------------------------------------------------------|
- * |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl|
- * `-----------------------------------------------------------'
- */
- KEYMAP(
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
- GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
- TAB, Q, D, R, W, B, J, F, U, P, SCLN,LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9,
- BSPC,A, S, H, T, G, Y, N, E, O, I, QUOT, ENT, P4, P5, P6, PPLS,
- LSFT,Z, X, M, C, V, K, L, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3,
- LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
- ),
-
- /* 5: Mouse keys
- * ,-----------------------------------------------------------.
- * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Backspa|
- * |-----------------------------------------------------------|
- * |Tab |MwL|MwU|McU|WwU|WwR|MwL|MwD|MwU|MwR| | | | \|
- * |-----------------------------------------------------------|
- * |CapsLo| |McL|McD|McR| |McL|McD|McU|McR|Fn0| |Return |
- * |-----------------------------------------------------------|
- * |Shift |VoD|VoU|Mut|Mb2|Mb3|Mb2|Mb1|VoD|VoU|Mut|Shift |
- * |-----------------------------------------------------------|
- * |Ctrl |Gui |Alt | Mb1 |Alt |Gui |Menu|Ctrl|
- * `-----------------------------------------------------------'
- * Mc = mouse cursor, Mw = mouse wheel, Mb = mouse button
- * Vo = Volume, Mut = Mute
- */
- KEYMAP(
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F8, F10, F11, F12, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
- TAB, WH_L,WH_D,MS_U,WH_U,WH_R,WH_L,WH_D,WH_U,WH_R,NO, NO, NO, BSLS, DEL, END, PGDN, P7, P8, P9,
- CAPS,NO, MS_L,MS_D,MS_R,NO, MS_L,MS_D,MS_U,MS_R,FN0, NO, ENT, P4, P5, P6, PPLS,
- LSFT,VOLD,VOLU,MUTE,BTN2,BTN3,BTN2,BTN1,VOLD,VOLU,MUTE, RSFT, UP, P1, P2, P3,
- LCTL,LGUI,LALT, BTN1, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
- ),
-
- /* 6: Cursor keys
- * ,-----------------------------------------------------------.
- * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Backspa|
- * |-----------------------------------------------------------|
- * |Tab |Hom|PgU| Up|PgU|End|Hom|PgD|PgU|End| | | | \|
- * |-----------------------------------------------------------|
- * |CapsLo| |Lef|Dow|Rig| |Lef|Dow| Up|Rig| | |Return |
- * |-----------------------------------------------------------|
- * |Shift | | | | | |Hom|PgD|PgU|End|Fn1|Shift |
- * |-----------------------------------------------------------|
- * |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl|
- * `-----------------------------------------------------------'
- */
- KEYMAP(
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F8, F10, F11, F12, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
- TAB, NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, NO, NO, NO, BSLS, DEL, END, PGDN, P7, P8, P9,
- CAPS,NO, NO, NO, NO, NO, LEFT,DOWN,UP, RGHT,NO, NO, ENT, P4, P5, P6, PPLS,
- LSFT,VOLD,VOLU,MUTE,NO, NO, HOME,PGDN,PGUP,END, FN1, RSFT, UP, P1, P2, P3,
- LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
- ),
-};
-
-
-uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col)
-{
- return pgm_read_byte(&keymaps[(layer)][(row)][(col)]);
-}
-
-uint8_t keymap_fn_layer(uint8_t index)
-{
- return pgm_read_byte(&fn_layer[index]);
-}
-
-uint8_t keymap_fn_keycode(uint8_t index)
-{
- return pgm_read_byte(&fn_keycode[index]);
-}
diff --git a/converter/ps2_usb/keymap_common.c b/converter/ps2_usb/keymap_common.c
new file mode 100644
index 000000000..241d2e33b
--- /dev/null
+++ b/converter/ps2_usb/keymap_common.c
@@ -0,0 +1,30 @@
+/*
+Copyright 2011,2012,2013 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "keymap_common.h"
+
+
+/* translates key to keycode */
+uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
+{
+ return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]);
+}
+
+/* translates Fn keycode to action */
+action_t keymap_fn_to_action(uint8_t keycode)
+{
+ return (action_t){ .code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]) };
+}
diff --git a/converter/ps2_usb/keymap_common.h b/converter/ps2_usb/keymap_common.h
new file mode 100644
index 000000000..216a8dc02
--- /dev/null
+++ b/converter/ps2_usb/keymap_common.h
@@ -0,0 +1,174 @@
+/*
+Copyright 2011,2012,2013 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef KEYMAP_COMMON_H
+#define KEYMAP_COMMON_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <avr/pgmspace.h>
+#include "keycode.h"
+#include "action.h"
+#include "action_macro.h"
+#include "report.h"
+#include "print.h"
+#include "debug.h"
+#include "keymap.h"
+
+
+// 32*8(256) byte array which converts PS/2 code into USB code
+extern const uint8_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
+extern const uint16_t fn_actions[];
+
+
+/* All keys */
+#define KEYMAP_ALL( \
+ K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
+ K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
+ K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \
+ K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \
+ K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
+ K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \
+ \
+ K61, /* for European ISO */ \
+ K51, K13, K6A, K64, K67, /* for Japanese JIS */ \
+ K08, K10, K18, K20, K28, K30, K38, K40, K48, K50, K57, K5F, /* F13-24 */ \
+ KB7, KBF, KDE, /* System Power, Sleep, Wake */ \
+ KA3, KB2, KA1, /* Mute, Volume Up, Volume Down */ \
+ KCD, K95, KBB, KB4, KD0, /* Next, Previous, Stop, Pause, Media Select */ \
+ KC8, KAB, KC0, /* Mail, Calculator, My Computer */ \
+ K90, KBA, KB8, KB0, /* WWW Search, Home, Back, Forward */ \
+ KA8, KA0, K98 /* WWW Stop, Refresh, Favorites */ \
+) { \
+ { KC_NO, KC_##K01, KC_NO, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \
+ { KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K0D, KC_##K0E, KC_NO }, \
+ { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_NO }, \
+ { KC_##K18, KC_NO, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_##K1E, KC_NO }, \
+ { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_NO }, \
+ { KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_NO }, \
+ { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_NO }, \
+ { KC_##K38, KC_NO, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_NO }, \
+ { KC_##K40, KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_##K45, KC_##K46, KC_NO }, \
+ { KC_##K48, KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E, KC_NO }, \
+ { KC_##K50, KC_##K51, KC_##K52, KC_NO, KC_##K54, KC_##K55, KC_NO, KC_##K57 }, \
+ { KC_##K58, KC_##K59, KC_##K5A, KC_##K5B, KC_NO, KC_##K5D, KC_NO, KC_##K5F }, \
+ { KC_NO, KC_##K61, KC_NO, KC_NO, KC_##K64, KC_NO, KC_##K66, KC_##K67 }, \
+ { KC_NO, KC_##K69, KC_##K6A, KC_##K6B, KC_##K6C, KC_NO, KC_NO, KC_NO }, \
+ { KC_##K70, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_##K77 }, \
+ { KC_##K78, KC_##K79, KC_##K7A, KC_##K7B, KC_##K7C, KC_##K7D, KC_##K7E, KC_NO }, \
+ { KC_NO, KC_NO, KC_NO, KC_##K83, KC_NO, KC_NO, KC_NO, KC_NO }, \
+ { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
+ { KC_##K90, KC_##K91, KC_NO, KC_NO, KC_##K94, KC_##K95, KC_NO, KC_NO }, \
+ { KC_##K98, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_##K9F }, \
+ { KC_##KA0, KC_##KA1, KC_NO, KC_##KA3, KC_NO, KC_NO, KC_NO, KC_##KA7 }, \
+ { KC_##KA8, KC_NO, KC_NO, KC_##KAB, KC_NO, KC_NO, KC_NO, KC_##KAF }, \
+ { KC_##KB0, KC_NO, KC_##KB2, KC_NO, KC_##KB4, KC_NO, KC_NO, KC_##KB7 }, \
+ { KC_##KB8, KC_NO, KC_##KBA, KC_##KBB, KC_NO, KC_NO, KC_NO, KC_##KBF }, \
+ { KC_##KC0, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
+ { KC_##KC8, KC_NO, KC_##KCA, KC_NO, KC_NO, KC_##KCD, KC_NO, KC_NO }, \
+ { KC_##KD0, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
+ { KC_NO, KC_NO, KC_##KDA, KC_NO, KC_NO, KC_NO, KC_##KDE, KC_NO }, \
+ { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
+ { KC_NO, KC_##KE9, KC_NO, KC_##KEB, KC_##KEC, KC_NO, KC_NO, KC_NO }, \
+ { KC_##KF0, KC_##KF1, KC_##KF2, KC_NO, KC_##KF4, KC_##KF5, KC_NO, KC_NO }, \
+ { KC_NO, KC_NO, KC_##KFA, KC_NO, KC_##KFC, KC_##KFD, KC_##KFE, KC_NO }, \
+}
+
+/* US layout */
+#define KEYMAP( \
+ K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
+ K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
+ K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \
+ K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \
+ K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
+ K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA \
+) \
+KEYMAP_ALL( \
+ K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
+ K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
+ K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \
+ K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \
+ K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
+ K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \
+ \
+ NUBS, \
+ RO, KANA, JYEN, HENK, MHEN, \
+ F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, \
+ SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE, \
+ AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN, \
+ MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT, \
+ MAIL, CALCULATOR, MY_COMPUTER, \
+ WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD, \
+ WWW_STOP, WWW_REFRESH, WWW_FAVORITES \
+)
+
+/* ISO layout */
+#define KEYMAP_ISO( \
+ K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
+ K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
+ K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B, KF1,KE9,KFA, K6C,K75,K7D, \
+ K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,K5D,K5A, K6B,K73,K74,K79, \
+ K12,K61,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
+ K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA \
+) \
+KEYMAP_ALL( \
+ K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
+ K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
+ K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \
+ K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \
+ K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
+ K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \
+ \
+ K61, \
+ RO, KANA, JYEN, HENK, MHEN, \
+ F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, \
+ SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE, \
+ AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN, \
+ MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT, \
+ MAIL, CALCULATOR, MY_COMPUTER, \
+ WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD, \
+ WWW_STOP, WWW_REFRESH, WWW_FAVORITES \
+)
+
+/* JIS layout */
+#define KEYMAP_JIS( \
+ K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
+ K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K6A,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
+ K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B, KF1,KE9,KFA, K6C,K75,K7D, \
+ K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,K5D, K5A, K6B,K73,K74,K79, \
+ K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,K51, K59, KF5, K69,K72,K7A, \
+ K14,K9F,K11, K67,K29,K64,K13, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA \
+) \
+KEYMAP_ALL( \
+ K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
+ K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
+ K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \
+ K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \
+ K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
+ K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \
+ \
+ NUBS, \
+ K51, K13, K6A, K64, K67, \
+ F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, \
+ SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE, \
+ AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN, \
+ MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT, \
+ MAIL, CALCULATOR, MY_COMPUTER, \
+ WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD, \
+ WWW_STOP, WWW_REFRESH, WWW_FAVORITES \
+)
+
+#endif
diff --git a/converter/ps2_usb/keymap_plain.c b/converter/ps2_usb/keymap_plain.c
new file mode 100644
index 000000000..9c6e7d9ff
--- /dev/null
+++ b/converter/ps2_usb/keymap_plain.c
@@ -0,0 +1,50 @@
+/*
+Copyright 2011,2012,2013 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "keymap_common.h"
+
+
+const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /* 0: default
+ * ,---. ,---------------. ,---------------. ,---------------. ,-----------. ,-----------.
+ * |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |Pwr|Slp|Wak|
+ * `---' `---------------' `---------------' `---------------' `-----------' `-----------'
+ * ,-----------------------------------------------------------. ,-----------. ,---------------.
+ * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| |Ins|Hom|PgU| |NmL| /| *| -|
+ * |-----------------------------------------------------------| |-----------| |---------------|
+ * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| |
+ * |-----------------------------------------------------------| `-----------' |-----------| +|
+ * |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return | | 4| 5| 6| |
+ * |-----------------------------------------------------------| ,---. |---------------|
+ * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| |
+ * |-----------------------------------------------------------| ,-----------. |-----------|Ent|
+ * |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl| |Lef|Dow|Rig| | 0| .| |
+ * `-----------------------------------------------------------' `-----------' `---------------'
+ * ; = Fn0(to Layer 5)
+ * / = Fn1(to Layer 6)
+ */
+ KEYMAP(
+ ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
+ GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
+ TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9,
+ CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS,
+ LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3,
+ LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
+ ),
+};
+
+const uint16_t PROGMEM fn_actions[] = {
+};
diff --git a/converter/ps2_usb/matrix.c b/converter/ps2_usb/matrix.c
index 4187ea060..45344c0f7 100644
--- a/converter/ps2_usb/matrix.c
+++ b/converter/ps2_usb/matrix.c
@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdbool.h>
#include <avr/io.h>
#include <util/delay.h>
+#include "action.h"
#include "print.h"
#include "util.h"
#include "debug.h"
@@ -28,6 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
static void matrix_make(uint8_t code);
static void matrix_break(uint8_t code);
+static void matrix_clear(void);
#ifdef MATRIX_HAS_GHOST
static bool matrix_has_ghost_in_row(uint8_t row);
#endif
@@ -83,6 +85,7 @@ uint8_t matrix_cols(void)
void matrix_init(void)
{
+ debug_enable = true;
ps2_host_init();
// initialize matrix state: all keys off
@@ -185,8 +188,8 @@ uint8_t matrix_scan(void)
matrix_break(PAUSE);
}
- uint8_t code;
- while ((code = ps2_host_recv())) {
+ uint8_t code = ps2_host_recv();
+ if (!ps2_error) {
switch (state) {
case INIT:
switch (code) {
@@ -207,11 +210,19 @@ uint8_t matrix_scan(void)
matrix_make(PRINT_SCREEN);
state = INIT;
break;
+ case 0x00: // Overrun [3]p.25
+ matrix_clear();
+ clear_keyboard();
+ print("Overrun\n");
+ state = INIT;
+ break;
default: // normal key make
if (code < 0x80) {
matrix_make(code);
} else {
- debug("unexpected scan code at INIT: "); debug_hex(code); debug("\n");
+ matrix_clear();
+ clear_keyboard();
+ xprintf("unexpected scan code at INIT: %02X\n", code);
}
state = INIT;
}
@@ -232,7 +243,9 @@ uint8_t matrix_scan(void)
if (code < 0x80) {
matrix_make(code|0x80);
} else {
- debug("unexpected scan code at E0: "); debug_hex(code); debug("\n");
+ matrix_clear();
+ clear_keyboard();
+ xprintf("unexpected scan code at E0: %02X\n", code);
}
state = INIT;
}
@@ -247,11 +260,18 @@ uint8_t matrix_scan(void)
matrix_break(PRINT_SCREEN);
state = INIT;
break;
+ case 0xF0:
+ matrix_clear();
+ clear_keyboard();
+ xprintf("unexpected scan code at F0: F0(clear and cont.)\n");
+ break;
default:
if (code < 0x80) {
matrix_break(code);
} else {
- debug("unexpected scan code at F0: "); debug_hex(code); debug("\n");
+ matrix_clear();
+ clear_keyboard();
+ xprintf("unexpected scan code at F0: %02X\n", code);
}
state = INIT;
}
@@ -266,7 +286,9 @@ uint8_t matrix_scan(void)
if (code < 0x80) {
matrix_break(code|0x80);
} else {
- debug("unexpected scan code at E0_F0: "); debug_hex(code); debug("\n");
+ matrix_clear();
+ clear_keyboard();
+ xprintf("unexpected scan code at E0_F0: %02X\n", code);
}
state = INIT;
}
@@ -357,8 +379,15 @@ uint8_t matrix_scan(void)
default:
state = INIT;
}
- phex(code);
}
+
+ // TODO: request RESEND when error occurs?
+/*
+ if (PS2_IS_FAILED(ps2_error)) {
+ uint8_t ret = ps2_host_send(PS2_RESEND);
+ xprintf("Resend: %02X\n", ret);
+ }
+*/
return 1;
}
@@ -450,3 +479,9 @@ static void matrix_break(uint8_t code)
is_modified = true;
}
}
+
+inline
+static void matrix_clear(void)
+{
+ for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
+}
diff --git a/converter/terminal_bluefruit/Makefile b/converter/terminal_bluefruit/Makefile
new file mode 100644
index 000000000..83d68fc25
--- /dev/null
+++ b/converter/terminal_bluefruit/Makefile
@@ -0,0 +1,113 @@
+# Target file name (without extension).
+TARGET = terminal_bluefruit
+
+# Directory common source filess exist
+TOP_DIR = ../..
+
+# Directory keyboard dependent files exist
+TARGET_DIR = .
+
+# keyboard dependent files
+SRC = keymap.c \
+ matrix.c \
+ led.c
+
+CONFIG_H = config.h
+
+BLUEFRUIT_TRACE_SERIAL=true
+
+# 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
+
+
+#
+# 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
+OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
+
+
+# Boot Section Size in bytes
+# Teensy halfKay 512
+# Atmel DFU loader 4096
+# LUFA bootloader 4096
+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(+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
+
+
+#
+# PS/2 protocol implementations
+# USART is recommended if it is available, others are for reference purpose.
+# INT implementation will drop simultaneous key strokes.
+#
+#PS2_USE_USART = yes # uses hardware USART engine for PS/2 signal receive(recomened)
+PS2_USE_INT = yes # uses external interrupt for falling edge of PS/2 clock pin
+#PS2_USE_BUSYWAIT = yes # uses primitive reference code
+
+ifdef PS2_USE_USART
+ SRC += protocol/ps2_usart.c
+ OPT_DEFS += -DPS2_USE_USART
+endif
+
+ifdef PS2_USE_INT
+ SRC += protocol/ps2.c
+ OPT_DEFS += -DPS2_USE_INT
+endif
+
+ifdef PS2_USE_BUSYWAIT
+ SRC += protocol/ps2.c
+ OPT_DEFS += -DPS2_USE_BUSYWAIT
+endif
+
+#---------------- Programming Options --------------------------
+PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex
+
+
+# Search Path
+VPATH += $(TARGET_DIR)
+VPATH += $(TOP_DIR)
+
+
+include $(TOP_DIR)/protocol/bluefruit.mk
+include $(TOP_DIR)/protocol.mk
+include $(TOP_DIR)/common.mk
+include $(TOP_DIR)/rules.mk
diff --git a/converter/terminal_bluefruit/README b/converter/terminal_bluefruit/README
new file mode 100644
index 000000000..6ff1bc92f
--- /dev/null
+++ b/converter/terminal_bluefruit/README
@@ -0,0 +1,37 @@
+Keyboard converter for IBM terminal keyboard
+============================================
+It supports PS/2 Scan Code Set 3 and runs on USB AVR chips such like PJRC Teensy.
+I tested the converter on ATMega32U4 with 1392595(102keys) and 6110345(122keys).
+
+Source code: https://github.com/tmk/tmk_keyboard
+Article: http://geekhack.org/index.php?topic=27272.0
+
+
+CONNECTION
+----------
+Keyboard ATMega32U4
+----------------------
+Data: PD2
+Clock: PD5
+
+And VCC and GND, of course. See RESOURCE for keyboard connector pin assign.
+
+
+BUILD
+-----
+$ git clone https://github.com/tmk/tmk_keyboard.git
+$ cd converter/terminal_usb
+$ make
+
+
+RESOURCE
+--------
+Soarer's Converter: http://geekhack.org/index.php?topic=17458.0
+102keys(1392595): http://geekhack.org/index.php?topic=10737.0
+122keys(1390876): http://www.seasip.info/VintagePC/ibm_1390876.html
+KbdBabel: http://www.kbdbabel.org/
+RJ45 Connector: http://www.kbdbabel.org/conn/kbd_connector_ibmterm.png
+DIN Connector: http://www.kbdbabel.org/conn/kbd_connector_ibm3179_318x_319x.png
+WinAVR: http://winavr.sourceforge.net/
+
+EOF
diff --git a/converter/terminal_bluefruit/config.h b/converter/terminal_bluefruit/config.h
new file mode 100644
index 000000000..8bf139d35
--- /dev/null
+++ b/converter/terminal_bluefruit/config.h
@@ -0,0 +1,112 @@
+/*
+Converter for 70% IBM Terminal Keyboard
+Author: Benjamin Gould, 2013
+Based on code Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+
+#define VENDOR_ID 0xFEED
+#define PRODUCT_ID 0x6535
+#define DEVICE_VER 0x0100
+#define MANUFACTURER t.m.k.
+#define PRODUCT 70% IBM Terminal Keyboard Converter w/ Bluetooth
+#define DESCRIPTION USB converter for IBM Terminal Keyboard w/ Bluetooth
+
+
+/* matrix size */
+#define MATRIX_ROWS 17 // keycode bit: 3-0
+#define MATRIX_COLS 8 // keycode bit: 6-4
+
+
+/* legacy keymap support */
+// #define USE_LEGACY_KEYMAP
+
+
+/* key combination for command */
+#define IS_COMMAND() ( \
+ (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) || \
+ (keyboard_report->mods == (MOD_BIT(KC_RALT) | MOD_BIT(KC_RCTL))) \
+)
+
+/* USART configuration
+ * asynchronous, 9600baud, 8-data bit, non parity, 1-stop bit, no flow control
+ */
+#ifdef __AVR_ATmega32U4__
+ #define SERIAL_UART_BAUD 9600
+ #define SERIAL_UART_DATA UDR1
+ #define SERIAL_UART_UBRR ((F_CPU/(16UL*SERIAL_UART_BAUD))-1)
+ #define SERIAL_UART_RXD_VECT USART1_RX_vect
+ #define SERIAL_UART_TXD_READY (UCSR1A&(1<<UDRE1))
+ #define SERIAL_UART_INIT() do { \
+ UBRR1L = (uint8_t) SERIAL_UART_UBRR; /* baud rate */ \
+ UBRR1H = (uint8_t) (SERIAL_UART_UBRR>>8); /* baud rate */ \
+ UCSR1B = (1<<TXEN1); /* TX: enable */ \
+ UCSR1C = (0<<UPM11) | (0<<UPM10) | /* parity: none(00), even(01), odd(11) */ \
+ (0<<UCSZ12) | (1<<UCSZ11) | (1<<UCSZ10); /* data-8bit(011) */ \
+ sei(); \
+ } while(0)
+#else
+# error "USART configuration is needed."
+#endif
+
+/*
+ * PS/2 Interrupt configuration
+ */
+#ifdef PS2_USE_INT
+/* uses INT1 for clock line(ATMega32U4) */
+#define PS2_CLOCK_PORT PORTD
+#define PS2_CLOCK_PIN PIND
+#define PS2_CLOCK_DDR DDRD
+#define PS2_CLOCK_BIT 1
+
+#define PS2_DATA_PORT PORTD
+#define PS2_DATA_PIN PIND
+#define PS2_DATA_DDR DDRD
+#define PS2_DATA_BIT 0
+
+#define PS2_INT_INIT() do { \
+ EICRA |= ((1<<ISC11) | \
+ (0<<ISC10)); \
+} while (0)
+#define PS2_INT_ON() do { \
+ EIMSK |= (1<<INT1); \
+} while (0)
+#define PS2_INT_OFF() do { \
+ EIMSK &= ~(1<<INT1); \
+} while (0)
+#define PS2_INT_VECT INT1_vect
+#endif
+
+
+/*
+ * PS/2 Busywait configuration
+ */
+#ifdef PS2_USE_BUSYWAIT
+#define PS2_CLOCK_PORT PORTD
+#define PS2_CLOCK_PIN PIND
+#define PS2_CLOCK_DDR DDRD
+#define PS2_CLOCK_BIT 1
+
+#define PS2_DATA_PORT PORTD
+#define PS2_DATA_PIN PIND
+#define PS2_DATA_DDR DDRD
+#define PS2_DATA_BIT 0
+#endif
+
+#endif
diff --git a/converter/terminal_bluefruit/keymap.c b/converter/terminal_bluefruit/keymap.c
new file mode 100644
index 000000000..716590a45
--- /dev/null
+++ b/converter/terminal_bluefruit/keymap.c
@@ -0,0 +1,227 @@
+/*
+Converter for 70% IBM Terminal Keyboard
+Author: Benjamin Gould, 2013
+Based on code Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <avr/pgmspace.h>
+#include "keycode.h"
+#include "print.h"
+#include "debug.h"
+#include "util.h"
+#include "keymap.h"
+
+
+
+
+/*
+ * IBM Terminal keyboard 6110345(122keys)/1392595(102keys)
+ * http://geekhack.org/showthread.php?10737-What-Can-I-Do-With-a-Terminal-Model-M
+ * http://www.seasip.info/VintagePC/ibm_1391406.html
+ *
+ * Keymap array:
+ * 8 bytes
+ * +---------+
+ * 0| |
+ * :| | 0x00-0x87
+ * ;| |
+ * 17| |
+ * +---------+
+ */
+#define KEYMAP( \
+ K08,K10,K18,K20,K28,K30,K38,K40,K48,K50,K57,K5F, \
+ K07,K0F,K17,K1F,K27,K2F,K37,K3F,K47,K4F,K56,K5E, \
+ \
+ K05,K06, K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K5D,K66, K67,K6E,K6F, K76,K77,K7E,K84, \
+ K04,K0C, K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B, K5C, K64,K65,K6D, K6C,K75,K7D,K7C, \
+ K03,K0B, K14,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K53,K5A, K63, K6B,K73,K74,K7B, \
+ K83,K0A, K12,K13,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K51,K59, K61,K62,K6A, K69,K72,K7A,K79, \
+ K01,K09, K11, K19, K29, K39, K58, K60, K68,K70,K71,K78 \
+) { \
+ { KC_NO, KC_##K01, KC_NO, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07 }, \
+ { KC_##K08, KC_##K09, KC_##K0A, KC_##K0B, KC_##K0C, KC_##K0D, KC_##K0E, KC_##K0F }, \
+ { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17 }, \
+ { KC_##K18, KC_##K19, KC_##K1A, KC_##K1B, KC_##K1C, KC_##K1D, KC_##K1E, KC_##K1F }, \
+ { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27 }, \
+ { KC_##K28, KC_##K29, KC_##K2A, KC_##K2B, KC_##K2C, KC_##K2D, KC_##K2E, KC_##K2F }, \
+ { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36, KC_##K37 }, \
+ { KC_##K38, KC_##K39, KC_##K3A, KC_##K3B, KC_##K3C, KC_##K3D, KC_##K3E, KC_##K3F }, \
+ { KC_##K40, KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_##K45, KC_##K46, KC_##K47 }, \
+ { KC_##K48, KC_##K49, KC_##K4A, KC_##K4B, KC_##K4C, KC_##K4D, KC_##K4E, KC_##K4F }, \
+ { KC_##K50, KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55, KC_##K56, KC_##K57 }, \
+ { KC_##K58, KC_##K59, KC_##K5A, KC_##K5B, KC_##K5C, KC_##K5D, KC_##K5E, KC_##K5F }, \
+ { KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_##K66, KC_##K67 }, \
+ { KC_##K68, KC_##K69, KC_##K6A, KC_##K6B, KC_##K6C, KC_##K6D, KC_##K6E, KC_##K6F }, \
+ { KC_##K70, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76, KC_##K77 }, \
+ { KC_##K78, KC_##K79, KC_##K7A, KC_##K7B, KC_##K7C, KC_##K7D, KC_##K7E, KC_NO }, \
+ { KC_NO, KC_NO, KC_NO, KC_##K83, KC_##K84, KC_NO, KC_NO, KC_NO, }, \
+}
+
+static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ /* 0: default
+ * ,---. ,---------------. ,---------------. ,---------------. ,-----------.
+ * |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau|
+ * `---' `---------------' `---------------' `---------------' `-----------'
+ * ,-----------------------------------------------------------. ,-----------. ,---------------.
+ * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \|BS | |Ins|Hom|PgU| |NmL| /| *| -|
+ * |-----------------------------------------------------------| |-----------| |---------------|
+ * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| |
+ * |-----------------------------------------------------------| `-----------' |-----------| +|
+ * |CapsLo| A| S| D| F| G| H| J| K| L| ;| '| #|Retu| | 4| 5| 6| |
+ * |-----------------------------------------------------------| ,---. |---------------|
+ * |Shif| \| Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| |
+ * |-----------------------------------------------------------| ,-----------. |-----------|Ent|
+ * |Ctrl| |Alt | Space |Alt | |Ctrl| |Lef|Dow|Rig| | 0| .| |
+ * `----' `---------------------------------------' `----' `-----------' `---------------'
+ */
+/*
+ KEYMAP(
+ F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,
+ F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
+
+ PSCR,ESC, GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, JYEN,BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
+ SLCK,INT4, TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, BSLS, DEL, END, PGDN, P7, P8, P9, PPLS,
+ PAUS,INT5, CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, NUHS,ENT, UP, P4, P5, P6, PCMM,
+ APP, INT6, LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RO, RSFT, LEFT,INT2,RGHT, P1, P2, P3, PENT,
+ RGUI,LGUI, LCTL, LALT, SPC, RALT, RCTL, DOWN, NO, P0, PDOT,NO
+ ),
+*/
+ /*
+ KEYMAP(
+ TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
+ TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
+
+ TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
+ TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
+ TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,
+ TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
+ TRNS,TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS,TRNS,TRNS,TRNS
+ ),
+ */
+ // pseudo ANSI
+
+ KEYMAP(
+ FN0, NO, NO, NO, NO, NO, NO, NO, NO, NO, NO, NO,
+ PSCR,PAUS,PGUP,PGDN,HOME,END, INS, DEL, LEFT,DOWN,UP, RGHT,
+
+ NO, NO, ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, GRV, BSPC, NO, NO, NO, NO, NO, NO, NO,
+ NO, NO, TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, BSLS, NO, NO, NO, NO, NO, NO, NO,
+ NO, NO, LCTL,A, S, D, F, G, H, J, K, L, SCLN,QUOT, BSLS,ENT, NO, NO, NO, NO, NO,
+ NO, NO, LSFT,FN1 ,Z, X, C, V, B, N, M, COMM,DOT, SLSH, FN1, RSFT, NO, NO, NO, NO, NO, NO, NO,
+ NO, NO, LCTL, LALT, SPC, LGUI, APP, NO, NO, NO, NO, NO
+ ),
+
+ // Momentary Function Layer
+ KEYMAP(
+ TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
+ TRNS,MUTE,VOLD,VOLU,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
+
+ TRNS,TRNS, TRNS,F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
+ TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,HOME,UP ,END, TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
+ TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,MS_L,MS_D,MS_U,MS_R,LEFT,DOWN, RGHT,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,
+ TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PGUP,PGDN,TRNS, TRNS,RSFT, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
+ TRNS,TRNS, BTN2, TRNS, BTN1, RALT, RCTL, TRNS, TRNS,TRNS,TRNS,TRNS
+ ),
+
+ // Mouse Layer
+ KEYMAP(
+ FN0, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
+ TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
+
+ TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,NO, TRNS, NO, NO, NO, NO, NO, NO, NO,
+ TRNS,TRNS, TRNS,NO, NO, MS_U,NO, NO, WH_L,WH_D,WH_U,WH_R,NO, NO, NO, TRNS, NO, NO, NO, NO, NO, NO, NO,
+ TRNS,TRNS, BTN2,BTN1,MS_L,MS_D,MS_R,NO, MS_L,MS_D,MS_U,MS_R,NO, NO, NO, ENT, NO, NO, NO, NO, NO,
+ TRNS,TRNS, TRNS,TRNS,NO, NO, NO, NO, NO, NO, NO, NO, NO, NO, NO, RSFT, NO, NO, NO, NO, NO, NO, NO,
+ TRNS,TRNS, TRNS, TRNS, BTN1, BTN2, TRNS, NO, NO, NO, NO, NO
+ ),
+
+ // vi Layer
+ KEYMAP(
+ FN0, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
+ TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
+
+ TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,NO, TRNS, NO, NO, NO, NO, NO, NO, NO,
+ TRNS,TRNS, TRNS,HOME,PGDN,UP, PGUP,END, HOME,PGDN,PGUP,END, NO, NO, NO, TRNS, NO, NO, NO, NO, NO, NO, NO,
+ TRNS,TRNS, TRNS,NO, LEFT,DOWN,RGHT,NO, LEFT,DOWN,UP, RGHT,NO, NO, NO, ENT, NO, NO, NO, NO, NO,
+ TRNS,TRNS, TRNS,TRNS,NO, NO, NO, NO, NO, NO, NO, NO, NO, NO, NO, RSFT, NO, NO, NO, NO, NO, NO, NO,
+ TRNS,TRNS, TRNS, TRNS, SPC, RALT, RCTL, NO, NO, NO, NO, NO
+ ),
+
+ // num lock layer
+ KEYMAP(
+ FN0, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
+ TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
+
+ TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
+ TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
+ TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,
+ TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
+ TRNS,TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS,TRNS,TRNS,TRNS
+ ),
+
+};
+
+
+static const uint16_t fn_actions[] PROGMEM = {
+ [0] = ACTION_DEFAULT_LAYER_SET(0),
+ [1] = ACTION_LAYER_MOMENTARY(1),
+ [2] = ACTION_LAYER_MOMENTARY(2), //ACTION_LAYER_ON(2, ON_RELEASE),
+ [3] = KC_NO, //ACTION_LAYER_ON(3, ON_RELEASE),
+ [4] = KC_NO, //ACTION_LAYER_ON(4, ON_RELEASE),
+ [5] = KC_NO,
+ [6] = KC_NO,
+ [7] = KC_NO,
+};
+
+/*
+enum macro_id {
+ MS_UL,
+ MS_UR,
+ MS_DL,
+ MS_DR,
+};
+
+const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+ keyevent_t event = record->event;
+
+ switch (id) {
+ case MS_UL:
+ return (event.pressed ? MACRO( D(MS_L), D(MS_U), END ) : MACRO( U(MS_L), U(MS_U), END ) );
+ case MS_UR:
+ return (event.pressed ? MACRO( D(MS_R), D(MS_U), END ) : MACRO( U(MS_L), U(MS_U), END ) );
+ case MS_DL:
+ return (event.pressed ? MACRO( D(MS_L), D(MS_D), END ) : MACRO( U(MS_L), U(MS_U), END ) );
+ case MS_DR:
+ return (event.pressed ? MACRO( D(MS_R), D(MS_D), END ) : MACRO( U(MS_L), U(MS_U), END ) );
+ }
+ return MACRO_NONE;
+}
+*/
+
+uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
+{
+ return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]);
+}
+
+action_t keymap_fn_to_action(uint8_t keycode)
+{
+ action_t action;
+ action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]);
+ return action;
+}
diff --git a/converter/terminal_bluefruit/led.c b/converter/terminal_bluefruit/led.c
new file mode 100644
index 000000000..e5bf41d4a
--- /dev/null
+++ b/converter/terminal_bluefruit/led.c
@@ -0,0 +1,35 @@
+/*
+Converter for 70% IBM Terminal Keyboard
+Author: Benjamin Gould, 2013
+Based on code Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stdint.h"
+#include "ps2.h"
+#include "led.h"
+
+
+void led_set(uint8_t usb_led)
+{
+ uint8_t ps2_led = 0;
+ if (usb_led & (1<<USB_LED_SCROLL_LOCK))
+ ps2_led |= (1<<PS2_LED_SCROLL_LOCK);
+ if (usb_led & (1<<USB_LED_NUM_LOCK))
+ ps2_led |= (1<<PS2_LED_NUM_LOCK);
+ if (usb_led & (1<<USB_LED_CAPS_LOCK))
+ ps2_led |= (1<<PS2_LED_CAPS_LOCK);
+ ps2_host_set_led(ps2_led);
+}
diff --git a/converter/terminal_bluefruit/matrix.c b/converter/terminal_bluefruit/matrix.c
new file mode 100644
index 000000000..36901536f
--- /dev/null
+++ b/converter/terminal_bluefruit/matrix.c
@@ -0,0 +1,262 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <avr/io.h>
+#include <util/delay.h>
+#include "print.h"
+#include "util.h"
+#include "debug.h"
+#include "ps2.h"
+#include "matrix.h"
+
+
+static void matrix_make(uint8_t code);
+static void matrix_break(uint8_t code);
+#ifdef MATRIX_HAS_GHOST
+static bool matrix_has_ghost_in_row(uint8_t row);
+#endif
+
+
+/*
+ * Matrix Array usage:
+ * 'Scan Code Set 3' is assigned into 17x8 cell matrix.
+ *
+ * 8bit wide
+ * +---------+
+ * 0| |
+ * :| | 0x00-0x87
+ * ;| |
+ * 17| |
+ * +---------+
+ */
+static uint8_t matrix[MATRIX_ROWS];
+#define ROW(code) (code>>3)
+#define COL(code) (code&0x07)
+
+static bool is_modified = false;
+
+
+inline
+uint8_t matrix_rows(void)
+{
+ return MATRIX_ROWS;
+}
+
+inline
+uint8_t matrix_cols(void)
+{
+ return MATRIX_COLS;
+}
+
+void matrix_init(void)
+{
+ debug_enable = true;
+ //debug_matrix = true;
+ //debug_keyboard = true;
+ //debug_mouse = false;
+
+ ps2_host_init();
+
+ // initialize matrix state: all keys off
+ for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
+
+ return;
+}
+
+uint8_t matrix_scan(void)
+{
+
+ // scan code reading states
+ static enum {
+ RESET,
+ RESET_RESPONSE,
+ KBD_ID0,
+ KBD_ID1,
+ CONFIG,
+ READY,
+ F0,
+ } state = RESET;
+
+ is_modified = false;
+
+ uint8_t code;
+ if ((code = ps2_host_recv())) {
+ debug("r"); debug_hex(code); debug(" ");
+ }
+
+ switch (state) {
+ case RESET:
+ debug("wFF ");
+ if (ps2_host_send(0xFF) == 0xFA) {
+ debug("[ack]\nRESET_RESPONSE: ");
+ state = RESET_RESPONSE;
+ }
+ break;
+ case RESET_RESPONSE:
+ if (code == 0xAA) {
+ debug("[ok]\nKBD_ID: ");
+ state = KBD_ID0;
+ } else if (code) {
+ debug("err\nRESET: ");
+ state = RESET;
+ }
+ break;
+ // after reset receive keyboad ID(2 bytes)
+ case KBD_ID0:
+ if (code) {
+ state = KBD_ID1;
+ }
+ break;
+ case KBD_ID1:
+ if (code) {
+ debug("\nCONFIG: ");
+ state = CONFIG;
+ }
+ break;
+ case CONFIG:
+ debug("wF8 ");
+ if (ps2_host_send(0xF8) == 0xFA) {
+ debug("[ack]\nREADY\n");
+ state = READY;
+ }
+ break;
+ case READY:
+ switch (code) {
+ case 0x00:
+ break;
+ case 0xF0:
+ state = F0;
+ debug(" ");
+ break;
+ default: // normal key make
+ if (code < 0x88) {
+ matrix_make(code);
+ } else {
+ debug("unexpected scan code at READY: "); debug_hex(code); debug("\n");
+ }
+ state = READY;
+ debug("\n");
+ }
+ break;
+ case F0: // Break code
+ switch (code) {
+ case 0x00:
+ break;
+ default:
+ if (code < 0x88) {
+ matrix_break(code);
+ } else {
+ debug("unexpected scan code at F0: "); debug_hex(code); debug("\n");
+ }
+ state = READY;
+ debug("\n");
+ }
+ break;
+ }
+ return 1;
+}
+
+bool matrix_is_modified(void)
+{
+ return is_modified;
+}
+
+inline
+bool matrix_has_ghost(void)
+{
+#ifdef MATRIX_HAS_GHOST
+ for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
+ if (matrix_has_ghost_in_row(i))
+ return true;
+ }
+#endif
+ return false;
+}
+
+inline
+bool matrix_is_on(uint8_t row, uint8_t col)
+{
+ return (matrix[row] & (1<<col));
+}
+
+inline
+uint8_t matrix_get_row(uint8_t row)
+{
+ return matrix[row];
+}
+
+void matrix_print(void)
+{
+ print("\nr/c 01234567\n");
+ for (uint8_t row = 0; row < matrix_rows(); row++) {
+ phex(row); print(": ");
+ pbin_reverse(matrix_get_row(row));
+#ifdef MATRIX_HAS_GHOST
+ if (matrix_has_ghost_in_row(row)) {
+ print(" <ghost");
+ }
+#endif
+ print("\n");
+ }
+}
+
+uint8_t matrix_key_count(void)
+{
+ uint8_t count = 0;
+ for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
+ count += bitpop(matrix[i]);
+ }
+ return count;
+}
+
+#ifdef MATRIX_HAS_GHOST
+inline
+static bool matrix_has_ghost_in_row(uint8_t row)
+{
+ // no ghost exists in case less than 2 keys on
+ if (((matrix[row] - 1) & matrix[row]) == 0)
+ return false;
+
+ // ghost exists in case same state as other row
+ for (uint8_t i=0; i < MATRIX_ROWS; i++) {
+ if (i != row && (matrix[i] & matrix[row]) == matrix[row])
+ return true;
+ }
+ return false;
+}
+#endif
+
+
+inline
+static void matrix_make(uint8_t code)
+{
+ if (!matrix_is_on(ROW(code), COL(code))) {
+ matrix[ROW(code)] |= 1<<COL(code);
+ is_modified = true;
+ }
+}
+
+inline
+static void matrix_break(uint8_t code)
+{
+ if (matrix_is_on(ROW(code), COL(code))) {
+ matrix[ROW(code)] &= ~(1<<COL(code));
+ is_modified = true;
+ }
+}
diff --git a/doc/keymap.md b/doc/keymap.md
index 11e80a9c3..3a549de62 100644
--- a/doc/keymap.md
+++ b/doc/keymap.md
@@ -526,6 +526,12 @@ Say you want to type 'The', you have to push and hold Shift key before type 't'
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.
+### 4.4 Tap Toggle Mods
+Similar to layer tap toggle, this works as a momentary modifier when holding, but toggles on with several taps. A single tap will 'unstick' the modifier again.
+
+ ACTION_MODS_TAP_TOGGLE(MOD_LSFT)
+
+
## 5. Legacy Keymap
diff --git a/keyboard/onekey/Makefile.lufa b/keyboard/onekey/Makefile
index 60a84ba00..78732e470 100644
--- a/keyboard/onekey/Makefile.lufa
+++ b/keyboard/onekey/Makefile
@@ -116,8 +116,8 @@ CONSOLE_ENABLE = yes # Console for debug(+400)
#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
#NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
-PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support
-PS2_USE_BUSYWAIT = yes # uses primitive reference code
+#PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support
+#PS2_USE_BUSYWAIT = yes # uses primitive reference code
#PS2_USE_INT = yes # uses external interrupt for falling edge of PS/2 clock pin
#PS2_USE_USART = yes # uses hardware USART engine for PS/2 signal receive(recomened)
diff --git a/keyboard/onekey/README.md b/keyboard/onekey/README.md
index 6ccc99929..7413f3880 100644
--- a/keyboard/onekey/README.md
+++ b/keyboard/onekey/README.md
@@ -1,5 +1,5 @@
Onekey
======
-Just one key keyboard for example. It sends 'a' key if pins PD0 and PD1 are short-circuited.
+Just one key keyboard for example. It sends 'a' key if pins PB0 and PB1 are short-circuited.
https://github.com/tmk/tmk_keyboard/issues/56
diff --git a/keyboard/onekey/config.h b/keyboard/onekey/config.h
index 1d2e052bf..bf1d2b1ed 100644
--- a/keyboard/onekey/config.h
+++ b/keyboard/onekey/config.h
@@ -73,7 +73,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
# define PS2_CLOCK_PORT PORTD
# define PS2_CLOCK_PIN PIND
# define PS2_CLOCK_DDR DDRD
-# define PS2_CLOCK_BIT 5
+# define PS2_CLOCK_BIT 1
# define PS2_DATA_PORT PORTD
# define PS2_DATA_PIN PIND
# define PS2_DATA_DDR DDRD
@@ -87,7 +87,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define PS2_CLOCK_PORT PORTD
#define PS2_CLOCK_PIN PIND
#define PS2_CLOCK_DDR DDRD
-#define PS2_CLOCK_BIT 5
+#define PS2_CLOCK_BIT 1
#define PS2_DATA_PORT PORTD
#define PS2_DATA_PIN PIND
#define PS2_DATA_DDR DDRD
diff --git a/keyboard/onekey/matrix.c b/keyboard/onekey/matrix.c
index a0a14ff82..29df86832 100644
--- a/keyboard/onekey/matrix.c
+++ b/keyboard/onekey/matrix.c
@@ -139,29 +139,29 @@ uint8_t matrix_key_count(void)
/* Column pin configuration
* col: 0
- * pin: D0
+ * pin: B0
*/
static void init_cols(void)
{
// Input with pull-up(DDR:0, PORT:1)
- DDRD &= ~(1<<0);
- PORTD |= (1<<0);
+ DDRB &= ~(1<<0);
+ PORTB |= (1<<0);
}
static matrix_row_t read_cols(void)
{
- return (PIND&(1<<0) ? 0 : (1<<0));
+ return (PINB&(1<<0) ? 0 : (1<<0));
}
/* Row pin configuration
* row: 0
- * pin: D1
+ * pin: B1
*/
static void unselect_rows(void)
{
// Hi-Z(DDR:0, PORT:0) to unselect
- DDRD &= ~0b00000010;
- PORTD &= ~0b00000010;
+ DDRB &= ~0b00000010;
+ PORTB &= ~0b00000010;
}
static void select_row(uint8_t row)
@@ -169,8 +169,8 @@ static void select_row(uint8_t row)
// Output low(DDR:1, PORT:0) to select
switch (row) {
case 0:
- DDRD |= (1<<1);
- PORTD &= ~(1<<1);
+ DDRB |= (1<<1);
+ PORTB &= ~(1<<1);
break;
}
}
diff --git a/protocol.mk b/protocol.mk
index 0d5f06c7e..7f561e62d 100644
--- a/protocol.mk
+++ b/protocol.mk
@@ -8,12 +8,12 @@ ifdef PS2_MOUSE_ENABLE
endif
ifdef PS2_USE_BUSYWAIT
- SRC += protocol/ps2.c
+ SRC += protocol/ps2_busywait.c
OPT_DEFS += -DPS2_USE_BUSYWAIT
endif
ifdef PS2_USE_INT
- SRC += protocol/ps2.c
+ SRC += protocol/ps2_interrupt.c
OPT_DEFS += -DPS2_USE_INT
endif
diff --git a/protocol/bluefruit.mk b/protocol/bluefruit.mk
new file mode 100644
index 000000000..7e6328f6c
--- /dev/null
+++ b/protocol/bluefruit.mk
@@ -0,0 +1,27 @@
+BLUEFRUIT_DIR = protocol/bluefruit
+PJRC_DIR = protocol/pjrc
+
+SRC += $(BLUEFRUIT_DIR)/main.c \
+ $(BLUEFRUIT_DIR)/bluefruit.c \
+ serial_uart.c \
+ $(PJRC_DIR)/pjrc.c \
+ $(PJRC_DIR)/usb_keyboard.c \
+ $(PJRC_DIR)/usb_debug.c \
+ $(PJRC_DIR)/usb.c
+
+# Option modules
+ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE)
+ SRC += $(PJRC_DIR)/usb_mouse.c
+endif
+
+ifdef EXTRAKEY_ENABLE
+ SRC += $(PJRC_DIR)/usb_extra.c
+endif
+
+# Search Path
+VPATH += $(TOP_DIR)/$(BLUEFRUIT_DIR)
+#VPATH += $(TOP_DIR)/$(BLUEFRUIT_DIR)/usb_debug_only
+VPATH += $(TOP_DIR)/$(PJRC_DIR)
+
+OPT_DEFS += -DPROTOCOL_BLUEFRUIT
+OPT_DEFS += -DPROTOCOL_PJRC
diff --git a/protocol/bluefruit/bluefruit.c b/protocol/bluefruit/bluefruit.c
new file mode 100644
index 000000000..f991e4d04
--- /dev/null
+++ b/protocol/bluefruit/bluefruit.c
@@ -0,0 +1,202 @@
+/*
+Bluefruit Protocol for TMK firmware
+Author: Benjamin Gould, 2013
+Based on code Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <stdint.h>
+#include "host.h"
+#include "report.h"
+#include "print.h"
+#include "debug.h"
+#include "host_driver.h"
+#include "serial.h"
+#include "bluefruit.h"
+
+#define BLUEFRUIT_TRACE_SERIAL 1
+
+static uint8_t bluefruit_keyboard_leds = 0;
+
+static void bluefruit_serial_send(uint8_t);
+
+void bluefruit_keyboard_print_report(report_keyboard_t *report)
+{
+ if (!debug_keyboard) return;
+ dprintf("keys: "); for (int i = 0; i < REPORT_KEYS; i++) { debug_hex8(report->keys[i]); dprintf(" "); }
+ dprintf(" mods: "); debug_hex8(report->mods);
+ dprintf(" reserved: "); debug_hex8(report->reserved);
+ dprintf("\n");
+}
+
+#ifdef BLUEFRUIT_TRACE_SERIAL
+static void bluefruit_trace_header()
+{
+ dprintf("+------------------------------------+\n");
+ dprintf("| HID report to Bluefruit via serial |\n");
+ dprintf("+------------------------------------+\n|");
+}
+
+static void bluefruit_trace_footer()
+{
+ dprintf("|\n+------------------------------------+\n\n");
+}
+#endif
+
+static void bluefruit_serial_send(uint8_t data)
+{
+#ifdef BLUEFRUIT_TRACE_SERIAL
+ dprintf(" ");
+ debug_hex8(data);
+ dprintf(" ");
+#endif
+ serial_send(data);
+}
+
+/*------------------------------------------------------------------*
+ * Host driver
+ *------------------------------------------------------------------*/
+
+static uint8_t keyboard_leds(void);
+static void send_keyboard(report_keyboard_t *report);
+static void send_mouse(report_mouse_t *report);
+static void send_system(uint16_t data);
+static void send_consumer(uint16_t data);
+
+static host_driver_t driver = {
+ keyboard_leds,
+ send_keyboard,
+ send_mouse,
+ send_system,
+ send_consumer
+};
+
+host_driver_t *bluefruit_driver(void)
+{
+ return &driver;
+}
+
+static uint8_t keyboard_leds(void) {
+ return bluefruit_keyboard_leds;
+}
+
+static void send_keyboard(report_keyboard_t *report)
+{
+#ifdef BLUEFRUIT_TRACE_SERIAL
+ bluefruit_trace_header();
+#endif
+ bluefruit_serial_send(0xFD);
+ for (uint8_t i = 0; i < REPORT_SIZE; i++) {
+ bluefruit_serial_send(report->raw[i]);
+ }
+#ifdef BLUEFRUIT_TRACE_SERIAL
+ bluefruit_trace_footer();
+#endif
+}
+
+static void send_mouse(report_mouse_t *report)
+{
+#ifdef BLUEFRUIT_TRACE_SERIAL
+ bluefruit_trace_header();
+#endif
+ bluefruit_serial_send(0xFD);
+ bluefruit_serial_send(0x00);
+ bluefruit_serial_send(0x03);
+ bluefruit_serial_send(report->buttons);
+ bluefruit_serial_send(report->x);
+ bluefruit_serial_send(report->y);
+ bluefruit_serial_send(report->v); // should try sending the wheel v here
+ bluefruit_serial_send(report->h); // should try sending the wheel h here
+ bluefruit_serial_send(0x00);
+#ifdef BLUEFRUIT_TRACE_SERIAL
+ bluefruit_trace_footer();
+#endif
+}
+
+static void send_system(uint16_t data)
+{
+}
+
+/*
++-----------------+-------------------+-------+
+| Consumer Key | Bit Map | Hex |
++-----------------+-------------------+-------+
+| Home | 00000001 00000000 | 01 00 |
+| KeyboardLayout | 00000010 00000000 | 02 00 |
+| Search | 00000100 00000000 | 04 00 |
+| Snapshot | 00001000 00000000 | 08 00 |
+| VolumeUp | 00010000 00000000 | 10 00 |
+| VolumeDown | 00100000 00000000 | 20 00 |
+| Play/Pause | 01000000 00000000 | 40 00 |
+| Fast Forward | 10000000 00000000 | 80 00 |
+| Rewind | 00000000 00000001 | 00 01 |
+| Scan Next Track | 00000000 00000010 | 00 02 |
+| Scan Prev Track | 00000000 00000100 | 00 04 |
+| Random Play | 00000000 00001000 | 00 08 |
+| Stop | 00000000 00010000 | 00 10 |
++-------------------------------------+-------+
+*/
+#define CONSUMER2BLUEFRUIT(usage) \
+ (usage == AUDIO_MUTE ? 0x0000 : \
+ (usage == AUDIO_VOL_UP ? 0x1000 : \
+ (usage == AUDIO_VOL_DOWN ? 0x2000 : \
+ (usage == TRANSPORT_NEXT_TRACK ? 0x0002 : \
+ (usage == TRANSPORT_PREV_TRACK ? 0x0004 : \
+ (usage == TRANSPORT_STOP ? 0x0010 : \
+ (usage == TRANSPORT_STOP_EJECT ? 0x0000 : \
+ (usage == TRANSPORT_PLAY_PAUSE ? 0x4000 : \
+ (usage == AL_CC_CONFIG ? 0x0000 : \
+ (usage == AL_EMAIL ? 0x0000 : \
+ (usage == AL_CALCULATOR ? 0x0000 : \
+ (usage == AL_LOCAL_BROWSER ? 0x0000 : \
+ (usage == AC_SEARCH ? 0x0400 : \
+ (usage == AC_HOME ? 0x0100 : \
+ (usage == AC_BACK ? 0x0000 : \
+ (usage == AC_FORWARD ? 0x0000 : \
+ (usage == AC_STOP ? 0x0000 : \
+ (usage == AC_REFRESH ? 0x0000 : \
+ (usage == AC_BOOKMARKS ? 0x0000 : 0)))))))))))))))))))
+
+static void send_consumer(uint16_t data)
+{
+ static uint16_t last_data = 0;
+ if (data == last_data) return;
+ last_data = data;
+
+ uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
+
+#ifdef BLUEFRUIT_TRACE_SERIAL
+ dprintf("\nData: ");
+ debug_hex16(data);
+ dprintf("; bitmap: ");
+ debug_hex16(bitmap);
+ dprintf("\n");
+ bluefruit_trace_header();
+#endif
+ bluefruit_serial_send(0xFD);
+ bluefruit_serial_send(0x00);
+ bluefruit_serial_send(0x02);
+ bluefruit_serial_send((bitmap>>8)&0xFF);
+ bluefruit_serial_send(bitmap&0xFF);
+ bluefruit_serial_send(0x00);
+ bluefruit_serial_send(0x00);
+ bluefruit_serial_send(0x00);
+ bluefruit_serial_send(0x00);
+#ifdef BLUEFRUIT_TRACE_SERIAL
+ bluefruit_trace_footer();
+#endif
+}
+
diff --git a/protocol/bluefruit/bluefruit.h b/protocol/bluefruit/bluefruit.h
new file mode 100644
index 000000000..4f9b58836
--- /dev/null
+++ b/protocol/bluefruit/bluefruit.h
@@ -0,0 +1,28 @@
+/*
+Bluefruit Protocol for TMK firmware
+Author: Benjamin Gould, 2013
+Based on code Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef VUSB_H
+#define VUSB_H
+
+#include "host_driver.h"
+
+
+host_driver_t *bluefruit_driver(void);
+
+#endif
diff --git a/protocol/bluefruit/main.c b/protocol/bluefruit/main.c
new file mode 100644
index 000000000..871062ab1
--- /dev/null
+++ b/protocol/bluefruit/main.c
@@ -0,0 +1,116 @@
+/*
+Bluefruit Protocol for TMK firmware
+Author: Benjamin Gould, 2013
+Based on code Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdint.h>
+#include <avr/interrupt.h>
+#include <avr/wdt.h>
+#include <avr/sleep.h>
+#include <util/delay.h>
+#include "serial.h"
+#include "keyboard.h"
+#include "usb.h"
+#include "host.h"
+#include "timer.h"
+#include "print.h"
+#include "debug.h"
+#include "sendchar.h"
+#include "suspend.h"
+#include "bluefruit.h"
+#include "pjrc.h"
+
+#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
+
+#define HOST_DRIVER_NOT_SET 0
+#define BLUEFRUIT_HOST_DRIVER 1
+#define PJRC_HOST_DRIVER 2
+
+int main(void)
+{
+
+ CPU_PRESCALE(0);
+
+ DDRD = _BV(PD5);
+ DDRB = _BV(PB0);
+
+ PORTD = _BV(PD5);
+ PORTB = _BV(PB0);
+
+ print_set_sendchar(sendchar);
+
+ usb_init();
+ _delay_ms(2000);
+ // while (!usb_configured()) /* wait */
+
+ dprintf("Initializing keyboard...\n");
+ keyboard_init();
+
+ // This implementation is pretty simplistic... if the USB connection
+ // is not configured, choose the Bluefruit, otherwise use USB
+ // Definitely would prefer to have this driven by an input pin and make
+ // it switch dynamically - BCG
+ if (!usb_configured()) {
+
+ // Send power to Bluefruit... Adafruit says it takes 27 mA, I think
+ // the pins should provide 40 mA, but just in case I switch the
+ // Bluefruit using a transistor - BCG
+ DDRB = _BV(PB6);
+ PORTB |= _BV(PB6);
+
+ dprintf("Setting host driver to bluefruit...\n");
+ host_set_driver(bluefruit_driver());
+
+ dprintf("Initializing serial...\n");
+ serial_init();
+
+ // wait an extra second for the PC's operating system
+ // to load drivers and do whatever it does to actually
+ // be ready for input
+ _delay_ms(1000);
+ PORTD = ~_BV(PD5);
+ dprintf("Starting main loop");
+ while (1) {
+ keyboard_task();
+ }
+
+ } else {
+
+ // I'm not smart enough to get this done with LUFA - BCG
+ dprintf("Setting host driver to PJRC...\n");
+ host_set_driver(pjrc_driver());
+#ifdef SLEEP_LED_ENABLE
+ sleep_led_init();
+#endif
+ // wait an extra second for the PC's operating system
+ // to load drivers and do whatever it does to actually
+ // be ready for input
+ _delay_ms(1000);
+ PORTB = ~_BV(PB0);
+ dprintf("Starting main loop");
+ while (1) {
+ while (suspend) {
+ suspend_power_down();
+ if (remote_wakeup && suspend_wakeup_condition()) {
+ usb_remote_wakeup();
+ }
+ }
+ keyboard_task();
+ }
+ }
+
+}
diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c
index 04e8e78f3..eca51c878 100644
--- a/protocol/lufa/lufa.c
+++ b/protocol/lufa/lufa.c
@@ -148,7 +148,6 @@ static void Console_Task(void)
*/
void EVENT_USB_Device_Connect(void)
{
- led_set(0x1f); // all on
}
void EVENT_USB_Device_Disconnect(void)
@@ -172,8 +171,9 @@ void EVENT_USB_Device_WakeUp()
#ifdef SLEEP_LED_ENABLE
sleep_led_disable();
-#endif
+ // NOTE: converters may not accept this
led_set(host_keyboard_leds());
+#endif
}
void EVENT_USB_Device_StartOfFrame(void)
diff --git a/protocol/pjrc/usb.c b/protocol/pjrc/usb.c
index 84c99972f..393b36f78 100644
--- a/protocol/pjrc/usb.c
+++ b/protocol/pjrc/usb.c
@@ -662,8 +662,9 @@ ISR(USB_GEN_vect)
suspend_wakeup_init();
#ifdef SLEEP_LED_ENABLE
sleep_led_disable();
-#endif
+ // NOTE: converters may not accept this
led_set(host_keyboard_leds());
+#endif
UDIEN |= (1<<SUSPE);
UDIEN &= ~(1<<WAKEUPE);
diff --git a/protocol/ps2.h b/protocol/ps2.h
index 834165356..483eea720 100644
--- a/protocol/ps2.h
+++ b/protocol/ps2.h
@@ -1,5 +1,5 @@
/*
-Copyright 2010,2011 Jun WAKO <wakojun@gmail.com>
+Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com>
This software is licensed with a Modified BSD License.
All of this is supposed to be Free Software, Open Source, DFSG-free,
@@ -37,32 +37,46 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef PS2_H
#define PS2_H
+
+#include <stdbool.h>
+#include <util/delay.h>
+#include <avr/io.h>
+
/*
* Primitive PS/2 Library for AVR
+ *
+ * PS/2 Resources
+ * --------------
+ * [1] The PS/2 Mouse/Keyboard Protocol
+ * http://www.computer-engineering.org/ps2protocol/
+ * Concise and thorough primer of PS/2 protocol.
+ *
+ * [2] Keyboard and Auxiliary Device Controller
+ * http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
+ * Signal Timing and Format
+ *
+ * [3] Keyboards(101- and 102-key)
+ * http://www.mcamafia.de/pdf/ibm_hitrc11.pdf
+ * Keyboard Layout, Scan Code Set, POR, and Commands.
+ *
+ * [4] PS/2 Reference Manuals
+ * http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
+ * Collection of IBM Personal System/2 documents.
+ *
+ * [5] TrackPoint Engineering Specifications for version 3E
+ * https://web.archive.org/web/20100526161812/http://wwwcssrv.almaden.ibm.com/trackpoint/download.html
*/
-
-
-/* port settings for clock and data line */
-#if !(defined(PS2_CLOCK_PORT) && \
- defined(PS2_CLOCK_PIN) && \
- defined(PS2_CLOCK_DDR) && \
- defined(PS2_CLOCK_BIT))
-# error "PS/2 clock port setting is required in config.h"
-#endif
-
-#if !(defined(PS2_DATA_PORT) && \
- defined(PS2_DATA_PIN) && \
- defined(PS2_DATA_DDR) && \
- defined(PS2_DATA_BIT))
-# error "PS/2 data port setting is required in config.h"
-#endif
-
#define PS2_ACK 0xFA
#define PS2_RESEND 0xFE
#define PS2_SET_LED 0xED
-#define PS2_ERR_NONE 0
-#define PS2_ERR_PARITY 0x10
+// TODO: error numbers
+#define PS2_ERR_NONE 0
+#define PS2_ERR_STARTBIT1 1
+#define PS2_ERR_STARTBIT2 2
+#define PS2_ERR_STARTBIT3 3
+#define PS2_ERR_PARITY 0x10
+#define PS2_ERR_NODATA 0x20
#define PS2_LED_SCROLL_LOCK 0
#define PS2_LED_NUM_LOCK 1
@@ -71,13 +85,101 @@ POSSIBILITY OF SUCH DAMAGE.
extern uint8_t ps2_error;
-/* host role */
void ps2_host_init(void);
uint8_t ps2_host_send(uint8_t data);
uint8_t ps2_host_recv_response(void);
uint8_t ps2_host_recv(void);
void ps2_host_set_led(uint8_t usb_led);
-/* device role */
+
+/* Check port settings for clock and data line */
+#if !(defined(PS2_CLOCK_PORT) && \
+ defined(PS2_CLOCK_PIN) && \
+ defined(PS2_CLOCK_DDR) && \
+ defined(PS2_CLOCK_BIT))
+# error "PS/2 clock port setting is required in config.h"
+#endif
+
+#if !(defined(PS2_DATA_PORT) && \
+ defined(PS2_DATA_PIN) && \
+ defined(PS2_DATA_DDR) && \
+ defined(PS2_DATA_BIT))
+# error "PS/2 data port setting is required in config.h"
+#endif
+
+/*--------------------------------------------------------------------
+ * static functions
+ *------------------------------------------------------------------*/
+static inline void clock_lo(void)
+{
+ PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT);
+ PS2_CLOCK_DDR |= (1<<PS2_CLOCK_BIT);
+}
+static inline void clock_hi(void)
+{
+ /* input with pull up */
+ PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
+ PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
+}
+static inline bool clock_in(void)
+{
+ PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
+ PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
+ _delay_us(1);
+ return PS2_CLOCK_PIN&(1<<PS2_CLOCK_BIT);
+}
+static inline void data_lo(void)
+{
+ PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT);
+ PS2_DATA_DDR |= (1<<PS2_DATA_BIT);
+}
+static inline void data_hi(void)
+{
+ /* input with pull up */
+ PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
+ PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
+}
+static inline bool data_in(void)
+{
+ PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
+ PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
+ _delay_us(1);
+ return PS2_DATA_PIN&(1<<PS2_DATA_BIT);
+}
+
+static inline uint16_t wait_clock_lo(uint16_t us)
+{
+ while (clock_in() && us) { asm(""); _delay_us(1); us--; }
+ return us;
+}
+static inline uint16_t wait_clock_hi(uint16_t us)
+{
+ while (!clock_in() && us) { asm(""); _delay_us(1); us--; }
+ return us;
+}
+static inline uint16_t wait_data_lo(uint16_t us)
+{
+ while (data_in() && us) { asm(""); _delay_us(1); us--; }
+ return us;
+}
+static inline uint16_t wait_data_hi(uint16_t us)
+{
+ while (!data_in() && us) { asm(""); _delay_us(1); us--; }
+ return us;
+}
+
+/* idle state that device can send */
+static inline void idle(void)
+{
+ clock_hi();
+ data_hi();
+}
+
+/* inhibit device to send */
+static inline void inhibit(void)
+{
+ clock_lo();
+ data_hi();
+}
#endif
diff --git a/protocol/ps2_busywait.c b/protocol/ps2_busywait.c
new file mode 100644
index 000000000..05dd7b27e
--- /dev/null
+++ b/protocol/ps2_busywait.c
@@ -0,0 +1,185 @@
+/*
+Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com>
+
+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.
+*/
+
+/*
+ * PS/2 protocol busywait version
+ */
+
+#include <stdbool.h>
+#include <util/delay.h>
+#include "ps2.h"
+#include "debug.h"
+
+
+#define WAIT(stat, us, err) do { \
+ if (!wait_##stat(us)) { \
+ ps2_error = err; \
+ goto ERROR; \
+ } \
+} while (0)
+
+
+uint8_t ps2_error = PS2_ERR_NONE;
+
+
+void ps2_host_init(void)
+{
+ // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
+ _delay_ms(2500);
+
+ inhibit();
+}
+
+uint8_t ps2_host_send(uint8_t data)
+{
+ bool parity = true;
+ ps2_error = PS2_ERR_NONE;
+
+ /* terminate a transmission if we have */
+ inhibit();
+ _delay_us(100); // 100us [4]p.13, [5]p.50
+
+ /* 'Request to Send' and Start bit */
+ data_lo();
+ clock_hi();
+ WAIT(clock_lo, 10000, 10); // 10ms [5]p.50
+
+ /* Data bit */
+ for (uint8_t i = 0; i < 8; i++) {
+ _delay_us(15);
+ if (data&(1<<i)) {
+ parity = !parity;
+ data_hi();
+ } else {
+ data_lo();
+ }
+ WAIT(clock_hi, 50, 2);
+ WAIT(clock_lo, 50, 3);
+ }
+
+ /* Parity bit */
+ _delay_us(15);
+ if (parity) { data_hi(); } else { data_lo(); }
+ WAIT(clock_hi, 50, 4);
+ WAIT(clock_lo, 50, 5);
+
+ /* Stop bit */
+ _delay_us(15);
+ data_hi();
+
+ /* Ack */
+ WAIT(data_lo, 50, 6);
+ WAIT(clock_lo, 50, 7);
+
+ /* wait for idle state */
+ WAIT(clock_hi, 50, 8);
+ WAIT(data_hi, 50, 9);
+
+ inhibit();
+ return ps2_host_recv_response();
+ERROR:
+ inhibit();
+ return 0;
+}
+
+/* receive data when host want else inhibit communication */
+uint8_t ps2_host_recv_response(void)
+{
+ // Command may take 25ms/20ms at most([5]p.46, [3]p.21)
+ // 250 * 100us(wait for start bit in ps2_host_recv)
+ uint8_t data = 0;
+ uint8_t try = 250;
+ do {
+ data = ps2_host_recv();
+ } while (try-- && ps2_error);
+ return data;
+}
+
+/* called after start bit comes */
+uint8_t ps2_host_recv(void)
+{
+ uint8_t data = 0;
+ bool parity = true;
+ ps2_error = PS2_ERR_NONE;
+
+ /* release lines(idle state) */
+ idle();
+
+ /* start bit [1] */
+ WAIT(clock_lo, 100, 1); // TODO: this is enough?
+ WAIT(data_lo, 1, 2);
+ WAIT(clock_hi, 50, 3);
+
+ /* data [2-9] */
+ for (uint8_t i = 0; i < 8; i++) {
+ WAIT(clock_lo, 50, 4);
+ if (data_in()) {
+ parity = !parity;
+ data |= (1<<i);
+ }
+ WAIT(clock_hi, 50, 5);
+ }
+
+ /* parity [10] */
+ WAIT(clock_lo, 50, 6);
+ if (data_in() != parity) {
+ ps2_error = PS2_ERR_PARITY;
+ goto ERROR;
+ }
+ WAIT(clock_hi, 50, 7);
+
+ /* stop bit [11] */
+ WAIT(clock_lo, 50, 8);
+ WAIT(data_hi, 1, 9);
+ WAIT(clock_hi, 50, 10);
+
+ inhibit();
+ return data;
+ERROR:
+ if (ps2_error > PS2_ERR_STARTBIT3) {
+ xprintf("x%02X\n", ps2_error);
+ }
+ inhibit();
+ return 0;
+}
+
+/* send LED state to keyboard */
+void ps2_host_set_led(uint8_t led)
+{
+ ps2_host_send(0xED);
+ ps2_host_send(led);
+}
diff --git a/protocol/ps2.c b/protocol/ps2_interrupt.c
index e5873a9bf..259d25400 100644
--- a/protocol/ps2.c
+++ b/protocol/ps2_interrupt.c
@@ -35,47 +35,15 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * PS/2 protocol Pin interrupt version
+ */
+
#include <stdbool.h>
-#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "ps2.h"
-#include "debug.h"
-
-
-#ifndef PS2_USE_INT
-static uint8_t recv_data(void);
-#endif
-static inline void clock_lo(void);
-static inline void clock_hi(void);
-static inline bool clock_in(void);
-static inline void data_lo(void);
-static inline void data_hi(void);
-static inline bool data_in(void);
-static inline uint16_t wait_clock_lo(uint16_t us);
-static inline uint16_t wait_clock_hi(uint16_t us);
-static inline uint16_t wait_data_lo(uint16_t us);
-static inline uint16_t wait_data_hi(uint16_t us);
-static inline void idle(void);
-static inline void inhibit(void);
-
-
-/*
-Primitive PS/2 Library for AVR
-==============================
-Host side is only supported now.
-
-
-I/O control
------------
-High state is asserted by input with pull up.
-
-
-PS/2 References
----------------
-http://www.computer-engineering.org/ps2protocol/
-http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
-*/
+#include "print.h"
#define WAIT(stat, us, err) do { \
@@ -89,35 +57,38 @@ http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
uint8_t ps2_error = PS2_ERR_NONE;
+static inline uint8_t pbuf_dequeue(void);
+static inline void pbuf_enqueue(uint8_t data);
+static inline bool pbuf_has_data(void);
+static inline void pbuf_clear(void);
+
+
void ps2_host_init(void)
{
-#ifdef PS2_USE_INT
+ idle();
PS2_INT_INIT();
PS2_INT_ON();
- idle();
-#else
- inhibit();
-#endif
+ // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
+ //_delay_ms(2500);
}
-// TODO: send using interrupt if available
uint8_t ps2_host_send(uint8_t data)
{
- uint8_t res = 0;
bool parity = true;
ps2_error = PS2_ERR_NONE;
-#ifdef PS2_USE_INT
+
PS2_INT_OFF();
-#endif
+
/* terminate a transmission if we have */
inhibit();
- _delay_us(200); // at least 100us
+ _delay_us(100); // 100us [4]p.13, [5]p.50
- /* start bit [1] */
+ /* 'Request to Send' and Start bit */
data_lo();
clock_hi();
- WAIT(clock_lo, 20000, 10); // may take 15ms at most until device starts clocking
- /* data [2-9] */
+ WAIT(clock_lo, 10000, 10); // 10ms [5]p.50
+
+ /* Data bit[2-9] */
for (uint8_t i = 0; i < 8; i++) {
_delay_us(15);
if (data&(1<<i)) {
@@ -129,15 +100,18 @@ uint8_t ps2_host_send(uint8_t data)
WAIT(clock_hi, 50, 2);
WAIT(clock_lo, 50, 3);
}
- /* parity [10] */
+
+ /* Parity bit */
_delay_us(15);
if (parity) { data_hi(); } else { data_lo(); }
WAIT(clock_hi, 50, 4);
WAIT(clock_lo, 50, 5);
- /* stop bit [11] */
+
+ /* Stop bit */
_delay_us(15);
data_hi();
- /* ack [12] */
+
+ /* Ack */
WAIT(data_lo, 50, 6);
WAIT(clock_lo, 50, 7);
@@ -145,116 +119,35 @@ uint8_t ps2_host_send(uint8_t data)
WAIT(clock_hi, 50, 8);
WAIT(data_hi, 50, 9);
-#ifdef PS2_USE_INT
+ idle();
PS2_INT_ON();
-#endif
- res = ps2_host_recv_response();
+ return ps2_host_recv_response();
ERROR:
-#ifdef PS2_USE_INT
- PS2_INT_ON();
idle();
-#else
- inhibit();
-#endif
- return res;
+ PS2_INT_ON();
+ return 0;
}
-#ifndef PS2_USE_INT
-/* receive data when host want else inhibit communication */
uint8_t ps2_host_recv_response(void)
{
- uint8_t data = 0;
-
-#ifdef PS2_USE_INT
- PS2_INT_OFF();
-#endif
- /* terminate a transmission if we have */
- inhibit();
- _delay_us(100);
-
- /* release lines(idle state) */
- idle();
-
- /* wait start bit */
- wait_clock_lo(25000); // command response may take 20 ms at most
- data = recv_data();
-
- inhibit();
- return data;
-}
-#endif
-
-#ifndef PS2_USE_INT
-uint8_t ps2_host_recv(void)
-{
- return ps2_host_recv_response();
-}
-#else
-/* ring buffer to store ps/2 key data */
-#define PBUF_SIZE 32
-static uint8_t pbuf[PBUF_SIZE];
-static uint8_t pbuf_head = 0;
-static uint8_t pbuf_tail = 0;
-static inline void pbuf_enqueue(uint8_t data)
-{
- uint8_t sreg = SREG;
- cli();
- uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
- if (next != pbuf_tail) {
- pbuf[pbuf_head] = data;
- pbuf_head = next;
- } else {
- debug("pbuf: full\n");
- }
- SREG = sreg;
-}
-static inline uint8_t pbuf_dequeue(void)
-{
- uint8_t val = 0;
-
- uint8_t sreg = SREG;
- cli();
- if (pbuf_head != pbuf_tail) {
- val = pbuf[pbuf_tail];
- pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
+ // Command may take 25ms/20ms at most([5]p.46, [3]p.21)
+ uint8_t retry = 25;
+ while (retry-- && !pbuf_has_data()) {
+ _delay_ms(1);
}
- SREG = sreg;
-
- return val;
-}
-static inline bool pbuf_has_data(void)
-{
- uint8_t sreg = SREG;
- cli();
- bool has_data = (pbuf_head != pbuf_tail);
- SREG = sreg;
- return has_data;
-}
-static inline void pbuf_clear(void)
-{
- uint8_t sreg = SREG;
- cli();
- pbuf_head = pbuf_tail = 0;
- SREG = sreg;
+ return pbuf_dequeue();
}
/* get data received by interrupt */
uint8_t ps2_host_recv(void)
{
- if (ps2_error) {
- print("x");
- phex(ps2_error);
- ps2_host_send(0xFE); // request to resend
+ if (pbuf_has_data()) {
ps2_error = PS2_ERR_NONE;
+ return pbuf_dequeue();
+ } else {
+ ps2_error = PS2_ERR_NODATA;
+ return 0;
}
- idle();
- return pbuf_dequeue();
-}
-
-uint8_t ps2_host_recv_response(void)
-{
- while (!pbuf_has_data()) ;
- return pbuf_dequeue();
}
ISR(PS2_INT_VECT)
@@ -309,7 +202,6 @@ ISR(PS2_INT_VECT)
if (!data_in())
goto ERROR;
pbuf_enqueue(data);
-//phex(data);
goto DONE;
break;
default:
@@ -317,7 +209,6 @@ ISR(PS2_INT_VECT)
}
goto RETURN;
ERROR:
- inhibit();
ps2_error = state;
DONE:
state = INIT;
@@ -326,8 +217,6 @@ DONE:
RETURN:
return;
}
-#endif
-
/* send LED state to keyboard */
void ps2_host_set_led(uint8_t led)
@@ -337,116 +226,53 @@ void ps2_host_set_led(uint8_t led)
}
-#ifndef PS2_USE_INT
-/* called after start bit comes */
-static uint8_t recv_data(void)
+/*--------------------------------------------------------------------
+ * Ring buffer to store scan codes from keyboard
+ *------------------------------------------------------------------*/
+#define PBUF_SIZE 32
+static uint8_t pbuf[PBUF_SIZE];
+static uint8_t pbuf_head = 0;
+static uint8_t pbuf_tail = 0;
+static inline void pbuf_enqueue(uint8_t data)
{
- uint8_t data = 0;
- bool parity = true;
- ps2_error = PS2_ERR_NONE;
-
- /* start bit [1] */
- WAIT(clock_lo, 1, 1);
- WAIT(data_lo, 1, 2);
- WAIT(clock_hi, 50, 3);
-
- /* data [2-9] */
- for (uint8_t i = 0; i < 8; i++) {
- WAIT(clock_lo, 50, 4);
- if (data_in()) {
- parity = !parity;
- data |= (1<<i);
- }
- WAIT(clock_hi, 50, 5);
- }
-
- /* parity [10] */
- WAIT(clock_lo, 50, 6);
- if (data_in() != parity) {
- ps2_error = PS2_ERR_PARITY;
- goto ERROR;
+ uint8_t sreg = SREG;
+ cli();
+ uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
+ if (next != pbuf_tail) {
+ pbuf[pbuf_head] = data;
+ pbuf_head = next;
+ } else {
+ print("pbuf: full\n");
}
- WAIT(clock_hi, 50, 7);
-
- /* stop bit [11] */
- WAIT(clock_lo, 50, 8);
- WAIT(data_hi, 1, 9);
- WAIT(clock_hi, 50, 10);
-
- return data;
-ERROR:
- return 0;
-}
-#endif
-
-static inline void clock_lo()
-{
- PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT);
- PS2_CLOCK_DDR |= (1<<PS2_CLOCK_BIT);
-}
-static inline void clock_hi()
-{
- /* input with pull up */
- PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
- PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
-}
-static inline bool clock_in()
-{
- PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
- PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
- _delay_us(1);
- return PS2_CLOCK_PIN&(1<<PS2_CLOCK_BIT);
-}
-static inline void data_lo()
-{
- PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT);
- PS2_DATA_DDR |= (1<<PS2_DATA_BIT);
-}
-static inline void data_hi()
-{
- /* input with pull up */
- PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
- PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
+ SREG = sreg;
}
-static inline bool data_in()
+static inline uint8_t pbuf_dequeue(void)
{
- PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
- PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
- _delay_us(1);
- return PS2_DATA_PIN&(1<<PS2_DATA_BIT);
-}
+ uint8_t val = 0;
-static inline uint16_t wait_clock_lo(uint16_t us)
-{
- while (clock_in() && us) { asm(""); _delay_us(1); us--; }
- return us;
-}
-static inline uint16_t wait_clock_hi(uint16_t us)
-{
- while (!clock_in() && us) { asm(""); _delay_us(1); us--; }
- return us;
-}
-static inline uint16_t wait_data_lo(uint16_t us)
-{
- while (data_in() && us) { asm(""); _delay_us(1); us--; }
- return us;
+ uint8_t sreg = SREG;
+ cli();
+ if (pbuf_head != pbuf_tail) {
+ val = pbuf[pbuf_tail];
+ pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
+ }
+ SREG = sreg;
+
+ return val;
}
-static inline uint16_t wait_data_hi(uint16_t us)
+static inline bool pbuf_has_data(void)
{
- while (!data_in() && us) { asm(""); _delay_us(1); us--; }
- return us;
+ uint8_t sreg = SREG;
+ cli();
+ bool has_data = (pbuf_head != pbuf_tail);
+ SREG = sreg;
+ return has_data;
}
-
-/* idle state that device can send */
-static inline void idle(void)
+static inline void pbuf_clear(void)
{
- clock_hi();
- data_hi();
+ uint8_t sreg = SREG;
+ cli();
+ pbuf_head = pbuf_tail = 0;
+ SREG = sreg;
}
-/* inhibit device to send */
-static inline void inhibit(void)
-{
- clock_lo();
- data_hi();
-}
diff --git a/protocol/ps2_usart.c b/protocol/ps2_usart.c
index 40c46c497..c2d9d0a20 100644
--- a/protocol/ps2_usart.c
+++ b/protocol/ps2_usart.c
@@ -36,32 +36,14 @@ POSSIBILITY OF SUCH DAMAGE.
*/
/*
-Primitive PS/2 Library for AVR
-==============================
-Host side is only supported now.
-Synchronous USART is used to receive data by hardware process
-rather than interrupt. During V-USB interrupt runs, CLOCK interrupt
-cannot interpose. In the result it is prone to lost CLOCK edge.
+ * PS/2 protocol USART version
+ */
-
-I/O control
------------
-High state is asserted by internal pull-up.
-If you have a signaling problem, you may need to have
-external pull-up resisters on CLOCK and DATA line.
-
-
-PS/2 References
----------------
-http://www.computer-engineering.org/ps2protocol/
-http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
-*/
#include <stdbool.h>
-#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "ps2.h"
-#include "debug.h"
+#include "print.h"
#define WAIT(stat, us, err) do { \
@@ -75,18 +57,6 @@ http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
uint8_t ps2_error = PS2_ERR_NONE;
-static inline void clock_lo(void);
-static inline void clock_hi(void);
-static inline bool clock_in(void);
-static inline void data_lo(void);
-static inline void data_hi(void);
-static inline bool data_in(void);
-static inline uint16_t wait_clock_lo(uint16_t us);
-static inline uint16_t wait_clock_hi(uint16_t us);
-static inline uint16_t wait_data_lo(uint16_t us);
-static inline uint16_t wait_data_hi(uint16_t us);
-static inline void idle(void);
-static inline void inhibit(void);
static inline uint8_t pbuf_dequeue(void);
static inline void pbuf_enqueue(uint8_t data);
static inline bool pbuf_has_data(void);
@@ -95,14 +65,15 @@ static inline void pbuf_clear(void);
void ps2_host_init(void)
{
- idle();
+ idle(); // without this many USART errors occur when cable is disconnected
PS2_USART_INIT();
PS2_USART_RX_INT_ON();
+ // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
+ //_delay_ms(2500);
}
uint8_t ps2_host_send(uint8_t data)
{
- uint8_t res = 0;
bool parity = true;
ps2_error = PS2_ERR_NONE;
@@ -110,13 +81,14 @@ uint8_t ps2_host_send(uint8_t data)
/* terminate a transmission if we have */
inhibit();
- _delay_us(100);
+ _delay_us(100); // [4]p.13
- /* start bit [1] */
+ /* 'Request to Send' and Start bit */
data_lo();
clock_hi();
- WAIT(clock_lo, 15000, 1);
- /* data [2-9] */
+ WAIT(clock_lo, 10000, 10); // 10ms [5]p.50
+
+ /* Data bit[2-9] */
for (uint8_t i = 0; i < 8; i++) {
_delay_us(15);
if (data&(1<<i)) {
@@ -128,15 +100,18 @@ uint8_t ps2_host_send(uint8_t data)
WAIT(clock_hi, 50, 2);
WAIT(clock_lo, 50, 3);
}
- /* parity [10] */
+
+ /* Parity bit */
_delay_us(15);
if (parity) { data_hi(); } else { data_lo(); }
WAIT(clock_hi, 50, 4);
WAIT(clock_lo, 50, 5);
- /* stop bit [11] */
+
+ /* Stop bit */
_delay_us(15);
data_hi();
- /* ack [12] */
+
+ /* Ack */
WAIT(data_lo, 50, 6);
WAIT(clock_lo, 50, 7);
@@ -144,127 +119,55 @@ uint8_t ps2_host_send(uint8_t data)
WAIT(clock_hi, 50, 8);
WAIT(data_hi, 50, 9);
+ idle();
PS2_USART_INIT();
PS2_USART_RX_INT_ON();
- res = ps2_host_recv_response();
+ return ps2_host_recv_response();
ERROR:
idle();
PS2_USART_INIT();
PS2_USART_RX_INT_ON();
- return res;
+ return 0;
}
-// Do polling data from keyboard to get response to last command.
uint8_t ps2_host_recv_response(void)
{
- while (!pbuf_has_data()) {
- _delay_ms(1); // without this delay it seems to fall into deadlock
+ // Command may take 25ms/20ms at most([5]p.46, [3]p.21)
+ uint8_t retry = 25;
+ while (retry-- && !pbuf_has_data()) {
+ _delay_ms(1);
}
return pbuf_dequeue();
}
uint8_t ps2_host_recv(void)
{
- return pbuf_dequeue();
+ if (pbuf_has_data()) {
+ ps2_error = PS2_ERR_NONE;
+ return pbuf_dequeue();
+ } else {
+ ps2_error = PS2_ERR_NODATA;
+ return 0;
+ }
}
ISR(PS2_USART_RX_VECT)
{
- uint8_t error = PS2_USART_ERROR;
+ // TODO: request RESEND when error occurs?
+ uint8_t error = PS2_USART_ERROR; // USART error should be read before data
uint8_t data = PS2_USART_RX_DATA;
if (!error) {
pbuf_enqueue(data);
+ } else {
+ xprintf("PS2 USART error: %02X data: %02X\n", error, data);
}
}
/* send LED state to keyboard */
void ps2_host_set_led(uint8_t led)
{
- // send 0xED then keyboard keeps waiting for next LED data
- // and keyboard does not send any scan codes during waiting.
- // If fail to send LED data keyboard looks like being freezed.
- uint8_t retry = 3;
- while (retry-- && ps2_host_send(PS2_SET_LED) != PS2_ACK)
- ;
- retry = 3;
- while (retry-- && ps2_host_send(led) != PS2_ACK)
- ;
-}
-
-
-/*--------------------------------------------------------------------
- * static functions
- *------------------------------------------------------------------*/
-static inline void clock_lo()
-{
- PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT);
- PS2_CLOCK_DDR |= (1<<PS2_CLOCK_BIT);
-}
-static inline void clock_hi()
-{
- /* input with pull up */
- PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
- PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
-}
-static inline bool clock_in()
-{
- PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
- PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
- _delay_us(1);
- return PS2_CLOCK_PIN&(1<<PS2_CLOCK_BIT);
-}
-static inline void data_lo()
-{
- PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT);
- PS2_DATA_DDR |= (1<<PS2_DATA_BIT);
-}
-static inline void data_hi()
-{
- /* input with pull up */
- PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
- PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
-}
-static inline bool data_in()
-{
- PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
- PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
- _delay_us(1);
- return PS2_DATA_PIN&(1<<PS2_DATA_BIT);
-}
-
-static inline uint16_t wait_clock_lo(uint16_t us)
-{
- while (clock_in() && us) { asm(""); _delay_us(1); us--; }
- return us;
-}
-static inline uint16_t wait_clock_hi(uint16_t us)
-{
- while (!clock_in() && us) { asm(""); _delay_us(1); us--; }
- return us;
-}
-static inline uint16_t wait_data_lo(uint16_t us)
-{
- while (data_in() && us) { asm(""); _delay_us(1); us--; }
- return us;
-}
-static inline uint16_t wait_data_hi(uint16_t us)
-{
- while (!data_in() && us) { asm(""); _delay_us(1); us--; }
- return us;
-}
-
-/* idle state that device can send */
-static inline void idle(void)
-{
- clock_hi();
- data_hi();
-}
-
-/* inhibit device to send */
-static inline void inhibit(void)
-{
- clock_lo();
- data_hi();
+ ps2_host_send(0xED);
+ ps2_host_send(led);
}
@@ -284,11 +187,10 @@ static inline void pbuf_enqueue(uint8_t data)
pbuf[pbuf_head] = data;
pbuf_head = next;
} else {
- debug("pbuf: full\n");
+ print("pbuf: full\n");
}
SREG = sreg;
}
-
static inline uint8_t pbuf_dequeue(void)
{
uint8_t val = 0;