uint8_t matrix_scan(void) { uint16_t code; code = serial_recv2(); if (code == -1) { #ifdef PC98_LED_CONTROL // Before sending command we have to make sure that there is no unprocessed key in queue // otherwise keys will be missed during sending command if (pc98_led) { pc98_led_set(); pc98_led = 0; } #endif return 0; } print_hex8(code); print(" "); if (code&0x80) { // break code if (matrix_is_on(ROW(code), COL(code))) { matrix[ROW(code)] &= ~(1<<COL(code)); } } else { // make code if (!matrix_is_on(ROW(code), COL(code))) { matrix[ROW(code)] |= (1<<COL(code)); } } return code; }
uint8_t matrix_scan(void) { is_modified = false; uint16_t code; code = serial_recv2(); if (code == -1) { return 0; } dprintf("%02X\n", code); if (code&0x80) { // break code if (matrix_is_on(ROW(code), COL(code))) { matrix[ROW(code)] &= ~(1<<COL(code)); is_modified = true; } } else { // make code if (!matrix_is_on(ROW(code), COL(code))) { matrix[ROW(code)] |= (1<<COL(code)); is_modified = true; } } return code; }
uint8_t matrix_scan(void) { is_modified = false; uint8_t code; code = serial_recv(); if (!code) return 0; debug_hex(code); debug(" "); switch (code) { case 0xFF: // reset success: FF 04 print("reset: "); _delay_ms(500); code = serial_recv(); xprintf("%02X\n", code); if (code == 0x04) { // LED status led_set(host_keyboard_leds()); } return 0; case 0xFE: // layout: FE <layout> print("layout: "); _delay_ms(500); xprintf("%02X\n", serial_recv()); return 0; case 0x7E: // reset fail: 7E 01 print("reset fail: "); _delay_ms(500); xprintf("%02X\n", serial_recv()); return 0; case 0x7F: // all keys up for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00; return 0; } if (code&0x80) { // break code if (matrix_is_on(ROW(code), COL(code))) { matrix[ROW(code)] &= ~(1<<COL(code)); is_modified = true; } } else { // make code if (!matrix_is_on(ROW(code), COL(code))) { matrix[ROW(code)] |= (1<<COL(code)); is_modified = true; } } return code; }
inline static void matrix_break(uint8_t code) { if (matrix_is_on(ROW(code), COL(code))) { matrix[ROW(code)] &= ~(1<<COL(code)); } }
inline static void matrix_make(uint8_t code) { if (!matrix_is_on(ROW(code), COL(code))) { matrix[ROW(code)] |= 1<<COL(code); } }
void NeXTMatrix::_make(uint8_t code) { if (!matrix_is_on(NEXT_KBD_ROW(code), NEXT_KBD_COL(code))) { matrix[NEXT_KBD_ROW(code)] |= 1<<NEXT_KBD_COL(code); _is_modified = true; } }
uint8_t matrix_scan(void) { is_modified = false; uint8_t code; code = serial_recv(); if (!code) return 0; print_hex8(code); switch (code) { case 0xFF: // reset success case 0xFE: // layout case 0x7E: // reset fail if (code == 0xFF) print("reset: 0xFF "); if (code == 0x7E) print("reset fail: 0x7E "); if (code == 0xFE) print("layout: 0xFE "); // response byte _delay_ms(500); if (code = serial_recv()) print_hex8(code); print("\n"); // FALL THROUGH case 0x7F: // all keys up for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00; return 0; } if (code&0x80) { // break code if (matrix_is_on(ROW(code), COL(code))) { matrix[ROW(code)] &= ~(1<<COL(code)); is_modified = true; } } else { // make code if (!matrix_is_on(ROW(code), COL(code))) { matrix[ROW(code)] |= (1<<COL(code)); is_modified = true; } } return code; }
uint8_t matrix_key_count(void) { uint8_t count = 0; for (uint8_t i = 0; i < MATRIX_ROWS; i++) { for (uint8_t j = 0; j < MATRIX_COLS; j++) { if (matrix_is_on(i, j)) count++; } } return count; }
uint8_t matrix_scan(void) { uint16_t code; PC98_RDY_PORT |= (1<<PC98_RDY_BIT); _delay_us(30); code = serial_recv2(); PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT); if (code == -1) return 0; if (code == 0x60) { pc98_inhibit_repeat(); /* PC98_RDY_PORT |= (1<<PC98_RDY_BIT); _delay_ms(100); serial_send(0x96); PC98_RDY_PORT &= ~(1<<PC98_RDY_BIT); */ return 0; } print_hex8(code); print(" "); if (code&0x80) { // break code if (matrix_is_on(ROW(code), COL(code))) { matrix[ROW(code)] &= ~(1<<COL(code)); } } else { // make code if (!matrix_is_on(ROW(code), COL(code))) { matrix[ROW(code)] |= (1<<COL(code)); } } return code; }
uint8_t matrix_scan(void) { uint8_t key; is_modified = false; key = m0110_recv_key(); #ifdef MATRIX_HAS_LOCKING_CAPS // Send Caps key up event if (matrix_is_on(ROW(CAPS), COL(CAPS))) { is_modified = true; register_key(CAPS_UP); } #endif if (key == M0110_NULL) { return 0; } else { #ifdef MATRIX_HAS_LOCKING_CAPS if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) { // CAPS LOCK on: // Ignore LockingCaps key down event if (key == CAPS) return 0; // Convert LockingCaps key up event into down event if (key == CAPS_UP) key = CAPS; } else { // CAPS LOCK off: // Ignore LockingCaps key up event if (key == CAPS_UP) return 0; } #endif is_modified = true; register_key(key); } if (debug_enable) { print("key: "); phex(key); print("\n"); } return 1; }
void type_o_matic_animation_loop(void) { uint8_t led_row; uint8_t led_col; bool is_left_side; for (uint8_t row = 0; row < MATRIX_ROWS; ++row) { for (uint8_t col = 0; col < MATRIX_COLS; ++col) { uint8_t color; getLedPosByMatrixKey(row, col, &led_row, &led_col, &is_left_side); if (is_left_side != is_left_side_of_keyboard()) continue; if (matrix_is_on(row, col)) { issi.drawPixel(led_col, led_row, animation.brightness); } else { color = issi.getPixel(led_col, led_row); if (color >= 5) color -= 5; else color = 0; issi.drawPixel(led_col, led_row, color); } } } issi.blitToFrame(animation_frame); }
/* * PS/2 Scan Code Set 2: Exceptional Handling * * There are several keys to be handled exceptionally. * The scan code for these keys are varied or prefix/postfix'd * depending on modifier key state. * * Keyboard Scan Code Specification: * http://www.microsoft.com/whdc/archive/scancode.mspx * http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc * * * 1) Insert, Delete, Home, End, PageUp, PageDown, Up, Down, Right, Left * a) when Num Lock is off * modifiers | make | break * ----------+---------------------------+---------------------- * Ohter | <make> | <break> * LShift | E0 F0 12 <make> | <break> E0 12 * RShift | E0 F0 59 <make> | <break> E0 59 * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12 * * b) when Num Lock is on * modifiers | make | break * ----------+---------------------------+---------------------- * Other | E0 12 <make> | <break> E0 F0 12 * Shift'd | <make> | <break> * * Handling: These prefix/postfix codes are ignored. * * * 2) Keypad / * modifiers | make | break * ----------+---------------------------+---------------------- * Ohter | <make> | <break> * LShift | E0 F0 12 <make> | <break> E0 12 * RShift | E0 F0 59 <make> | <break> E0 59 * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12 * * Handling: These prefix/postfix codes are ignored. * * * 3) PrintScreen * modifiers | make | break * ----------+--------------+----------------------------------- * Other | E0 12 E0 7C | E0 F0 7C E0 F0 12 * Shift'd | E0 7C | E0 F0 7C * Control'd | E0 7C | E0 F0 7C * Alt'd | 84 | F0 84 * * Handling: These prefix/postfix codes are ignored, and both scan codes * 'E0 7C' and 84 are seen as PrintScreen. * * 4) Pause * modifiers | make(no break code) * ----------+-------------------------------------------------- * Other | E1 14 77 E1 F0 14 F0 77 * Control'd | E0 7E E0 F0 7E * * Handling: Both code sequences are treated as a whole. * And we need a ad hoc 'pseudo break code' hack to get the key off * because it has no break code. * */ uint8_t matrix_scan(void) { // scan code reading states static enum { INIT, F0, E0, E0_F0, // Pause E1, E1_14, E1_14_77, E1_14_77_E1, E1_14_77_E1_F0, E1_14_77_E1_F0_14, E1_14_77_E1_F0_14_F0, // Control'd Pause E0_7E, E0_7E_E0, E0_7E_E0_F0, } state = INIT; is_modified = false; // 'pseudo break code' hack if (matrix_is_on(ROW(PAUSE), COL(PAUSE))) { matrix_break(PAUSE); } uint8_t code = ps2_host_recv(); if (!ps2_error) { switch (state) { case INIT: switch (code) { case 0xE0: state = E0; break; case 0xF0: state = F0; break; case 0xE1: state = E1; break; case 0x83: // F7 matrix_make(F7); state = INIT; break; case 0x84: // Alt'd PrintScreen matrix_make(PRINT_SCREEN); state = INIT; break; case 0x00: // Overrun [3]p.25 matrix_clear(); clear_keyboard(); print("Overrun\n"); state = INIT; break; default: // normal key make if (code < 0x80) { matrix_make(code); } else { matrix_clear(); clear_keyboard(); xprintf("unexpected scan code at INIT: %02X\n", code); } state = INIT; } break; case E0: // E0-Prefixed switch (code) { case 0x12: // to be ignored case 0x59: // to be ignored state = INIT; break; case 0x7E: // Control'd Pause state = E0_7E; break; case 0xF0: state = E0_F0; break; default: if (code < 0x80) { matrix_make(code|0x80); } else { matrix_clear(); clear_keyboard(); xprintf("unexpected scan code at E0: %02X\n", code); } state = INIT; } break; case F0: // Break code switch (code) { case 0x83: // F7 matrix_break(F7); state = INIT; break; case 0x84: // Alt'd PrintScreen matrix_break(PRINT_SCREEN); state = INIT; break; case 0xF0: matrix_clear(); clear_keyboard(); xprintf("unexpected scan code at F0: F0(clear and cont.)\n"); break; default: if (code < 0x80) { matrix_break(code); } else { matrix_clear(); clear_keyboard(); xprintf("unexpected scan code at F0: %02X\n", code); } state = INIT; } break; case E0_F0: // Break code of E0-prefixed switch (code) { case 0x12: // to be ignored case 0x59: // to be ignored state = INIT; break; default: if (code < 0x80) { matrix_break(code|0x80); } else { matrix_clear(); clear_keyboard(); xprintf("unexpected scan code at E0_F0: %02X\n", code); } state = INIT; } break; // following are states of Pause case E1: switch (code) { case 0x14: state = E1_14; break; default: state = INIT; } break; case E1_14: switch (code) { case 0x77: state = E1_14_77; break; default: state = INIT; } break; case E1_14_77: switch (code) { case 0xE1: state = E1_14_77_E1; break; default: state = INIT; } break; case E1_14_77_E1: switch (code) { case 0xF0: state = E1_14_77_E1_F0; break; default: state = INIT; } break; case E1_14_77_E1_F0: switch (code) { case 0x14: state = E1_14_77_E1_F0_14; break; default: state = INIT; } break; case E1_14_77_E1_F0_14: switch (code) { case 0xF0: state = E1_14_77_E1_F0_14_F0; break; default: state = INIT; } break; case E1_14_77_E1_F0_14_F0: switch (code) { case 0x77: matrix_make(PAUSE); state = INIT; break; default: state = INIT; } break; // Following are states of Control'd Pause case E0_7E: if (code == 0xE0) state = E0_7E_E0; else state = INIT; break; case E0_7E_E0: if (code == 0xF0) state = E0_7E_E0_F0; else state = INIT; break; case E0_7E_E0_F0: if (code == 0x7E) matrix_make(PAUSE); state = INIT; break; default: state = INIT; } } // TODO: request RESEND when error occurs? /* if (PS2_IS_FAILED(ps2_error)) { uint8_t ret = ps2_host_send(PS2_RESEND); xprintf("Resend: %02X\n", ret); } */ return 1; }
/* * PS/2 Scan Code Set 2: Exceptional Handling * * There are several keys to be handled exceptionally. * The scan code for these keys are varied or prefix/postfix'd * depending on modifier key state. * * References: * http://www.microsoft.com/whdc/archive/scancode.mspx * http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc * * * Insert, Delete, Home, End, PageUp, PageDown, Up, Down, Right, Left: * Num Lock: off * modifiers | make | break * ----------+---------------------------+---------------------- * Ohter | <make> | <break> * LShift | E0 F0 12 <make> | <break> E0 12 * RShift | E0 F0 59 <make> | <break> E0 59 * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12 * * Num Lock: on * modifiers | make | break * ----------+---------------------------+---------------------- * Other | E0 12 <make> | <break> E0 F0 12 * Shift'd | <make> | <break> * * Handling: ignore these prefix/postfix codes * * * Keypad-/: * modifiers | make | break * ----------+---------------------------+---------------------- * Ohter | <make> | <break> * LShift | E0 F0 12 <make> | <break> E0 12 * RShift | E0 F0 59 <make> | <break> E0 59 * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12 * * Handling: ignore these prefix/postfix codes * * * PrintScreen: * With hoding down modifiers, the scan code is sent as following: * * modifiers | make | break * ----------+--------------+----------------------------------- * Other | E0 12 E0 7C | E0 F0 7C E0 F0 12 * Shift'd | E0 7C | E0 F0 7C * Control'd | E0 7C | E0 F0 7C * Alt'd | 84 | F0 84 * * Handling: ignore prefix/postfix codes and treat both scan code * E0 7C and 84 as PrintScreen. * * Pause: * With hoding down modifiers, the scan code is sent as following: * * modifiers | make(no break code) * ----------+-------------------------------------------------- * no mods | E1 14 77 E1 F0 14 F0 77 * Control'd | E0 7E E0 F0 7E * * Handling: treat these two code sequence as Pause * */ uint8_t matrix_scan(void) { static enum { INIT, F0, E0, E0_F0, // states for Pause/Break E1, E1_14, E1_14_77, E1_14_77_E1, E1_14_77_E1_F0, E1_14_77_E1_F0_14, E1_14_77_E1_F0_14_F0, } state = INIT; is_modified = false; // Pause/Break off(PS/2 has no break for this key) if (matrix_is_on(ROW(PAUSE), COL(PAUSE))) { matrix_break(PAUSE); } uint8_t code; while ((code = ps2_host_recv())) { switch (state) { case INIT: switch (code) { case 0xE0: // 2byte make state = E0; break; case 0xF0: // break code state = F0; break; case 0xE1: // Pause/Break state = E1; break; case 0x83: // F8 matrix_make(F8); state = INIT; break; case 0x84: // PrintScreen matrix_make(PRINT_SCREEN); state = INIT; break; default: // normal key make if (code < 0x80) { matrix_make(code); } else { debug("unexpected scan code at INIT: "); debug_hex(code); debug("\n"); } state = INIT; } break; case E0: switch (code) { case 0x12: // postfix/postfix code for exceptional keys case 0x59: // postfix/postfix code for exceptional keys // ignore state = INIT; break; case 0x7E: // former part of Control-Pause[E0 7E E0 F0 7E] matrix_make(PAUSE); state = INIT; break; case 0xF0: // E0 break state = E0_F0; break; default: // E0 make if (code < 0x80) { matrix_make(code|0x80); } else { debug("unexpected scan code at E0: "); debug_hex(code); debug("\n"); } state = INIT; } break; case F0: switch (code) { case 0x83: matrix_break(F8); state = INIT; break; case 0x84: matrix_break(PRINT_SCREEN); state = INIT; break; default: if (code < 0x80) { matrix_break(code); } else { debug("unexpected scan code at F0: "); debug_hex(code); debug("\n"); } state = INIT; } break; case E0_F0: // E0 break switch (code) { case 0x12: // postfix/postfix code for exceptional keys case 0x59: // postfix/postfix code for exceptional keys case 0x7E: // latter part of Control-Pause[E0 7E E0 F0 7E] // ignore state = INIT; break; default: if (code < 0x80) { matrix_break(code|0x80); } else { debug("unexpected scan code at E0_F0: "); debug_hex(code); debug("\n"); } state = INIT; } break; /* Pause */ case E1: switch (code) { case 0x14: state = E1_14; break; default: state = INIT; } break; case E1_14: switch (code) { case 0x77: state = E1_14_77; break; default: state = INIT; } break; case E1_14_77: switch (code) { case 0xE1: state = E1_14_77_E1; break; default: state = INIT; } break; case E1_14_77_E1: switch (code) { case 0xF0: state = E1_14_77_E1_F0; break; default: state = INIT; } break; case E1_14_77_E1_F0: switch (code) { case 0x14: state = E1_14_77_E1_F0_14; break; default: state = INIT; } break; case E1_14_77_E1_F0_14: switch (code) { case 0xF0: state = E1_14_77_E1_F0_14_F0; break; default: state = INIT; } break; case E1_14_77_E1_F0_14_F0: switch (code) { case 0x77: matrix_make(PAUSE); state = INIT; break; default: state = INIT; } break; default: state = INIT; } phex(code); } return 1; }
uint8_t matrix_scan(void) { // scan code reading states static enum { INIT, E0, E0_2A, E0_2A_E0, E0_B7, E0_B7_E0, // print screen E1, E1_1D, E1_1D_45, E1_1D_45_E1, E1_1D_45_E1_9D, // pause } state = INIT; is_modified = false; // 'pseudo break code' hack if (matrix_is_on(ROW(PAUSE), COL(PAUSE))) { matrix_break(PAUSE); } uint8_t code = xt_host_recv(); switch (state) { case INIT: switch (code) { case 0xE0: state = E0; break; case 0xE1: state = E1; break; default: // normal key make if (code < 0x80 && code != 0x00) { xprintf("make: %X\r\n", code); matrix_make(code); } else if (code > 0x80 && code < 0xFF && code != 0x00) { xprintf("break %X\r\n", code); matrix_break(code - 0x80); } state = INIT; } break; case E0: // E0-Prefixed switch (code) { //move these codes to unused places on the matrix case 0x2A: state = E0_2A; break; case 0xB7: state = E0_B7; break; default: if (code < 0x80 && code != 0x00) { matrix_make(move_codes(code)); } else if (code > 0x80 && code < 0xFF && code != 0x00) { matrix_break(move_codes(code - 0x80)); } state = INIT; } break; case E0_2A: if(code == 0xE0) state = E0_2A_E0; else state = INIT; break; case E0_2A_E0: if(code == 0x37) matrix_make(PRINT_SCREEN); else state = INIT; break; case E0_B7: if(code == 0xE0) state = E0_B7; else state = INIT; break; case E0_B7_E0: if(code == 0xAA) matrix_break(PRINT_SCREEN); else state = INIT; break; case E1: if (code == 0x1D) state = E1_1D; else state = INIT; break; case E1_1D: if(code == 0x45) state = E1_1D_45; else state = INIT; break; case E1_1D_45: if(code == 0xE1) state = E1_1D_45_E1; else state = INIT; break; case E1_1D_45_E1: if(code == 0x9D) state = E1_1D_45_E1_9D; else state = INIT; break; case E1_1D_45_E1_9D: if(code == 0xC5) matrix_make(PAUSE); else state = INIT; break; default: state = INIT; } return 1; }