From f2e24dc5b161c6f1b3535f6f36e9994e0ee8bc09 Mon Sep 17 00:00:00 2001 From: Markus Koch Date: Sat, 5 May 2018 22:28:43 +0200 Subject: [PATCH] keyboard: Add preliminary keyboard controller --- keyboard/.gitignore | 1 + keyboard/avr/.gitignore | 4 + keyboard/avr/Makefile | 26 +++ keyboard/avr/keyboard-controller.pro | 9 + keyboard/avr/main.c | 257 +++++++++++++++++++++ keyboard/keyboard-test-uart/.gitignore | 3 + keyboard/keyboard-test-uart/CMakeLists.txt | 4 + keyboard/keyboard-test-uart/main.c | 158 +++++++++++++ 8 files changed, 462 insertions(+) create mode 100644 keyboard/.gitignore create mode 100644 keyboard/avr/.gitignore create mode 100644 keyboard/avr/Makefile create mode 100644 keyboard/avr/keyboard-controller.pro create mode 100644 keyboard/avr/main.c create mode 100644 keyboard/keyboard-test-uart/.gitignore create mode 100644 keyboard/keyboard-test-uart/CMakeLists.txt create mode 100644 keyboard/keyboard-test-uart/main.c diff --git a/keyboard/.gitignore b/keyboard/.gitignore new file mode 100644 index 0000000..dd07bff --- /dev/null +++ b/keyboard/.gitignore @@ -0,0 +1 @@ +build-* diff --git a/keyboard/avr/.gitignore b/keyboard/avr/.gitignore new file mode 100644 index 0000000..4402f46 --- /dev/null +++ b/keyboard/avr/.gitignore @@ -0,0 +1,4 @@ +*.hex +*.o +*.pro.user + diff --git a/keyboard/avr/Makefile b/keyboard/avr/Makefile new file mode 100644 index 0000000..789172f --- /dev/null +++ b/keyboard/avr/Makefile @@ -0,0 +1,26 @@ +MCU=atmega8 +CFLAGS=-g -Wall -mcall-prologues -mmcu=$(MCU) -Os -DF_CPU=8000000 +LDFLAGS=-Wl,-gc-sections -Wl,-relax +CC=avr-gcc +TARGET=main +OBJECT_FILES=main.o + +all: $(TARGET).hex + +clean: + rm -f *.o *.hex *.obj *.hex + +%.hex: %.obj + avr-objcopy -R .eeprom -O ihex $< $@ + +%.obj: $(OBJECT_FILES) + $(CC) $(CFLAGS) $(OBJECT_FILES) $(LDFLAGS) -o $@ + +program: $(TARGET).hex + avrdude -p $(MCU) -c usbasp -U flash:w:$(TARGET).hex + #avrdude -p $(MCU) -P /dev/ttyUSB1 -c arduino -b 57600 -U flash:w:$(TARGET).hex + +fuse: + avrdude -p m8 -c usbasp -U lfuse:w:0xe4:m -U hfuse:w:0xd9:m + +.phony: program fuse diff --git a/keyboard/avr/keyboard-controller.pro b/keyboard/avr/keyboard-controller.pro new file mode 100644 index 0000000..4e0df99 --- /dev/null +++ b/keyboard/avr/keyboard-controller.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +CONFIG += console +CONFIG -= app_bundle +CONFIG -= qt + +INCLUDEPATH += /usr/avr/include + +SOURCES += \ + main.c diff --git a/keyboard/avr/main.c b/keyboard/avr/main.c new file mode 100644 index 0000000..db62b5c --- /dev/null +++ b/keyboard/avr/main.c @@ -0,0 +1,257 @@ +#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); + } + } +} diff --git a/keyboard/keyboard-test-uart/.gitignore b/keyboard/keyboard-test-uart/.gitignore new file mode 100644 index 0000000..20ee59c --- /dev/null +++ b/keyboard/keyboard-test-uart/.gitignore @@ -0,0 +1,3 @@ +*.o +*.user +main diff --git a/keyboard/keyboard-test-uart/CMakeLists.txt b/keyboard/keyboard-test-uart/CMakeLists.txt new file mode 100644 index 0000000..385057c --- /dev/null +++ b/keyboard/keyboard-test-uart/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required(VERSION 2.8) + +project(keyboard-test-uart) +add_executable(${PROJECT_NAME} "main.c") diff --git a/keyboard/keyboard-test-uart/main.c b/keyboard/keyboard-test-uart/main.c new file mode 100644 index 0000000..f4ca64d --- /dev/null +++ b/keyboard/keyboard-test-uart/main.c @@ -0,0 +1,158 @@ +#include + +#define DN 0 +#define UP 1 + +static char *keycode_table[] = { + "NULL", + "ESC", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0", + "-", + "=", + "BS", + "TAB", + "Q", + "W", + "E", + "R", + "T", + "Y", + "U", + "I", + "O", + "P", + "[", + "]", + "ENTER", + "L CTRL", + "A", + "S", + "D", + "F", + "G", + "H", + "J", + "K", + "L", + ";", + "'", + "`", + "L SHIFT", + "\\", + "Z", + "X", + "C", + "V", + "B", + "N", + "M", + ",", + ".", + "/", + "R SHIFT", + "*", + "L ALT", + "SPACE", + "CAPS LOCK", + "F1", + "F2", + "F3", + "F4", + "F5", + "F6", + "F7", + "F8", + "F9", + "F10", + "NUM LOCK", + "SCROLL LOCK", + "HOME 7", + "UP 8", + "PGUP 9", + "-", + "LEFT 4", + "KP 5", + "RT ARROW 6", + "+", + "END 1", + "DOWN 2", + "PGDN 3", + "INS", + "DEL", + "84", + "85", + "86", + "F11", + "F12", + "89", + "90", + "91", + "92", + "93", + "94", + "95", + "R ENTER", + "R CTRL", + "/", + "PRT SCR", + "R ALT", + "101", + "Home", + "Up", + "PgUp", + "Left", + "Right", + "End", + "Down", + "PgDn", + "Insert", + "Del", + "112", + "113", + "114", + "115", + "116", + "117", + "118", + "Pause" +}; + +int main() +{ + FILE *f; + char c; + int ev = 0; + + f = fopen("/dev/ttyUSB1", "rwb"); + + if (f) { + while (1) { + c = getc(f); + + if (c < 0) { + c += 128; + ev = DN; + } else { + ev = UP; + } + + printf("Key %3d (%s) %s\n", + c, keycode_table[c], (ev == UP ? "UP" : "DOWN")); + } + + fclose(f); + } else { + fprintf(stderr, "Error: Could not open serial device."); + } + + return 0; +}