#include #include #define MATRIX_X(t) t##B #define MATRIX_Y1(t) t##C #define MATRIX_Y2(t) t##D #define MATRIX_Y_SPLIT 6 #define MATRIX_Y2_DELTA (-1) #define MASK_Y1 0b00111111 #define MASK_Y2 0b11100000 #define DELAY_ROW_SWITCH() _delay_ms(1) //_delay_us(1) #define BAUDRATE 9600 /* Keycode from include/linux/input.h */ #define KEY_RESERVED 0 #define KEY_ESC 1 #define KEY_1 2 #define KEY_2 3 #define KEY_3 4 #define KEY_4 5 #define KEY_5 6 #define KEY_6 7 #define KEY_7 8 #define KEY_8 9 #define KEY_9 10 #define KEY_0 11 #define KEY_MINUS 12 #define KEY_EQUAL 13 #define KEY_BACKSPACE 14 #define KEY_TAB 15 #define KEY_Q 16 #define KEY_W 17 #define KEY_E 18 #define KEY_R 19 #define KEY_T 20 #define KEY_Y 21 #define KEY_U 22 #define KEY_I 23 #define KEY_O 24 #define KEY_P 25 #define KEY_LEFTBRACE 26 #define KEY_RIGHTBRACE 27 #define KEY_ENTER 28 #define KEY_LEFTCTRL 29 #define KEY_A 30 #define KEY_S 31 #define KEY_D 32 #define KEY_F 33 #define KEY_G 34 #define KEY_H 35 #define KEY_J 36 #define KEY_K 37 #define KEY_L 38 #define KEY_SEMICOLON 39 #define KEY_APOSTROPHE 40 #define KEY_GRAVE 41 #define KEY_LEFTSHIFT 42 #define KEY_BACKSLASH 43 #define KEY_Z 44 #define KEY_X 45 #define KEY_C 46 #define KEY_V 47 #define KEY_B 48 #define KEY_N 49 #define KEY_M 50 #define KEY_COMMA 51 #define KEY_DOT 52 #define KEY_SLASH 53 #define KEY_RIGHTSHIFT 54 #define KEY_KPASTERISK 55 #define KEY_LEFTALT 56 #define KEY_SPACE 57 #define KEY_CAPSLOCK 58 #define KEY_F1 59 #define KEY_F2 60 #define KEY_F3 61 #define KEY_F4 62 #define KEY_F5 63 #define KEY_F6 64 #define KEY_F7 65 #define KEY_F8 66 #define KEY_F9 67 #define KEY_F10 68 #define KEY_NUMLOCK 69 #define KEY_SCROLLLOCK 70 #define KEY_KP7 71 #define KEY_KP8 72 #define KEY_KP9 73 #define KEY_KPMINUS 74 #define KEY_KP4 75 #define KEY_KP5 76 #define KEY_KP6 77 #define KEY_KPPLUS 78 #define KEY_KP1 79 #define KEY_KP2 80 #define KEY_KP3 81 #define KEY_KP0 82 #define KEY_KPDOT 83 #define KEY_ZENKAKUHANKAKU 85 #define KEY_102ND 86 #define KEY_F11 87 #define KEY_F12 88 #define KEY_RO 89 #define KEY_KATAKANA 90 #define KEY_HIRAGANA 91 #define KEY_HENKAN 92 #define KEY_KATAKANAHIRAGANA 93 #define KEY_MUHENKAN 94 #define KEY_KPJPCOMMA 95 #define KEY_KPENTER 96 #define KEY_RIGHTCTRL 97 #define KEY_KPSLASH 98 #define KEY_SYSRQ 99 #define KEY_RIGHTALT 100 #define KEY_LINEFEED 101 #define KEY_HOME 102 #define KEY_UP 103 #define KEY_PAGEUP 104 #define KEY_LEFT 105 #define KEY_RIGHT 106 #define KEY_END 107 #define KEY_DOWN 108 #define KEY_PAGEDOWN 109 #define KEY_INSERT 110 #define KEY_DELETE 111 #define KEY_MACRO 112 #define KEY_MUTE 113 #define KEY_VOLUMEDOWN 114 #define KEY_VOLUMEUP 115 #define KEY_POWER 116 /* SC System Power Down */ #define KEY_KPEQUAL 117 #define KEY_KPPLUSMINUS 118 #define KEY_PAUSE 119 #define KEY_SCALE 120 /* AL Compiz Scale (Expose) */ #define KEY_KPCOMMA 121 #define KEY_HANGEUL 122 #define KEY_HANGUEL KEY_HANGEUL #define KEY_HANJA 123 #define KEY_YEN 124 #define KEY_LEFTMETA 125 #define KEY_RIGHTMETA 126 #define KEY_COMPOSE 127 #define SKEY_FN 255 #define KEYCODE_FN 127 /* * Special keys: * * Control : Code * * Alt : Del * * FN : Delword * * Del : Inhalt * * ` : SM * * Escape : Storno * * Print : Menu * * Pause : GS End * * FN Keymap: * * F-Keys : Number keys for F1-F10, and ? and ` for F11-F12 * * Home / End / PGUP / PGDN : Arrow keys * * Sys rq : Print */ static uint8_t keycode_translation_matrix[2][9][8] = { { /* Standard keymap */ {KEY_5, KEY_6, KEY_R, KEY_T, KEY_C, KEY_F, KEY_UP, 0}, {KEY_8, KEY_7, KEY_Y, KEY_H, KEY_G, KEY_V, KEY_PAUSE, 0}, {KEY_1, KEY_2, KEY_Q, KEY_Z, KEY_A, KEY_S, KEY_CAPSLOCK, 0}, {KEY_9, KEY_J, KEY_I, KEY_U, KEY_B, KEY_N, KEY_RIGHT, 0}, {KEY_MINUS, KEY_0, KEY_P, KEY_O, KEY_M, KEY_COMMA, KEY_SYSRQ, 0}, {KEY_DELETE, KEY_SEMICOLON, KEY_RIGHTBRACE, KEY_LEFTBRACE, KEY_LEFT, KEY_DOWN, 0, KEY_LEFTCTRL}, {KEY_4, KEY_3, KEY_W, KEY_E, KEY_D, KEY_X, KEY_TAB, 0}, {KEY_GRAVE, KEY_ESC, KEY_ENTER, KEY_BACKSPACE, KEY_LEFTALT, SKEY_FN, KEY_LEFTSHIFT, KEY_SPACE}, {KEY_EQUAL, KEY_L, KEY_BACKSLASH, KEY_K, KEY_DOT, KEY_SLASH, 0, KEY_APOSTROPHE} }, { /* FN keymap */ {KEY_F5, KEY_F6, KEY_R, KEY_T, KEY_C, KEY_F, KEY_PAGEUP, 0}, {KEY_F8, KEY_F7, KEY_Z, KEY_H, KEY_G, KEY_V, KEY_PAUSE, 0}, {KEY_F1, KEY_F2, KEY_Q, KEY_102ND, KEY_A, KEY_S, KEY_CAPSLOCK, 0}, {KEY_F9, KEY_J, KEY_I, KEY_U, KEY_B, KEY_N, KEY_END, 0}, {KEY_F11, KEY_F10, KEY_P, KEY_O, KEY_M, KEY_COMMA, KEY_SYSRQ, 0}, {KEY_DELETE, KEY_SEMICOLON, KEY_RIGHTBRACE, KEY_LEFTBRACE, KEY_HOME, KEY_PAGEDOWN, 0, KEY_LEFTCTRL}, {KEY_F4, KEY_F3, KEY_W, KEY_E, KEY_D, KEY_X, KEY_TAB, 0}, {KEY_GRAVE, KEY_ESC, KEY_ENTER, KEY_BACKSPACE, KEY_LEFTALT, SKEY_FN, KEY_LEFTSHIFT, KEY_SPACE}, {KEY_F12, KEY_L, KEY_BACKSLASH, KEY_K, KEY_DOT, KEY_SLASH, 0, KEY_APOSTROPHE} } }; uint8_t matrix_state_last_vector[9] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint8_t fn_active = 0; void process_key_event(uint8_t col, uint8_t row, uint8_t state) { char c; uint8_t keycode; keycode = keycode_translation_matrix[fn_active][col][row]; if (keycode == SKEY_FN) { fn_active = state; #ifdef KEYCODE_FN while (!(UCSRA & (1 << UDRE))); UDR = KEYCODE_FN | (state << 7); #endif } else { c = keycode | (state << 7); while (!(UCSRA & (1 << UDRE))); UDR = c; } } void matrix_scan_col(uint8_t col) { uint8_t matrix_state; uint8_t row; uint8_t bit; if (col < MATRIX_Y_SPLIT) { MATRIX_Y2(DDR) &= ~(MASK_Y2); MATRIX_Y1(DDR) = (MATRIX_Y1(DDR) & ~(MASK_Y1)) | (1 << col); } else { MATRIX_Y2(DDR) = (MATRIX_Y2(DDR) & ~(MASK_Y2)) | (1 << (col + MATRIX_Y2_DELTA)); MATRIX_Y1(DDR) &= ~(MASK_Y1); } DELAY_ROW_SWITCH(); matrix_state = MATRIX_X(PIN); for (row = 0; row < 8; ++row) { bit = (1 << row); if ((matrix_state ^ matrix_state_last_vector[col]) & bit) { process_key_event(col, row, !(matrix_state & bit)); } } matrix_state_last_vector[col] = matrix_state; } int main() { int col; /* Config I/O */ MATRIX_X(DDR) = 0; /* Columns as input */ MATRIX_X(PORT) = 0xFF; /* Enable pull-ups for columns */ MATRIX_Y1(DDR) &= ~MASK_Y1; /* Disable rows */ MATRIX_Y2(DDR) &= ~MASK_Y2; /* Disable rows */ MATRIX_Y1(PORT) &= ~MASK_Y1; /* Pull row low when selected */ MATRIX_Y2(PORT) &= ~MASK_Y2; /* Pull row low when selected */ UCSRB = (1 << TXEN); UBRRH = ((((F_CPU / BAUDRATE) / 16) - 1) >> 8); UBRRL = (((F_CPU / BAUDRATE) / 16) - 1); fn_active = 0; /* Continuously scan matrix */ while (1) { for (col = 0; col < 9; ++col) { matrix_scan_col(col); } } }