aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2012-04-28 01:57:36 +0900
committertmk <nobody@nowhere>2012-04-28 01:57:36 +0900
commit12f6e9ffa76f685f7256bf1421f918f90c93add1 (patch)
treea4f81dff6ea8450a4f482e06a957056e74d93734
parent0a4fa89548e8c098c65c289865ebbf1e1c29adf4 (diff)
downloadqmk_firmware-12f6e9ffa76f685f7256bf1421f918f90c93add1.tar.gz
qmk_firmware-12f6e9ffa76f685f7256bf1421f918f90c93add1.zip
Added M0110A support contributed by skagon@github.
- README is written with markdown notation. - m0110.c can handles Arrow keys and Calc keys of M0110A. - EXTRAFLAGS and EXTRALDFLAGS are added in rules.mk to give flags on make command line.
-rw-r--r--m0110.c79
-rw-r--r--m0110.h42
-rw-r--r--m0110_usb/README55
-rw-r--r--m0110_usb/README.md141
-rw-r--r--m0110_usb/config.h5
-rw-r--r--m0110_usb/keymap.c148
-rw-r--r--m0110_usb/matrix.c3
-rw-r--r--rules.mk9
8 files changed, 354 insertions, 128 deletions
diff --git a/m0110.c b/m0110.c
index 522c3ec0d..68ce2d1c5 100644
--- a/m0110.c
+++ b/m0110.c
@@ -34,6 +34,7 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35POSSIBILITY OF SUCH DAMAGE. 35POSSIBILITY OF SUCH DAMAGE.
36*/ 36*/
37/* M0110A Support was contributed by skagon@github */
37 38
38#include <stdbool.h> 39#include <stdbool.h>
39#include <avr/io.h> 40#include <avr/io.h>
@@ -43,6 +44,8 @@ POSSIBILITY OF SUCH DAMAGE.
43#include "debug.h" 44#include "debug.h"
44 45
45 46
47static inline uint8_t inquiry(void);
48static inline uint8_t instant(void);
46static inline void clock_lo(void); 49static inline void clock_lo(void);
47static inline void clock_hi(void); 50static inline void clock_hi(void);
48static inline bool clock_in(void); 51static inline bool clock_in(void);
@@ -106,6 +109,23 @@ KEY EVENT:
106 Moreover, the numpad keys =, /, * and + are preceded by shift-down 0x71 on press and shift-up 0xF1 on release. 109 Moreover, the numpad keys =, /, * and + are preceded by shift-down 0x71 on press and shift-up 0xF1 on release.
107 So, the data transferred by nupmad 5 is "79 2F" whereas for numpad + it's "71 79 0D". 110 So, the data transferred by nupmad 5 is "79 2F" whereas for numpad + it's "71 79 0D".
108 111
112ARROW KEYS:
113 Arrow keys and Pad+,*,/,=(Calc keys) share same byte sequence and its preceding byte
114 0x71 and 0xF1 means press and release event of SHIFT. These cause very confusing situation.
115 It is difficult or impossible to tell Calc key from Arrow key with SHIFT in some cases.
116
117 Raw key events:
118 press release
119 ---------------- ----------------
120 Left: 0x79, 0x0D 0x79, 0x8D
121 Right: 0x79, 0x05 0x79, 0x85
122 Up: 0x79, 0x1B 0x79, 0x9B
123 Down: 0x79, 0x11 0x79, 0x91
124 Pad+: 0x71, 0x79, 0x0D 0xF1, 0x79, 0x8D
125 Pad*: 0x71, 0x79, 0x05 0xF1, 0x79, 0x85
126 Pad/: 0x71, 0x79, 0x1B 0xF1, 0x79, 0x9B
127 Pad=: 0x71, 0x79, 0x11 0xF1, 0x79, 0x91
128
109SCAN CODE: 129SCAN CODE:
110 m0111_recv_key() function returns follwing scan codes instead of raw key events. 130 m0111_recv_key() function returns follwing scan codes instead of raw key events.
111 Scan codes are 1 byte long and bit7 is set when key is released. 131 Scan codes are 1 byte long and bit7 is set when key is released.
@@ -275,15 +295,62 @@ ERROR:
275 295
276uint8_t m0110_recv_key(void) 296uint8_t m0110_recv_key(void)
277{ 297{
278 uint8_t key; 298 static uint8_t keybuf = 0x00;
299 uint8_t key, key2, key3;
300
301 if (keybuf) {
302 key = keybuf;
303 keybuf = 0x00;
304 return key;
305 }
306 key = instant(); // Use INSTANT for better response. Should be INQUIRY ?
307 switch (key) {
308 case M0110_KEYPAD:
309 // Pad/Arrow keys
310 return (M0110_RAW2SCAN(instant()) | M0110_KEYPAD_OFFSET);
311 break;
312 case M0110_SHIFT_MAKE:
313 case M0110_SHIFT_BREAK:
314 key2 = instant();
315 if (key2 == M0110_KEYPAD) {
316 key3 = instant();
317 switch (key3) {
318 case M0110_ARROW_UP:
319 case M0110_ARROW_DOWN:
320 case M0110_ARROW_LEFT:
321 case M0110_ARROW_RIGHT:
322 // Calc keys
323 return (M0110_RAW2SCAN(key3) | M0110_CALC_OFFSET);
324 default:
325 // Shift + Pad/Arrow keys
326 keybuf = M0110_RAW2SCAN(key3);
327 return (M0110_RAW2SCAN(key) | M0110_KEYPAD_OFFSET);
328 }
329 } else {
330 // Shift + other keys
331 keybuf = M0110_RAW2SCAN(key2);
332 return M0110_RAW2SCAN(key);
333 }
334 break;
335 default:
336 // other keys
337 return M0110_RAW2SCAN(key);
338 break;
339 }
340}
341
342
343static inline uint8_t inquiry(void)
344{
279 m0110_send(M0110_INQUIRY); 345 m0110_send(M0110_INQUIRY);
280 key = m0110_recv(); 346 return m0110_recv();
281 if (key == 0xFF || key == M0110_NULL)
282 return M0110_NULL;
283 else
284 return M0110_RAW2SCAN(key);
285} 347}
286 348
349static inline uint8_t instant(void)
350{
351 m0110_send(M0110_INSTANT);
352 return m0110_recv();
353}
287 354
288static inline void clock_lo() 355static inline void clock_lo()
289{ 356{
diff --git a/m0110.h b/m0110.h
index 287c45b54..39da4ad66 100644
--- a/m0110.h
+++ b/m0110.h
@@ -54,23 +54,39 @@ POSSIBILITY OF SUCH DAMAGE.
54# error "M0110 data port setting is required in config.h" 54# error "M0110 data port setting is required in config.h"
55#endif 55#endif
56 56
57#define M0110_INQUIRY 0x10 57/* Commands */
58#define M0110_INSTANT 0x14 58#define M0110_INQUIRY 0x10
59#define M0110_MODEL 0x16 59#define M0110_INSTANT 0x14
60#define M0110_TEST 0x36 60#define M0110_MODEL 0x16
61 61#define M0110_TEST 0x36
62#define M0110_PAD 0x79 62
63#define M0110_NULL 0x7B 63/* Response(raw byte from M0110) */
64#define M0110_TEST_ACK 0x7D 64#define M0110_NULL 0x7B
65#define M0110_TEST_NAK 0x77 65#define M0110_KEYPAD 0x79
66 66#define M0110_TEST_ACK 0x7D
67#define M0110_TEST_NAK 0x77
68#define M0110_SHIFT_MAKE 0x71
69#define M0110_SHIFT_BREAK 0xF1
70#define M0110_ARROW_UP 0x1B
71#define M0110_ARROW_DOWN 0x11
72#define M0110_ARROW_LEFT 0x0D
73#define M0110_ARROW_RIGHT 0x05
74
75/* This inidcates no response. */
76#define M0110_ERROR 0xFF
67 77
68/* scan code offset for keypad and arrow keys */ 78/* scan code offset for keypad and arrow keys */
69#define M0110_KEYPAD_OFFSET 0x40 79#define M0110_KEYPAD_OFFSET 0x40
70#define M0110_ARROW_OFFSET 0x60 80#define M0110_CALC_OFFSET 0x60
71 81
72/* convert key event raw response into scan code */ 82/* convert key event raw response into scan code */
73#define M0110_RAW2SCAN(key) ((key&(1<<7)) | ((key&0x7F)>>1)) 83#define M0110_RAW2SCAN(key) ( \
84 (key == M0110_NULL) ? M0110_NULL : ( \
85 (key == M0110_ERROR) ? M0110_ERROR : ( \
86 ((key&0x80) | ((key&0x7F)>>1)) \
87 ) \
88 ) \
89)
74 90
75 91
76extern uint8_t m0110_error; 92extern uint8_t m0110_error;
@@ -80,5 +96,7 @@ void m0110_init(void);
80uint8_t m0110_send(uint8_t data); 96uint8_t m0110_send(uint8_t data);
81uint8_t m0110_recv(void); 97uint8_t m0110_recv(void);
82uint8_t m0110_recv_key(void); 98uint8_t m0110_recv_key(void);
99uint8_t m0110_inquiry(void);
100uint8_t m0110_instant(void);
83 101
84#endif 102#endif
diff --git a/m0110_usb/README b/m0110_usb/README
deleted file mode 100644
index 6ef98757a..000000000
--- a/m0110_usb/README
+++ /dev/null
@@ -1,55 +0,0 @@
1M0110 to USB keyboard converter
2===============================
3This firmware converts the protocol of Apple Macintosh keyboard M0110 into USB.
4
5
6Connection
7----------
8You need 4P4C plug and cable to connect Teensy into M0110.
9Teensy port F0 is assigned for CLOCK line and F1 for DATA by default, you can change pin configuration with editing config.h..
10
11Plug:
12 http://en.wikipedia.org/wiki/Modular_connector#4P4C
13
14Pinout:
15 http://www.kbdbabel.org/conn/kbd_connector_macplus.png
16 1(Black): GND
17 2(Red): CLOCK
18 3(Green): DATA
19 4(Yellow): +5V
20
21
22
23Build Frimware
24--------------
25Optionally edit Makefile and config.h for build options, pin configuration or MCU.
26
27$ cd m0110_usb
28$ make
29and program your Teensy with loader.
30
31
32
33Keymap
34------
35You can change a keymap by editing code of keymap.c like following.
36How to define the keymap is probably obvious. You can find key symbols in usb_keycodes.h.
37
38This is a default keymap for M0110.
39,---------------------------------------------------------.
40| `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Bacpa|
41|---------------------------------------------------------|
42|Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \|
43|---------------------------------------------------------|
44|CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return|
45|---------------------------------------------------------|
46|Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift |
47`---------------------------------------------------------'
48 |Opt|Alt | Space |Alt |Opt|
49 `-----------------------------------------------'
50
51
52Notes
53-----
54
55EOF
diff --git a/m0110_usb/README.md b/m0110_usb/README.md
new file mode 100644
index 000000000..a948af91b
--- /dev/null
+++ b/m0110_usb/README.md
@@ -0,0 +1,141 @@
1M0110/M0110A to USB keyboard converter
2======================================
3This firmware converts the protocol of Apple Macintosh keyboard M0110/M0110A into USB.
4Target board of this project is [PJRC Teensy](http://www.pjrc.com/teensy/), though,
5you can use other board with USB AVR like `ATmega32U4` and `AT90USB`.
6
7![M0110](https://github.com/tmk/tmk_keyboard/raw/master/m0110_usb/doc/m0110.jpg)
8
9M0110A support was contributed by [skagon@github](https://github.com/skagon).
10
11
12
13Connection
14----------
15You need 4P4C plug and cable to connect Teensy or other AVR dev board into the keyboard.
16Teensy port `PF0` is assigned for `CLOCK` line and `PF1` for `DATA` by default,
17you can change pin configuration with editing *config.h*.
18
19You can find 4P4C plugs on telephone handset cable. Note that it is *crossover* connection
20while Macintosh keyboard cable is *straight*.
21
22[![Conection](http://i.imgur.com/vJoVOm.jpg)](http://i.imgur.com/vJoVO.jpg)
23
24In this pic:
25
261. `GND`(Black)
272. `CLOCK`(Red)
283. `DATA`(Green)
294. `+5V`(Yellow)
30
31Not that wire colors may vary in your cable.
32
33
34### Pinout
35- <http://pinouts.ru/Inputs/MacKeyboard_pinout.shtml>
36- <http://en.wikipedia.org/wiki/Modular_connector#4P4C>
37
38![Jack fig](http://www.kbdbabel.org/conn/kbd_connector_macplus.png)
39
40
41### Pull-up Registor
42You may need pull-up registors on signal lines(`CLOCK`, `DATA`) in particular
43when you have long or coiled cable. 1k-10k Ohm will be OK for this purpose.
44In some cases MCU can't read signal from keyboard correctly without pull-up resistors.
45
46
47
48Building Frimware
49-----------------
50To compile firmware you need AVR GCC. You can use [WinAVR](http://winavr.sourceforge.net/) on Windows.
51You can edit *Makefile* and *config.h* to change compile options and pin configuration.
52
53 $ git clone ... (or download source)
54 $ cd m0110_usb
55 $ make
56
57and program your Teensy with [PJRC Teensy loader](http://www.pjrc.com/teensy/loader.html).
58
59
60
61Keymap
62------
63You can change keymaps by editing *keymap.c*.
64
65### M0110
66#### *Default*
67 ,---------------------------------------------------------.
68 | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs|
69 |---------------------------------------------------------|
70 |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \|
71 |---------------------------------------------------------|
72 |Fn0 | A| S| D| F| G| H| J| K| L| ;| '|Return|
73 |---------------------------------------------------------|
74 |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift |
75 `---------------------------------------------------------'
76 |Ctr|Alt | Space |Gui |Ctr|
77 `-----------------------------------------------'
78 You can register Esc by hitting(press&release) Fn0 quickly.
79
80#### *HHKB/WASD cursor Layer(Fn0)*
81 ,---------------------------------------------------------.
82 |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet|
83 |---------------------------------------------------------|
84 |Caps |Hom| Up|PgU| | | | |Psc|Slk|Pau|Up |Ins| \|
85 |---------------------------------------------------------|
86 |Fn0 |Lef|Dow|Rig| | | | |Hom|PgU|Lef|Rig|Return|
87 |---------------------------------------------------------|
88 |Shift |End| |PgD| |VoD|VoU|Mut|End|PgD|Dow|Shift |
89 `---------------------------------------------------------'
90 |Ctr|Alt | Space |Gui |Ctr|
91 `-----------------------------------------------'
92
93### M0110A
94#### *Default*
95 ,---------------------------------------------------------. ,---------------.
96 | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Gui| =| /| *|
97 |---------------------------------------------------------| |---------------|
98 |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -|
99 |-----------------------------------------------------' | |---------------|
100 |Fn0 | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +|
101 |---------------------------------------------------------| |---------------|
102 |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| |
103 |---------------------------------------------------------| |-----------|Ent|
104 |Ctrl |Alt | Space | \|Lft|Rgt|Dn | | 0| .| |
105 `---------------------------------------------------------' `---------------'
106#### *HHKB/WASD cursor Layer(Fn0)*
107 ,---------------------------------------------------------. ,---------------.
108 |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk| =| /| *|
109 |---------------------------------------------------------| |---------------|
110 |Caps |Hom| Up|PgU| | | | |Psc|Slk|Pau|Up |Ins| | | 7| 8| 9| -|
111 |-----------------------------------------------------' | |---------------|
112 |Fn0 |Lef|Dow|Rig| | | | |Hom|PgU|Lef|Rig|Return| | 4| 5| 6| +|
113 |---------------------------------------------------------| |---------------|
114 |Shift |End| |PgD| |VoD|VoU|Mut|End|PgD|Dow|Shif|Up | | 1| 2| 3| |
115 |---------------------------------------------------------| |-----------|Ent|
116 |Ctrl |Alt | Space | \|Lft|Rgt|Dn | | 0| .| |
117 `---------------------------------------------------------' `---------------'
118
119
120
121Debug
122-----
123You can use [PJRC HID listen](http://www.pjrc.com/teensy/hid_listen.html) to see debug output.
124
125The converter has some functions for debug, press `Alt+Gui+H` simultaneously to get help.
126These function is totally undocumented, tentative, inconsistent and buggy.
127
128
129
130Arrow Keys
131----------
132Dedicated arrow keys of the M0110A are transmitting the same scancodes as the keypad but also,
133its [=], [/], [*] and [+] keys (hereafter referred to as "calc" keys) are not assigned new
134scancodes but, instead, transmit a sequence of scancodes which emulates the [Shift] key press,
135followed by the same scancode sequence of the arrow keys!
136The problem with that approach is that, while in most cases it's easy to distinguish between
137a user-generated [Shift] key event (press or release) followed by an arrow or a calc key and
138a simulated [Shift] key event generated upon a calc key event, when the user is typing fairly
139fast, it is possible that the two events become indistinguishable, and produce undesired results
140-- nothing major, though, just one or two stray characters or cursor movements; it will NOT
141format your drives, kill your cat or make your wife run away with the pizza boy.
diff --git a/m0110_usb/config.h b/m0110_usb/config.h
index c12e0738d..de20d7c88 100644
--- a/m0110_usb/config.h
+++ b/m0110_usb/config.h
@@ -30,7 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
30 30
31 31
32/* matrix size */ 32/* matrix size */
33#define MATRIX_ROWS 8 33#define MATRIX_ROWS 14
34#define MATRIX_COLS 8 34#define MATRIX_COLS 8
35 35
36/* Locking Caps Lock support */ 36/* Locking Caps Lock support */
@@ -38,8 +38,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
38 38
39/* key combination for command */ 39/* key combination for command */
40#define IS_COMMAND() ( \ 40#define IS_COMMAND() ( \
41 keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_LCTRL) | MOD_BIT(KB_LALT) | MOD_BIT(KB_LGUI)) || \ 41 keyboard_report->mods == (MOD_BIT(KB_LALT) | MOD_BIT(KB_LGUI)) \
42 keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)) \
43) 42)
44 43
45 44
diff --git a/m0110_usb/keymap.c b/m0110_usb/keymap.c
index bbb699a9a..8c509a59b 100644
--- a/m0110_usb/keymap.c
+++ b/m0110_usb/keymap.c
@@ -14,10 +14,8 @@ GNU General Public License for more details.
14You should have received a copy of the GNU General Public License 14You 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/* M0110A Support was contributed by skagon@github */
17 18
18/*
19 * Keymap for ADB keyboard
20 */
21#include <stdint.h> 19#include <stdint.h>
22#include <stdbool.h> 20#include <stdbool.h>
23#include <avr/pgmspace.h> 21#include <avr/pgmspace.h>
@@ -31,16 +29,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
31 29
32#define KEYCODE(layer, row, col) (pgm_read_byte(&keymaps[(layer)][(row)][(col)])) 30#define KEYCODE(layer, row, col) (pgm_read_byte(&keymaps[(layer)][(row)][(col)]))
33 31
34// Convert physical keyboard layout to matrix array.
35// This is a macro to define keymap easily in keyboard layout form.
36// TODO: layout for M0110A
37/* M0110 */
38#define KEYMAP( \ 32#define KEYMAP( \
39 K32,K12,K13,K14,K15,K17,K16,K1A,K1C,K19,K1D,K1B,K18,K33, \ 33 K32,K12,K13,K14,K15,K17,K16,K1A,K1C,K19,K1D,K1B,K18,K33, K47,K68,K6D,K62, \
40 K30,K0C,K0D,K0E,K0F,K11,K10,K20,K22,K1F,K23,K21,K1E,K2A, \ 34 K30,K0C,K0D,K0E,K0F,K11,K10,K20,K22,K1F,K23,K21,K1E, K59,K5B,K5C,K4E, \
41 K39,K00,K01,K02,K03,K05,K04,K26,K28,K25,K29,K27, K24, \ 35 K39,K00,K01,K02,K03,K05,K04,K26,K28,K25,K29,K27, K24, K56,K57,K58,K66, \
42 K38,K06,K07,K08,K09,K0B,K2D,K2E,K2B,K2F,K2C, \ 36 K38,K06,K07,K08,K09,K0B,K2D,K2E,K2B,K2F,K2C, K4D, K53,K54,K55,K4C, \
43 K3A,K37, K31, K34 \ 37 K3A,K37, K31, K34,K2A,K46,K42,K48, K52, K41 \
44) { \ 38) { \
45 { KB_##K00, KB_##K01, KB_##K02, KB_##K03, KB_##K04, KB_##K05, KB_##K06, KB_##K07 }, \ 39 { KB_##K00, KB_##K01, KB_##K02, KB_##K03, KB_##K04, KB_##K05, KB_##K06, KB_##K07 }, \
46 { KB_##K08, KB_##K09, KB_NO, KB_##K0B, KB_##K0C, KB_##K0D, KB_##K0E, KB_##K0F }, \ 40 { KB_##K08, KB_##K09, KB_NO, KB_##K0B, KB_##K0C, KB_##K0D, KB_##K0E, KB_##K0F }, \
@@ -49,7 +43,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
49 { KB_##K20, KB_##K21, KB_##K22, KB_##K23, KB_##K24, KB_##K25, KB_##K26, KB_##K27 }, \ 43 { KB_##K20, KB_##K21, KB_##K22, KB_##K23, KB_##K24, KB_##K25, KB_##K26, KB_##K27 }, \
50 { KB_##K28, KB_##K29, KB_##K2A, KB_##K2B, KB_##K2C, KB_##K2D, KB_##K2E, KB_##K2F }, \ 44 { KB_##K28, KB_##K29, KB_##K2A, KB_##K2B, KB_##K2C, KB_##K2D, KB_##K2E, KB_##K2F }, \
51 { KB_##K30, KB_##K31, KB_##K32, KB_##K33, KB_##K34, KB_NO, KB_NO, KB_##K37 }, \ 45 { KB_##K30, KB_##K31, KB_##K32, KB_##K33, KB_##K34, KB_NO, KB_NO, KB_##K37 }, \
52 { KB_##K38, KB_##K39, KB_##K3A, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO } \ 46 { KB_##K38, KB_##K39, KB_##K3A, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \
47 { KB_NO, KB_##K41, KB_##K42, KB_NO, KB_NO, KB_NO, KB_##K46, KB_##K47 }, \
48 { KB_##K48, KB_NO, KB_NO, KB_NO, KB_##K4C, KB_##K4D, KB_##K4E, KB_NO }, \
49 { KB_NO, KB_NO, KB_##K52, KB_##K53, KB_##K54, KB_##K55, KB_##K56, KB_##K57 }, \
50 { KB_##K58, KB_##K59, KB_NO, KB_##K5B, KB_##K5C, KB_NO, KB_NO, KB_NO }, \
51 { KB_NO, KB_NO, KB_##K62, KB_NO, KB_NO, KB_NO, KB_##K66, KB_NO }, \
52 { KB_##K68, KB_NO, KB_NO, KB_NO, KB_NO, KB_##K6D, KB_NO, KB_NO }, \
53} 53}
54 54
55 55
@@ -68,9 +68,14 @@ static const uint8_t PROGMEM fn_layer[] = {
68// Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer. 68// Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer.
69// See layer.c for details. 69// See layer.c for details.
70static const uint8_t PROGMEM fn_keycode[] = { 70static const uint8_t PROGMEM fn_keycode[] = {
71 KB_SCOLON, // Fn0 71 KB_ESC, // Fn0
72 KB_SLASH, // Fn1 72#ifdef HASU
73 KB_SCOLON, // Fn1
74 KB_SLASH, // Fn2
75#else
76 KB_NO, // Fn1
73 KB_NO, // Fn2 77 KB_NO, // Fn2
78#endif
74 KB_NO, // Fn3 79 KB_NO, // Fn3
75 KB_NO, // Fn4 80 KB_NO, // Fn4
76 KB_NO, // Fn5 81 KB_NO, // Fn5
@@ -79,52 +84,97 @@ static const uint8_t PROGMEM fn_keycode[] = {
79}; 84};
80 85
81static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 86static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
82 // LShift and RShift are logically same one button. 87 /*
83 // LOption and ROption are logically same one button. 88 * The keymap works with both M0110 and M0110A keyboards. As you can see, the M0110A is a superset
84 /* Default Layer: plain keymap 89 * of the M0110 keyboard, with only one exception: the right Alt key(Enter in M0110) does not exist
85 * ,---------------------------------------------------------. 90 * on the M0110A, but since it generates a unique scan code which is not used for some other key in
86 * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Bacpa| 91 * the M0110A, they are totally interchangeable. In fact, the M0110A is functionally (almost)
87 * |---------------------------------------------------------| 92 * identical to the combination of the M0110 along with the M0120 keypad. The only difference
88 * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| 93 * (which is causing some problems as you will read below) is that the M0110+M0120 don't have
89 * |---------------------------------------------------------| 94 * dedicated arrow keys, while the M0110A does. However, the M0120 did have arrow keys, which
90 * |Contro| A| S| D| F| G| H| J| K| L|Fn0| '|Return| 95 * doubled as the [comma], [/], [*] and [+] keys, when used with the [Shift] key. The M0110A has
91 * |---------------------------------------------------------| 96 * substituted the [comma] key with the [=] key, however its scancode is the same.
92 * |Shift | Z| X| C| V| B| N| M| ,| ,|Fn1| Shift| 97 *
93 * `---------------------------------------------------------' 98 * Default:
94 * |Fn2|Alt | Space |Gui |Fn2| 99 * ,---------------------------------------------------------. ,---------------.
95 * `-----------------------------------------------' 100 * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Gui| =| /| *|
101 * |---------------------------------------------------------| |---------------|
102 * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -|
103 * |-----------------------------------------------------' | |---------------|
104 * |Fn0 | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +|
105 * |---------------------------------------------------------| |---------------|
106 * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| |
107 * |---------------------------------------------------------| |-----------|Ent|
108 * |Ctrl |Alt | Space |Gui| \|Lft|Rgt|Dn | | 0| .| |
109 * `---------------------------------------------------------' `---------------'
110 * You can register Esc by hitting(press&release) Fn0 quickly.
111 *
112 * HHKB/WASD cursor Layer(Fn0):
113 * ,---------------------------------------------------------. ,---------------.
114 * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk| =| /| *|
115 * |---------------------------------------------------------| |---------------|
116 * |Caps |Hom| Up|PgU| | | | |Psc|Slk|Pau|Up |Ins| | | 7| 8| 9| -|
117 * |-----------------------------------------------------' | |---------------|
118 * |Fn0 |Lef|Dow|Rig| | | | |Hom|PgU|Lef|Rig|Return| | 4| 5| 6| +|
119 * |---------------------------------------------------------| |---------------|
120 * |Shift |End| |PgD| |VoD|VoU|Mut|End|PgD|Dow|Shif|Up | | 1| 2| 3| |
121 * |---------------------------------------------------------| |-----------|Ent|
122 * |Ctrl |Alt | Space |Gui | \|Lft|Rgt|Dn | | 0| .| |
123 * `---------------------------------------------------------' `---------------'
124 *
125 * NOTE: Key between Space and \ in above diagram is M0110 Enter(assigned to Gui).
126 * NOTE: LShift and RShift are logically same key. (M0110, M0110A)
127 * NOTE: LOption and ROption are logically same key. (M0110)
96 */ 128 */
129#ifdef HASU
97 KEYMAP( 130 KEYMAP(
98 GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, 131 ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, ESC, PEQL,PSLS,PAST,
99 TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, 132 TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, P7, P8, P9, PMNS,
100 LCTL,A, S, D, F, G, H, J, K, L, FN0, QUOT, ENT, 133 LCTL,A, S, D, F, G, H, J, K, L, FN1, QUOT, ENT, P4, P5, P6, PPLS,
101 LSFT,Z, X, C, V, B, N, M, COMM,DOT, FN1, 134 LSFT,Z, X, C, V, B, N, M, COMM,DOT, FN2, UP, P1, P2, P3, PENT,
102 FN2, LALT, SPC, LGUI 135 FN0, LALT, SPC, LGUI,BSLS,LEFT,DOWN,RGHT, P0, PDOT
136 ),
137 // HHKB & WASD
138 KEYMAP(
139 GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,PEQL,PSLS,PAST,
140 CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,BRK, UP, INS, P7, P8, P9, PMNS,
141 LCTL,LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, ENT, P4, P5, P6, PPLS,
142 LSFT,END, NO, PGDN,NO, VOLD,VOLU,MUTE,END, PGDN,DOWN, UP, P1, P2, P3, PENT,
143 FN0, LALT, SPC, LGUI,BSLS,LEFT,DOWN,RGHT, P0, PDOT
103 ), 144 ),
104 // vi mousekeys 145 // vi mousekeys
105 KEYMAP( 146 KEYMAP(
106 ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, 147 GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,PEQL,PSLS,PAST,
107 CAPS,NO, NO, NO, NO, NO, WH_L,WH_D,WH_U,WH_R,NO, NO, NO, NO, 148 CAPS,NO, NO, NO, NO, NO, WH_L,WH_D,WH_U,WH_R,NO, NO, NO, P7, P8, P9, PMNS,
108 LCTL,VOLD,VOLU,MUTE,NO, NO, MS_L,MS_D,MS_U,MS_R,FN0, NO, ENT, 149 NO, VOLD,VOLU,MUTE,NO, NO, MS_L,MS_D,MS_U,MS_R,FN1, NO, ENT, P4, P5, P6, PPLS,
109 LSFT,NO, NO, NO, NO, BTN3,BTN2,BTN1,NO, NO, NO, 150 LSFT,NO, NO, NO, NO, BTN3,BTN2,BTN1,NO, NO, NO, UP, P1, P2, P3, PENT,
110 NO, LALT, BTN1, LGUI 151 LCTL,LALT, BTN1, LGUI,BSLS,LEFT,DOWN,RGHT, P0, PDOT
111 ), 152 ),
112 // vi cusorkeys 153 // vi cusorkeys
113 KEYMAP( 154 KEYMAP(
114 ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, 155 GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,PEQL,PSLS,PAST,
115 CAPS,NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, NO, NO, NO, NO, 156 CAPS,NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, NO, NO, NO, P7, P8, P9, PMNS,
116 LCTL,NO, NO, NO, NO, NO, LEFT,DOWN,UP, RGHT,NO, NO, ENT, 157 NO, NO, NO, NO, NO, NO, LEFT,DOWN,UP, RGHT,NO, NO, ENT, P4, P5, P6, PPLS,
117 LSFT,NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, FN1, 158 LSFT,NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, FN2, UP, P1, P2, P3, PENT,
118 NO, LALT, SPC, LGUI 159 LCTL,LALT, SPC, LGUI,BSLS,LEFT,DOWN,RGHT, P0, PDOT
160 ),
161#else
162 KEYMAP(
163 GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, LGUI,PEQL,PSLS,PAST,
164 TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, P7, P8, P9, PMNS,
165 FN0, A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS,
166 LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, UP, P1, P2, P3, PENT,
167 LCTL,LALT, SPC, LGUI,BSLS,LEFT,DOWN,RGHT, P0, PDOT
119 ), 168 ),
120 // HHKB & WASD 169 // HHKB & WASD
121 KEYMAP( 170 KEYMAP(
122 ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, 171 ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,PEQL,PSLS,PAST,
123 CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,BRK, UP, NO, NO, 172 CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,BRK, UP, INS, P7, P8, P9, PMNS,
124 LCTL,LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, ENT, 173 FN0, LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, ENT, P4, P5, P6, PPLS,
125 LSFT,END, NO, PGDN,NO, VOLD,VOLU,MUTE,END, PGDN,DOWN, 174 LSFT,END, NO, PGDN,NO, VOLD,VOLU,MUTE,END, PGDN,DOWN, UP, P1, P2, P3, PENT,
126 FN2, LALT, SPC, LGUI 175 LCTL,LALT, SPC, LGUI,BSLS,LEFT,DOWN,RGHT, P0, PDOT
127 ), 176 ),
177#endif
128}; 178};
129 179
130 180
diff --git a/m0110_usb/matrix.c b/m0110_usb/matrix.c
index f045920cc..11303ee0f 100644
--- a/m0110_usb/matrix.c
+++ b/m0110_usb/matrix.c
@@ -93,6 +93,9 @@ uint8_t matrix_scan(void)
93#endif 93#endif
94 if (key == M0110_NULL) { 94 if (key == M0110_NULL) {
95 return 0; 95 return 0;
96 } else if (key == M0110_ERROR) {
97 // TODO: error recovery or reinit
98 return 0;
96 } else { 99 } else {
97#ifdef MATRIX_HAS_LOCKING_CAPS 100#ifdef MATRIX_HAS_LOCKING_CAPS
98 if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) { 101 if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) {
diff --git a/rules.mk b/rules.mk
index 3d32adc5f..d575726c7 100644
--- a/rules.mk
+++ b/rules.mk
@@ -230,6 +230,8 @@ LDFLAGS += $(EXTMEMOPTS)
230LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) 230LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
231LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) 231LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
232#LDFLAGS += -T linker_script.x 232#LDFLAGS += -T linker_script.x
233# You can give EXTRALDFLAGS at 'make' command line.
234LDFLAGS += $(EXTRALDFLAGS)
233 235
234 236
235 237
@@ -315,9 +317,10 @@ GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
315 317
316# Combine all necessary flags and optional flags. 318# Combine all necessary flags and optional flags.
317# Add target processor to flags. 319# Add target processor to flags.
318ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) 320# You can give EXTRAFLAGS at 'make' command line.
319ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS) 321ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS)
320ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) 322ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS)
323ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) $(EXTRAFLAGS)
321 324
322 325
323 326