~ruther/qmk_firmware

f5f48c2a240b43e1773c3787b8fca8859f128cf7 — tmk 13 years ago d553289
Fix bug on RAW2SCAN. Add work around for M0110A.

- Bug fix: Macro RAW2SCAN doesn't work and converted into static inline function.
- Add Exceptional handling for M0110A arrow keys and calc keys.
- Fix keymap.
7 files changed, 223 insertions(+), 195 deletions(-)

M m0110.c
M m0110.h
M m0110_usb/doc/m0110.jpg -rwxr-xr-x => -rw-r--r--
M m0110_usb/doc/teensy.jpg -rwxr-xr-x => -rw-r--r--
M m0110_usb/keymap.c
M m0110_usb/matrix.c
M rules.mk
M m0110.c => m0110.c +164 -149
@@ 44,6 44,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "debug.h"


static inline uint8_t raw2scan(uint8_t raw);
static inline uint8_t inquiry(void);
static inline uint8_t instant(void);
static inline void clock_lo(void);


@@ 60,147 61,6 @@ static inline void idle(void);
static inline void request(void);


/*
Primitive M0110 Library for AVR
==============================


Signaling
---------
CLOCK is always from KEYBOARD. DATA are sent with MSB first.

1) IDLE: both lines are high.
    CLOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    DATA  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2) KEYBOARD->HOST: HOST reads bit on rising edge.
    CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~
    DATA  ~~~~~~~~~~~~X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~
                      <--> 160us(clock low)
                         <---> 180us(clock high)

3) HOST->KEYBOARD: HOST asserts bit on falling edge.
    CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~
    DATA  ~~~~~~|_____X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~
                <----> 840us(request to send by host)                     <---> 80us(hold DATA)
                      <--> 180us(clock low)
                         <---> 220us(clock high)


Protocol
--------
COMMAND:
    Inquiry     0x10    get key event
    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?)
                        bit4-6  next device model number
                        bit1-3  keyboard model number
                        bit 0   always 1
    Test        0x16    test(ACK:0x7D/NAK:0x77)

KEY EVENT:
    bit 7       key state(0:press 1:release)
    bit 6-1     scan code(see below)
    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".

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.

    Raw key events:
            press               release
            ----------------    ----------------
    Left:         0x79, 0x0D          0x79, 0x8D
    Right:        0x79, 0x05          0x79, 0x85
    Up:           0x79, 0x1B          0x79, 0x9B
    Down:         0x79, 0x11          0x79, 0x91
    Pad+:   0x71, 0x79, 0x0D    0xF1, 0x79, 0x8D
    Pad*:   0x71, 0x79, 0x05    0xF1, 0x79, 0x85
    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. 

    M0110
    ,---------------------------------------------------------.
    |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Backs|
    |---------------------------------------------------------|
    |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|  \|
    |---------------------------------------------------------|
    |CapsLo|  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|Return|
    |---------------------------------------------------------|
    |Shift   |  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /|        |
    `---------------------------------------------------------'
         |Opt|Mac |         Space               |Enter|Opt|
         `------------------------------------------------'
    ,---------------------------------------------------------.
    | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18|   33|
    |---------------------------------------------------------|
    |   30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A|
    |---------------------------------------------------------|
    |    39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27|    24|
    |---------------------------------------------------------|
    |      38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C|      38|
    `---------------------------------------------------------'
         | 3A|  37|             31              |   34| 3A|
         `------------------------------------------------'

    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|  .|   |
    `---------------------------------------------------------' `---------------'
    ,---------------------------------------------------------. ,---------------.
    | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18|   33| | 47| 68| 6D| 62|
    |---------------------------------------------------------| |---------------|
    |   30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E|   | | 59| 5B| 5C| 4E|
    |-----------------------------------------------------'   | |---------------|
    |    39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27|    24| | 56| 57| 58| 66|
    |---------------------------------------------------------| |---------------|
    |      38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C|  38| 4D| | 53| 54| 55|   |
    |---------------------------------------------------------' |-----------| 4C|
    |   3A|     37|            31             | 2A| 46| 42| 48| |     52| 41|   |
    `---------------------------------------------------------' `---------------'


References
----------
Technical Info for 128K/512K and Plus
    ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20128K.pdf
    ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20Plus.pdf
Protocol:
    Page 20 of Tech Info for 128K/512K
    http://www.mac.linux-m68k.org/devel/plushw.php
Connector:
    Page 20 of Tech Info for 128K/512K
    http://www.kbdbabel.org/conn/kbd_connector_macplus.png
Signaling:
    http://www.kbdbabel.org/signaling/kbd_signaling_mac.png
    http://typematic.blog.shinobi.jp/Entry/14/
Scan Codes:
    Page 22 of Tech Info for 128K/512K
    Page 07 of Tech Info for Plus
    http://m0115.web.fc2.com/m0110.jpg
    http://m0115.web.fc2.com/m0110a.jpg
*/


