forked from mirrors/qmk_userspace
		
	Fix key stuck bug of M0110A support.
- rewrite special key handling in m0110.c - add mouse keys to keymap
This commit is contained in:
		
					parent
					
						
							
								901503a1c7
							
						
					
				
			
			
				commit
				
					
						805ce3c130
					
				
			
		
					 6 changed files with 213 additions and 135 deletions
				
			
		
							
								
								
									
										229
									
								
								m0110.c
									
										
									
									
									
								
							
							
						
						
									
										229
									
								
								m0110.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2011 Jun WAKO <wakojun@gmail.com>
 | 
			
		||||
Copyright 2011,2012 Jun WAKO <wakojun@gmail.com>
 | 
			
		||||
 | 
			
		||||
This software is licensed with a Modified BSD License.
 | 
			
		||||
All of this is supposed to be Free Software, Open Source, DFSG-free,
 | 
			
		||||
| 
						 | 
				
			
			@ -82,6 +82,9 @@ static inline void request(void);
 | 
			
		|||
    } \
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
#define KEY(raw)        ((raw) & 0x7f)
 | 
			
		||||
#define IS_BREAK(raw)   (((raw) & 0x80) == 0x80)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint8_t m0110_error = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -92,10 +95,6 @@ void m0110_init(void)
 | 
			
		|||
    idle();
 | 
			
		||||
    _delay_ms(1000);
 | 
			
		||||
 | 
			
		||||
    // Model Number
 | 
			
		||||
    // M0110 : 0x09  00001001 : model number 4 (100)
 | 
			
		||||
    // M0110A: 0x0B  00001011 : model number 5 (101)
 | 
			
		||||
    // M0110 & M0120: ???
 | 
			
		||||
    m0110_send(M0110_MODEL);
 | 
			
		||||
    data = m0110_recv();
 | 
			
		||||
    print("m0110_init model: "); phex(data); print("\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -153,47 +152,151 @@ ERROR:
 | 
			
		|||
    return 0xFF;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Handling for exceptional case of key combinations for M0110A
 | 
			
		||||
 | 
			
		||||
Shift and Calc/Arrow key could be operated simultaneously:
 | 
			
		||||
 | 
			
		||||
    Case Shift   Arrow   Events          Interpret
 | 
			
		||||
    -------------------------------------------------------------------
 | 
			
		||||
    1    Down    Down    71, 79, DD      Calc(d)*a *b
 | 
			
		||||
    2    Down    Up      71, 79, UU      Arrow&Calc(u)*a
 | 
			
		||||
    3    Up      Down    F1, 79, DD      Shift(u) *c
 | 
			
		||||
    4    Up      Up      F1, 79, UU      Shift(u) and Arrow&Calc(u)*a
 | 
			
		||||
 | 
			
		||||
    Case Shift   Calc    Events          Interpret
 | 
			
		||||
    -------------------------------------------------------------------
 | 
			
		||||
    5(1) Down    Down    71, 71, 79, DD  Shift(d) and Cacl(d)
 | 
			
		||||
    6(2) Down    Up      F1, 71, 79, UU  Shift(u) and Arrow&Calc(u)*a
 | 
			
		||||
    7(1) Up      Down    F1, 71, 79, DD  Shift(u) and Calc(d)
 | 
			
		||||
    8(4) Up      Up      F1, F1, 79, UU  Shift(ux2) and Arrow&Calc(u)*a
 | 
			
		||||
 | 
			
		||||
During Calc key is hold:
 | 
			
		||||
    Case Shift   Arrow   Events          Interpret
 | 
			
		||||
    -------------------------------------------------------------------
 | 
			
		||||
    A(3) ----    Down    F1, 79, DD      Shift(u) *c
 | 
			
		||||
    B    ----    Up      79, UU          Arrow&Calc(u)*a
 | 
			
		||||
    C    Down    ----    F1, 71          Shift(u) and Shift(d)
 | 
			
		||||
    D    Up      ----    F1              Shift(u)
 | 
			
		||||
    E    Hold    Down    79, DD          Normal
 | 
			
		||||
    F    Hold    Up      79, UU          Arrow&Calc(u)*a
 | 
			
		||||
    G(1) Down    Down    F1, 71, 79, DD  Shift(u)*b and Calc(d)*a
 | 
			
		||||
    H(2) Down    Up      F1, 71, 79, UU  Shift(u) and Arrow&Calc(u)*a
 | 
			
		||||
    I(3) Up      Down    F1, F1, 79, DD  Shift(ux2) *c
 | 
			
		||||
    J(4) Up      Up      F1, 79, UU      Shift(u) and Arrow&Calc(u)*a
 | 
			
		||||
 | 
			
		||||
    Case Shift   Calc    Events          Interpret
 | 
			
		||||
    -------------------------------------------------------------------
 | 
			
		||||
    K(1) ----    Down    71, 79, DD      Calc(d)*a
 | 
			
		||||
    L(4) ----    Up      F1, 79, UU      Shift(u) and Arrow&Calc(u)*a
 | 
			
		||||
    M(1) Hold    Down    71, 79, DD      Calc(d)*a
 | 
			
		||||
    N    Hold    Up      79, UU          Arrow&Calc(u)*a
 | 
			
		||||
 | 
			
		||||
    Where DD/UU indicates part of Keypad Down/Up event.
 | 
			
		||||
    *a: Impossible to distinguish btween Arrow and Calc event.
 | 
			
		||||
    *b: Shift(d) event is ignored.
 | 
			
		||||
    *c: Arrow/Calc(d) event is ignored.
 | 
			
		||||
*/
 | 
			
		||||
uint8_t m0110_recv_key(void)
 | 
			
		||||
{
 | 
			
		||||
    static uint8_t keybuf = 0x00;
 | 
			
		||||
    uint8_t key, key2, key3;
 | 
			
		||||
    static uint8_t keybuf2 = 0x00;
 | 
			
		||||
    static uint8_t rawbuf = 0x00;
 | 
			
		||||
    uint8_t raw, raw2, raw3;
 | 
			
		||||
 | 
			
		||||
    if (keybuf) {
 | 
			
		||||
        key = keybuf;
 | 
			
		||||
        raw = keybuf;
 | 
			
		||||
        keybuf = 0x00;
 | 
			
		||||
        return key;
 | 
			
		||||
        return raw;
 | 
			
		||||
    }
 | 
			
		||||
    key = instant();  // Use INSTANT for better response. Should be INQUIRY ?
 | 
			
		||||
    switch (key & 0x7F) {
 | 
			
		||||
    if (keybuf2) {
 | 
			
		||||
        raw = keybuf2;
 | 
			
		||||
        keybuf2 = 0x00;
 | 
			
		||||
        return raw;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (rawbuf) {
 | 
			
		||||
        raw = rawbuf;
 | 
			
		||||
        rawbuf = 0x00;
 | 
			
		||||
    } else {
 | 
			
		||||
        raw = instant();  // Use INSTANT for better response. Should be INQUIRY ?
 | 
			
		||||
    }
 | 
			
		||||
    switch (KEY(raw)) {
 | 
			
		||||
        case M0110_KEYPAD:
 | 
			
		||||
            // Pad/Arrow keys
 | 
			
		||||
            return (raw2scan(instant()) | M0110_KEYPAD_OFFSET);
 | 
			
		||||
            raw2 = instant();
 | 
			
		||||
            switch (KEY(raw2)) {
 | 
			
		||||
                case M0110_ARROW_UP:
 | 
			
		||||
                case M0110_ARROW_DOWN:
 | 
			
		||||
                case M0110_ARROW_LEFT:
 | 
			
		||||
                case M0110_ARROW_RIGHT:
 | 
			
		||||
                    if (IS_BREAK(raw2)) {
 | 
			
		||||
                        // Case B,F,N:
 | 
			
		||||
                        keybuf = (raw2scan(raw2) | M0110_CALC_OFFSET); // Calc(u)
 | 
			
		||||
                        return (raw2scan(raw2) | M0110_KEYPAD_OFFSET); // Arrow(u)
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            // Keypad or Arrow
 | 
			
		||||
            return (raw2scan(raw2) | M0110_KEYPAD_OFFSET);
 | 
			
		||||
            break;
 | 
			
		||||
        case M0110_SHIFT:
 | 
			
		||||
            key2 = instant();
 | 
			
		||||
            if (key2 == M0110_KEYPAD) {
 | 
			
		||||
                key3 = instant();
 | 
			
		||||
                switch (key3 & 0x7F) {
 | 
			
		||||
                    case M0110_ARROW_UP:
 | 
			
		||||
                    case M0110_ARROW_DOWN:
 | 
			
		||||
                    case M0110_ARROW_LEFT:
 | 
			
		||||
                    case M0110_ARROW_RIGHT:
 | 
			
		||||
                        // Calc keys
 | 
			
		||||
                        return (raw2scan(key3) | M0110_CALC_OFFSET);
 | 
			
		||||
                    default:
 | 
			
		||||
                        // Shift + Pad/Arrow keys
 | 
			
		||||
                        keybuf = raw2scan(key3);
 | 
			
		||||
                        return (raw2scan(key) | M0110_KEYPAD_OFFSET);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                // Shift + other keys
 | 
			
		||||
                keybuf = raw2scan(key2);
 | 
			
		||||
                return raw2scan(key);
 | 
			
		||||
            raw2 = instant();
 | 
			
		||||
            switch (KEY(raw2)) {
 | 
			
		||||
                case M0110_SHIFT:
 | 
			
		||||
                    // Case: 5-8,C,G,H
 | 
			
		||||
                    rawbuf = raw2;
 | 
			
		||||
                    return raw2scan(raw); // Shift(d/u)
 | 
			
		||||
                    break;
 | 
			
		||||
                case M0110_KEYPAD:
 | 
			
		||||
                    // Shift + Arrow, Calc, or etc.
 | 
			
		||||
                    raw3 = instant();
 | 
			
		||||
                    switch (KEY(raw3)) {
 | 
			
		||||
                        case M0110_ARROW_UP:
 | 
			
		||||
                        case M0110_ARROW_DOWN:
 | 
			
		||||
                        case M0110_ARROW_LEFT:
 | 
			
		||||
                        case M0110_ARROW_RIGHT:
 | 
			
		||||
                            if (IS_BREAK(raw)) {
 | 
			
		||||
                                if (IS_BREAK(raw3)) {
 | 
			
		||||
                                    // Case 4:
 | 
			
		||||
                                    print("(4)\n");
 | 
			
		||||
                                    keybuf2 = raw2scan(raw); // Shift(u)
 | 
			
		||||
                                    keybuf  = (raw2scan(raw3) | M0110_CALC_OFFSET); // Calc(u)
 | 
			
		||||
                                    return (raw2scan(raw3) | M0110_KEYPAD_OFFSET);  // Arrow(u)
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    // Case 3:
 | 
			
		||||
                                    print("(3)\n");
 | 
			
		||||
                                    return (raw2scan(raw)); // Shift(u)
 | 
			
		||||
                                }
 | 
			
		||||
                            } else {
 | 
			
		||||
                                if (IS_BREAK(raw3)) {
 | 
			
		||||
                                    // Case 2:
 | 
			
		||||
                                    print("(2)\n");
 | 
			
		||||
                                    keybuf  = (raw2scan(raw3) | M0110_CALC_OFFSET); // Calc(u)
 | 
			
		||||
                                    return (raw2scan(raw3) | M0110_KEYPAD_OFFSET);  // Arrow(u)
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    // Case 1:
 | 
			
		||||
                                    print("(1)\n");
 | 
			
		||||
                                    return (raw2scan(raw3) | M0110_CALC_OFFSET); // Calc(d)
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            break;
 | 
			
		||||
                        default:
 | 
			
		||||
                            // Shift + Keypad
 | 
			
		||||
                            keybuf = (raw2scan(raw3) | M0110_KEYPAD_OFFSET);
 | 
			
		||||
                            return raw2scan(raw);   // Shift(d/u)
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    // Shift + Normal keys
 | 
			
		||||
                    keybuf = raw2scan(raw2);
 | 
			
		||||
                    return raw2scan(raw);   // Shift(d/u)
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            // other keys
 | 
			
		||||
            return raw2scan(key);
 | 
			
		||||
            // Normal keys
 | 
			
		||||
            return raw2scan(raw);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -216,10 +319,9 @@ static inline uint8_t inquiry(void)
 | 
			
		|||
static inline uint8_t instant(void)
 | 
			
		||||
{
 | 
			
		||||
    m0110_send(M0110_INSTANT);
 | 
			
		||||
    //return m0110_recv();
 | 
			
		||||
    uint8_t data = m0110_recv();
 | 
			
		||||
    if (data != 0x7B) {
 | 
			
		||||
        print("data: "); phex(data); print("\n");
 | 
			
		||||
    if (data != M0110_NULL) {
 | 
			
		||||
        phex(data); print(" ");
 | 
			
		||||
    }
 | 
			
		||||
    return data;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -326,7 +428,7 @@ CLOCK is always from KEYBOARD. DATA are sent with MSB first.
 | 
			
		|||
Protocol
 | 
			
		||||
--------
 | 
			
		||||
COMMAND:
 | 
			
		||||
    Inquiry     0x10    get key event
 | 
			
		||||
    Inquiry     0x10    get key event with block
 | 
			
		||||
    Instant     0x12    get key event
 | 
			
		||||
    Model       0x14    get model number(M0110 responds with 0x09)
 | 
			
		||||
                        bit 7   1 if another device connected(used when keypad exists?)
 | 
			
		||||
| 
						 | 
				
			
			@ -341,14 +443,13 @@ KEY EVENT:
 | 
			
		|||
    bit 0       always 1
 | 
			
		||||
    To get scan code use this: ((bits&(1<<7)) | ((bits&0x7F))>>1).
 | 
			
		||||
 | 
			
		||||
    Note: On the M0110A, the numpad keys and the arrow keys are preceded by 0x79.
 | 
			
		||||
          Moreover, the numpad keys =, /, * and + are preceded by shift-down 0x71 on press and shift-up 0xF1 on release.
 | 
			
		||||
          So, the data transferred by nupmad 5 is "79 2F" whereas for numpad + it's "71 79 0D".
 | 
			
		||||
    Note: On the M0110A, Keypad keys and Arrow keys are preceded by 0x79.
 | 
			
		||||
          Moreover, some Keypad keys(=, /, * and +) are preceded by 0x71 on press and 0xF1 on release.
 | 
			
		||||
 | 
			
		||||
ARROW KEYS:
 | 
			
		||||
    Arrow keys and Pad+,*,/,=(Calc keys) share same byte sequence and its preceding byte
 | 
			
		||||
    0x71 and 0xF1 means press and release event of SHIFT. These cause very confusing situation.
 | 
			
		||||
    It is difficult or impossible to tell Calc key from Arrow key with SHIFT in some cases.
 | 
			
		||||
    Arrow keys and Calc keys(+,*,/,= on keypad) share same byte sequence and preceding byte of
 | 
			
		||||
    Calc keys(0x71 and 0xF1) means press and release event of SHIFT. This causes a very confusing situation,
 | 
			
		||||
    it is difficult or impossible to tell Calc key from Arrow key plus SHIFT in some cases.
 | 
			
		||||
 | 
			
		||||
    Raw key events:
 | 
			
		||||
            press               release
 | 
			
		||||
| 
						 | 
				
			
			@ -362,9 +463,45 @@ ARROW KEYS:
 | 
			
		|||
    Pad/:   0x71, 0x79, 0x1B    0xF1, 0x79, 0x9B
 | 
			
		||||
    Pad=:   0x71, 0x79, 0x11    0xF1, 0x79, 0x91
 | 
			
		||||
 | 
			
		||||
SCAN CODE:
 | 
			
		||||
    m0111_recv_key() function returns follwing scan codes instead of raw key events.
 | 
			
		||||
    Scan codes are 1 byte long and bit7 is set when key is released. 
 | 
			
		||||
 | 
			
		||||
RAW CODE:
 | 
			
		||||
    M0110A
 | 
			
		||||
    ,---------------------------------------------------------. ,---------------.
 | 
			
		||||
    |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Bcksp| |Clr|  =|  /|  *|
 | 
			
		||||
    |---------------------------------------------------------| |---------------|
 | 
			
		||||
    |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|   | |  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|  ,|  ,|  /|Shft|Up | |  1|  2|  3|   |
 | 
			
		||||
    |---------------------------------------------------------' |-----------|Ent|
 | 
			
		||||
    |Optio|Mac    |           Space           |  \|Lft|Rgt|Dn | |      0|  .|   |
 | 
			
		||||
    `---------------------------------------------------------' `---------------'
 | 
			
		||||
    ,---------------------------------------------------------. ,---------------.
 | 
			
		||||
    | 65| 25| 27| 29| 2B| 2F| 2D| 35| 39| 33| 3B| 37| 31|   67| |+0F|*11|*1B|*05|
 | 
			
		||||
    |---------------------------------------------------------| |---------------|
 | 
			
		||||
    |   61| 19| 1B| 1D| 1F| 23| 21| 41| 45| 3F| 47| 43| 3D|   | |+33|+37|+39|+1D|
 | 
			
		||||
    |-----------------------------------------------------'   | |---------------|
 | 
			
		||||
    |    73| 01| 03| 05| 07| 0B| 09| 4D| 51| 4B| 53| 4F|    49| |+2D|+2F|+31|*0D|
 | 
			
		||||
    |---------------------------------------------------------| |---------------|
 | 
			
		||||
    |      71| 0D| 0F| 11| 13| 17| 5B| 5D| 27| 5F| 59|  71|+1B| |+27|+29|+2B|   |
 | 
			
		||||
    |---------------------------------------------------------' |-----------|+19|
 | 
			
		||||
    |   75|     6F|            63             | 55|+0D|+05|+11| |    +25|+03|   |
 | 
			
		||||
    `---------------------------------------------------------' `---------------'
 | 
			
		||||
    + 0x79, 0xDD / 0xF1, 0xUU
 | 
			
		||||
    * 0x71, 0x79,DD / 0xF1, 0x79, 0xUU
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
MODEL NUMBER:
 | 
			
		||||
    M0110:           0x09  00001001 : model number 4 (100)
 | 
			
		||||
    M0110A:          0x0B  00001011 : model number 5 (101)
 | 
			
		||||
    M0110 & M0120:   ???
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Scan Code
 | 
			
		||||
---------
 | 
			
		||||
    m0110_recv_key() function returns following scan codes instead of raw key events.
 | 
			
		||||
    Scan codes are 1 byte long and MSB(bit7) is set when key is released. 
 | 
			
		||||
 | 
			
		||||
    M0110
 | 
			
		||||
    ,---------------------------------------------------------.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								m0110.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								m0110.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2011 Jun WAKO <wakojun@gmail.com>
 | 
			
		||||
Copyright 2011,2012 Jun WAKO <wakojun@gmail.com>
 | 
			
		||||
 | 
			
		||||
This software is licensed with a Modified BSD License.
 | 
			
		||||
All of this is supposed to be Free Software, Open Source, DFSG-free,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -105,15 +105,15 @@ You can change keymaps by editing *keymap.c*.
 | 
			
		|||
    `---------------------------------------------------------' `---------------'
 | 
			
		||||
#### *HHKB/WASD cursor Layer(Fn0)*
 | 
			
		||||
    ,---------------------------------------------------------. ,---------------.
 | 
			
		||||
    |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk|  =|  /|  *|
 | 
			
		||||
    |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk|Mb1|Mb3|Mb2|
 | 
			
		||||
    |---------------------------------------------------------| |---------------|
 | 
			
		||||
    |Caps |Hom| Up|PgU|   |   |   |   |Psc|Slk|Pau|Up |Ins|   | |  7|  8|  9|  -|
 | 
			
		||||
    |Caps |Hom| Up|PgU|   |   |   |   |Psc|Slk|Pau|Up |Ins|   | |MwD|McU|MwU|MwU|
 | 
			
		||||
    |-----------------------------------------------------'   | |---------------|
 | 
			
		||||
    |Fn0   |Lef|Dow|Rig|   |   |   |   |Hom|PgU|Lef|Rig|Return| |  4|  5|  6|  +|
 | 
			
		||||
    |Fn0   |Lef|Dow|Rig|   |   |   |   |Hom|PgU|Lef|Rig|Return| |McL|McD|McR|MwD|
 | 
			
		||||
    |---------------------------------------------------------| |---------------|
 | 
			
		||||
    |Shift   |End|   |PgD|   |VoD|VoU|Mut|End|PgD|Dow|Shif|Up | |  1|  2|  3|   |
 | 
			
		||||
    |---------------------------------------------------------| |-----------|Ent|
 | 
			
		||||
    |Ctrl |Alt    |         Space             |  \|Lft|Rgt|Dn | |      0|  .|   |
 | 
			
		||||
    |Shift   |End|   |PgD|   |VoD|VoU|Mut|End|PgD|Dow|Shif|Up | |MwL|McD|MwR|   |
 | 
			
		||||
    |---------------------------------------------------------| |-----------|Mb2|
 | 
			
		||||
    |Ctrl |Alt    |         Space        |Gui |  \|Lft|Rgt|Dn | |    Mb1|Mb3|   |
 | 
			
		||||
    `---------------------------------------------------------' `---------------'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -124,18 +124,3 @@ You can use [PJRC HID listen](http://www.pjrc.com/teensy/hid_listen.html) to see
 | 
			
		|||
 | 
			
		||||
The converter has some functions for debug, press `Alt+Gui+H` simultaneously to get help.
 | 
			
		||||
These function is totally undocumented, tentative, inconsistent and buggy.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Arrow Keys
 | 
			
		||||
----------
 | 
			
		||||
Dedicated arrow keys of the M0110A are transmitting the same scancodes as the keypad but also,
 | 
			
		||||
its [=], [/], [*] and [+] keys (hereafter referred to as "calc" keys) are not assigned new
 | 
			
		||||
scancodes but, instead, transmit a sequence of scancodes which emulates the [Shift] key press,
 | 
			
		||||
followed by the same scancode sequence of the arrow keys!
 | 
			
		||||
The problem with that approach is that, while in most cases it's easy to distinguish between
 | 
			
		||||
a user-generated [Shift] key event (press or release) followed by an arrow or a calc key and
 | 
			
		||||
a simulated [Shift] key event generated upon a calc key event, when the user is typing fairly
 | 
			
		||||
fast, it is possible that the two events become indistinguishable, and produce undesired results
 | 
			
		||||
-- nothing major, though, just one or two stray characters or cursor movements; it will NOT
 | 
			
		||||
format your drives, kill your cat or make your wife run away with the pizza boy.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2011 Jun Wako <wakojun@gmail.com>
 | 
			
		||||
Copyright 2011,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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2011 Jun Wako <wakojun@gmail.com>
 | 
			
		||||
Copyright 2011,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
 | 
			
		||||
| 
						 | 
				
			
			@ -88,7 +88,7 @@ static const uint8_t PROGMEM fn_keycode[] = {
 | 
			
		|||
static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		||||
    /* 
 | 
			
		||||
     * The keymap works with both M0110 and M0110A keyboards. As you can see, the M0110A is a superset
 | 
			
		||||
     * of the M0110 keyboard, with only one exception: the right Alt key(Enter in M0110) does not exist
 | 
			
		||||
     * of the M0110 keyboard, with only one exception: 'Enter' in M0110 does not exist
 | 
			
		||||
     * on the M0110A, but since it generates a unique scan code which is not used for some other key in
 | 
			
		||||
     * the M0110A, they are totally interchangeable.  In fact, the M0110A is functionally (almost)
 | 
			
		||||
     * identical to the combination of the M0110 along with the M0120 keypad. The only difference
 | 
			
		||||
| 
						 | 
				
			
			@ -110,18 +110,19 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
     * |Ctrl |Alt    |         Space         |Gui|  \|Lft|Rgt|Dn | |      0|  .|   |
 | 
			
		||||
     * `---------------------------------------------------------' `---------------'
 | 
			
		||||
     *
 | 
			
		||||
     * HHKB/WASD cursor Layer(Fn0):
 | 
			
		||||
     * HHKB/WASD/Mouse Layer(Fn0):
 | 
			
		||||
     * ,---------------------------------------------------------. ,---------------.
 | 
			
		||||
     * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk|  =|  /|  *|
 | 
			
		||||
     * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk|Mb1|Mb3|Mb2|
 | 
			
		||||
     * |---------------------------------------------------------| |---------------|
 | 
			
		||||
     * |Caps |Hom| Up|PgU|   |   |   |   |Psc|Slk|Pau|Up |Ins|   | |  7|  8|  9|  -|
 | 
			
		||||
     * |Caps |Hom| Up|PgU|   |   |   |   |Psc|Slk|Pau|Up |Ins|   | |MwD|McU|MwU|MwU|
 | 
			
		||||
     * |-----------------------------------------------------'   | |---------------|
 | 
			
		||||
     * |Fn0   |Lef|Dow|Rig|   |   |   |   |Hom|PgU|Lef|Rig|Return| |  4|  5|  6|  +|
 | 
			
		||||
     * |Fn0   |Lef|Dow|Rig|   |   |   |   |Hom|PgU|Lef|Rig|Return| |McL|McD|McR|MwD|
 | 
			
		||||
     * |---------------------------------------------------------| |---------------|
 | 
			
		||||
     * |Shift   |End|   |PgD|   |VoD|VoU|Mut|End|PgD|Dow|Shif|Up | |  1|  2|  3|   |
 | 
			
		||||
     * |---------------------------------------------------------| |-----------|Ent|
 | 
			
		||||
     * |Ctrl |Alt    |         Space        |Gui |  \|Lft|Rgt|Dn | |      0|  .|   |
 | 
			
		||||
     * |Shift   |End|   |PgD|   |VoD|VoU|Mut|End|PgD|Dow|Shif|Up | |MwL|McD|MwR|   |
 | 
			
		||||
     * |---------------------------------------------------------| |-----------|Mb2|
 | 
			
		||||
     * |Ctrl |Alt    |         Space        |Gui |  \|Lft|Rgt|Dn | |    Mb1|Mb3|   |
 | 
			
		||||
     * `---------------------------------------------------------' `---------------'
 | 
			
		||||
     * Mb: Mouse Button / Mc: Mouse Cursor / Mw: Mouse Wheel
 | 
			
		||||
     *
 | 
			
		||||
     * NOTE: You can register Esc by hitting(press&release) Fn0 quickly.
 | 
			
		||||
     * NOTE: Gui between Space and \ is Enter on M0110 not exists on M0110A.
 | 
			
		||||
| 
						 | 
				
			
			@ -130,7 +131,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
     */
 | 
			
		||||
#ifndef HASU
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    GRV, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC,    LGUI,PEQL,PSLS,PAST,
 | 
			
		||||
    GRV, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC,    LGUI,EQL, PSLS,PAST,
 | 
			
		||||
    TAB, Q,   W,   E,   R,   T,   Y,   U,   I,   O,   P,   LBRC,RBRC,         P7,  P8,  P9,  PMNS,
 | 
			
		||||
    FN0, A,   S,   D,   F,   G,   H,   J,   K,   L,   SCLN,QUOT,     ENT,     P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, SLSH,          UP,      P1,  P2,  P3,  PENT,
 | 
			
		||||
| 
						 | 
				
			
			@ -138,17 +139,17 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
    ),
 | 
			
		||||
    // HHKB & WASD
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, DEL,     NLCK,PEQL,PSLS,PAST,
 | 
			
		||||
    CAPS,HOME,UP,  PGUP,NO,  NO,  NO,  NO,  PSCR,SLCK,BRK, UP,  INS,          P7,  P8,  P9,  PMNS,
 | 
			
		||||
    FN0, LEFT,DOWN,RGHT,NO,  NO,  NO,  NO,  HOME,PGUP,LEFT,RGHT,     ENT,     P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,END, NO,  PGDN,NO,  VOLD,VOLU,MUTE,END, PGDN,DOWN,          UP,      P1,  P2,  P3,  PENT,
 | 
			
		||||
    LCTL,LALT,               SPC,                LGUI,BSLS,LEFT,RGHT,DOWN,    P0,       PDOT
 | 
			
		||||
    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, DEL,     NLCK,BTN1,BTN3,BTN2,
 | 
			
		||||
    CAPS,HOME,UP,  PGUP,NO,  NO,  NO,  NO,  PSCR,SLCK,BRK, UP,  INS,          WH_D,MS_U,WH_U,WH_U,
 | 
			
		||||
    FN0, LEFT,DOWN,RGHT,NO,  NO,  NO,  NO,  HOME,PGUP,LEFT,RGHT,     ENT,     MS_L,MS_D,MS_R,WH_D,
 | 
			
		||||
    LSFT,END, NO,  PGDN,NO,  VOLD,VOLU,MUTE,END, PGDN,DOWN,          UP,      WH_L,MS_D,WH_R,BTN2,
 | 
			
		||||
    LCTL,LALT,               SPC,                LGUI,BSLS,LEFT,RGHT,DOWN,    BTN1,     BTN3
 | 
			
		||||
    ),
 | 
			
		||||
#else
 | 
			
		||||
    // hasu's keymap
 | 
			
		||||
    // To enable use this 'make' option: make EXTRAFLAGS=-DHASU
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    ESC, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC,    ESC, PEQL,PSLS,PAST,
 | 
			
		||||
    ESC, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC,    LGUI,EQL, PSLS,PAST,
 | 
			
		||||
    TAB, Q,   W,   E,   R,   T,   Y,   U,   I,   O,   P,   LBRC,RBRC,         P7,  P8,  P9,  PMNS,
 | 
			
		||||
    LCTL,A,   S,   D,   F,   G,   H,   J,   K,   L,   FN1, QUOT,     ENT,     P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, FN2,           FN3,     P1,  P2,  P3,  PENT,
 | 
			
		||||
| 
						 | 
				
			
			@ -156,7 +157,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
    ),
 | 
			
		||||
    // HHKB & WASD
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    GRV, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, DEL,     NLCK,PEQL,PSLS,PAST,
 | 
			
		||||
    GRV, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, DEL,     NLCK,EQL, PSLS,PAST,
 | 
			
		||||
    CAPS,HOME,UP,  PGUP,NO,  NO,  NO,  NO,  PSCR,SLCK,BRK, UP,  INS,          P7,  P8,  P9,  PMNS,
 | 
			
		||||
    LCTL,LEFT,DOWN,RGHT,NO,  NO,  NO,  NO,  HOME,PGUP,LEFT,RGHT,     ENT,     P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,END, NO,  PGDN,NO,  VOLD,VOLU,MUTE,END, PGDN,DOWN,          FN3,     P1,  P2,  P3,  PENT,
 | 
			
		||||
| 
						 | 
				
			
			@ -164,7 +165,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
    ),
 | 
			
		||||
    // vi mousekeys
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    GRV, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, DEL,     NLCK,PEQL,PSLS,PAST,
 | 
			
		||||
    GRV, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, DEL,     NLCK,EQL, PSLS,PAST,
 | 
			
		||||
    CAPS,NO,  NO,  NO,  NO,  NO,  WH_L,WH_D,WH_U,WH_R,NO,  NO,  NO,           P7,  P8,  P9,  PMNS,
 | 
			
		||||
    NO,  VOLD,VOLU,MUTE,NO,  NO,  MS_L,MS_D,MS_U,MS_R,FN1, NO,       ENT,     P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,NO,  NO,  NO,  NO,  BTN3,BTN2,BTN1,NO,  NO,  NO,            UP,      P1,  P2,  P3,  PENT,
 | 
			
		||||
| 
						 | 
				
			
			@ -172,7 +173,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		|||
    ),
 | 
			
		||||
    // vi cusorkeys
 | 
			
		||||
    KEYMAP(
 | 
			
		||||
    GRV, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, DEL,     NLCK,PEQL,PSLS,PAST,
 | 
			
		||||
    GRV, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, DEL,     NLCK,EQL, PSLS,PAST,
 | 
			
		||||
    CAPS,NO,  NO,  NO,  NO,  NO,  HOME,PGDN,PGUP,END, NO,  NO,  NO,           P7,  P8,  P9,  PMNS,
 | 
			
		||||
    NO,  NO,  NO,  NO,  NO,  NO,  LEFT,DOWN,UP,  RGHT,NO,  NO,       ENT,     P4,  P5,  P6,  PPLS,
 | 
			
		||||
    LSFT,NO,  NO,  NO,  NO,  NO,  HOME,PGDN,PGUP,END, FN2,           UP,      P1,  P2,  P3,  PENT,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2011 Jun Wako <wakojun@gmail.com>
 | 
			
		||||
Copyright 2011,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
 | 
			
		||||
| 
						 | 
				
			
			@ -36,11 +36,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define ROW(key)    ((key)>>3&0x0F)
 | 
			
		||||
#define COL(key)    ((key)&0x07)
 | 
			
		||||
 | 
			
		||||
#define ARROW_UP_BREAK      (0x4D | 0x80)
 | 
			
		||||
#define ARROW_DOWN_BREAK    (0x48 | 0x80)
 | 
			
		||||
#define ARROW_LEFT_BREAK    (0x46 | 0x80)
 | 
			
		||||
#define ARROW_RIGHT_BREAK   (0x42 | 0x80)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static bool is_modified = false;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -48,9 +43,6 @@ static bool is_modified = false;
 | 
			
		|||
static uint8_t *matrix;
 | 
			
		||||
static uint8_t _matrix0[MATRIX_ROWS];
 | 
			
		||||
 | 
			
		||||
#ifdef MATRIX_HAS_GHOST
 | 
			
		||||
static bool matrix_has_ghost_in_row(uint8_t row);
 | 
			
		||||
#endif
 | 
			
		||||
static void register_key(uint8_t key);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -100,20 +92,6 @@ uint8_t matrix_scan(void)
 | 
			
		|||
        return 0;
 | 
			
		||||
    } else if (key == M0110_ERROR) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    } else if (key == ARROW_UP_BREAK ||
 | 
			
		||||
               key == ARROW_DOWN_BREAK ||
 | 
			
		||||
               key == ARROW_LEFT_BREAK ||
 | 
			
		||||
               key == ARROW_RIGHT_BREAK) {
 | 
			
		||||
        // WORK AROUND: exceptional handling for M0110A
 | 
			
		||||
        // Unregister both Arrow key and coressponding Calc key when receive Arrow key break.
 | 
			
		||||
        //
 | 
			
		||||
        // Shift + Calc keys(=/*+):
 | 
			
		||||
        //    Send no Shift break(0xF1) when release Calc keys. Can't be desinguished from Arrow keys.
 | 
			
		||||
        //    (press: 0x71, 0x79, 0xXX      release: 0x79, 0xXX)
 | 
			
		||||
        //    See m0110.c for key events and scan codes.
 | 
			
		||||
        is_modified = true;
 | 
			
		||||
        register_key(key);
 | 
			
		||||
        register_key(key|M0110_CALC_OFFSET);
 | 
			
		||||
    } else {
 | 
			
		||||
#ifdef MATRIX_HAS_LOCKING_CAPS    
 | 
			
		||||
        if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -133,7 +111,7 @@ uint8_t matrix_scan(void)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    if (debug_enable) {
 | 
			
		||||
        print("key: "); phex(key); print("\n");
 | 
			
		||||
        print("["); phex(key); print("]\n");
 | 
			
		||||
    }
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -146,12 +124,6 @@ bool matrix_is_modified(void)
 | 
			
		|||
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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -186,23 +158,6 @@ uint8_t matrix_key_count(void)
 | 
			
		|||
    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 register_key(uint8_t key)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue