summaryrefslogtreecommitdiff
path: root/converter/ps2_usb
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2012-06-11 10:53:02 +0900
committertmk <nobody@nowhere>2012-06-11 10:53:02 +0900
commit62d1ebb91c7b381ce3d88aad9ee0b03bea9fce26 (patch)
tree6b10864a310f611187e1b61102da7da1db1d2e29 /converter/ps2_usb
parent225de7a847a511d004bf909b1334e19497cf2f9d (diff)
parent81706d1130fdc3c0d6d110f4d8665c47ffd7fb59 (diff)
Merge branch 'newdir'
Diffstat (limited to 'converter/ps2_usb')
-rw-r--r--converter/ps2_usb/Makefile58
-rw-r--r--converter/ps2_usb/Makefile.pjrc_usart58
-rw-r--r--converter/ps2_usb/Makefile.vusb92
-rw-r--r--converter/ps2_usb/README116
-rw-r--r--converter/ps2_usb/README.vusb37
-rw-r--r--converter/ps2_usb/config_pjrc.h59
-rw-r--r--converter/ps2_usb/config_pjrc_usart.h91
-rw-r--r--converter/ps2_usb/config_vusb.h133
-rw-r--r--converter/ps2_usb/keymap.c379
-rw-r--r--converter/ps2_usb/led.c33
-rw-r--r--converter/ps2_usb/matrix.c452
-rw-r--r--converter/ps2_usb/usbconfig.h378
12 files changed, 1886 insertions, 0 deletions
diff --git a/converter/ps2_usb/Makefile b/converter/ps2_usb/Makefile
new file mode 100644
index 0000000000..0bba191a38
--- /dev/null
+++ b/converter/ps2_usb/Makefile
@@ -0,0 +1,58 @@
+#
+# Makefile for PJRC Teensy
+#
+
+
+# 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 = main.c \
+ keymap.c \
+ matrix.c \
+ led.c \
+ ps2.c
+
+CONFIG_H = config_pjrc.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
+
+
+# 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
+
+
+
+#---------------- Programming Options --------------------------
+PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex
+
+
+
+include $(TOP_DIR)/protocol/pjrc.mk
+include $(TOP_DIR)/protocol.mk
+include $(TOP_DIR)/common.mk
+include $(TOP_DIR)/rules.mk
diff --git a/converter/ps2_usb/Makefile.pjrc_usart b/converter/ps2_usb/Makefile.pjrc_usart
new file mode 100644
index 0000000000..3dad7e2f8c
--- /dev/null
+++ b/converter/ps2_usb/Makefile.pjrc_usart
@@ -0,0 +1,58 @@
+#
+# Makefile for PJRC Teensy
+#
+
+
+# Target file name (without extension).
+TARGET = ps2_usb_pjrc_usart
+
+# Directory common source filess exist
+TOP_DIR = ../..
+
+# Directory keyboard dependent files exist
+TARGET_DIR = .
+
+# keyboard dependent files
+SRC = main.c \
+ keymap.c \
+ matrix.c \
+ led.c \
+ ps2_usart.c
+
+CONFIG_H = config_pjrc_usart.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
+
+
+# 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
+
+
+
+#---------------- Programming Options --------------------------
+PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex
+
+
+
+include $(TOP_DIR)/protocol/pjrc.mk
+include $(TOP_DIR)/protocol.mk
+include $(TOP_DIR)/common.mk
+include $(TOP_DIR)/rules.mk
diff --git a/converter/ps2_usb/Makefile.vusb b/converter/ps2_usb/Makefile.vusb
new file mode 100644
index 0000000000..4d5240c309
--- /dev/null
+++ b/converter/ps2_usb/Makefile.vusb
@@ -0,0 +1,92 @@
+#
+# Makefile for V-USB
+#
+
+
+# Target file name (without extension).
+TARGET = ps2_usb_vusb
+
+# Directory common source filess exist
+TOP_DIR = ../..
+
+# Directory keyboard dependent files exist
+TARGET_DIR = .
+
+# keyboard dependent files
+SRC = main.c \
+ keymap.c \
+ matrix.c \
+ led.c \
+ ps2_usart.c
+
+CONFIG_H = config_vusb.h
+
+
+# V-USB debug level: To use ps2_usart.c level must be 0
+# ps2_usart.c requires USART to receive PS/2 signal.
+OPT_DEFS = -DDEBUG_LEVEL=0
+
+
+# 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 = atmega168
+
+
+# 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 = 20000000
+
+
+# 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
+NO_UART = yes # UART is unavailable
+
+
+
+#---------------- Programming Options --------------------------
+AVRDUDE = avrdude
+# Type: avrdude -c ? to get a full listing.
+AVRDUDE_PROGRAMMER = usbasp
+AVRDUDE_PORT =
+AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
+#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
+
+# Uncomment the following if you want avrdude's erase cycle counter.
+# Note that this counter needs to be initialized first using -Yn,
+# see avrdude manual.
+#AVRDUDE_ERASE_COUNTER = -y
+
+# Uncomment the following if you do /not/ wish a verification to be
+# performed after programming the device.
+#AVRDUDE_NO_VERIFY = -V
+
+# Increase verbosity level. Please use this when submitting bug
+# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
+# to submit bug reports.
+#AVRDUDE_VERBOSE = -v -v
+
+#AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
+AVRDUDE_FLAGS = -p $(MCU) -c $(AVRDUDE_PROGRAMMER)
+AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
+AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
+AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
+
+PROGRAM_CMD = $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
+
+
+
+include $(TOP_DIR)/protocol/vusb.mk
+include $(TOP_DIR)/protocol.mk
+include $(TOP_DIR)/common.mk
+include $(TOP_DIR)/rules.mk
diff --git a/converter/ps2_usb/README b/converter/ps2_usb/README
new file mode 100644
index 0000000000..c10393e5e7
--- /dev/null
+++ b/converter/ps2_usb/README
@@ -0,0 +1,116 @@
+PS/2 to USB keyboard converter
+==============================
+This firmware converts PS/2 keyboard protocol to USB and for now supports only Scan Code Set 2.
+This will works on USB AVR(ATMega32U4, AT90USB) or V-USB.
+
+
+Features
+--------
+Mouse keys
+ You can emulates mouse move and button click using keyboard.
+System/Media control
+ You can sends Power event, Volume down/up and Mute.
+USB NKRO(actually 120KRO+8Modifiers)
+ You can tolggles NKRO feature.
+Keymap customization
+ You can customize keymaps easily by editing source code. See keymap.c.
+
+
+PS/2 signal handling implementations
+------------------------------------
+Following three methods are used to implement PS/2 signal handling.
+a. Simple and stupid wait & read loop(intensive use of cycles)
+ This is implemented with (expected) portable C code for reference. See ps2.c.
+b. Interrupt driven
+ See ps2_intr.c
+c. Using USART hardware module(no cycle needed)
+ This uses AVR USART function to recevie PS/2 signal and be used in V-USB converter.
+ See ps2_usart.c.
+
+
+Build Converter
+---------------
+Connect PS/2 keyboard into Teensy with 4 lines(Vcc, GND, Data, Clock).
+For a. Simple and stupid and b. Interrupt implementaion:
+ By default Clock is on PF0 and Data on PF1.
+ You can change this pin configuration by editing config_pjrc.h.
+ In this photo Vcc is yellow, GND is green, Data is red and Clock is black.
+ http://img17.imageshack.us/img17/7243/201101181933.jpg
+For c. USART implementation:
+ In case of Teensny(ATMega32u4) CLock is on PD5 and Data on PD2.
+
+
+Build Frimware
+--------------
+1. Edit Makefile for build options and MCU setting.
+ Use 'atmega32u4' for Teensy 2.0 or 'at90usb1286' for Teensy++ 2.0.
+2. make
+ Just type 'make' in a terminal.
+ Use '-f Makefile.pjrc_intr' option to use b. Interrupt.
+ Use '-f Makefile.pjrc_usart' option to use c. USART.
+ Use '-f Makefile.vusb' option to build V-USB converter.
+3. program with Teensy Loader.
+ http://www.pjrc.com/teensy/loader.html
+
+
+Demonstration of Features
+-------------------------
+In default configuration, you can try several keymaps, mousekeys and USB NKRO.
+Use following magic key combinations to enable some features.
+
+keymaps and NKRO:
+ Magic+0: Qwerty with mousekeys(default)
+ Magic+1: Qwerty without mousekeys
+ Magic+2: Colemak
+ Magic+3: Dvorak
+ Magic+4: Workman
+ Magic+N: toggles NKRO/6KRO(6KRO by default)
+ Magic+Esc: sends Power Event(Power button)
+
+ where Magic=(LShift+RShift) or (LControl+RShift)
+
+Fn layer function:
+ Fn0+(hjkl): Mousekey move(vi cursor like)
+ Fn0+(yuio): Mouse wheel(left,down,up,right)
+ Fn0+space: Mouse left button
+ Fn0+(mnb): Mouse buttons(m=left, n=right, b=middle)
+ Fn0+(zxc): Media control(Volup, Voldown, Mute)
+ Fn1+(hjkl): Cursor move(vi cursor like)
+ Fn1+(nm,.): Cursor move(Home,PageDown,PageUp,End)
+
+ where Fn0=;, Fn1=/
+
+
+Keymap
+------
+You can change a keymap by editing code of keymap.c like following.
+How to define the keymap is probably obvious. You can find key symbols in usb_keycodes.h.
+To define keymap layer switching may needs a bit of your effort at this time.
+
+ /* Default Layer: plain keymap
+ * ,---. ,---------------. ,---------------. ,---------------. ,-----------. ,-----------.
+ * |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| .| |
+ * `-----------------------------------------------------------' `-----------' `---------------'
+ */
+ KEYMAP(
+ ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, PWR, F13, F14,
+ 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
+ ),
+
+
+EOF
diff --git a/converter/ps2_usb/README.vusb b/converter/ps2_usb/README.vusb
new file mode 100644
index 0000000000..c92871bcdd
--- /dev/null
+++ b/converter/ps2_usb/README.vusb
@@ -0,0 +1,37 @@
+V-USB Support
+=============
+You can also use this converter on ATmega(168/328) with V-USB instead of Teensy.
+The converter on V-USB lacks some features for now: USB NKRO and System/Media control.
+
+To build a firmware use Makefile.vusb instead of Makefile.
+
+
+Circuit
+-------
+ +---+ +---------------+
+USB GND | | ATmega168 |
+=== C3 | |
+5V <-------+--------+---|Vcc,AVCC | PS/2
+ R1 | | ====
+D- <----+--+-----R2-----|INT1 RXD|------->DATA
+D+ <----|---+----R3-----|INT0 XCK|------->CLOCK
+ Z1 Z2 | | ->5V
+GND<----+---+--+--+-----|GND | ->GND
+ | | | |
+ | C2-+--|XTAL1 |
+ | X1 | |
+ +--C3-+--|XTAL2 |
+ +---------------+
+R1: 1.5K Ohm
+R2,R3: 68 Ohm
+Z1,Z2: Zenner 3.6V
+C1,C2: 22pF
+C3: 0.1uF
+X1: Crystal 20MHz(16MHz/12MHz)
+
+
+This is my V-USB converter on breadboard.
+[IMG]http://i.imgur.com/8jJCZl.jpg[/IMG]
+
+
+EOF
diff --git a/converter/ps2_usb/config_pjrc.h b/converter/ps2_usb/config_pjrc.h
new file mode 100644
index 0000000000..883ffab275
--- /dev/null
+++ b/converter/ps2_usb/config_pjrc.h
@@ -0,0 +1,59 @@
+/*
+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
+
+/* controller configuration */
+#include "controller_teensy.h"
+
+#define VENDOR_ID 0xFEED
+#define PRODUCT_ID 0x6512
+#define MANUFACTURER t.m.k.
+#define PRODUCT PS/2 keyboard converter
+#define DESCRIPTION convert PS/2 keyboard to USB
+
+
+/* matrix size */
+#define MATRIX_ROWS 32 // keycode bit: 3-0
+#define MATRIX_COLS 8 // keycode bit: 6-4
+
+
+/* key combination for command */
+#define IS_COMMAND() ( \
+ keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)) || \
+ keyboard_report->mods == (MOD_BIT(KB_LCTRL) | MOD_BIT(KB_RSHIFT)) \
+)
+
+
+/* mouse keys */
+#ifdef MOUSEKEY_ENABLE
+# define MOUSEKEY_DELAY_TIME 255
+#endif
+
+
+/* PS/2 lines */
+#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
diff --git a/converter/ps2_usb/config_pjrc_usart.h b/converter/ps2_usb/config_pjrc_usart.h
new file mode 100644
index 0000000000..83ddbf7703
--- /dev/null
+++ b/converter/ps2_usb/config_pjrc_usart.h
@@ -0,0 +1,91 @@
+/*
+Copyright 2012 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
+
+/* controller configuration */
+#include "controller_teensy.h"
+
+#define VENDOR_ID 0xFEED
+#define PRODUCT_ID 0x6513
+#define MANUFACTURER t.m.k.
+#define PRODUCT PS/2 keyboard converter(USART)
+#define DESCRIPTION convert PS/2 keyboard to USB
+
+
+/* matrix size */
+#define MATRIX_ROWS 32 // keycode bit: 3-0
+#define MATRIX_COLS 8 // keycode bit: 6-4
+
+
+/* key combination for command */
+#define IS_COMMAND() ( \
+ keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)) || \
+ keyboard_report->mods == (MOD_BIT(KB_LCTRL) | MOD_BIT(KB_RSHIFT)) \
+)
+
+
+/* mouse keys */
+#ifdef MOUSEKEY_ENABLE
+# define MOUSEKEY_DELAY_TIME 255
+#endif
+
+
+/* PS/2 lines */
+#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
+
+
+// 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 { \
+ PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT); \
+ PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); \
+ UCSR1C = ((1 << UMSEL10) | \
+ (3 << UPM10) | \
+ (0 << USBS1) | \
+ (3 << UCSZ10) | \
+ (0 << UCPOL1)); \
+ UCSR1A = 0; \
+ UBRR1H = 0; \
+ UBRR1L = 0; \
+} while (0)
+#define PS2_USART_RX_INT_ON() do { \
+ UCSR1B = ((1 << RXCIE1) | \
+ (1 << RXEN1)); \
+} while (0)
+#define PS2_USART_RX_POLL_ON() do { \
+ UCSR1B = (1 << RXEN1); \
+} while (0)
+#define PS2_USART_OFF() do { \
+ UCSR1C = 0; \
+ UCSR1B &= ~((1 << RXEN1) | \
+ (1 << TXEN1)); \
+} while (0)
+#define PS2_USART_RX_READY (UCSR1A & (1<<RXC1))
+#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
+
+#endif
diff --git a/converter/ps2_usb/config_vusb.h b/converter/ps2_usb/config_vusb.h
new file mode 100644
index 0000000000..afd2f7911f
--- /dev/null
+++ b/converter/ps2_usb/config_vusb.h
@@ -0,0 +1,133 @@
+/*
+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 0x2233
+// TODO: share these strings with usbconfig.h
+// Edit usbconfig.h to change these.
+#define MANUFACTURER t.m.k.
+#define PRODUCT PS/2 keyboard converter
+#define DESCRIPTION convert PS/2 keyboard to USB
+
+
+/* matrix size */
+#define MATRIX_ROWS 32 // keycode bit: 3-0
+#define MATRIX_COLS 8 // keycode bit: 6-4
+
+
+/* key combination for command */
+#define IS_COMMAND() ( \
+ keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)) || \
+ keyboard_report->mods == (MOD_BIT(KB_LCTRL) | MOD_BIT(KB_RSHIFT)) \
+)
+
+
+/* mouse keys */
+#ifdef MOUSEKEY_ENABLE
+# define MOUSEKEY_DELAY_TIME 255
+#endif
+
+
+/* PS/2 lines */
+#define PS2_CLOCK_PORT PORTD
+#define PS2_CLOCK_PIN PIND
+#define PS2_CLOCK_DDR DDRD
+#define PS2_CLOCK_BIT 4
+#define PS2_DATA_PORT PORTD
+#define PS2_DATA_PIN PIND
+#define PS2_DATA_DDR DDRD
+#define PS2_DATA_BIT 0
+
+
+// Synchronous USART is used to receive data from keyboard.
+// Use RXD pin for PS/2 DATA line and XCK for PS/2 CLOCK.
+// NOTE: This is recomended strongly if you use V-USB library.
+#define PS2_USE_USART
+
+// External or Pin Change Interrupt is used to receive data from keyboard.
+// Use INT1 or PCINTxx for PS/2 CLOCK line. see below.
+//#define PS2_USE_INT
+
+
+#ifdef PS2_USE_USART
+// 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 { \
+ PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT); \
+ PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); \
+ UCSR0C = ((1 << UMSEL00) | \
+ (3 << UPM00) | \
+ (0 << USBS0) | \
+ (3 << UCSZ00) | \
+ (0 << UCPOL0)); \
+ UCSR0A = 0; \
+ UBRR0H = 0; \
+ UBRR0L = 0; \
+} while (0)
+#define PS2_USART_RX_INT_ON() do { \
+ UCSR0B = ((1 << RXCIE0) | \
+ (1 << RXEN0)); \
+} while (0)
+#define PS2_USART_RX_POLL_ON() do { \
+ UCSR0B = (1 << RXEN0); \
+} while (0)
+#define PS2_USART_OFF() do { \
+ UCSR0C = 0; \
+ UCSR0B &= ~((1 << RXEN0) | \
+ (1 << TXEN0)); \
+} while (0)
+#define PS2_USART_RX_READY (UCSR0A & (1<<RXC0))
+#define PS2_USART_RX_DATA UDR0
+#define PS2_USART_ERROR (UCSR0A & ((1<<FE0) | (1<<DOR0) | (1<<UPE0)))
+#define PS2_USART_RX_VECT USART_RX_vect
+#endif
+
+
+#ifdef PS2_USE_INT
+/* INT1
+#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
+*/
+
+/* PCINT20 */
+#define PS2_INT_INIT() do { \
+ PCICR |= (1<<PCIE2); \
+} while (0)
+#define PS2_INT_ON() do { \
+ PCMSK2 |= (1<<PCINT20); \
+} while (0)
+#define PS2_INT_OFF() do { \
+ PCMSK2 &= ~(1<<PCINT20); \
+ PCICR &= ~(1<<PCIE2); \
+} while (0)
+#define PS2_INT_VECT PCINT2_vect
+#endif
+
+#endif
diff --git a/converter/ps2_usb/keymap.c b/converter/ps2_usb/keymap.c
new file mode 100644
index 0000000000..f1e34a929a
--- /dev/null
+++ b/converter/ps2_usb/keymap.c
@@ -0,0 +1,379 @@
+/*
+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 "usb_keycodes.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 */ \
+) { \
+ { KB_NO, KB_##K01, KB_NO, KB_##K03, KB_##K04, KB_##K05, KB_##K06, KB_##K07 }, \
+ { KB_##K08, KB_##K09, KB_##K0A, KB_##K0B, KB_##K0C, KB_##K0D, KB_##K0E, KB_NO }, \
+ { KB_##K10, KB_##K11, KB_##K12, KB_##K13, KB_##K14, KB_##K15, KB_##K16, KB_NO }, \
+ { KB_##K18, KB_NO, KB_##K1A, KB_##K1B, KB_##K1C, KB_##K1D, KB_##K1E, KB_NO }, \
+ { KB_##K20, KB_##K21, KB_##K22, KB_##K23, KB_##K24, KB_##K25, KB_##K26, KB_NO }, \
+ { KB_##K28, KB_##K29, KB_##K2A, KB_##K2B, KB_##K2C, KB_##K2D, KB_##K2E, KB_NO }, \
+ { KB_##K30, KB_##K31, KB_##K32, KB_##K33, KB_##K34, KB_##K35, KB_##K36, KB_NO }, \
+ { KB_##K38, KB_NO, KB_##K3A, KB_##K3B, KB_##K3C, KB_##K3D, KB_##K3E, KB_NO }, \
+ { KB_##K40, KB_##K41, KB_##K42, KB_##K43, KB_##K44, KB_##K45, KB_##K46, KB_NO }, \
+ { KB_##K48, KB_##K49, KB_##K4A, KB_##K4B, KB_##K4C, KB_##K4D, KB_##K4E, KB_NO }, \
+ { KB_##K50, KB_##K51, KB_##K52, KB_NO, KB_##K54, KB_##K55, KB_NO, KB_##K57 }, \
+ { KB_##K58, KB_##K59, KB_##K5A, KB_##K5B, KB_NO, KB_##K5D, KB_NO, KB_##K5F }, \
+ { KB_NO, KB_##K61, KB_NO, KB_NO, KB_##K64, KB_NO, KB_##K66, KB_##K67 }, \
+ { KB_NO, KB_##K69, KB_##K6A, KB_##K6B, KB_##K6C, KB_NO, KB_NO, KB_NO }, \
+ { KB_##K70, KB_##K71, KB_##K72, KB_##K73, KB_##K74, KB_##K75, KB_##K76, KB_##K77 }, \
+ { KB_##K78, KB_##K79, KB_##K7A, KB_##K7B, KB_##K7C, KB_##K7D, KB_##K7E, KB_NO }, \
+ { KB_NO, KB_NO, KB_NO, KB_##K83, KB_NO, KB_NO, KB_NO, KB_NO }, \
+ { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \
+ { KB_##K90, KB_##K91, KB_NO, KB_NO, KB_##K94, KB_##K95, KB_NO, KB_NO }, \
+ { KB_##K98, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_##K9F }, \
+ { KB_##KA0, KB_##KA1, KB_NO, KB_##KA3, KB_NO, KB_NO, KB_NO, KB_##KA7 }, \
+ { KB_##KA8, KB_NO, KB_NO, KB_##KAB, KB_NO, KB_NO, KB_NO, KB_##KAF }, \
+ { KB_##KB0, KB_NO, KB_##KB2, KB_NO, KB_##KB4, KB_NO, KB_NO, KB_##KB7 }, \
+ { KB_##KB8, KB_NO, KB_##KBA, KB_##KBB, KB_NO, KB_NO, KB_NO, KB_##KBF }, \
+ { KB_##KC0, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \
+ { KB_##KC8, KB_NO, KB_##KCA, KB_NO, KB_NO, KB_##KCD, KB_NO, KB_NO }, \
+ { KB_##KD0, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \
+ { KB_NO, KB_NO, KB_##KDA, KB_NO, KB_NO, KB_NO, KB_##KDE, KB_NO }, \
+ { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \
+ { KB_NO, KB_##KE9, KB_NO, KB_##KEB, KB_##KEC, KB_NO, KB_NO, KB_NO }, \
+ { KB_##KF0, KB_##KF1, KB_##KF2, KB_NO, KB_##KF4, KB_##KF5, KB_NO, KB_NO }, \
+ { KB_NO, KB_NO, KB_##KFA, KB_NO, KB_##KFC, KB_##KFD, KB_##KFE, KB_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[] = {
+ KB_SCLN, // Fn0
+ KB_SLSH, // Fn1
+ KB_NO, // Fn2
+ KB_NO, // Fn3
+ KB_NO, // Fn4
+ KB_NO, // Fn5
+ KB_NO, // Fn6
+ KB_NO // Fn7
+};
+
+
+// The keymap is a 32*8 byte array which convert a PS/2 scan code into a USB keycode.
+// See usb_keycodes.h for USB keycodes. You should omit a 'KB_' 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 fn_bits)
+{
+ return pgm_read_byte(&fn_layer[biton(fn_bits)]);
+}
+
+uint8_t keymap_fn_keycode(uint8_t fn_bits)
+{
+ return pgm_read_byte(&fn_keycode[(biton(fn_bits))]);
+}
diff --git a/converter/ps2_usb/led.c b/converter/ps2_usb/led.c
new file mode 100644
index 0000000000..e448e84ec7
--- /dev/null
+++ b/converter/ps2_usb/led.c
@@ -0,0 +1,33 @@
+/*
+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/ps2_usb/matrix.c b/converter/ps2_usb/matrix.c
new file mode 100644
index 0000000000..4187ea0601
--- /dev/null
+++ b/converter/ps2_usb/matrix.c
@@ -0,0 +1,452 @@
+/*
+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 2' is assigned into 256(32x8)cell matrix.
+ * Hmm, it is very sparse and not efficient :(
+ *
+ * Notes:
+ * Both 'Hanguel/English'(F1) and 'Hanja'(F2) collide with 'Delete'(E0 71) and 'Down'(E0 72).
+ * These two Korean keys need exceptional handling and are not supported for now. Sorry.
+ *
+ * 8bit wide
+ * +---------+
+ * 0| |
+ * :| XX | 00-7F for normal codes(without E0-prefix)
+ * f|_________|
+ * 10| |
+ * :| E0 YY | 80-FF for E0-prefixed codes
+ * 1f| | (<YY>|0x80) is used as matrix position.
+ * +---------+
+ *
+ * Exceptions:
+ * 0x83: F7(0x83) This is a normal code but beyond 0x7F.
+ * 0xFC: PrintScreen
+ * 0xFE: Pause
+ */
+static uint8_t matrix[MATRIX_ROWS];
+#define ROW(code) (code>>3)
+#define COL(code) (code&0x07)
+
+// matrix positions for exceptional keys
+#define F7 (0x83)
+#define PRINT_SCREEN (0xFC)
+#define PAUSE (0xFE)
+
+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)
+{
+ ps2_host_init();
+
+ // initialize matrix state: all keys off
+ for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
+
+ return;
+}
+
+/*
+ * PS/2 Scan Code Set 2: Exceptional Handling
+ *
+ * There are several keys to be handled exceptionally.
+ * The scan code for these keys are varied or prefix/postfix'd
+ * depending on modifier key state.
+ *
+ * Keyboard Scan Code Specification:
+ * http://www.microsoft.com/whdc/archive/scancode.mspx
+ * http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
+ *
+ *
+ * 1) Insert, Delete, Home, End, PageUp, PageDown, Up, Down, Right, Left
+ * a) when Num Lock is off
+ * modifiers | make | break
+ * ----------+---------------------------+----------------------
+ * Ohter | <make> | <break>
+ * LShift | E0 F0 12 <make> | <break> E0 12
+ * RShift | E0 F0 59 <make> | <break> E0 59
+ * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12
+ *
+ * b) when Num Lock is on
+ * modifiers | make | break
+ * ----------+---------------------------+----------------------
+ * Other | E0 12 <make> | <break> E0 F0 12
+ * Shift'd | <make> | <break>
+ *
+ * Handling: These prefix/postfix codes are ignored.
+ *
+ *
+ * 2) Keypad /
+ * modifiers | make | break
+ * ----------+---------------------------+----------------------
+ * Ohter | <make> | <break>
+ * LShift | E0 F0 12 <make> | <break> E0 12
+ * RShift | E0 F0 59 <make> | <break> E0 59
+ * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12
+ *
+ * Handling: These prefix/postfix codes are ignored.
+ *
+ *
+ * 3) PrintScreen
+ * modifiers | make | break
+ * ----------+--------------+-----------------------------------
+ * Other | E0 12 E0 7C | E0 F0 7C E0 F0 12
+ * Shift'd | E0 7C | E0 F0 7C
+ * Control'd | E0 7C | E0 F0 7C
+ * Alt'd | 84 | F0 84
+ *
+ * Handling: These prefix/postfix codes are ignored, and both scan codes
+ * 'E0 7C' and 84 are seen as PrintScreen.
+ *
+ * 4) Pause
+ * modifiers | make(no break code)
+ * ----------+--------------------------------------------------
+ * Other | E1 14 77 E1 F0 14 F0 77
+ * Control'd | E0 7E E0 F0 7E
+ *
+ * Handling: Both code sequences are treated as a whole.
+ * And we need a ad hoc 'pseudo break code' hack to get the key off
+ * because it has no break code.
+ *
+ */
+uint8_t matrix_scan(void)
+{
+
+ // scan code reading states
+ static enum {
+ INIT,
+ F0,
+ E0,
+ E0_F0,
+ // Pause
+ E1,
+ E1_14,
+ E1_14_77,
+ E1_14_77_E1,
+ E1_14_77_E1_F0,
+ E1_14_77_E1_F0_14,
+ E1_14_77_E1_F0_14_F0,
+ // Control'd Pause
+ E0_7E,
+ E0_7E_E0,
+ E0_7E_E0_F0,
+ } state = INIT;
+
+
+ is_modified = false;
+
+ // 'pseudo break code' hack
+ if (matrix_is_on(ROW(PAUSE), COL(PAUSE))) {
+ matrix_break(PAUSE);
+ }
+
+ uint8_t code;
+ while ((code = ps2_host_recv())) {
+ switch (state) {
+ case INIT:
+ switch (code) {
+ case 0xE0:
+ state = E0;
+ break;
+ case 0xF0:
+ state = F0;
+ break;
+ case 0xE1:
+ state = E1;
+ break;
+ case 0x83: // F7
+ matrix_make(F7);
+ state = INIT;
+ break;
+ case 0x84: // Alt'd PrintScreen
+ matrix_make(PRINT_SCREEN);
+ 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");
+ }
+ state = INIT;
+ }
+ break;
+ case E0: // E0-Prefixed
+ switch (code) {
+ case 0x12: // to be ignored
+ case 0x59: // to be ignored
+ state = INIT;
+ break;
+ case 0x7E: // Control'd Pause
+ state = E0_7E;
+ break;
+ case 0xF0:
+ state = E0_F0;
+ break;
+ default:
+ if (code < 0x80) {
+ matrix_make(code|0x80);
+ } else {
+ debug("unexpected scan code at E0: "); debug_hex(code); debug("\n");
+ }
+ state = INIT;
+ }
+ break;
+ case F0: // Break code
+ switch (code) {
+ case 0x83: // F7
+ matrix_break(F7);
+ state = INIT;
+ break;
+ case 0x84: // Alt'd PrintScreen
+ matrix_break(PRINT_SCREEN);
+ state = INIT;
+ break;
+ default:
+ if (code < 0x80) {
+ matrix_break(code);
+ } else {
+ debug("unexpected scan code at F0: "); debug_hex(code); debug("\n");
+ }
+ state = INIT;
+ }
+ break;
+ case E0_F0: // Break code of E0-prefixed
+ switch (code) {
+ case 0x12: // to be ignored
+ case 0x59: // to be ignored
+ state = INIT;
+ break;
+ default:
+ if (code < 0x80) {
+ matrix_break(code|0x80);
+ } else {
+ debug("unexpected scan code at E0_F0: "); debug_hex(code); debug("\n");
+ }
+ state = INIT;
+ }
+ break;
+ // following are states of Pause
+ case E1:
+ switch (code) {
+ case 0x14:
+ state = E1_14;
+ break;
+ default:
+ state = INIT;
+ }
+ break;
+ case E1_14:
+ switch (code) {
+ case 0x77:
+ state = E1_14_77;
+ break;
+ default:
+ state = INIT;
+ }
+ break;
+ case E1_14_77:
+ switch (code) {
+ case 0xE1:
+ state = E1_14_77_E1;
+ break;
+ default:
+ state = INIT;
+ }
+ break;
+ case E1_14_77_E1:
+ switch (code) {
+ case 0xF0:
+ state = E1_14_77_E1_F0;
+ break;
+ default:
+ state = INIT;
+ }
+ break;
+ case E1_14_77_E1_F0:
+ switch (code) {
+ case 0x14:
+ state = E1_14_77_E1_F0_14;
+ break;
+ default:
+ state = INIT;
+ }
+ break;
+ case E1_14_77_E1_F0_14:
+ switch (code) {
+ case 0xF0:
+ state = E1_14_77_E1_F0_14_F0;
+ break;
+ default:
+ state = INIT;
+ }
+ break;
+ case E1_14_77_E1_F0_14_F0:
+ switch (code) {
+ case 0x77:
+ matrix_make(PAUSE);
+ state = INIT;
+ break;
+ default:
+ state = INIT;
+ }
+ break;
+ // Following are states of Control'd Pause
+ case E0_7E:
+ if (code == 0xE0)
+ state = E0_7E_E0;
+ else
+ state = INIT;
+ break;
+ case E0_7E_E0:
+ if (code == 0xF0)
+ state = E0_7E_E0_F0;
+ else
+ state = INIT;
+ break;
+ case E0_7E_E0_F0:
+ if (code == 0x7E)
+ matrix_make(PAUSE);
+ state = INIT;
+ break;
+ default:
+ state = INIT;
+ }
+ phex(code);
+ }
+ 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/converter/ps2_usb/usbconfig.h b/converter/ps2_usb/usbconfig.h
new file mode 100644
index 0000000000..9038f1eb8c
--- /dev/null
+++ b/converter/ps2_usb/usbconfig.h
@@ -0,0 +1,378 @@
+/* Name: usbconfig.h
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2005-04-01
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: usbconfig-prototype.h 785 2010-05-30 17:57:07Z cs $
+ */
+
+#ifndef __usbconfig_h_included__
+#define __usbconfig_h_included__
+
+#include "config_vusb.h"
+
+/*
+General Description:
+This file is an example configuration (with inline documentation) for the USB
+driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
+also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
+wire the lines to any other port, as long as D+ is also wired to INT0 (or any
+other hardware interrupt, as long as it is the highest level interrupt, see
+section at the end of this file).
+*/
+
+/* ---------------------------- Hardware Config ---------------------------- */
+
+#define USB_CFG_IOPORTNAME D
+/* This is the port where the USB bus is connected. When you configure it to
+ * "B", the registers PORTB, PINB and DDRB will be used.
+ */
+#define USB_CFG_DMINUS_BIT 3
+/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
+ * This may be any bit in the port.
+ */
+#define USB_CFG_DPLUS_BIT 2
+/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
+ * This may be any bit in the port. Please note that D+ must also be connected
+ * to interrupt pin INT0! [You can also use other interrupts, see section
+ * "Optional MCU Description" below, or you can connect D- to the interrupt, as
+ * it is required if you use the USB_COUNT_SOF feature. If you use D- for the
+ * interrupt, the USB interrupt will also be triggered at Start-Of-Frame
+ * markers every millisecond.]
+ */
+#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
+/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000,
+ * 16500, 18000 and 20000. The 12.8 MHz and 16.5 MHz versions of the code
+ * require no crystal, they tolerate +/- 1% deviation from the nominal
+ * frequency. All other rates require a precision of 2000 ppm and thus a
+ * crystal!
+ * Since F_CPU should be defined to your actual clock rate anyway, you should
+ * not need to modify this setting.
+ */
+#define USB_CFG_CHECK_CRC 0
+/* Define this to 1 if you want that the driver checks integrity of incoming
+ * data packets (CRC checks). CRC checks cost quite a bit of code size and are
+ * currently only available for 18 MHz crystal clock. You must choose
+ * USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
+ */
+
+/* ----------------------- Optional Hardware Config ------------------------ */
+
+/* #define USB_CFG_PULLUP_IOPORTNAME D */
+/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
+ * V+, you can connect and disconnect the device from firmware by calling
+ * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
+ * This constant defines the port on which the pullup resistor is connected.
+ */
+/* #define USB_CFG_PULLUP_BIT 4 */
+/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
+ * above) where the 1.5k pullup resistor is connected. See description
+ * above for details.
+ */
+
+/* --------------------------- Functional Range ---------------------------- */
+
+#define USB_CFG_HAVE_INTRIN_ENDPOINT 1
+/* Define this to 1 if you want to compile a version with two endpoints: The
+ * default control endpoint 0 and an interrupt-in endpoint (any other endpoint
+ * number).
+ */
+#define USB_CFG_HAVE_INTRIN_ENDPOINT3 1
+/* Define this to 1 if you want to compile a version with three endpoints: The
+ * default control endpoint 0, an interrupt-in endpoint 3 (or the number
+ * configured below) and a catch-all default interrupt-in endpoint as above.
+ * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
+ */
+#define USB_CFG_EP3_NUMBER 3
+/* If the so-called endpoint 3 is used, it can now be configured to any other
+ * endpoint number (except 0) with this macro. Default if undefined is 3.
+ */
+/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */
+/* The above macro defines the startup condition for data toggling on the
+ * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1.
+ * Since the token is toggled BEFORE sending any data, the first packet is
+ * sent with the oposite value of this configuration!
+ */
+#define USB_CFG_IMPLEMENT_HALT 0
+/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature
+ * for endpoint 1 (interrupt endpoint). Although you may not need this feature,
+ * it is required by the standard. We have made it a config option because it
+ * bloats the code considerably.
+ */
+#define USB_CFG_SUPPRESS_INTR_CODE 0
+/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
+ * want to send any data over them. If this macro is defined to 1, functions
+ * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if
+ * you need the interrupt-in endpoints in order to comply to an interface
+ * (e.g. HID), but never want to send any data. This option saves a couple
+ * of bytes in flash memory and the transmit buffers in RAM.
+ */
+#define USB_CFG_INTR_POLL_INTERVAL 10
+/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
+ * interval. The value is in milliseconds and must not be less than 10 ms for
+ * low speed devices.
+ */
+#define USB_CFG_IS_SELF_POWERED 0
+/* Define this to 1 if the device has its own power supply. Set it to 0 if the
+ * device is powered from the USB bus.
+ */
+#define USB_CFG_MAX_BUS_POWER 100
+/* Set this variable to the maximum USB bus power consumption of your device.
+ * The value is in milliamperes. [It will be divided by two since USB
+ * communicates power requirements in units of 2 mA.]
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITE 1
+/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
+ * transfers. Set it to 0 if you don't need it and want to save a couple of
+ * bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_READ 0
+/* Set this to 1 if you need to send control replies which are generated
+ * "on the fly" when usbFunctionRead() is called. If you only want to send
+ * data from a static buffer, set it to 0 and return the data from
+ * usbFunctionSetup(). This saves a couple of bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0
+/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints.
+ * You must implement the function usbFunctionWriteOut() which receives all
+ * interrupt/bulk data sent to any endpoint other than 0. The endpoint number
+ * can be found in 'usbRxToken'.
+ */
+#define USB_CFG_HAVE_FLOWCONTROL 0
+/* Define this to 1 if you want flowcontrol over USB data. See the definition
+ * of the macros usbDisableAllRequests() and usbEnableAllRequests() in
+ * usbdrv.h.
+ */
+#define USB_CFG_DRIVER_FLASH_PAGE 0
+/* If the device has more than 64 kBytes of flash, define this to the 64 k page
+ * where the driver's constants (descriptors) are located. Or in other words:
+ * Define this to 1 for boot loaders on the ATMega128.
+ */
+#define USB_CFG_LONG_TRANSFERS 0
+/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
+ * in a single control-in or control-out transfer. Note that the capability
+ * for long transfers increases the driver size.
+ */
+/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
+/* This macro is a hook if you want to do unconventional things. If it is
+ * defined, it's inserted at the beginning of received message processing.
+ * If you eat the received message and don't want default processing to
+ * proceed, do a return after doing your things. One possible application
+ * (besides debugging) is to flash a status LED on each packet.
+ */
+/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */
+/* This macro is a hook if you need to know when an USB RESET occurs. It has
+ * one parameter which distinguishes between the start of RESET state and its
+ * end.
+ */
+/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */
+/* This macro (if defined) is executed when a USB SET_ADDRESS request was
+ * received.
+ */
+#define USB_COUNT_SOF 0
+/* define this macro to 1 if you need the global variable "usbSofCount" which
+ * counts SOF packets. This feature requires that the hardware interrupt is
+ * connected to D- instead of D+.
+ */
+/* #ifdef __ASSEMBLER__
+ * macro myAssemblerMacro
+ * in YL, TCNT0
+ * sts timer0Snapshot, YL
+ * endm
+ * #endif
+ * #define USB_SOF_HOOK myAssemblerMacro
+ * This macro (if defined) is executed in the assembler module when a
+ * Start Of Frame condition is detected. It is recommended to define it to
+ * the name of an assembler macro which is defined here as well so that more
+ * than one assembler instruction can be used. The macro may use the register
+ * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
+ * immediately after an SOF pulse may be lost and must be retried by the host.
+ * What can you do with this hook? Since the SOF signal occurs exactly every
+ * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
+ * designs running on the internal RC oscillator.
+ * Please note that Start Of Frame detection works only if D- is wired to the
+ * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
+ */
+#define USB_CFG_CHECK_DATA_TOGGLING 0
+/* define this macro to 1 if you want to filter out duplicate data packets
+ * sent by the host. Duplicates occur only as a consequence of communication
+ * errors, when the host does not receive an ACK. Please note that you need to
+ * implement the filtering yourself in usbFunctionWriteOut() and
+ * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
+ * for each control- and out-endpoint to check for duplicate packets.
+ */
+#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
+/* define this macro to 1 if you want the function usbMeasureFrameLength()
+ * compiled in. This function can be used to calibrate the AVR's RC oscillator.
+ */
+#define USB_USE_FAST_CRC 0
+/* The assembler module has two implementations for the CRC algorithm. One is
+ * faster, the other is smaller. This CRC routine is only used for transmitted
+ * messages where timing is not critical. The faster routine needs 31 cycles
+ * per byte while the smaller one needs 61 to 69 cycles. The faster routine
+ * may be worth the 32 bytes bigger code size if you transmit lots of data and
+ * run the AVR close to its limit.
+ */
+
+/* -------------------------- Device Description --------------------------- */
+
+#define USB_CFG_VENDOR_ID (VENDOR_ID & 0xFF), ((VENDOR_ID >> 8) & 0xFF)
+/* USB vendor ID for the device, low byte first. If you have registered your
+ * own Vendor ID, define it here. Otherwise you may use one of obdev's free
+ * shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules!
+ * *** IMPORTANT NOTE ***
+ * This template uses obdev's shared VID/PID pair for Vendor Class devices
+ * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
+ * the implications!
+ */
+#define USB_CFG_DEVICE_ID (PRODUCT_ID & 0xFF), ((PRODUCT_ID >> 8) & 0xFF)
+/* This is the ID of the product, low byte first. It is interpreted in the
+ * scope of the vendor ID. If you have registered your own VID with usb.org
+ * or if you have licensed a PID from somebody else, define it here. Otherwise
+ * you may use one of obdev's free shared VID/PID pairs. See the file
+ * USB-IDs-for-free.txt for details!
+ * *** IMPORTANT NOTE ***
+ * This template uses obdev's shared VID/PID pair for Vendor Class devices
+ * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
+ * the implications!
+ */
+#define USB_CFG_DEVICE_VERSION 0x00, 0x01
+/* Version number of the device: Minor number first, then major number.
+ */
+#define USB_CFG_VENDOR_NAME 't', '.', 'm', '.', 'k', '.'
+#define USB_CFG_VENDOR_NAME_LEN 6
+/* These two values define the vendor name returned by the USB device. The name
+ * must be given as a list of characters under single quotes. The characters
+ * are interpreted as Unicode (UTF-16) entities.
+ * If you don't want a vendor name string, undefine these macros.
+ * ALWAYS define a vendor name containing your Internet domain name if you use
+ * obdev's free shared VID/PID pair. See the file USB-IDs-for-free.txt for
+ * details.
+ */
+#define USB_CFG_DEVICE_NAME 'P', 'S', '/', '2', ' ', 'k', 'e', 'y', 'b', 'o', 'a', 'r', 'd', ' ', 'c', 'o', 'n', 'v', 'e', 'r', 't', 'e', 'r'
+#define USB_CFG_DEVICE_NAME_LEN 23
+/* Same as above for the device name. If you don't want a device name, undefine
+ * the macros. See the file USB-IDs-for-free.txt before you assign a name if
+ * you use a shared VID/PID.
+ */
+/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */
+/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */
+/* Same as above for the serial number. If you don't want a serial number,
+ * undefine the macros.
+ * It may be useful to provide the serial number through other means than at
+ * compile time. See the section about descriptor properties below for how
+ * to fine tune control over USB descriptors such as the string descriptor
+ * for the serial number.
+ */
+#define USB_CFG_DEVICE_CLASS 0
+#define USB_CFG_DEVICE_SUBCLASS 0
+/* See USB specification if you want to conform to an existing device class.
+ * Class 0xff is "vendor specific".
+ */
+#define USB_CFG_INTERFACE_CLASS 3 /* HID */
+#define USB_CFG_INTERFACE_SUBCLASS 1 /* Boot */
+#define USB_CFG_INTERFACE_PROTOCOL 1 /* Keyboard */
+/* See USB specification if you want to conform to an existing device class or
+ * protocol. The following classes must be set at interface level:
+ * HID class is 3, no subclass and protocol required (but may be useful!)
+ * CDC class is 2, use subclass 2 and protocol 1 for ACM
+ */
+#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 0
+/* Define this to the length of the HID report descriptor, if you implement
+ * an HID device. Otherwise don't define it or define it to 0.
+ * If you use this define, you must add a PROGMEM character array named
+ * "usbHidReportDescriptor" to your code which contains the report descriptor.
+ * Don't forget to keep the array and this define in sync!
+ */
+
+/* #define USB_PUBLIC static */
+/* Use the define above if you #include usbdrv.c instead of linking against it.
+ * This technique saves a couple of bytes in flash memory.
+ */
+
+/* ------------------- Fine Control over USB Descriptors ------------------- */
+/* If you don't want to use the driver's default USB descriptors, you can
+ * provide our own. These can be provided as (1) fixed length static data in
+ * flash memory, (2) fixed length static data in RAM or (3) dynamically at
+ * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more
+ * information about this function.
+ * Descriptor handling is configured through the descriptor's properties. If
+ * no properties are defined or if they are 0, the default descriptor is used.
+ * Possible properties are:
+ * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
+ * at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is
+ * used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if
+ * you want RAM pointers.
+ * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
+ * in static memory is in RAM, not in flash memory.
+ * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
+ * the driver must know the descriptor's length. The descriptor itself is
+ * found at the address of a well known identifier (see below).
+ * List of static descriptor names (must be declared PROGMEM if in flash):
+ * char usbDescriptorDevice[];
+ * char usbDescriptorConfiguration[];
+ * char usbDescriptorHidReport[];
+ * char usbDescriptorString0[];
+ * int usbDescriptorStringVendor[];
+ * int usbDescriptorStringDevice[];
+ * int usbDescriptorStringSerialNumber[];
+ * Other descriptors can't be provided statically, they must be provided
+ * dynamically at runtime.
+ *
+ * Descriptor properties are or-ed or added together, e.g.:
+ * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18))
+ *
+ * The following descriptors are defined:
+ * USB_CFG_DESCR_PROPS_DEVICE
+ * USB_CFG_DESCR_PROPS_CONFIGURATION
+ * USB_CFG_DESCR_PROPS_STRINGS
+ * USB_CFG_DESCR_PROPS_STRING_0
+ * USB_CFG_DESCR_PROPS_STRING_VENDOR
+ * USB_CFG_DESCR_PROPS_STRING_PRODUCT
+ * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
+ * USB_CFG_DESCR_PROPS_HID
+ * USB_CFG_DESCR_PROPS_HID_REPORT
+ * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
+ *
+ * Note about string descriptors: String descriptors are not just strings, they
+ * are Unicode strings prefixed with a 2 byte header. Example:
+ * int serialNumberDescriptor[] = {
+ * USB_STRING_DESCRIPTOR_HEADER(6),
+ * 'S', 'e', 'r', 'i', 'a', 'l'
+ * };
+ */
+
+#define USB_CFG_DESCR_PROPS_DEVICE 0
+#define USB_CFG_DESCR_PROPS_CONFIGURATION USB_PROP_IS_DYNAMIC
+//#define USB_CFG_DESCR_PROPS_CONFIGURATION 0
+#define USB_CFG_DESCR_PROPS_STRINGS 0
+#define USB_CFG_DESCR_PROPS_STRING_0 0
+#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0
+#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0
+#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0
+//#define USB_CFG_DESCR_PROPS_HID USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_HID 0
+#define USB_CFG_DESCR_PROPS_HID_REPORT USB_PROP_IS_DYNAMIC
+//#define USB_CFG_DESCR_PROPS_HID_REPORT 0
+#define USB_CFG_DESCR_PROPS_UNKNOWN 0
+
+/* ----------------------- Optional MCU Description ------------------------ */
+
+/* The following configurations have working defaults in usbdrv.h. You
+ * usually don't need to set them explicitly. Only if you want to run
+ * the driver on a device which is not yet supported or with a compiler
+ * which is not fully supported (such as IAR C) or if you use a differnt
+ * interrupt than INT0, you may have to define some of these.
+ */
+/* #define USB_INTR_CFG MCUCR */
+/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */
+/* #define USB_INTR_CFG_CLR 0 */
+/* #define USB_INTR_ENABLE GIMSK */
+/* #define USB_INTR_ENABLE_BIT INT0 */
+/* #define USB_INTR_PENDING GIFR */
+/* #define USB_INTR_PENDING_BIT INTF0 */
+/* #define USB_INTR_VECTOR INT0_vect */
+
+#endif /* __usbconfig_h_included__ */