#define WAIT_US(stat, us, err) do { \
    if (!wait_##stat(us)) { \
        m0110_error = err; \


@@ 307,7 167,7 @@ uint8_t m0110_recv_key(void)
    switch (key & 0x7F) {
        case M0110_KEYPAD:
            // Pad/Arrow keys
            return (M0110_RAW2SCAN(instant()) | M0110_KEYPAD_OFFSET);
            return (raw2scan(instant()) | M0110_KEYPAD_OFFSET);
            break;
        case M0110_SHIFT:
            key2 = instant();


@@ 319,26 179,34 @@ uint8_t m0110_recv_key(void)
                    case M0110_ARROW_LEFT:
                    case M0110_ARROW_RIGHT:
                        // Calc keys
                        return (M0110_RAW2SCAN(key3) | M0110_CALC_OFFSET);
                        return (raw2scan(key3) | M0110_CALC_OFFSET);
                    default:
                        // Shift + Pad/Arrow keys
                        keybuf = M0110_RAW2SCAN(key3);
                        return (M0110_RAW2SCAN(key) | M0110_KEYPAD_OFFSET);
                        keybuf = raw2scan(key3);
                        return (raw2scan(key) | M0110_KEYPAD_OFFSET);
                }
            } else {
                // Shift + other keys
                keybuf = M0110_RAW2SCAN(key2);
                return M0110_RAW2SCAN(key);
                keybuf = raw2scan(key2);
                return raw2scan(key);
            }
            break;
        default:
            // other keys
            return M0110_RAW2SCAN(key);
            return raw2scan(key);
            break;
    }
}


static inline uint8_t raw2scan(uint8_t raw) {
    return (raw == M0110_NULL) ?  M0110_NULL : (
                (raw == M0110_ERROR) ?  M0110_ERROR : (
                    ((raw&0x80) | ((raw&0x7F)>>1))
                )
           );
}

static inline uint8_t inquiry(void)
{
    m0110_send(M0110_INQUIRY);


@@ 348,7 216,12 @@ static inline uint8_t inquiry(void)
static inline uint8_t instant(void)
{
    m0110_send(M0110_INSTANT);
    return m0110_recv();
    //return m0110_recv();
    uint8_t data = m0110_recv();
    if (data != 0x7B) {
        print("data: "); phex(data); print("\n");
    }
    return data;
}

static inline void clock_lo()


@@ 420,3 293,145 @@ static inline void request(void)
    clock_hi();
    data_lo();
}



