diff options
| -rw-r--r-- | m0110.c | 488 | ||||
| -rw-r--r-- | m0110.h | 38 | ||||
| -rw-r--r-- | m0110_usb/README | 55 | ||||
| -rw-r--r-- | m0110_usb/README.md | 126 | ||||
| -rw-r--r-- | m0110_usb/config.h | 7 | ||||
| -rw-r--r--[-rwxr-xr-x] | m0110_usb/doc/m0110.jpg | bin | 49360 -> 49360 bytes | |||
| -rw-r--r--[-rwxr-xr-x] | m0110_usb/doc/teensy.jpg | bin | 50081 -> 50081 bytes | |||
| -rw-r--r-- | m0110_usb/keymap.c | 161 | ||||
| -rw-r--r-- | m0110_usb/matrix.c | 40 | ||||
| -rw-r--r-- | rules.mk | 9 |
10 files changed, 627 insertions, 297 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | Copyright 2011 Jun WAKO <wakojun@gmail.com> | 2 | Copyright 2011,2012 Jun WAKO <wakojun@gmail.com> |
| 3 | 3 | ||
| 4 | This software is licensed with a Modified BSD License. | 4 | This software is licensed with a Modified BSD License. |
| 5 | All of this is supposed to be Free Software, Open Source, DFSG-free, | 5 | All of this is supposed to be Free Software, Open Source, DFSG-free, |
| @@ -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,9 @@ POSSIBILITY OF SUCH DAMAGE. | |||
| 43 | #include "debug.h" | 44 | #include "debug.h" |
| 44 | 45 | ||
| 45 | 46 | ||
| 47 | static inline uint8_t raw2scan(uint8_t raw); | ||
| 48 | static inline uint8_t inquiry(void); | ||
| 49 | static inline uint8_t instant(void); | ||
| 46 | static inline void clock_lo(void); | 50 | static inline void clock_lo(void); |
| 47 | static inline void clock_hi(void); | 51 | static inline void clock_hi(void); |
| 48 | static inline bool clock_in(void); | 52 | static inline bool clock_in(void); |
| @@ -57,130 +61,6 @@ static inline void idle(void); | |||
| 57 | static inline void request(void); | 61 | static inline void request(void); |
| 58 | 62 | ||
| 59 | 63 | ||
| 60 | /* | ||
| 61 | Primitive M0110 Library for AVR | ||
| 62 | ============================== | ||
| 63 | |||
| 64 | |||
| 65 | Signaling | ||
| 66 | --------- | ||
| 67 | CLOCK is always from KEYBOARD. DATA are sent with MSB first. | ||
| 68 | |||
| 69 | 1) IDLE: both lines are high. | ||
| 70 | CLOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 71 | DATA ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 72 | |||
| 73 | 2) KEYBOARD->HOST: HOST reads bit on rising edge. | ||
| 74 | CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ | ||
| 75 | DATA ~~~~~~~~~~~~X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ | ||
| 76 | <--> 160us(clock low) | ||
| 77 | <---> 180us(clock high) | ||
| 78 | |||
| 79 | 3) HOST->KEYBOARD: HOST asserts bit on falling edge. | ||
| 80 | CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ | ||
| 81 | DATA ~~~~~~|_____X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ | ||
| 82 | <----> 840us(request to send by host) <---> 80us(hold DATA) | ||
| 83 | <--> 180us(clock low) | ||
| 84 | <---> 220us(clock high) | ||
| 85 | |||
| 86 | |||
| 87 | Protocol | ||
| 88 | -------- | ||
| 89 | COMMAND: | ||
| 90 | Inquiry 0x10 get key event | ||
| 91 | Instant 0x12 get key event | ||
| 92 | Model 0x14 get model number(M0110 responds with 0x09) | ||
| 93 | bit 7 1 if another device connected(used when keypad exists?) | ||
| 94 | bit4-6 next device model number | ||
| 95 | bit1-3 keyboard model number | ||
| 96 | bit 0 always 1 | ||
| 97 | Test 0x16 test(ACK:0x7D/NAK:0x77) | ||
| 98 | |||
| 99 | KEY EVENT: | ||
| 100 | bit 7 key state(0:press 1:release) | ||
| 101 | bit 6-1 scan code(see below) | ||
| 102 | bit 0 always 1 | ||
| 103 | To get scan code use this: ((bits&(1<<7)) | ((bits&0x7F))>>1). | ||
| 104 | |||
| 105 | Note: On the M0110A, the numpad keys and the arrow keys are preceded by 0x79. | ||
| 106 | 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". | ||
| 108 | |||
| 109 | SCAN CODE: | ||
| 110 | 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. | ||
| 112 | |||
| 113 | M0110 | ||
| 114 | ,---------------------------------------------------------. | ||
| 115 | | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| | ||
| 116 | |---------------------------------------------------------| | ||
| 117 | |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | ||
| 118 | |---------------------------------------------------------| | ||
| 119 | |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | ||
| 120 | |---------------------------------------------------------| | ||
| 121 | |Shift | Z| X| C| V| B| N| M| ,| ,| /| | | ||
| 122 | `---------------------------------------------------------' | ||
| 123 | |Opt|Mac | Space |Enter|Opt| | ||
| 124 | `------------------------------------------------' | ||
| 125 | ,---------------------------------------------------------. | ||
| 126 | | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | ||
| 127 | |---------------------------------------------------------| | ||
| 128 | | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A| | ||
| 129 | |---------------------------------------------------------| | ||
| 130 | | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | ||
| 131 | |---------------------------------------------------------| | ||
| 132 | | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| | ||
| 133 | `---------------------------------------------------------' | ||
| 134 | | 3A| 37| 31 | 34| 3A| | ||
| 135 | `------------------------------------------------' | ||
| 136 | |||
| 137 | M0110A | ||
| 138 | ,---------------------------------------------------------. ,---------------. | ||
| 139 | | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Bcksp| |Clr| =| /| *| | ||
| 140 | |---------------------------------------------------------| |---------------| | ||
| 141 | |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| | ||
| 142 | |-----------------------------------------------------' | |---------------| | ||
| 143 | |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| | ||
| 144 | |---------------------------------------------------------| |---------------| | ||
| 145 | |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| | | ||
| 146 | |---------------------------------------------------------' |-----------|Ent| | ||
| 147 | |Optio|Mac | Space | \|Lft|Rgt|Dn | | 0| .| | | ||
| 148 | `---------------------------------------------------------' `---------------' | ||
| 149 | ,---------------------------------------------------------. ,---------------. | ||
| 150 | | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | 47| 68| 6D| 62| | ||
| 151 | |---------------------------------------------------------| |---------------| | ||
| 152 | | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| | | 59| 5B| 5C| 4E| | ||
| 153 | |-----------------------------------------------------' | |---------------| | ||
| 154 | | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | 56| 57| 58| 66| | ||
| 155 | |---------------------------------------------------------| |---------------| | ||
| 156 | | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| 4D| | 53| 54| 55| | | ||
| 157 | |---------------------------------------------------------' |-----------| 4C| | ||
| 158 | | 3A| 37| 31 | 2A| 46| 42| 48| | 52| 41| | | ||
| 159 | `---------------------------------------------------------' `---------------' | ||
| 160 | |||
| 161 | |||
| 162 | References | ||
| 163 | ---------- | ||
| 164 | Technical Info for 128K/512K and Plus | ||
| 165 | ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20128K.pdf | ||
| 166 | ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20Plus.pdf | ||
| 167 | Protocol: | ||
| 168 | Page 20 of Tech Info for 128K/512K | ||
| 169 | http://www.mac.linux-m68k.org/devel/plushw.php | ||
| 170 | Connector: | ||
| 171 | Page 20 of Tech Info for 128K/512K | ||
| 172 | http://www.kbdbabel.org/conn/kbd_connector_macplus.png | ||
| 173 | Signaling: | ||
| 174 | http://www.kbdbabel.org/signaling/kbd_signaling_mac.png | ||
| 175 | http://typematic.blog.shinobi.jp/Entry/14/ | ||
| 176 | Scan Codes: | ||
| 177 | Page 22 of Tech Info for 128K/512K | ||
| 178 | Page 07 of Tech Info for Plus | ||
| 179 | http://m0115.web.fc2.com/m0110.jpg | ||
| 180 | http://m0115.web.fc2.com/m0110a.jpg | ||
| 181 | */ | ||
| 182 | |||
| 183 | |||
| 184 | #define WAIT_US(stat, us, err) do { \ | 64 | #define WAIT_US(stat, us, err) do { \ |
| 185 | if (!wait_##stat(us)) { \ | 65 | if (!wait_##stat(us)) { \ |
| 186 | m0110_error = err; \ | 66 | m0110_error = err; \ |
| @@ -202,6 +82,9 @@ Scan Codes: | |||
| 202 | } \ | 82 | } \ |
| 203 | } while (0) | 83 | } while (0) |
| 204 | 84 | ||
| 85 | #define KEY(raw) ((raw) & 0x7f) | ||
| 86 | #define IS_BREAK(raw) (((raw) & 0x80) == 0x80) | ||
| 87 | |||
| 205 | 88 | ||
| 206 | uint8_t m0110_error = 0; | 89 | uint8_t m0110_error = 0; |
| 207 | 90 | ||
| @@ -212,10 +95,6 @@ void m0110_init(void) | |||
| 212 | idle(); | 95 | idle(); |
| 213 | _delay_ms(1000); | 96 | _delay_ms(1000); |
| 214 | 97 | ||
| 215 | // Model Number | ||
| 216 | // M0110 : 0x09 00001001 : model number 4 (100) | ||
| 217 | // M0110A: 0x0B 00001011 : model number 5 (101) | ||
| 218 | // M0110 & M0120: ??? | ||
| 219 | m0110_send(M0110_MODEL); | 98 | m0110_send(M0110_MODEL); |
| 220 | data = m0110_recv(); | 99 | data = m0110_recv(); |
| 221 | print("m0110_init model: "); phex(data); print("\n"); | 100 | print("m0110_init model: "); phex(data); print("\n"); |
| @@ -273,17 +152,179 @@ ERROR: | |||
| 273 | return 0xFF; | 152 | return 0xFF; |
| 274 | } | 153 | } |
| 275 | 154 | ||
| 155 | /* | ||
| 156 | Handling for exceptional case of key combinations for M0110A | ||
| 157 | |||
| 158 | Shift and Calc/Arrow key could be operated simultaneously: | ||
| 159 | |||
| 160 | Case Shift Arrow Events Interpret | ||
| 161 | ------------------------------------------------------------------- | ||
| 162 | 1 Down Down 71, 79, DD Calc(d)*a *b | ||
| 163 | 2 Down Up 71, 79, UU Arrow&Calc(u)*a | ||
| 164 | 3 Up Down F1, 79, DD Shift(u) *c | ||
| 165 | 4 Up Up F1, 79, UU Shift(u) and Arrow&Calc(u)*a | ||
| 166 | |||
| 167 | Case Shift Calc Events Interpret | ||
| 168 | ------------------------------------------------------------------- | ||
| 169 | 5(1) Down Down 71, 71, 79, DD Shift(d) and Cacl(d) | ||
| 170 | 6(2) Down Up F1, 71, 79, UU Shift(u) and Arrow&Calc(u)*a | ||
| 171 | 7(1) Up Down F1, 71, 79, DD Shift(u) and Calc(d) | ||
| 172 | 8(4) Up Up F1, F1, 79, UU Shift(ux2) and Arrow&Calc(u)*a | ||
| 173 | |||
| 174 | During Calc key is hold: | ||
| 175 | Case Shift Arrow Events Interpret | ||
| 176 | ------------------------------------------------------------------- | ||
| 177 | A(3) ---- Down F1, 79, DD Shift(u) *c | ||
| 178 | B ---- Up 79, UU Arrow&Calc(u)*a | ||
| 179 | C Down ---- F1, 71 Shift(u) and Shift(d) | ||
| 180 | D Up ---- F1 Shift(u) | ||
| 181 | E Hold Down 79, DD Normal | ||
| 182 | F Hold Up 79, UU Arrow&Calc(u)*a | ||
| 183 | G(1) Down Down F1, 71, 79, DD Shift(u)*b and Calc(d)*a | ||
| 184 | H(2) Down Up F1, 71, 79, UU Shift(u) and Arrow&Calc(u)*a | ||
| 185 | I(3) Up Down F1, F1, 79, DD Shift(ux2) *c | ||
| 186 | J(4) Up Up F1, 79, UU Shift(u) and Arrow&Calc(u)*a | ||
| 187 | |||
| 188 | Case Shift Calc Events Interpret | ||
| 189 | ------------------------------------------------------------------- | ||
| 190 | K(1) ---- Down 71, 79, DD Calc(d)*a | ||
| 191 | L(4) ---- Up F1, 79, UU Shift(u) and Arrow&Calc(u)*a | ||
| 192 | M(1) Hold Down 71, 79, DD Calc(d)*a | ||
| 193 | N Hold Up 79, UU Arrow&Calc(u)*a | ||
| 194 | |||
| 195 | Where DD/UU indicates part of Keypad Down/Up event. | ||
| 196 | *a: Impossible to distinguish btween Arrow and Calc event. | ||
| 197 | *b: Shift(d) event is ignored. | ||
| 198 | *c: Arrow/Calc(d) event is ignored. | ||
| 199 | */ | ||
| 276 | uint8_t m0110_recv_key(void) | 200 | uint8_t m0110_recv_key(void) |
| 277 | { | 201 | { |
| 278 | uint8_t key; | 202 | static uint8_t keybuf = 0x00; |
| 203 | static uint8_t keybuf2 = 0x00; | ||
| 204 | static uint8_t rawbuf = 0x00; | ||
| 205 | uint8_t raw, raw2, raw3; | ||
| 206 | |||
| 207 | if (keybuf) { | ||
| 208 | raw = keybuf; | ||
| 209 | keybuf = 0x00; | ||
| 210 | return raw; | ||
| 211 | } | ||
| 212 | if (keybuf2) { | ||
| 213 | raw = keybuf2; | ||
| 214 | keybuf2 = 0x00; | ||
| 215 | return raw; | ||
| 216 | } | ||
| 217 | |||
| 218 | if (rawbuf) { | ||
| 219 | raw = rawbuf; | ||
| 220 | rawbuf = 0x00; | ||
| 221 | } else { | ||
| 222 | raw = instant(); // Use INSTANT for better response. Should be INQUIRY ? | ||
| 223 | } | ||
| 224 | switch (KEY(raw)) { | ||
| 225 | case M0110_KEYPAD: | ||
| 226 | raw2 = instant(); | ||
| 227 | switch (KEY(raw2)) { | ||
| 228 | case M0110_ARROW_UP: | ||
| 229 | case M0110_ARROW_DOWN: | ||
| 230 | case M0110_ARROW_LEFT: | ||
| 231 | case M0110_ARROW_RIGHT: | ||
| 232 | if (IS_BREAK(raw2)) { | ||
| 233 | // Case B,F,N: | ||
| 234 | keybuf = (raw2scan(raw2) | M0110_CALC_OFFSET); // Calc(u) | ||
| 235 | return (raw2scan(raw2) | M0110_KEYPAD_OFFSET); // Arrow(u) | ||
| 236 | } | ||
| 237 | break; | ||
| 238 | } | ||
| 239 | // Keypad or Arrow | ||
| 240 | return (raw2scan(raw2) | M0110_KEYPAD_OFFSET); | ||
| 241 | break; | ||
| 242 | case M0110_SHIFT: | ||
| 243 | raw2 = instant(); | ||
| 244 | switch (KEY(raw2)) { | ||
| 245 | case M0110_SHIFT: | ||
| 246 | // Case: 5-8,C,G,H | ||
| 247 | rawbuf = raw2; | ||
| 248 | return raw2scan(raw); // Shift(d/u) | ||
| 249 | break; | ||
| 250 | case M0110_KEYPAD: | ||
| 251 | // Shift + Arrow, Calc, or etc. | ||
| 252 | raw3 = instant(); | ||
| 253 | switch (KEY(raw3)) { | ||
| 254 | case M0110_ARROW_UP: | ||
| 255 | case M0110_ARROW_DOWN: | ||
| 256 | case M0110_ARROW_LEFT: | ||
| 257 | case M0110_ARROW_RIGHT: | ||
| 258 | if (IS_BREAK(raw)) { | ||
| 259 | if (IS_BREAK(raw3)) { | ||
| 260 | // Case 4: | ||
| 261 | print("(4)\n"); | ||
| 262 | keybuf2 = raw2scan(raw); // Shift(u) | ||
| 263 | keybuf = (raw2scan(raw3) | M0110_CALC_OFFSET); // Calc(u) | ||
| 264 | return (raw2scan(raw3) | M0110_KEYPAD_OFFSET); // Arrow(u) | ||
| 265 | } else { | ||
| 266 | // Case 3: | ||
| 267 | print("(3)\n"); | ||
| 268 | return (raw2scan(raw)); // Shift(u) | ||
| 269 | } | ||
| 270 | } else { | ||
| 271 | if (IS_BREAK(raw3)) { | ||
| 272 | // Case 2: | ||
| 273 | print("(2)\n"); | ||
| 274 | keybuf = (raw2scan(raw3) | M0110_CALC_OFFSET); // Calc(u) | ||
| 275 | return (raw2scan(raw3) | M0110_KEYPAD_OFFSET); // Arrow(u) | ||
| 276 | } else { | ||
| 277 | // Case 1: | ||
| 278 | print("(1)\n"); | ||
| 279 | return (raw2scan(raw3) | M0110_CALC_OFFSET); // Calc(d) | ||
| 280 | } | ||
| 281 | } | ||
| 282 | break; | ||
| 283 | default: | ||
| 284 | // Shift + Keypad | ||
| 285 | keybuf = (raw2scan(raw3) | M0110_KEYPAD_OFFSET); | ||
| 286 | return raw2scan(raw); // Shift(d/u) | ||
| 287 | break; | ||
| 288 | } | ||
| 289 | break; | ||
| 290 | default: | ||
| 291 | // Shift + Normal keys | ||
| 292 | keybuf = raw2scan(raw2); | ||
| 293 | return raw2scan(raw); // Shift(d/u) | ||
| 294 | break; | ||
| 295 | } | ||
| 296 | break; | ||
| 297 | default: | ||
| 298 | // Normal keys | ||
| 299 | return raw2scan(raw); | ||
| 300 | break; | ||
| 301 | } | ||
| 302 | } | ||
| 303 | |||
| 304 | |||
| 305 | static inline uint8_t raw2scan(uint8_t raw) { | ||
| 306 | return (raw == M0110_NULL) ? M0110_NULL : ( | ||
| 307 | (raw == M0110_ERROR) ? M0110_ERROR : ( | ||
| 308 | ((raw&0x80) | ((raw&0x7F)>>1)) | ||
| 309 | ) | ||
| 310 | ); | ||
| 311 | } | ||
| 312 | |||
| 313 | static inline uint8_t inquiry(void) | ||
| 314 | { | ||
| 279 | m0110_send(M0110_INQUIRY); | 315 | m0110_send(M0110_INQUIRY); |
| 280 | key = m0110_recv(); | 316 | return m0110_recv(); |
| 281 | if (key == 0xFF || key == M0110_NULL) | ||
| 282 | return M0110_NULL; | ||
| 283 | else | ||
| 284 | return M0110_RAW2SCAN(key); | ||
| 285 | } | 317 | } |
| 286 | 318 | ||
| 319 | static inline uint8_t instant(void) | ||
| 320 | { | ||
| 321 | m0110_send(M0110_INSTANT); | ||
| 322 | uint8_t data = m0110_recv(); | ||
| 323 | if (data != M0110_NULL) { | ||
| 324 | phex(data); print(" "); | ||
| 325 | } | ||
| 326 | return data; | ||
| 327 | } | ||
| 287 | 328 | ||
| 288 | static inline void clock_lo() | 329 | static inline void clock_lo() |
| 289 | { | 330 | { |
| @@ -354,3 +395,180 @@ static inline void request(void) | |||
| 354 | clock_hi(); | 395 | clock_hi(); |
| 355 | data_lo(); | 396 | data_lo(); |
| 356 | } | 397 | } |
| 398 | |||
| 399 | |||
| 400 | |||
| 401 | /* | ||
| 402 | Primitive M0110 Library for AVR | ||
| 403 | ============================== | ||
| 404 | |||
| 405 | |||
| 406 | Signaling | ||
| 407 | --------- | ||
| 408 | CLOCK is always from KEYBOARD. DATA are sent with MSB first. | ||
| 409 | |||
| 410 | 1) IDLE: both lines are high. | ||
| 411 | CLOCK ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 412 | DATA ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 413 | |||
| 414 | 2) KEYBOARD->HOST: HOST reads bit on rising edge. | ||
| 415 | CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ | ||
| 416 | DATA ~~~~~~~~~~~~X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ | ||
| 417 | <--> 160us(clock low) | ||
| 418 | <---> 180us(clock high) | ||
| 419 | |||
| 420 | 3) HOST->KEYBOARD: HOST asserts bit on falling edge. | ||
| 421 | CLOCK ~~~~~~~~~~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~|__|~~~~~~~~~~~ | ||
| 422 | DATA ~~~~~~|_____X777777X666666X555555X444444X333333X222222X111111X000000X~~~~~~~ | ||
| 423 | <----> 840us(request to send by host) <---> 80us(hold DATA) | ||
| 424 | <--> 180us(clock low) | ||
| 425 | <---> 220us(clock high) | ||
| 426 | |||
| 427 | |||
| 428 | Protocol | ||
| 429 | -------- | ||
| 430 | COMMAND: | ||
| 431 | Inquiry 0x10 get key event with block | ||
| 432 | Instant 0x12 get key event | ||
| 433 | Model 0x14 get model number(M0110 responds with 0x09) | ||
| 434 | bit 7 1 if another device connected(used when keypad exists?) | ||
| 435 | bit4-6 next device model number | ||
| 436 | bit1-3 keyboard model number | ||
| 437 | bit 0 always 1 | ||
| 438 | Test 0x16 test(ACK:0x7D/NAK:0x77) | ||
| 439 | |||
| 440 | KEY EVENT: | ||
| 441 | bit 7 key state(0:press 1:release) | ||
| 442 | bit 6-1 scan code(see below) | ||
| 443 | bit 0 always 1 | ||
| 444 | To get scan code use this: ((bits&(1<<7)) | ((bits&0x7F))>>1). | ||
| 445 | |||
| 446 | Note: On the M0110A, Keypad keys and Arrow keys are preceded by 0x79. | ||
| 447 | Moreover, some Keypad keys(=, /, * and +) are preceded by 0x71 on press and 0xF1 on release. | ||
| 448 | |||
| 449 | ARROW KEYS: | ||
| 450 | Arrow keys and Calc keys(+,*,/,= on keypad) share same byte sequence and preceding byte of | ||
| 451 | Calc keys(0x71 and 0xF1) means press and release event of SHIFT. This causes a very confusing situation, | ||
| 452 | it is difficult or impossible to tell Calc key from Arrow key plus SHIFT in some cases. | ||
| 453 | |||
| 454 | Raw key events: | ||
| 455 | press release | ||
| 456 | ---------------- ---------------- | ||
| 457 | Left: 0x79, 0x0D 0x79, 0x8D | ||
| 458 | Right: 0x79, 0x05 0x79, 0x85 | ||
| 459 | Up: 0x79, 0x1B 0x79, 0x9B | ||
| 460 | Down: 0x79, 0x11 0x79, 0x91 | ||
| 461 | Pad+: 0x71, 0x79, 0x0D 0xF1, 0x79, 0x8D | ||
| 462 | Pad*: 0x71, 0x79, 0x05 0xF1, 0x79, 0x85 | ||
| 463 | Pad/: 0x71, 0x79, 0x1B 0xF1, 0x79, 0x9B | ||
| 464 | Pad=: 0x71, 0x79, 0x11 0xF1, 0x79, 0x91 | ||
| 465 | |||
| 466 | |||
| 467 | RAW CODE: | ||
| 468 | M0110A | ||
| 469 | ,---------------------------------------------------------. ,---------------. | ||
| 470 | | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Bcksp| |Clr| =| /| *| | ||
| 471 | |---------------------------------------------------------| |---------------| | ||
| 472 | |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| | ||
| 473 | |-----------------------------------------------------' | |---------------| | ||
| 474 | |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| | ||
| 475 | |---------------------------------------------------------| |---------------| | ||
| 476 | |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| | | ||
| 477 | |---------------------------------------------------------' |-----------|Ent| | ||
| 478 | |Optio|Mac | Space | \|Lft|Rgt|Dn | | 0| .| | | ||
| 479 | `---------------------------------------------------------' `---------------' | ||
| 480 | ,---------------------------------------------------------. ,---------------. | ||
| 481 | | 65| 25| 27| 29| 2B| 2F| 2D| 35| 39| 33| 3B| 37| 31| 67| |+0F|*11|*1B|*05| | ||
| 482 | |---------------------------------------------------------| |---------------| | ||
| 483 | | 61| 19| 1B| 1D| 1F| 23| 21| 41| 45| 3F| 47| 43| 3D| | |+33|+37|+39|+1D| | ||
| 484 | |-----------------------------------------------------' | |---------------| | ||
| 485 | | 73| 01| 03| 05| 07| 0B| 09| 4D| 51| 4B| 53| 4F| 49| |+2D|+2F|+31|*0D| | ||
| 486 | |---------------------------------------------------------| |---------------| | ||
| 487 | | 71| 0D| 0F| 11| 13| 17| 5B| 5D| 27| 5F| 59| 71|+1B| |+27|+29|+2B| | | ||
| 488 | |---------------------------------------------------------' |-----------|+19| | ||
| 489 | | 75| 6F| 63 | 55|+0D|+05|+11| | +25|+03| | | ||
| 490 | `---------------------------------------------------------' `---------------' | ||
| 491 | + 0x79, 0xDD / 0xF1, 0xUU | ||
| 492 | * 0x71, 0x79,DD / 0xF1, 0x79, 0xUU | ||
| 493 | |||
| 494 | |||
| 495 | MODEL NUMBER: | ||
| 496 | M0110: 0x09 00001001 : model number 4 (100) | ||
| 497 | M0110A: 0x0B 00001011 : model number 5 (101) | ||
| 498 | M0110 & M0120: ??? | ||
| 499 | |||
| 500 | |||
| 501 | Scan Code | ||
| 502 | --------- | ||
| 503 | m0110_recv_key() function returns following scan codes instead of raw key events. | ||
| 504 | Scan codes are 1 byte long and MSB(bit7) is set when key is released. | ||
| 505 | |||
| 506 | M0110 | ||
| 507 | ,---------------------------------------------------------. | ||
| 508 | | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| | ||
| 509 | |---------------------------------------------------------| | ||
| 510 | |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| | ||
| 511 | |---------------------------------------------------------| | ||
| 512 | |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | ||
| 513 | |---------------------------------------------------------| | ||
| 514 | |Shift | Z| X| C| V| B| N| M| ,| ,| /| | | ||
| 515 | `---------------------------------------------------------' | ||
| 516 | |Opt|Mac | Space |Enter|Opt| | ||
| 517 | `------------------------------------------------' | ||
| 518 | ,---------------------------------------------------------. | ||
| 519 | | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | ||
| 520 | |---------------------------------------------------------| | ||
| 521 | | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| 2A| | ||
| 522 | |---------------------------------------------------------| | ||
| 523 | | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | ||
| 524 | |---------------------------------------------------------| | ||
| 525 | | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| | ||
| 526 | `---------------------------------------------------------' | ||
| 527 | | 3A| 37| 31 | 34| 3A| | ||
| 528 | `------------------------------------------------' | ||
| 529 | |||
| 530 | M0110A | ||
| 531 | ,---------------------------------------------------------. ,---------------. | ||
| 532 | | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Bcksp| |Clr| =| /| *| | ||
| 533 | |---------------------------------------------------------| |---------------| | ||
| 534 | |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| | ||
| 535 | |-----------------------------------------------------' | |---------------| | ||
| 536 | |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| | ||
| 537 | |---------------------------------------------------------| |---------------| | ||
| 538 | |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| | | ||
| 539 | |---------------------------------------------------------' |-----------|Ent| | ||
| 540 | |Optio|Mac | Space | \|Lft|Rgt|Dn | | 0| .| | | ||
| 541 | `---------------------------------------------------------' `---------------' | ||
| 542 | ,---------------------------------------------------------. ,---------------. | ||
| 543 | | 32| 12| 13| 14| 15| 17| 16| 1A| 1C| 19| 1D| 1B| 18| 33| | 47| 68| 6D| 62| | ||
| 544 | |---------------------------------------------------------| |---------------| | ||
| 545 | | 30| 0C| 0D| 0E| 0F| 10| 11| 20| 22| 1F| 23| 21| 1E| | | 59| 5B| 5C| 4E| | ||
| 546 | |-----------------------------------------------------' | |---------------| | ||
| 547 | | 39| 00| 01| 02| 03| 05| 04| 26| 28| 25| 29| 27| 24| | 56| 57| 58| 66| | ||
| 548 | |---------------------------------------------------------| |---------------| | ||
| 549 | | 38| 06| 07| 08| 09| 0B| 2D| 2E| 2B| 2F| 2C| 38| 4D| | 53| 54| 55| | | ||
| 550 | |---------------------------------------------------------' |-----------| 4C| | ||
| 551 | | 3A| 37| 31 | 2A| 46| 42| 48| | 52| 41| | | ||
| 552 | `---------------------------------------------------------' `---------------' | ||
| 553 | |||
| 554 | |||
| 555 | References | ||
| 556 | ---------- | ||
| 557 | Technical Info for 128K/512K and Plus | ||
| 558 | ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20128K.pdf | ||
| 559 | ftp://ftp.apple.asimov.net/pub/apple_II/documentation/macintosh/Mac%20Hardware%20Info%20-%20Mac%20Plus.pdf | ||
| 560 | Protocol: | ||
| 561 | Page 20 of Tech Info for 128K/512K | ||
| 562 | http://www.mac.linux-m68k.org/devel/plushw.php | ||
| 563 | Connector: | ||
| 564 | Page 20 of Tech Info for 128K/512K | ||
| 565 | http://www.kbdbabel.org/conn/kbd_connector_macplus.png | ||
| 566 | Signaling: | ||
| 567 | http://www.kbdbabel.org/signaling/kbd_signaling_mac.png | ||
| 568 | http://typematic.blog.shinobi.jp/Entry/14/ | ||
| 569 | Scan Codes: | ||
| 570 | Page 22 of Tech Info for 128K/512K | ||
| 571 | Page 07 of Tech Info for Plus | ||
| 572 | http://m0115.web.fc2.com/m0110.jpg | ||
| 573 | http://m0115.web.fc2.com/m0110a.jpg | ||
| 574 | */ | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | Copyright 2011 Jun WAKO <wakojun@gmail.com> | 2 | Copyright 2011,2012 Jun WAKO <wakojun@gmail.com> |
| 3 | 3 | ||
| 4 | This software is licensed with a Modified BSD License. | 4 | This software is licensed with a Modified BSD License. |
| 5 | All of this is supposed to be Free Software, Open Source, DFSG-free, | 5 | All of this is supposed to be Free Software, Open Source, DFSG-free, |
| @@ -54,23 +54,29 @@ 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 0x71 | ||
| 69 | #define M0110_ARROW_UP 0x1B | ||
| 70 | #define M0110_ARROW_DOWN 0x11 | ||
| 71 | #define M0110_ARROW_LEFT 0x0D | ||
| 72 | #define M0110_ARROW_RIGHT 0x05 | ||
| 73 | |||
| 74 | /* This inidcates no response. */ | ||
| 75 | #define M0110_ERROR 0xFF | ||
| 67 | 76 | ||
| 68 | /* scan code offset for keypad and arrow keys */ | 77 | /* scan code offset for keypad and arrow keys */ |
| 69 | #define M0110_KEYPAD_OFFSET 0x40 | 78 | #define M0110_KEYPAD_OFFSET 0x40 |
| 70 | #define M0110_ARROW_OFFSET 0x60 | 79 | #define M0110_CALC_OFFSET 0x60 |
| 71 | |||
| 72 | /* convert key event raw response into scan code */ | ||
| 73 | #define M0110_RAW2SCAN(key) ((key&(1<<7)) | ((key&0x7F)>>1)) | ||
| 74 | 80 | ||
| 75 | 81 | ||
| 76 | extern uint8_t m0110_error; | 82 | extern uint8_t m0110_error; |
| @@ -80,5 +86,7 @@ void m0110_init(void); | |||
| 80 | uint8_t m0110_send(uint8_t data); | 86 | uint8_t m0110_send(uint8_t data); |
| 81 | uint8_t m0110_recv(void); | 87 | uint8_t m0110_recv(void); |
| 82 | uint8_t m0110_recv_key(void); | 88 | uint8_t m0110_recv_key(void); |
| 89 | uint8_t m0110_inquiry(void); | ||
| 90 | uint8_t m0110_instant(void); | ||
| 83 | 91 | ||
| 84 | #endif | 92 | #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..92b58f684 --- /dev/null +++ b/m0110_usb/README.md | |||
| @@ -0,0 +1,126 @@ | |||
| 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|Mb1|Mb3|Mb2| | ||
| 109 | |---------------------------------------------------------| |---------------| | ||
| 110 | |Caps |Hom| Up|PgU| | | | |Psc|Slk|Pau|Up |Ins| | |MwD|McU|MwU|MwU| | ||
| 111 | |-----------------------------------------------------' | |---------------| | ||
| 112 | |Fn0 |Lef|Dow|Rig| | | | |Hom|PgU|Lef|Rig|Return| |McL|McD|McR|MwD| | ||
| 113 | |---------------------------------------------------------| |---------------| | ||
| 114 | |Shift |End| |PgD| |VoD|VoU|Mut|End|PgD|Dow|Shif|Up | |MwL|McD|MwR| | | ||
| 115 | |---------------------------------------------------------| |-----------|Mb2| | ||
| 116 | |Ctrl |Alt | Space |Gui | \|Lft|Rgt|Dn | | Mb1|Mb3| | | ||
| 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. | ||
diff --git a/m0110_usb/config.h b/m0110_usb/config.h index c12e0738d..4563d6da5 100644 --- a/m0110_usb/config.h +++ b/m0110_usb/config.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | 2 | Copyright 2011,2012 Jun Wako <wakojun@gmail.com> |
| 3 | 3 | ||
| 4 | This program is free software: you can redistribute it and/or modify | 4 | This program is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
| @@ -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/doc/m0110.jpg b/m0110_usb/doc/m0110.jpg index ef9a123ab..ef9a123ab 100755..100644 --- a/m0110_usb/doc/m0110.jpg +++ b/m0110_usb/doc/m0110.jpg | |||
| Binary files differ | |||
diff --git a/m0110_usb/doc/teensy.jpg b/m0110_usb/doc/teensy.jpg index 96e93e7e2..96e93e7e2 100755..100644 --- a/m0110_usb/doc/teensy.jpg +++ b/m0110_usb/doc/teensy.jpg | |||
| Binary files differ | |||
diff --git a/m0110_usb/keymap.c b/m0110_usb/keymap.c index bbb699a9a..939010c6d 100644 --- a/m0110_usb/keymap.c +++ b/m0110_usb/keymap.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | 2 | Copyright 2011,2012 Jun Wako <wakojun@gmail.com> |
| 3 | 3 | ||
| 4 | This program is free software: you can redistribute it and/or modify | 4 | This program is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
| @@ -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 | ||
| @@ -58,7 +58,7 @@ static const uint8_t PROGMEM fn_layer[] = { | |||
| 58 | 1, // Fn0 | 58 | 1, // Fn0 |
| 59 | 2, // Fn1 | 59 | 2, // Fn1 |
| 60 | 3, // Fn2 | 60 | 3, // Fn2 |
| 61 | 0, // Fn3 | 61 | 1, // Fn3 |
| 62 | 0, // Fn4 | 62 | 0, // Fn4 |
| 63 | 0, // Fn5 | 63 | 0, // Fn5 |
| 64 | 0, // Fn6 | 64 | 0, // Fn6 |
| @@ -68,10 +68,17 @@ 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 | #ifndef HASU |
| 72 | KB_SLASH, // Fn1 | 72 | KB_ESC, // Fn0 |
| 73 | KB_NO, // Fn1 | ||
| 73 | KB_NO, // Fn2 | 74 | KB_NO, // Fn2 |
| 74 | KB_NO, // Fn3 | 75 | KB_NO, // Fn3 |
| 76 | #else | ||
| 77 | KB_NO, // Fn0 | ||
| 78 | KB_SCOLON, // Fn1 | ||
| 79 | KB_SLASH, // Fn2 | ||
| 80 | KB_UP, // Fn3 | ||
| 81 | #endif | ||
| 75 | KB_NO, // Fn4 | 82 | KB_NO, // Fn4 |
| 76 | KB_NO, // Fn5 | 83 | KB_NO, // Fn5 |
| 77 | KB_NO, // Fn6 | 84 | KB_NO, // Fn6 |
| @@ -79,52 +86,100 @@ static const uint8_t PROGMEM fn_keycode[] = { | |||
| 79 | }; | 86 | }; |
| 80 | 87 | ||
| 81 | static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | 88 | static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { |
| 82 | // LShift and RShift are logically same one button. | 89 | /* |
| 83 | // LOption and ROption are logically same one button. | 90 | * The keymap works with both M0110 and M0110A keyboards. As you can see, the M0110A is a superset |
| 84 | /* Default Layer: plain keymap | 91 | * of the M0110 keyboard, with only one exception: 'Enter' in M0110 does not exist |
| 85 | * ,---------------------------------------------------------. | 92 | * 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| | 93 | * the M0110A, they are totally interchangeable. In fact, the M0110A is functionally (almost) |
| 87 | * |---------------------------------------------------------| | 94 | * 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| [| ]| \| | 95 | * (which is causing some problems as you will read below) is that the M0110+M0120 don't have |
| 89 | * |---------------------------------------------------------| | 96 | * 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| | 97 | * doubled as the [comma], [/], [*] and [+] keys, when used with the [Shift] key. The M0110A has |
| 91 | * |---------------------------------------------------------| | 98 | * substituted the [comma] key with the [=] key, however its scancode is the same. |
| 92 | * |Shift | Z| X| C| V| B| N| M| ,| ,|Fn1| Shift| | 99 | * |
| 93 | * `---------------------------------------------------------' | 100 | * Default: |
| 94 | * |Fn2|Alt | Space |Gui |Fn2| | 101 | * ,---------------------------------------------------------. ,---------------. |
| 95 | * `-----------------------------------------------' | 102 | * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backs| |Gui| =| /| *| |
| 103 | * |---------------------------------------------------------| |---------------| | ||
| 104 | * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | 7| 8| 9| -| | ||
| 105 | * |-----------------------------------------------------' | |---------------| | ||
| 106 | * |Fn0 | A| S| D| F| G| H| J| K| L| ;| '|Return| | 4| 5| 6| +| | ||
| 107 | * |---------------------------------------------------------| |---------------| | ||
| 108 | * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shft|Up | | 1| 2| 3| | | ||
| 109 | * |---------------------------------------------------------| |-----------|Ent| | ||
| 110 | * |Ctrl |Alt | Space |Gui| \|Lft|Rgt|Dn | | 0| .| | | ||
| 111 | * `---------------------------------------------------------' `---------------' | ||
| 112 | * | ||
| 113 | * HHKB/WASD/Mouse Layer(Fn0): | ||
| 114 | * ,---------------------------------------------------------. ,---------------. | ||
| 115 | * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delet| |Nlk|Mb1|Mb3|Mb2| | ||
| 116 | * |---------------------------------------------------------| |---------------| | ||
| 117 | * |Caps |Hom| Up|PgU| | | | |Psc|Slk|Pau|Up |Ins| | |MwD|McU|MwU|MwU| | ||
| 118 | * |-----------------------------------------------------' | |---------------| | ||
| 119 | * |Fn0 |Lef|Dow|Rig| | | | |Hom|PgU|Lef|Rig|Return| |McL|McD|McR|MwD| | ||
| 120 | * |---------------------------------------------------------| |---------------| | ||
| 121 | * |Shift |End| |PgD| |VoD|VoU|Mut|End|PgD|Dow|Shif|Up | |MwL|McD|MwR| | | ||
| 122 | * |---------------------------------------------------------| |-----------|Mb2| | ||
| 123 | * |Ctrl |Alt | Space |Gui | \|Lft|Rgt|Dn | | Mb1|Mb3| | | ||
| 124 | * `---------------------------------------------------------' `---------------' | ||
| 125 | * Mb: Mouse Button / Mc: Mouse Cursor / Mw: Mouse Wheel | ||
| 126 | * | ||
| 127 | * NOTE: You can register Esc by hitting(press&release) Fn0 quickly. | ||
| 128 | * NOTE: Gui between Space and \ is Enter on M0110 not exists on M0110A. | ||
| 129 | * NOTE: LShift and RShift are logically same key. (M0110, M0110A) | ||
| 130 | * NOTE: LOption and ROption are logically same key. (M0110) | ||
| 96 | */ | 131 | */ |
| 132 | #ifndef HASU | ||
| 97 | KEYMAP( | 133 | KEYMAP( |
| 98 | GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, | 134 | GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, LGUI,EQL, PSLS,PAST, |
| 99 | TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, | 135 | 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, | 136 | FN0, A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS, |
| 101 | LSFT,Z, X, C, V, B, N, M, COMM,DOT, FN1, | 137 | LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, UP, P1, P2, P3, PENT, |
| 102 | FN2, LALT, SPC, LGUI | 138 | LCTL,LALT, SPC, LGUI,BSLS,LEFT,RGHT,DOWN, P0, PDOT |
| 103 | ), | 139 | ), |
| 104 | // vi mousekeys | 140 | // HHKB & WASD |
| 105 | KEYMAP( | 141 | KEYMAP( |
| 106 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, | 142 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,BTN1,BTN3,BTN2, |
| 107 | CAPS,NO, NO, NO, NO, NO, WH_L,WH_D,WH_U,WH_R,NO, NO, NO, NO, | 143 | CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,BRK, UP, INS, WH_D,MS_U,WH_U,WH_U, |
| 108 | LCTL,VOLD,VOLU,MUTE,NO, NO, MS_L,MS_D,MS_U,MS_R,FN0, NO, ENT, | 144 | FN0, LEFT,DOWN,RGHT,NO, NO, NO, NO, HOME,PGUP,LEFT,RGHT, ENT, MS_L,MS_D,MS_R,WH_D, |
| 109 | LSFT,NO, NO, NO, NO, BTN3,BTN2,BTN1,NO, NO, NO, | 145 | LSFT,END, NO, PGDN,NO, VOLD,VOLU,MUTE,END, PGDN,DOWN, UP, WH_L,MS_D,WH_R,BTN2, |
| 110 | NO, LALT, BTN1, LGUI | 146 | LCTL,LALT, SPC, LGUI,BSLS,LEFT,RGHT,DOWN, BTN1, BTN3 |
| 111 | ), | 147 | ), |
| 112 | // vi cusorkeys | 148 | #else |
| 149 | // hasu's keymap | ||
| 150 | // To enable use this 'make' option: make EXTRAFLAGS=-DHASU | ||
| 113 | KEYMAP( | 151 | KEYMAP( |
| 114 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, | 152 | ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, LGUI,EQL, PSLS,PAST, |
| 115 | CAPS,NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, NO, NO, NO, NO, | 153 | TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, P7, P8, P9, PMNS, |
| 116 | LCTL,NO, NO, NO, NO, NO, LEFT,DOWN,UP, RGHT,NO, NO, ENT, | 154 | LCTL,A, S, D, F, G, H, J, K, L, FN1, QUOT, ENT, P4, P5, P6, PPLS, |
| 117 | LSFT,NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, FN1, | 155 | LSFT,Z, X, C, V, B, N, M, COMM,DOT, FN2, FN3, P1, P2, P3, PENT, |
| 118 | NO, LALT, SPC, LGUI | 156 | LCTL,LALT, SPC, LGUI,BSLS,LEFT,RGHT,DOWN, LGUI, PDOT |
| 119 | ), | 157 | ), |
| 120 | // HHKB & WASD | 158 | // HHKB & WASD |
| 121 | KEYMAP( | 159 | KEYMAP( |
| 122 | ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, | 160 | GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,EQL, PSLS,PAST, |
| 123 | CAPS,HOME,UP, PGUP,NO, NO, NO, NO, PSCR,SLCK,BRK, UP, NO, NO, | 161 | 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, | 162 | LCTL,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, | 163 | LSFT,END, NO, PGDN,NO, VOLD,VOLU,MUTE,END, PGDN,DOWN, FN3, P1, P2, P3, PENT, |
| 126 | FN2, LALT, SPC, LGUI | 164 | LCTL,LALT, SPC, LGUI,BSLS,LEFT,RGHT,DOWN, P0, PDOT |
| 165 | ), | ||
| 166 | // vi mousekeys | ||
| 167 | KEYMAP( | ||
| 168 | GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,EQL, PSLS,PAST, | ||
| 169 | CAPS,NO, NO, NO, NO, NO, WH_L,WH_D,WH_U,WH_R,NO, NO, NO, P7, P8, P9, PMNS, | ||
| 170 | NO, VOLD,VOLU,MUTE,NO, NO, MS_L,MS_D,MS_U,MS_R,FN1, NO, ENT, P4, P5, P6, PPLS, | ||
| 171 | LSFT,NO, NO, NO, NO, BTN3,BTN2,BTN1,NO, NO, NO, UP, P1, P2, P3, PENT, | ||
| 172 | LCTL,LALT, BTN1, LGUI,BSLS,LEFT,RGHT,DOWN, P0, PDOT | ||
| 173 | ), | ||
| 174 | // vi cusorkeys | ||
| 175 | KEYMAP( | ||
| 176 | GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, NLCK,EQL, PSLS,PAST, | ||
| 177 | CAPS,NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, NO, NO, NO, P7, P8, P9, PMNS, | ||
| 178 | NO, NO, NO, NO, NO, NO, LEFT,DOWN,UP, RGHT,NO, NO, ENT, P4, P5, P6, PPLS, | ||
| 179 | LSFT,NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, FN2, UP, P1, P2, P3, PENT, | ||
| 180 | LCTL,LALT, SPC, LGUI,BSLS,LEFT,RGHT,DOWN, P0, PDOT | ||
| 127 | ), | 181 | ), |
| 182 | #endif | ||
| 128 | }; | 183 | }; |
| 129 | 184 | ||
| 130 | 185 | ||
diff --git a/m0110_usb/matrix.c b/m0110_usb/matrix.c index f045920cc..1ca6894c4 100644 --- a/m0110_usb/matrix.c +++ b/m0110_usb/matrix.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | Copyright 2011 Jun Wako <wakojun@gmail.com> | 2 | Copyright 2011,2012 Jun Wako <wakojun@gmail.com> |
| 3 | 3 | ||
| 4 | This program is free software: you can redistribute it and/or modify | 4 | This program is free software: you can redistribute it and/or modify |
| 5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
| @@ -32,7 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 32 | 32 | ||
| 33 | 33 | ||
| 34 | #define CAPS 0x39 | 34 | #define CAPS 0x39 |
| 35 | #define CAPS_UP (CAPS | 0x80) | 35 | #define CAPS_BREAK (CAPS | 0x80) |
| 36 | #define ROW(key) ((key)>>3&0x0F) | 36 | #define ROW(key) ((key)>>3&0x0F) |
| 37 | #define COL(key) ((key)&0x07) | 37 | #define COL(key) ((key)&0x07) |
| 38 | 38 | ||
| @@ -43,9 +43,6 @@ static bool is_modified = false; | |||
| 43 | static uint8_t *matrix; | 43 | static uint8_t *matrix; |
| 44 | static uint8_t _matrix0[MATRIX_ROWS]; | 44 | static uint8_t _matrix0[MATRIX_ROWS]; |
| 45 | 45 | ||
| 46 | #ifdef MATRIX_HAS_GHOST | ||
| 47 | static bool matrix_has_ghost_in_row(uint8_t row); | ||
| 48 | #endif | ||
| 49 | static void register_key(uint8_t key); | 46 | static void register_key(uint8_t key); |
| 50 | 47 | ||
| 51 | 48 | ||
| @@ -88,11 +85,13 @@ uint8_t matrix_scan(void) | |||
| 88 | // Send Caps key up event | 85 | // Send Caps key up event |
| 89 | if (matrix_is_on(ROW(CAPS), COL(CAPS))) { | 86 | if (matrix_is_on(ROW(CAPS), COL(CAPS))) { |
| 90 | is_modified = true; | 87 | is_modified = true; |
| 91 | register_key(CAPS_UP); | 88 | register_key(CAPS_BREAK); |
| 92 | } | 89 | } |
| 93 | #endif | 90 | #endif |
| 94 | if (key == M0110_NULL) { | 91 | if (key == M0110_NULL) { |
| 95 | return 0; | 92 | return 0; |
| 93 | } else if (key == M0110_ERROR) { | ||
| 94 | return 0; | ||
| 96 | } else { | 95 | } else { |
| 97 | #ifdef MATRIX_HAS_LOCKING_CAPS | 96 | #ifdef MATRIX_HAS_LOCKING_CAPS |
| 98 | if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) { | 97 | if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) { |
| @@ -100,11 +99,11 @@ uint8_t matrix_scan(void) | |||
| 100 | // Ignore LockingCaps key down event | 99 | // Ignore LockingCaps key down event |
| 101 | if (key == CAPS) return 0; | 100 | if (key == CAPS) return 0; |
| 102 | // Convert LockingCaps key up event into down event | 101 | // Convert LockingCaps key up event into down event |
| 103 | if (key == CAPS_UP) key = CAPS; | 102 | if (key == CAPS_BREAK) key = CAPS; |
| 104 | } else { | 103 | } else { |
| 105 | // CAPS LOCK off: | 104 | // CAPS LOCK off: |
| 106 | // Ignore LockingCaps key up event | 105 | // Ignore LockingCaps key up event |
| 107 | if (key == CAPS_UP) return 0; | 106 | if (key == CAPS_BREAK) return 0; |
| 108 | } | 107 | } |
| 109 | #endif | 108 | #endif |
| 110 | is_modified = true; | 109 | is_modified = true; |
| @@ -112,7 +111,7 @@ uint8_t matrix_scan(void) | |||
| 112 | } | 111 | } |
| 113 | 112 | ||
| 114 | if (debug_enable) { | 113 | if (debug_enable) { |
| 115 | print("key: "); phex(key); print("\n"); | 114 | print("["); phex(key); print("]\n"); |
| 116 | } | 115 | } |
| 117 | return 1; | 116 | return 1; |
| 118 | } | 117 | } |
| @@ -125,12 +124,6 @@ bool matrix_is_modified(void) | |||
| 125 | inline | 124 | inline |
| 126 | bool matrix_has_ghost(void) | 125 | bool matrix_has_ghost(void) |
| 127 | { | 126 | { |
| 128 | #ifdef MATRIX_HAS_GHOST | ||
| 129 | for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | ||
| 130 | if (matrix_has_ghost_in_row(i)) | ||
| 131 | return true; | ||
| 132 | } | ||
| 133 | #endif | ||
| 134 | return false; | 127 | return false; |
| 135 | } | 128 | } |
| 136 | 129 | ||
| @@ -165,23 +158,6 @@ uint8_t matrix_key_count(void) | |||
| 165 | return count; | 158 | return count; |
| 166 | } | 159 | } |
| 167 | 160 | ||
| 168 | #ifdef MATRIX_HAS_GHOST | ||
| 169 | inline | ||
| 170 | static bool matrix_has_ghost_in_row(uint8_t row) | ||
| 171 | { | ||
| 172 | // no ghost exists in case less than 2 keys on | ||
| 173 | if (((matrix[row] - 1) & matrix[row]) == 0) | ||
| 174 | return false; | ||
| 175 | |||
| 176 | // ghost exists in case same state as other row | ||
| 177 | for (uint8_t i=0; i < MATRIX_ROWS; i++) { | ||
| 178 | if (i != row && (matrix[i] & matrix[row]) == matrix[row]) | ||
| 179 | return true; | ||
| 180 | } | ||
| 181 | return false; | ||
| 182 | } | ||
| 183 | #endif | ||
| 184 | |||
| 185 | inline | 161 | inline |
| 186 | static void register_key(uint8_t key) | 162 | static void register_key(uint8_t key) |
| 187 | { | 163 | { |
| @@ -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 extra flags at 'make' command line like: make EXTRAFLAGS=-DFOO=bar |
| 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 | ||
