keyboard: Add preliminary keyboard controller

This commit is contained in:
Markus Koch 2018-05-05 22:28:43 +02:00
parent 9a67dfb1b2
commit f2e24dc5b1
8 changed files with 462 additions and 0 deletions

1
keyboard/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build-*

4
keyboard/avr/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
*.hex
*.o
*.pro.user

26
keyboard/avr/Makefile Normal file
View File

@ -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

View File

@ -0,0 +1,9 @@
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
INCLUDEPATH += /usr/avr/include
SOURCES += \
main.c

257
keyboard/avr/main.c Normal file
View File

@ -0,0 +1,257 @@
#include <avr/io.h>
#include <util/delay.h>
#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);
}
}
}

View File

@ -0,0 +1,3 @@
*.o
*.user
main

View File

@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 2.8)
project(keyboard-test-uart)
add_executable(${PROJECT_NAME} "main.c")

View File

@ -0,0 +1,158 @@
#include <stdio.h>
#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;
}