/*
Primitive M0110 Library for AVR
==============================


Signaling
---------
CLOCK is always from KEYBOARD. DATA are sent with MSB first.

1) IDLE: both lines are high.
    CLOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    DATA  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2) KEYBOARD->HOST: HOST reads bit on rising edge.
    CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~
    DATA  ~~~~~~~~~~~~X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~
                      <--> 160us(clock low)
                         <---> 180us(clock high)

3) HOST->KEYBOARD: HOST asserts bit on falling edge.
    CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~
    DATA  ~~~~~~|_____X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~
                <----> 840us(request to send by host)                     <---> 80us(hold DATA)
                      <--> 180us(clock low)
                         <---> 220us(clock high)


Protocol
--------
COMMAND:
    Inquiry     0x10    get key event
    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?)
                        bit4-6  next device model number
                        bit1-3  keyboard model number
                        bit 0   always 1
    Test        0x16    test(ACK:0x7D/NAK:0x77)

KEY EVENT:
    bit 7       key state(0:press 1:release)
    bit 6-1     scan code(see below)
    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".

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.

    Raw key events:
            press               release
            ----------------    ----------------
    Left:         0x79, 0x0D          0x79, 0x8D
    Right:        0x79, 0x05          0x79, 0x85
    Up:           0x79, 0x1B          0x79, 0x9B
    Down:         0x79, 0x11          0x79, 0x91
    Pad+:   0x71, 0x79, 0x0D    0xF1, 0x79, 0x8D
    Pad*:   0x71, 0x79, 0x05    0xF1, 0x79, 0x85
    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. 

    M0110
    ,---------------------------------------------------------.
    |  `|  1|  2|  3|  4|  5|  6|  7|  8|  9|  0|  -|  =|Backs|
    |---------------------------------------------------------|
    |Tab  |  Q|  W|  E|  R|  T|  Y|  U|  I|  O|  P|  [|  ]|  \|
    |---------------------------------------------------------|
    |CapsLo|  A|  S|  D|  F|  G|  H|  J|  K|  L|  ;|  '|Return|
    |---------------------------------------------------------|
    |Shift   |  Z|  X|  C|  V|  B|  N|  M|  ,|  ,|  /|        |
    `---------------------------------------------------------'
         |Opt|Mac |         Space               |Enter|Opt|
         `------------------------------------------------'
    ,---------------------------------------------------------.
    | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18|   33|
    |---------------------------------------------------------|
    |   30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A|
    |---------------------------------------------------------|
    |    39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27|    24|
    |---------------------------------------------------------|
    |      38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C|      38|
    `---------------------------------------------------------'
         | 3A|  37|             31              |   34| 3A|
         `------------------------------------------------'

    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|  .|   |
    `---------------------------------------------------------' `---------------'
    ,---------------------------------------------------------. ,---------------.
    | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18|   33| | 47| 68| 6D| 62|
    |---------------------------------------------------------| |---------------|
    |   30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E|   | | 59| 5B| 5C| 4E|
    |-----------------------------------------------------'   | |---------------|
    |    39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27|    24| | 56| 57| 58| 66|
    |---------------------------------------------------------| |---------------|
    |      38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C|  38| 4D| | 53| 54| 55|   |
    |---------------------------------------------------------' |-----------| 4C|
    |   3A|     37|            31             | 2A| 46| 42| 48| |     52| 41|   |
    `---------------------------------------------------------' `---------------'


References
----------
Technical Info for 128K/512K and Plus
    ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20128K.pdf
    ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20Plus.pdf
Protocol:
    Page 20 of Tech Info for 128K/512K
    http://www.mac.linux-m68k.org/devel/plushw.php
Connector:
    Page 20 of Tech Info for 128K/512K
    http://www.kbdbabel.org/conn/kbd_connector_macplus.png
Signaling:
    http://www.kbdbabel.org/signaling/kbd_signaling_mac.png
    http://typematic.blog.shinobi.jp/Entry/14/
Scan Codes:
    Page 22 of Tech Info for 128K/512K
    Page 07 of Tech Info for Plus
    http://m0115.web.fc2.com/m0110.jpg
    http://m0115.web.fc2.com/m0110a.jpg
*/

M m0110.h => m0110.h +0 -9
@@ 78,15 78,6 @@ POSSIBILITY OF SUCH DAMAGE.
#define M0110_KEYPAD_OFFSET 0x40
#define M0110_CALC_OFFSET   0x60

/* convert key event raw response into scan code */
#define M0110_RAW2SCAN(key) ( \
    (key == M0110_NULL) ?  M0110_NULL : ( \
        (key == M0110_ERROR) ?  M0110_ERROR : ( \
            ((key&0x80) | ((key&0x7F)>>1)) \
        ) \
    ) \
)


extern uint8_t m0110_error;


