aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ps2_usb/README138
-rw-r--r--ps2_usb/README.vusb37
-rw-r--r--ps2_usb/keymap.c103
-rw-r--r--ps2_usb/matrix.c184
-rw-r--r--usb_keycodes.h2
5 files changed, 262 insertions, 202 deletions
diff --git a/ps2_usb/README b/ps2_usb/README
index 0fdeaf1df..b3bcfbe4d 100644
--- a/ps2_usb/README
+++ b/ps2_usb/README
@@ -1,111 +1,75 @@
1PS/2 to USB keyboard converter 1PS/2 to USB keyboard converter
2============================== 2==============================
3 3This firmware converts PS/2 keyboard protocol to USB and for now supports only Scan Code Set 2.
4This firmware converts PS/2 keyboard protocol to USB.
5
6
7Demostration build
8------------------
9In this demo build, you can try several layouts,
10mouse keys and USB NKRO.
11
12Special keys:
13 Magic+0: Qwerty with mouse keys(default)
14 Magic+1: Qwerty
15 Magic+2: Colemak
16 Magic+3: Dvorak
17 Magic+4: Workman
18 Magic+N: toggles NKRO/6KRO(6KRO by default)
19 Magic+Esc: sends Power Event
20 where Magic=(LShift+RShift) or (LControl+RShift)
21
22Keybinds:
23 Fn0+(hjkl): Mouse key move(vi cursor)
24 Fn0+(yuio): Mouse wheel(left,down,up,right)
25 Fn0+space: Mouse button1
26 Fn0+(mnb): Mouse buttons(1,2,3)
27 Fn0+(zxc): Media control(Volup, Voldown, Mute)
28 Fn1+(hjkl): Cursor move(vi cursor)
29 Fn1+(nm,.): Cursor move(Home,PageDown,PageUp,End)
30
31 Fn2+(esdf): Mouse key move(invert T cursor)
32 Fn2+(qwrt): Mouse wheel(left,down,up,right)
33 Fn2+space: Mouse button1
34 Fn2+(,./): Media control(Volup, Voldown, Mute)
35 where Fn0=;, Fn1=/, Fn2=a
36 4
37 5
38Features 6Features
39-------- 7--------
40Mouse keys 8Mouse keys
41 You can emulates mouse move and button click using keyboard. 9 You can emulates mouse move and button click using keyboard.
10
42System/Media control 11System/Media control
43 You can sends Power event, Volume down/up and Mute. 12 You can sends Power event, Volume down/up and Mute.
13
44USB NKRO(actually 120KRO+8Modifiers) 14USB NKRO(actually 120KRO+8Modifiers)
45 You can tolggles NKRO/6KRO.(Not tested on Mac.) 15 You can tolggles NKRO feature.
16
46Keymap customization 17Keymap customization
47 You can customize keymaps easily by editing source code. 18 You can customize keymaps easily by editing source code. See keymap.c.
48 19
49 20
50Build for Teensy 21Build Converter
51---------------- 22---------------
520. Connect PS/2 keyboard to Teensy by 4 lines(Vcc, GND, Data, Clock). 230. Connect PS/2 keyboard into Teensy with 4 lines(Vcc, GND, Data, Clock).
531. Define following macros for PS/2 connection in config_pjrc.h: 24 By default Clock is on PF0 and Data on PF1.
54 PS2_DATA_PORT 25 You can change this pin configuration by editing config_pjrc.h.
55 PS2_DATA_PIN 26 In this photo Vcc is yellow, GND is green, Data is red and Clock is black.
56 PS2_DATA_DDR 27 http://img17.imageshack.us/img17/7243/201101181933.jpg
57 PS2_DATA_BIT 28
58 PS2_CLOCK_PORT 29
59 PS2_CLOCK_PIN 30Build Frimware
60 PS2_CLOCK_DDR 31--------------
61 PS2_CLOCK_BIT 321. Edit Makefile for build options and MCU setting.
622. Edit Makefile for build options and MCU setting. 33 Use 'atmega32u4' for Teensy 2.0 or 'at90usb1286' for Teensy++ 2.0.
632. make 342. make
643. program Teensy. 35 Just type 'make' in a terminal.
363. program with Teensy Loader.
65 http://www.pjrc.com/teensy/loader.html 37 http://www.pjrc.com/teensy/loader.html
66 38
67 39
68Build for V-USB 40Demonstration of Features
69--------------- 41-------------------------
700. Build V-USB controller board and connect PS/2 keyboard. 42In default configuration, you can try several keymaps, mousekeys and USB NKRO.
711. Define macros in config_vusb.h if needed. 43Use following magic key combinations to enable some features.
722. Edit Makefile.vusb for build options and MCU setting. 44
733. make -f Makefile.vusb 45keymaps and NKRO:
744. program your V-USB controller. 46 Magic+0: Qwerty with mousekeys(default)
75 47 Magic+1: Qwerty without mousekeys
76 48 Magic+2: Colemak
77V-USB Circuit 49 Magic+3: Dvorak
78------------- 50 Magic+4: Workman
79 +---+ +---------------+ 51 Magic+N: toggles NKRO/6KRO(6KRO by default)
80USB GND | | ATmega168 | 52 Magic+Esc: sends Power Event(Power button)
81=== C3 | | 53
825V <-------+--------+---|Vcc,AVCC | PS/2 54 where Magic=(LShift+RShift) or (LControl+RShift)
83 R1 | | ==== 55
84D- <----+--+-----R2-----|INT1 RXD|------->DATA 56Fn layer function:
85D+ <----|---+----R3-----|INT0 XCK|------->CLOCK 57 Fn0+(hjkl): Mousekey move(vi cursor like)
86 Z1 Z2 | | ->5V 58 Fn0+(yuio): Mouse wheel(left,down,up,right)
87GND<----+---+--+--+-----|GND | ->GND 59 Fn0+space: Mouse left button
88 | | | | 60 Fn0+(mnb): Mouse buttons(m=left, n=right, b=middle)
89 | C2-+--|XTAL1 | 61 Fn0+(zxc): Media control(Volup, Voldown, Mute)
90 | X1 | | 62 Fn1+(hjkl): Cursor move(vi cursor like)
91 +--C3-+--|XTAL2 | 63 Fn1+(nm,.): Cursor move(Home,PageDown,PageUp,End)
92 +---------------+ 64
93R1: 1.5K Ohm 65 where Fn0=;, Fn1=/
94R2,R3: 68 Ohm
95Z1,Z2: Zenner 3.6V
96C1,C2: 22pF
97C3: 0.1uF
98X1: Crystal 20MHz(16MHz/12MHz)
99 66
100 67
101Keymap 68Keymap
102------ 69------
103You can change a keymap by editing code of keymap.c like following. 70You can change a keymap by editing code of keymap.c like following.
104How to define the keymap is probably obvious. You can find key 71How to define the keymap is probably obvious. You can find key symbols in usb_keycodes.h.
105symbols in usb_keycodes.h. 72To define keymap layer switching may needs a bit of your effort at this time.
106If you want to define more than one keymap, see hhkb/keymap.c and
107macway/keymap.c as examples. To define keymap(layer) switching may
108needs a bit of your effort at this time.
109 73
110 /* Default Layer: plain keymap 74 /* Default Layer: plain keymap
111 * ,---. ,---------------. ,---------------. ,---------------. ,-----------. ,-----------. 75 * ,---. ,---------------. ,---------------. ,---------------. ,-----------. ,-----------.
diff --git a/ps2_usb/README.vusb b/ps2_usb/README.vusb
new file mode 100644
index 000000000..c92871bcd
--- /dev/null
+++ b/ps2_usb/README.vusb
@@ -0,0 +1,37 @@
1V-USB Support
2=============
3You can also use this converter on ATmega(168/328) with V-USB instead of Teensy.
4The converter on V-USB lacks some features for now: USB NKRO and System/Media control.
5
6To build a firmware use Makefile.vusb instead of Makefile.
7
8
9Circuit
10-------
11 +---+ +---------------+
12USB GND | | ATmega168 |
13=== C3 | |
145V <-------+--------+---|Vcc,AVCC | PS/2
15 R1 | | ====
16D- <----+--+-----R2-----|INT1 RXD|------->DATA
17D+ <----|---+----R3-----|INT0 XCK|------->CLOCK
18 Z1 Z2 | | ->5V
19GND<----+---+--+--+-----|GND | ->GND
20 | | | |
21 | C2-+--|XTAL1 |
22 | X1 | |
23 +--C3-+--|XTAL2 |
24 +---------------+
25R1: 1.5K Ohm
26R2,R3: 68 Ohm
27Z1,Z2: Zenner 3.6V
28C1,C2: 22pF
29C3: 0.1uF
30X1: Crystal 20MHz(16MHz/12MHz)
31
32
33This is my V-USB converter on breadboard.
34[IMG]http://i.imgur.com/8jJCZl.jpg[/IMG]
35
36
37EOF
diff --git a/ps2_usb/keymap.c b/ps2_usb/keymap.c
index e84e8c29b..fc429212d 100644
--- a/ps2_usb/keymap.c
+++ b/ps2_usb/keymap.c
@@ -28,11 +28,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
28#include "keymap.h" 28#include "keymap.h"
29 29
30 30
31#define KEYCODE(layer, row, col) (pgm_read_byte(&keymaps[(layer)][(row)][(col)]))
32 31
33 32
34// The keymap is a 32*8 matrix which convert a PS/2 scancode into a USB keycode. 33// Following macros help you to define a keymap with the form of actual keyboard layout.
35// See matrix.c for the detail of matrix. 34
35/* US layout plus all other various keys */
36#define KEYMAP_ALL( \ 36#define KEYMAP_ALL( \
37 K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \ 37 K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
38 K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \ 38 K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
@@ -41,6 +41,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
41 K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \ 41 K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
42 K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \ 42 K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \
43 \ 43 \
44 K61, /* for European ISO */ \
45 K51, K13, K6A, K64, K67, /* for Japanese JIS */ \
46 K08, K10, K18, K20, K28, K30, K38, K40, K48, K50, K57, K5F, /* F13-24 */ \
44 KB7, KBF, KDE, /* System Power, Sleep, Wake */ \ 47 KB7, KBF, KDE, /* System Power, Sleep, Wake */ \
45 KA3, KB2, KA1, /* Mute, Volume Up, Volume Down */ \ 48 KA3, KB2, KA1, /* Mute, Volume Up, Volume Down */ \
46 KCD, K95, KBB, KB4, KD0, /* Next, Previous, Stop, Pause, Media Select */ \ 49 KCD, K95, KBB, KB4, KD0, /* Next, Previous, Stop, Pause, Media Select */ \
@@ -49,19 +52,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
49 KA8, KA0, K98 /* WWW Stop, Refresh, Favorites */ \ 52 KA8, KA0, K98 /* WWW Stop, Refresh, Favorites */ \
50) { \ 53) { \
51 { KB_NO, KB_##K01, KB_NO, KB_##K03, KB_##K04, KB_##K05, KB_##K06, KB_##K07 }, \ 54 { KB_NO, KB_##K01, KB_NO, KB_##K03, KB_##K04, KB_##K05, KB_##K06, KB_##K07 }, \
52 { KB_NO, KB_##K09, KB_##K0A, KB_##K0B, KB_##K0C, KB_##K0D, KB_##K0E, KB_NO }, \ 55 { KB_##K08, KB_##K09, KB_##K0A, KB_##K0B, KB_##K0C, KB_##K0D, KB_##K0E, KB_NO }, \
53 { KB_NO, KB_##K11, KB_##K12, KB_NO, KB_##K14, KB_##K15, KB_##K16, KB_NO }, \ 56 { KB_##K10, KB_##K11, KB_##K12, KB_##K13, KB_##K14, KB_##K15, KB_##K16, KB_NO }, \
54 { KB_NO, KB_NO, KB_##K1A, KB_##K1B, KB_##K1C, KB_##K1D, KB_##K1E, KB_NO }, \ 57 { KB_##K18, KB_NO, KB_##K1A, KB_##K1B, KB_##K1C, KB_##K1D, KB_##K1E, KB_NO }, \
55 { KB_NO, KB_##K21, KB_##K22, KB_##K23, KB_##K24, KB_##K25, KB_##K26, KB_NO }, \ 58 { KB_##K20, KB_##K21, KB_##K22, KB_##K23, KB_##K24, KB_##K25, KB_##K26, KB_NO }, \
56 { KB_NO, KB_##K29, KB_##K2A, KB_##K2B, KB_##K2C, KB_##K2D, KB_##K2E, KB_NO }, \ 59 { KB_##K28, KB_##K29, KB_##K2A, KB_##K2B, KB_##K2C, KB_##K2D, KB_##K2E, KB_NO }, \
57 { KB_NO, KB_##K31, KB_##K32, KB_##K33, KB_##K34, KB_##K35, KB_##K36, KB_NO }, \ 60 { KB_##K30, KB_##K31, KB_##K32, KB_##K33, KB_##K34, KB_##K35, KB_##K36, KB_NO }, \
58 { KB_NO, KB_NO, KB_##K3A, KB_##K3B, KB_##K3C, KB_##K3D, KB_##K3E, KB_NO }, \ 61 { KB_##K38, KB_NO, KB_##K3A, KB_##K3B, KB_##K3C, KB_##K3D, KB_##K3E, KB_NO }, \
59 { KB_NO, KB_##K41, KB_##K42, KB_##K43, KB_##K44, KB_##K45, KB_##K46, KB_NO }, \ 62 { KB_##K40, KB_##K41, KB_##K42, KB_##K43, KB_##K44, KB_##K45, KB_##K46, KB_NO }, \
60 { KB_NO, KB_##K49, KB_##K4A, KB_##K4B, KB_##K4C, KB_##K4D, KB_##K4E, KB_NO }, \ 63 { KB_##K48, KB_##K49, KB_##K4A, KB_##K4B, KB_##K4C, KB_##K4D, KB_##K4E, KB_NO }, \
61 { KB_NO, KB_NO, KB_##K52, KB_NO, KB_##K54, KB_##K55, KB_NO, KB_NO }, \ 64 { KB_##K50, KB_##K51, KB_##K52, KB_NO, KB_##K54, KB_##K55, KB_NO, KB_##K57 }, \
62 { KB_##K58, KB_##K59, KB_##K5A, KB_##K5B, KB_NO, KB_##K5D, KB_NO, KB_NO }, \ 65 { KB_##K58, KB_##K59, KB_##K5A, KB_##K5B, KB_NO, KB_##K5D, KB_NO, KB_##K5F }, \
63 { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_##K66, KB_NO }, \ 66 { KB_NO, KB_##K61, KB_NO, KB_NO, KB_##K64, KB_NO, KB_##K66, KB_##K67 }, \
64 { KB_NO, KB_##K69, KB_NO, KB_##K6B, KB_##K6C, KB_NO, KB_NO, KB_NO }, \ 67 { KB_NO, KB_##K69, KB_##K6A, KB_##K6B, KB_##K6C, KB_NO, KB_NO, KB_NO }, \
65 { KB_##K70, KB_##K71, KB_##K72, KB_##K73, KB_##K74, KB_##K75, KB_##K76, KB_##K77 }, \ 68 { KB_##K70, KB_##K71, KB_##K72, KB_##K73, KB_##K74, KB_##K75, KB_##K76, KB_##K77 }, \
66 { KB_##K78, KB_##K79, KB_##K7A, KB_##K7B, KB_##K7C, KB_##K7D, KB_##K7E, KB_NO }, \ 69 { KB_##K78, KB_##K79, KB_##K7A, KB_##K7B, KB_##K7C, KB_##K7D, KB_##K7E, KB_NO }, \
67 { KB_NO, KB_NO, KB_NO, KB_##K83, KB_NO, KB_NO, KB_NO, KB_NO }, \ 70 { KB_NO, KB_NO, KB_NO, KB_##K83, KB_NO, KB_NO, KB_NO, KB_NO }, \
@@ -82,6 +85,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
82 { KB_NO, KB_NO, KB_##KFA, KB_NO, KB_##KFC, KB_##KFD, KB_##KFE, KB_NO }, \ 85 { KB_NO, KB_NO, KB_##KFA, KB_NO, KB_##KFC, KB_##KFD, KB_##KFE, KB_NO }, \
83} 86}
84 87
88/* US layout */
85#define KEYMAP( \ 89#define KEYMAP( \
86 K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \ 90 K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
87 K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \ 91 K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
@@ -98,6 +102,65 @@ KEYMAP_ALL( \
98 K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \ 102 K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
99 K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \ 103 K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \
100 \ 104 \
105 NUBS, \
106 RO, KANA, JYEN, HENK, MHEN, \
107 F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, \
108 SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE, \
109 AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN, \
110 MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT, \
111 MAIL, CALCULATOR, MY_COMPUTER, \
112 WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD, \
113 WWW_STOP, WWW_REFRESH, WWW_FAVORITES \
114)
115
116/* ISO layout */
117#define KEYMAP_ISO( \
118 K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
119 K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
120 K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B, KF1,KE9,KFA, K6C,K75,K7D, \
121 K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,K5D,K5A, K6B,K73,K74,K79, \
122 K12,K61,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
123 K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA \
124) \
125KEYMAP_ALL( \
126 K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
127 K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
128 K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \
129 K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \
130 K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
131 K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \
132 \
133 K61, \
134 RO, KANA, JYEN, HENK, MHEN, \
135 F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, \
136 SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE, \
137 AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN, \
138 MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT, \
139 MAIL, CALCULATOR, MY_COMPUTER, \
140 WWW_SEARCH, WWW_HOME, WWW_BACK, WWW_FORWARD, \
141 WWW_STOP, WWW_REFRESH, WWW_FAVORITES \
142)
143
144/* JIS layout */
145#define KEYMAP_JIS( \
146 K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
147 K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K6A,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
148 K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B, KF1,KE9,KFA, K6C,K75,K7D, \
149 K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52,K5D, K5A, K6B,K73,K74,K79, \
150 K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A,K51, K59, KF5, K69,K72,K7A, \
151 K14,K9F,K11, K67,K29,K64,K13, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA \
152) \
153KEYMAP_ALL( \
154 K76,K05,K06,K04,K0C,K03,K0B,K83,K0A,K01,K09,K78,K07, KFC,K7E,KFE, \
155 K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
156 K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \
157 K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \
158 K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
159 K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA, \
160 \
161 NUBS, \
162 K51, K13, K6A, K64, K67, \
163 F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, \
101 SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE, \ 164 SYSTEM_POWER, SYSTEM_SLEEP, SYSTEM_WAKE, \
102 AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN, \ 165 AUDIO_MUTE, AUDIO_VOL_UP, AUDIO_VOL_DOWN, \
103 MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT, \ 166 MEDIA_NEXT_TRACK, MEDIA_PREV_TRACK, MEDIA_STOP, MEDIA_PLAY_PAUSE, MEDIA_SELECT, \
@@ -111,7 +174,7 @@ KEYMAP_ALL( \
111static const uint8_t PROGMEM fn_layer[] = { 174static const uint8_t PROGMEM fn_layer[] = {
112 5, // Fn0 175 5, // Fn0
113 6, // Fn1 176 6, // Fn1
114 5, // Fn2 177 0, // Fn2
115 0, // Fn3 178 0, // Fn3
116 0, // Fn4 179 0, // Fn4
117 0, // Fn5 180 0, // Fn5
@@ -132,6 +195,10 @@ static const uint8_t PROGMEM fn_keycode[] = {
132 KB_NO // Fn7 195 KB_NO // Fn7
133}; 196};
134 197
198
199// The keymap is a 32*8 byte array which convert a PS/2 scan code into a USB keycode.
200// See usb_keycodes.h for USB keycodes. You should omit a 'KB_' prefix of USB keycodes in keymap macro.
201// Use KEYMAP_ISO() or KEYMAP_JIS() instead of KEYMAP() if your keyboard is ISO or JIS.
135static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 202static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
136 /* keymap 203 /* keymap
137 * ,---. ,---------------. ,---------------. ,---------------. ,-----------. ,-----------. 204 * ,---. ,---------------. ,---------------. ,---------------. ,-----------. ,-----------.
@@ -223,7 +290,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
223 290
224uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col) 291uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col)
225{ 292{
226 return KEYCODE(layer, row, col); 293 return pgm_read_byte(&keymaps[(layer)][(row)][(col)]);
227} 294}
228 295
229uint8_t keymap_fn_layer(uint8_t fn_bits) 296uint8_t keymap_fn_layer(uint8_t fn_bits)
diff --git a/ps2_usb/matrix.c b/ps2_usb/matrix.c
index 1aac3f866..4187ea060 100644
--- a/ps2_usb/matrix.c
+++ b/ps2_usb/matrix.c
@@ -15,9 +15,6 @@ You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>. 15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17 17
18/*
19 * scan matrix
20 */
21#include <stdint.h> 18#include <stdint.h>
22#include <stdbool.h> 19#include <stdbool.h>
23#include <avr/io.h> 20#include <avr/io.h>
@@ -29,53 +26,47 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
29#include "matrix.h" 26#include "matrix.h"
30 27
31 28
32#if (MATRIX_COLS > 16) 29static void matrix_make(uint8_t code);
33# error "MATRIX_COLS must not exceed 16" 30static void matrix_break(uint8_t code);
34#endif 31#ifdef MATRIX_HAS_GHOST
35#if (MATRIX_ROWS > 255) 32static bool matrix_has_ghost_in_row(uint8_t row);
36# error "MATRIX_ROWS must not exceed 255"
37#endif 33#endif
38 34
39 35
40/* 36/*
41 * Matrix usage: 37 * Matrix Array usage:
42 * "PS/2 Scan Codes Set 2" is assigned to 256(32x8)cells matrix. 38 * 'Scan Code Set 2' is assigned into 256(32x8)cell matrix.
43 * Hmm, It is very sparse and not efficient :( 39 * Hmm, it is very sparse and not efficient :(
40 *
41 * Notes:
42 * Both 'Hanguel/English'(F1) and 'Hanja'(F2) collide with 'Delete'(E0 71) and 'Down'(E0 72).
43 * These two Korean keys need exceptional handling and are not supported for now. Sorry.
44 * 44 *
45 * 8bit 45 * 8bit wide
46 * --------- 46 * +---------+
47 * 0| | 47 * 0| |
48 * :| XX | 00-7F for normal codes(without E0-prefix) 48 * :| XX | 00-7F for normal codes(without E0-prefix)
49 * f|_________| 49 * f|_________|
50 * 10| | 50 * 10| |
51 * :| E0 XX | 80-FF for E0-prefix codes(use (XX|0x80) as code) 51 * :| E0 YY | 80-FF for E0-prefixed codes
52 * 1f| | 52 * 1f| | (<YY>|0x80) is used as matrix position.
53 * --------- 53 * +---------+
54 * exceptions: 54 *
55 * 83: F8[0x83](normal codes but > 0x7F) 55 * Exceptions:
56 * FC: PrintScreen[E0 7C or 84] 56 * 0x83: F7(0x83) This is a normal code but beyond 0x7F.
57 * FE: Puause 57 * 0xFC: PrintScreen
58 * 0xFE: Pause
58 */ 59 */
59#define F8 (0x83) 60static uint8_t matrix[MATRIX_ROWS];
60#define PRINT_SCREEN (0xFC)
61#define PAUSE (0xFE)
62#define ROW(code) (code>>3) 61#define ROW(code) (code>>3)
63#define COL(code) (code&0x07) 62#define COL(code) (code&0x07)
64 63
65static bool is_modified = false; 64// matrix positions for exceptional keys
66 65#define F7 (0x83)
67// matrix state buffer(1:on, 0:off) 66#define PRINT_SCREEN (0xFC)
68#if (MATRIX_COLS <= 8) 67#define PAUSE (0xFE)
69static uint8_t matrix[MATRIX_ROWS];
70#else
71static uint16_t matrix[MATRIX_ROWS];
72#endif
73 68
74#ifdef MATRIX_HAS_GHOST 69static bool is_modified = false;
75static bool matrix_has_ghost_in_row(uint8_t row);
76#endif
77static void matrix_make(uint8_t code);
78static void matrix_break(uint8_t code);
79 70
80 71
81inline 72inline
@@ -107,13 +98,13 @@ void matrix_init(void)
107 * The scan code for these keys are varied or prefix/postfix'd 98 * The scan code for these keys are varied or prefix/postfix'd
108 * depending on modifier key state. 99 * depending on modifier key state.
109 * 100 *
110 * References: 101 * Keyboard Scan Code Specification:
111 * http://www.microsoft.com/whdc/archive/scancode.mspx 102 * http://www.microsoft.com/whdc/archive/scancode.mspx
112 * http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc 103 * http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
113 * 104 *
114 * 105 *
115 * Insert, Delete, Home, End, PageUp, PageDown, Up, Down, Right, Left: 106 * 1) Insert, Delete, Home, End, PageUp, PageDown, Up, Down, Right, Left
116 * Num Lock: off 107 * a) when Num Lock is off
117 * modifiers | make | break 108 * modifiers | make | break
118 * ----------+---------------------------+---------------------- 109 * ----------+---------------------------+----------------------
119 * Ohter | <make> | <break> 110 * Ohter | <make> | <break>
@@ -121,16 +112,16 @@ void matrix_init(void)
121 * RShift | E0 F0 59 <make> | <break> E0 59 112 * RShift | E0 F0 59 <make> | <break> E0 59
122 * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12 113 * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12
123 * 114 *
124 * Num Lock: on 115 * b) when Num Lock is on
125 * modifiers | make | break 116 * modifiers | make | break
126 * ----------+---------------------------+---------------------- 117 * ----------+---------------------------+----------------------
127 * Other | E0 12 <make> | <break> E0 F0 12 118 * Other | E0 12 <make> | <break> E0 F0 12
128 * Shift'd | <make> | <break> 119 * Shift'd | <make> | <break>
129 * 120 *
130 * Handling: ignore these prefix/postfix codes 121 * Handling: These prefix/postfix codes are ignored.
131 * 122 *
132 * 123 *
133 * Keypad-/: 124 * 2) Keypad /
134 * modifiers | make | break 125 * modifiers | make | break
135 * ----------+---------------------------+---------------------- 126 * ----------+---------------------------+----------------------
136 * Ohter | <make> | <break> 127 * Ohter | <make> | <break>
@@ -138,12 +129,10 @@ void matrix_init(void)
138 * RShift | E0 F0 59 <make> | <break> E0 59 129 * RShift | E0 F0 59 <make> | <break> E0 59
139 * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12 130 * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12
140 * 131 *
141 * Handling: ignore these prefix/postfix codes 132 * Handling: These prefix/postfix codes are ignored.
142 * 133 *
143 * 134 *
144 * PrintScreen: 135 * 3) PrintScreen
145 * With hoding down modifiers, the scan code is sent as following:
146 *
147 * modifiers | make | break 136 * modifiers | make | break
148 * ----------+--------------+----------------------------------- 137 * ----------+--------------+-----------------------------------
149 * Other | E0 12 E0 7C | E0 F0 7C E0 F0 12 138 * Other | E0 12 E0 7C | E0 F0 7C E0 F0 12
@@ -151,29 +140,30 @@ void matrix_init(void)
151 * Control'd | E0 7C | E0 F0 7C 140 * Control'd | E0 7C | E0 F0 7C
152 * Alt'd | 84 | F0 84 141 * Alt'd | 84 | F0 84
153 * 142 *
154 * Handling: ignore prefix/postfix codes and treat both scan code 143 * Handling: These prefix/postfix codes are ignored, and both scan codes
155 * E0 7C and 84 as PrintScreen. 144 * 'E0 7C' and 84 are seen as PrintScreen.
156 *
157 * Pause:
158 * With hoding down modifiers, the scan code is sent as following:
159 * 145 *
146 * 4) Pause
160 * modifiers | make(no break code) 147 * modifiers | make(no break code)
161 * ----------+-------------------------------------------------- 148 * ----------+--------------------------------------------------
162 * no mods | E1 14 77 E1 F0 14 F0 77 149 * Other | E1 14 77 E1 F0 14 F0 77
163 * Control'd | E0 7E E0 F0 7E 150 * Control'd | E0 7E E0 F0 7E
164 * 151 *
165 * Handling: treat these two code sequence as Pause 152 * Handling: Both code sequences are treated as a whole.
153 * And we need a ad hoc 'pseudo break code' hack to get the key off
154 * because it has no break code.
166 * 155 *
167 */ 156 */
168uint8_t matrix_scan(void) 157uint8_t matrix_scan(void)
169{ 158{
170 159
160 // scan code reading states
171 static enum { 161 static enum {
172 INIT, 162 INIT,
173 F0, 163 F0,
174 E0, 164 E0,
175 E0_F0, 165 E0_F0,
176 // states for Pause/Break 166 // Pause
177 E1, 167 E1,
178 E1_14, 168 E1_14,
179 E1_14_77, 169 E1_14_77,
@@ -181,12 +171,16 @@ uint8_t matrix_scan(void)
181 E1_14_77_E1_F0, 171 E1_14_77_E1_F0,
182 E1_14_77_E1_F0_14, 172 E1_14_77_E1_F0_14,
183 E1_14_77_E1_F0_14_F0, 173 E1_14_77_E1_F0_14_F0,
174 // Control'd Pause
175 E0_7E,
176 E0_7E_E0,
177 E0_7E_E0_F0,
184 } state = INIT; 178 } state = INIT;
185 179
186 180
187 is_modified = false; 181 is_modified = false;
188 182
189 // Pause/Break off(PS/2 has no break for this key) 183 // 'pseudo break code' hack
190 if (matrix_is_on(ROW(PAUSE), COL(PAUSE))) { 184 if (matrix_is_on(ROW(PAUSE), COL(PAUSE))) {
191 matrix_break(PAUSE); 185 matrix_break(PAUSE);
192 } 186 }
@@ -196,20 +190,20 @@ uint8_t matrix_scan(void)
196 switch (state) { 190 switch (state) {
197 case INIT: 191 case INIT:
198 switch (code) { 192 switch (code) {
199 case 0xE0: // 2byte make 193 case 0xE0:
200 state = E0; 194 state = E0;
201 break; 195 break;
202 case 0xF0: // break code 196 case 0xF0:
203 state = F0; 197 state = F0;
204 break; 198 break;
205 case 0xE1: // Pause/Break 199 case 0xE1:
206 state = E1; 200 state = E1;
207 break; 201 break;
208 case 0x83: // F8 202 case 0x83: // F7
209 matrix_make(F8); 203 matrix_make(F7);
210 state = INIT; 204 state = INIT;
211 break; 205 break;
212 case 0x84: // PrintScreen 206 case 0x84: // Alt'd PrintScreen
213 matrix_make(PRINT_SCREEN); 207 matrix_make(PRINT_SCREEN);
214 state = INIT; 208 state = INIT;
215 break; 209 break;
@@ -222,21 +216,19 @@ uint8_t matrix_scan(void)
222 state = INIT; 216 state = INIT;
223 } 217 }
224 break; 218 break;
225 case E0: 219 case E0: // E0-Prefixed
226 switch (code) { 220 switch (code) {
227 case 0x12: // postfix/postfix code for exceptional keys 221 case 0x12: // to be ignored
228 case 0x59: // postfix/postfix code for exceptional keys 222 case 0x59: // to be ignored
229 // ignore
230 state = INIT; 223 state = INIT;
231 break; 224 break;
232 case 0x7E: // former part of Control-Pause[E0 7E E0 F0 7E] 225 case 0x7E: // Control'd Pause
233 matrix_make(PAUSE); 226 state = E0_7E;
234 state = INIT;
235 break; 227 break;
236 case 0xF0: // E0 break 228 case 0xF0:
237 state = E0_F0; 229 state = E0_F0;
238 break; 230 break;
239 default: // E0 make 231 default:
240 if (code < 0x80) { 232 if (code < 0x80) {
241 matrix_make(code|0x80); 233 matrix_make(code|0x80);
242 } else { 234 } else {
@@ -245,13 +237,13 @@ uint8_t matrix_scan(void)
245 state = INIT; 237 state = INIT;
246 } 238 }
247 break; 239 break;
248 case F0: 240 case F0: // Break code
249 switch (code) { 241 switch (code) {
250 case 0x83: 242 case 0x83: // F7
251 matrix_break(F8); 243 matrix_break(F7);
252 state = INIT; 244 state = INIT;
253 break; 245 break;
254 case 0x84: 246 case 0x84: // Alt'd PrintScreen
255 matrix_break(PRINT_SCREEN); 247 matrix_break(PRINT_SCREEN);
256 state = INIT; 248 state = INIT;
257 break; 249 break;
@@ -264,12 +256,10 @@ uint8_t matrix_scan(void)
264 state = INIT; 256 state = INIT;
265 } 257 }
266 break; 258 break;
267 case E0_F0: // E0 break 259 case E0_F0: // Break code of E0-prefixed
268 switch (code) { 260 switch (code) {
269 case 0x12: // postfix/postfix code for exceptional keys 261 case 0x12: // to be ignored
270 case 0x59: // postfix/postfix code for exceptional keys 262 case 0x59: // to be ignored
271 case 0x7E: // latter part of Control-Pause[E0 7E E0 F0 7E]
272 // ignore
273 state = INIT; 263 state = INIT;
274 break; 264 break;
275 default: 265 default:
@@ -281,7 +271,7 @@ uint8_t matrix_scan(void)
281 state = INIT; 271 state = INIT;
282 } 272 }
283 break; 273 break;
284 /* Pause */ 274 // following are states of Pause
285 case E1: 275 case E1:
286 switch (code) { 276 switch (code) {
287 case 0x14: 277 case 0x14:
@@ -346,6 +336,24 @@ uint8_t matrix_scan(void)
346 state = INIT; 336 state = INIT;
347 } 337 }
348 break; 338 break;
339 // Following are states of Control'd Pause
340 case E0_7E:
341 if (code == 0xE0)
342 state = E0_7E_E0;
343 else
344 state = INIT;
345 break;
346 case E0_7E_E0:
347 if (code == 0xF0)
348 state = E0_7E_E0_F0;
349 else
350 state = INIT;
351 break;
352 case E0_7E_E0_F0:
353 if (code == 0x7E)
354 matrix_make(PAUSE);
355 state = INIT;
356 break;
349 default: 357 default:
350 state = INIT; 358 state = INIT;
351 } 359 }
@@ -378,29 +386,17 @@ bool matrix_is_on(uint8_t row, uint8_t col)
378} 386}
379 387
380inline 388inline
381#if (MATRIX_COLS <= 8)
382uint8_t matrix_get_row(uint8_t row) 389uint8_t matrix_get_row(uint8_t row)
383#else
384uint16_t matrix_get_row(uint8_t row)
385#endif
386{ 390{
387 return matrix[row]; 391 return matrix[row];
388} 392}
389 393
390void matrix_print(void) 394void matrix_print(void)
391{ 395{
392#if (MATRIX_COLS <= 8)
393 print("\nr/c 01234567\n"); 396 print("\nr/c 01234567\n");
394#else
395 print("\nr/c 0123456789ABCDEF\n");
396#endif
397 for (uint8_t row = 0; row < matrix_rows(); row++) { 397 for (uint8_t row = 0; row < matrix_rows(); row++) {
398 phex(row); print(": "); 398 phex(row); print(": ");
399#if (MATRIX_COLS <= 8)
400 pbin_reverse(matrix_get_row(row)); 399 pbin_reverse(matrix_get_row(row));
401#else
402 pbin_reverse16(matrix_get_row(row));
403#endif
404#ifdef MATRIX_HAS_GHOST 400#ifdef MATRIX_HAS_GHOST
405 if (matrix_has_ghost_in_row(row)) { 401 if (matrix_has_ghost_in_row(row)) {
406 print(" <ghost"); 402 print(" <ghost");
@@ -414,11 +410,7 @@ uint8_t matrix_key_count(void)
414{ 410{
415 uint8_t count = 0; 411 uint8_t count = 0;
416 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 412 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
417#if (MATRIX_COLS <= 8)
418 count += bitpop(matrix[i]); 413 count += bitpop(matrix[i]);
419#else
420 count += bitpop16(matrix[i]);
421#endif
422 } 414 }
423 return count; 415 return count;
424} 416}
diff --git a/usb_keycodes.h b/usb_keycodes.h
index 391d21f20..6cc98682b 100644
--- a/usb_keycodes.h
+++ b/usb_keycodes.h
@@ -68,12 +68,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
68#define KB_NUHS KB_NONUS_HASH 68#define KB_NUHS KB_NONUS_HASH
69#define KB_NUBS KB_NONUS_BSLASH 69#define KB_NUBS KB_NONUS_BSLASH
70/* for Japanese */ 70/* for Japanese */
71#define KB_ZKHK KB_GRAVE
71#define KB_RO KB_INT1 72#define KB_RO KB_INT1
72#define KB_KANA KB_INT2 73#define KB_KANA KB_INT2
73#define KB_JYEN KB_INT3 74#define KB_JYEN KB_INT3
74#define KB_HENK KB_INT4 75#define KB_HENK KB_INT4
75#define KB_MHEN KB_INT5 76#define KB_MHEN KB_INT5
76#define KB_ZEHA KB_GRAVE
77/* Keypad */ 77/* Keypad */
78#define KB_P1 KB_KP_1 78#define KB_P1 KB_KP_1
79#define KB_P2 KB_KP_2 79#define KB_P2 KB_KP_2