#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 #define UBRR 51 // (F_CPU / BAUDRATE) / 32 /* 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 static uint8_t keycode_translation_matrix[2][9][8] = { { /* Standard keymap */ {KEY_4, KEY_3, 3, 4, 5, 6, 7, 8}, {KEY_5, KEY_6, 13, 14, 15, 16, 17, 18}, {KEY_8, KEY_7, 23, 24, 25, 26, 27, 28}, {KEY_1, KEY_2, 33, 34, 35, 36, 37, 38}, {KEY_9, 42, 43, 44, 45, 46, 47, 48}, {51, KEY_0, 53, 54, 55, 56, 57, 58}, {61, 62, 63, 64, 65, 66, 67, 68}, {71, 72, 73, 74, 75, SKEY_FN, 77, 78}, {81, 82, 83, 84, 85, 86, 87, 88} }, { /* FN keymap */ { 1, 2, 3, 4, 5, 6, 7, 8}, {11, 12, 13, 14, 15, 16, 17, 18}, {21, 22, 23, 24, 25, 26, 27, 28}, {31, 32, 33, 34, 35, 36, 37, 38}, {41, 42, 43, 44, 45, 46, 47, 48}, {51, 52, 53, 54, 55, 56, 57, 58}, {61, 62, 63, 64, 65, 66, 67, 68}, {71, 72, 73, 74, 75, SKEY_FN, 77, 78}, {81, 82, 83, 84, 85, 86, 87, 88} } }; 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 = (UBRR >> 8) & 0xFF; UBRRL = UBRR & 0xFF; fn_active = 0; /* Continuously scan matrix */ while (1) { for (col = 0; col < 9; ++col) { matrix_scan_col(col); } } }