M m0110_usb/doc/m0110.jpg => m0110_usb/doc/m0110.jpg +0 -0
M m0110_usb/doc/teensy.jpg => m0110_usb/doc/teensy.jpg +0 -0
M m0110_usb/keymap.c => m0110_usb/keymap.c +35 -31
@@ 58,7 58,7 @@ static const uint8_t PROGMEM fn_layer[] = {
    1,              // Fn0
    2,              // Fn1
    3,              // Fn2
    0,              // Fn3
    1,              // Fn3
    0,              // Fn4
    0,              // Fn5
    0,              // Fn6


@@ 68,15 68,17 @@ static const uint8_t PROGMEM fn_layer[] = {
// Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer.
// See layer.c for details.
static const uint8_t PROGMEM fn_keycode[] = {
#ifndef HASU
    KB_ESC,         // Fn0
#ifdef HASU
    KB_SCOLON,      // Fn1
    KB_SLASH,       // Fn2
#else
    KB_NO,          // Fn1
    KB_NO,          // Fn2
#endif
    KB_NO,          // Fn3
#else
    KB_NO,          // Fn0
    KB_SCOLON,      // Fn1
    KB_SLASH,       // Fn2
    KB_UP,          // Fn3
#endif
    KB_NO,          // Fn4
    KB_NO,          // Fn5
    KB_NO,          // Fn6


@@ 107,7 109,6 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
     * |---------------------------------------------------------| |-----------|Ent|
     * |Ctrl |Alt    |         Space         |Gui|  \|Lft|Rgt|Dn | |      0|  .|   |
     * `---------------------------------------------------------' `---------------'
     * You can register Esc by hitting(press&release) Fn0 quickly.
     *
     * HHKB/WASD cursor Layer(Fn0):
     * ,---------------------------------------------------------. ,---------------.


@@ 122,25 123,44 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
     * |Ctrl |Alt    |         Space        |Gui |  \|Lft|Rgt|Dn | |      0|  .|   |
     * `---------------------------------------------------------' `---------------'
     *
     * NOTE: Key between Space and \ in above diagram is M0110 Enter(assigned to Gui).
     * NOTE: You can register Esc by hitting(press&release) Fn0 quickly.
     * NOTE: Gui between Space and \ is Enter on M0110 not exists on M0110A.
     * NOTE: LShift and RShift are logically same key. (M0110, M0110A)
     * NOTE: LOption and ROption are logically same key. (M0110)
     */
#ifdef HASU
#ifndef HASU
    KEYMAP(
    GRV, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC,    LGUI,PEQL,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,
    LCTL,LALT,               SPC,                LGUI,BSLS,LEFT,RGHT,DOWN,    P0,       PDOT
    ),
    // 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
    ),
#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,
    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,           UP,      P1,  P2,  P3,  PENT,
    FN0, LALT,               SPC,                LGUI,BSLS,LEFT,DOWN,RGHT,    P0,       PDOT
    LSFT,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, FN2,           FN3,     P1,  P2,  P3,  PENT,
    LCTL,LALT,               SPC,                LGUI,BSLS,LEFT,RGHT,DOWN,    P0,       PDOT
    ),
    // HHKB & WASD
    KEYMAP(
    GRV, 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,
    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,          UP,      P1,  P2,  P3,  PENT,
    FN0, LALT,               SPC,                LGUI,BSLS,LEFT,DOWN,RGHT,    P0,       PDOT
    LSFT,END, NO,  PGDN,NO,  VOLD,VOLU,MUTE,END, PGDN,DOWN,          FN3,     P1,  P2,  P3,  PENT,
    LCTL,LALT,               SPC,                LGUI,BSLS,LEFT,RGHT,DOWN,    P0,       PDOT
    ),
    // vi mousekeys
    KEYMAP(


@@ 148,7 168,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    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,
    LCTL,LALT,               BTN1,               LGUI,BSLS,LEFT,DOWN,RGHT,    P0,       PDOT
    LCTL,LALT,               BTN1,               LGUI,BSLS,LEFT,RGHT,DOWN,    P0,       PDOT
    ),
    // vi cusorkeys
    KEYMAP(


@@ 156,23 176,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    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,
    LCTL,LALT,               SPC,                LGUI,BSLS,LEFT,DOWN,RGHT,    P0,       PDOT
    ),
#else
    KEYMAP(
    GRV, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, BSPC,    LGUI,PEQL,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,
    LCTL,LALT,               SPC,                LGUI,BSLS,LEFT,DOWN,RGHT,    P0,       PDOT
    ),
    // 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,DOWN,RGHT,    P0,       PDOT
    LCTL,LALT,               SPC,                LGUI,BSLS,LEFT,RGHT,DOWN,    P0,       PDOT
    ),
#endif
};

M m0110_usb/matrix.c => m0110_usb/matrix.c +23 -5
@@ 32,10 32,15 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.


#define CAPS        0x39
#define CAPS_UP     (CAPS | 0x80)
#define CAPS_BREAK  (CAPS | 0x80)
#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;



@@ 88,14 93,27 @@ uint8_t matrix_scan(void)
    // Send Caps key up event
    if (matrix_is_on(ROW(CAPS), COL(CAPS))) {
        is_modified = true;
        register_key(CAPS_UP);
        register_key(CAPS_BREAK);
    }
#endif
    if (key == M0110_NULL) {
        return 0;
    } else if (key == M0110_ERROR) {
        // TODO: error recovery or reinit
        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)) {


@@ 103,11 121,11 @@ uint8_t matrix_scan(void)
            // Ignore LockingCaps key down event
            if (key == CAPS) return 0;
            // Convert LockingCaps key up event into down event
            if (key == CAPS_UP) key = CAPS;
            if (key == CAPS_BREAK) key = CAPS;
        } else {
            // CAPS LOCK off:
            // Ignore LockingCaps key up event
            if (key == CAPS_UP) return 0;
            if (key == CAPS_BREAK) return 0;
        }
#endif        
        is_modified = true;

M rules.mk => rules.mk +1 -1
@@ 317,7 317,7 @@ GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d

# Combine all necessary flags and optional flags.
# Add target processor to flags.
# You can give EXTRAFLAGS at 'make' command line.
# You can give extra flags at 'make' command line like: make EXTRAFLAGS=-DFOO=bar
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS)
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) $(EXTRAFLAGS)