diff options
| author | tmk <nobody@nowhere> | 2012-04-28 01:57:36 +0900 |
|---|---|---|
| committer | tmk <nobody@nowhere> | 2012-04-28 01:57:36 +0900 |
| commit | 12f6e9ffa76f685f7256bf1421f918f90c93add1 (patch) | |
| tree | a4f81dff6ea8450a4f482e06a957056e74d93734 | |
| parent | 0a4fa89548e8c098c65c289865ebbf1e1c29adf4 (diff) | |
| download | qmk_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.c | 79 | ||||
| -rw-r--r-- | m0110.h | 42 | ||||
| -rw-r--r-- | m0110_usb/README | 55 | ||||
| -rw-r--r-- | m0110_usb/README.md | 141 | ||||
| -rw-r--r-- | m0110_usb/config.h | 5 | ||||
| -rw-r--r-- | m0110_usb/keymap.c | 148 | ||||
| -rw-r--r-- | m0110_usb/matrix.c | 3 | ||||
| -rw-r--r-- | rules.mk | 9 |
8 files changed, 354 insertions, 128 deletions
| @@ -34,6 +34,7 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||
| 34 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 34 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 35 | POSSIBILITY OF SUCH DAMAGE. | 35 | POSSIBILITY 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 | ||
| 47 | static inline uint8_t inquiry(void); | ||
| 48 | static inline uint8_t instant(void); | ||
| 46 | static inline void clock_lo(void); | 49 | static inline void clock_lo(void); |
| 47 | static inline void clock_hi(void); | 50 | static inline void clock_hi(void); |
| 48 | static inline bool clock_in(void); | 51 | static 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 | ||
| 112 | ARROW 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 | |||
| 109 | SCAN CODE: | 129 | SCAN 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 | ||
| 276 | uint8_t m0110_recv_key(void) | 296 | uint8_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 | |||
| 343 | static 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 | ||
| 349 | static inline uint8_t instant(void) | ||
| 350 | { | ||
| 351 | m0110_send(M0110_INSTANT); | ||
| 352 | return m0110_recv(); | ||
| 353 | } | ||
| 287 | 354 | ||
| 288 | static inline void clock_lo() | 355 | static inline void clock_lo() |
| 289 | { | 356 | { |
| @@ -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 | ||
| 76 | extern uint8_t m0110_error; | 92 | extern uint8_t m0110_error; |
| @@ -80,5 +96,7 @@ void m0110_init(void); | |||
| 80 | uint8_t m0110_send(uint8_t data); | 96 | uint8_t m0110_send(uint8_t data); |
| 81 | uint8_t m0110_recv(void); | 97 | uint8_t m0110_recv(void); |
| 82 | uint8_t m0110_recv_key(void); | 98 | uint8_t m0110_recv_key(void); |
| 99 | uint8_t m0110_inquiry(void); | ||
| 100 | uint8_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 @@ | |||
| 1 | M0110 to USB keyboard converter | ||
| 2 | =============================== | ||
| 3 | This firmware converts the protocol of Apple Macintosh keyboard M0110 into USB. | ||
| 4 | |||
| 5 | |||
| 6 | Connection | ||
| 7 | ---------- | ||
| 8 | You need 4P4C plug and cable to connect Teensy into M0110. | ||
| 9 | Teensy port F0 is assigned for CLOCK line and F1 for DATA by default, you can change pin configuration with editing config.h.. | ||
| 10 | |||
| 11 | Plug: | ||
| 12 | http://en.wikipedia.org/wiki/Modular_connector#4P4C | ||
| 13 | |||
| 14 | Pinout: | ||
| 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 | |||
| 23 | Build Frimware | ||
| 24 | -------------- | ||
| 25 | Optionally edit Makefile and config.h for build options, pin configuration or MCU. | ||
| 26 | |||
| 27 | $ cd m0110_usb | ||
| 28 | $ make | ||
| 29 | and program your Teensy with loader. | ||
| 30 | |||
| 31 | |||
| 32 | |||
| 33 | Keymap | ||
| 34 | ------ | ||
| 35 | You can change a keymap by editing code of keymap.c like following. | ||
| 36 | How to define the keymap is probably obvious. You can find key symbols in usb_keycodes.h. | ||
| 37 | |||
| 38 | This 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 | |||
| 52 | Notes | ||
| 53 | ----- | ||
| 54 | |||
| 55 | EOF | ||
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 @@ | |||
| 1 | M0110/M0110A to USB keyboard converter | ||
| 2 | ====================================== | ||
| 3 | This firmware converts the protocol of Apple Macintosh keyboard M0110/M0110A into USB. | ||
| 4 | Target board of this project is [PJRC Teensy](http://www.pjrc.com/teensy/), though, | ||
| 5 | you can use other board with USB AVR like `ATmega32U4` and `AT90USB`. | ||
| 6 | |||
| 7 |  | ||
| 8 | |||
| 9 | M0110A support was contributed by [skagon@github](https://github.com/skagon). | ||
| 10 | |||
| 11 | |||
| 12 | |||
| 13 | Connection | ||
| 14 | ---------- | ||
| 15 | You need 4P4C plug and cable to connect Teensy or other AVR dev board into the keyboard. | ||
| 16 | Teensy port `PF0` is assigned for `CLOCK` line and `PF1` for `DATA` by default, | ||
| 17 | you can change pin configuration with editing *config.h*. | ||
| 18 | |||
| 19 | You can find 4P4C plugs on telephone handset cable. Note that it is *crossover* connection | ||
| 20 | while Macintosh keyboard cable is *straight*. | ||
| 21 | |||
| 22 | [](http://i.imgur.com/vJoVO.jpg) | ||
| 23 | |||
| 24 | In this pic: | ||
| 25 | |||
| 26 | 1. `GND`(Black) | ||
| 27 | 2. `CLOCK`(Red) | ||
| 28 | 3. `DATA`(Green) | ||
| 29 | 4. `+5V`(Yellow) | ||
| 30 | |||
| 31 | Not 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 |  | ||
| 39 | |||
| 40 | |||
| 41 | ### Pull-up Registor | ||
| 42 | You may need pull-up registors on signal lines(`CLOCK`, `DATA`) in particular | ||
| 43 | when you have long or coiled cable. 1k-10k Ohm will be OK for this purpose. | ||
| 44 | In some cases MCU can't read signal from keyboard correctly without pull-up resistors. | ||
| 45 | |||
| 46 | |||
| 47 | |||
| 48 | Building Frimware | ||
| 49 | ----------------- | ||
| 50 | To compile firmware you need AVR GCC. You can use [WinAVR](http://winavr.sourceforge.net/) on Windows. | ||
| 51 | You 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 | |||
| 57 | and program your Teensy with [PJRC Teensy loader](http://www.pjrc.com/teensy/loader.html). | ||
| 58 | |||
| 59 | |||
| 60 | |||
| 61 | Keymap | ||
| 62 | ------ | ||
| 63 | You 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 | |||
| 121 | Debug | ||
| 122 | ----- | ||
| 123 | You can use [PJRC HID listen](http://www.pjrc.com/teensy/hid_listen.html) to see debug output. | ||
| 124 | |||
| 125 | The converter has some functions for debug, press `Alt+Gui+H` simultaneously to get help. | ||
| 126 | These function is totally undocumented, tentative, inconsistent and buggy. | ||
| 127 | |||
| 128 | |||
| 129 | |||
| 130 | Arrow Keys | ||
| 131 | ---------- | ||
| 132 | Dedicated arrow keys of the M0110A are transmitting the same scancodes as the keypad but also, | ||
| 133 | its [=], [/], [*] and [+] keys (hereafter referred to as "calc" keys) are not assigned new | ||
| 134 | scancodes but, instead, transmit a sequence of scancodes which emulates the [Shift] key press, | ||
| 135 | followed by the same scancode sequence of the arrow keys! | ||
| 136 | The problem with that approach is that, while in most cases it's easy to distinguish between | ||
| 137 | a user-generated [Shift] key event (press or release) followed by an arrow or a calc key and | ||
| 138 | a simulated [Shift] key event generated upon a calc key event, when the user is typing fairly | ||
| 139 | fast, 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 | ||
| 141 | format 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. | |||
| 14 | You should have received a copy of the GNU General Public License | 14 | You should have received a copy of the GNU General Public License |
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 15 | along 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. |
| 70 | static const uint8_t PROGMEM fn_keycode[] = { | 70 | static 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 | ||
| 81 | static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | 86 | static 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)) { |
| @@ -230,6 +230,8 @@ LDFLAGS += $(EXTMEMOPTS) | |||
| 230 | LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) | 230 | LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) |
| 231 | LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) | 231 | LDFLAGS += $(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. | ||
| 234 | LDFLAGS += $(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. |
| 318 | ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) | 320 | # You can give EXTRAFLAGS at 'make' command line. |
| 319 | ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS) | 321 | ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS) |
| 320 | ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) | 322 | ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS) |
| 323 | ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) $(EXTRAFLAGS) | ||
| 321 | 324 | ||
| 322 | 325 | ||
| 323 | 326 | ||
