2018-05-05 22:28:43 +02:00
|
|
|
#include <avr/io.h>
|
|
|
|
#include <util/delay.h>
|
2019-12-27 23:13:51 +01:00
|
|
|
#include <avr/interrupt.h>
|
2018-05-05 22:28:43 +02:00
|
|
|
|
|
|
|
#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)
|
|
|
|
|
2019-11-10 19:44:14 +01:00
|
|
|
#define BAUDRATE 19200
|
2018-05-05 22:28:43 +02:00
|
|
|
|
2020-01-03 16:46:14 +01:00
|
|
|
#define PRINTER_PACKET_SIZE 6
|
2019-12-27 23:13:51 +01:00
|
|
|
|
2018-05-05 22:28:43 +02:00
|
|
|
/* 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
|
2019-11-01 19:52:44 +01:00
|
|
|
// #define KEYCODE_FN 127
|
2018-05-05 22:28:43 +02:00
|
|
|
|
2019-10-26 22:31:05 +02:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
*/
|
2018-05-05 22:28:43 +02:00
|
|
|
static uint8_t keycode_translation_matrix[2][9][8] = {
|
|
|
|
{ /* Standard keymap */
|
2019-10-26 22:31:05 +02:00
|
|
|
{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},
|
2019-10-26 22:47:36 +02:00
|
|
|
{KEY_MINUS, KEY_0, KEY_P, KEY_O, KEY_M, KEY_COMMA, KEY_SYSRQ, 0},
|
2019-10-26 22:31:05 +02:00
|
|
|
{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}
|
2018-05-05 22:28:43 +02:00
|
|
|
},
|
|
|
|
{ /* FN keymap */
|
2019-10-26 22:31:05 +02:00
|
|
|
{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}
|
2018-05-05 22:28:43 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
uint8_t matrix_state_last_vector[9] = {0xFF, 0xFF, 0xFF, 0xFF,
|
|
|
|
0xFF, 0xFF, 0xFF, 0xFF,
|
|
|
|
0xFF};
|
|
|
|
|
|
|
|
uint8_t fn_active = 0;
|
|
|
|
|
2019-12-27 23:13:51 +01:00
|
|
|
/* UART forwarding */
|
|
|
|
#define RING_BUFFER_SIZE 256 // Important: must be 256 atm, when changed, you need to change code handling print_buffer_*.
|
|
|
|
volatile char ring_buffer[RING_BUFFER_SIZE];
|
|
|
|
volatile uint8_t ring_buffer_wr = 0;
|
|
|
|
volatile uint8_t ring_buffer_rd = 0;
|
|
|
|
#define UART_BYTE_READY (UCSRA & (1 << RXC))
|
|
|
|
|
2019-11-01 19:52:10 +01:00
|
|
|
void uart_putc(char c)
|
|
|
|
{
|
|
|
|
while (!(UCSRA & (1 << UDRE)));
|
|
|
|
UDR = c;
|
|
|
|
}
|
|
|
|
|
2019-12-27 23:13:51 +01:00
|
|
|
ISR(USART_RXC_vect)
|
|
|
|
{
|
|
|
|
if (UCSRA & (1 << RXC)) {
|
2020-01-03 16:46:14 +01:00
|
|
|
ring_buffer[ring_buffer_wr] = UDR;
|
|
|
|
ring_buffer_wr++; // WARNING: No overflow protection
|
2019-12-27 23:13:51 +01:00
|
|
|
// Will auto wrap at 256; print_buffer_wr = print_buffer_wr % PRINT_BUFFER_SIZE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void uart_forward_packets()
|
|
|
|
{
|
|
|
|
uint8_t size;
|
|
|
|
uint8_t i;
|
|
|
|
|
|
|
|
if (ring_buffer_wr > ring_buffer_rd)
|
|
|
|
size = ring_buffer_wr - ring_buffer_rd;
|
|
|
|
else
|
|
|
|
size = ring_buffer_rd - ring_buffer_wr;
|
|
|
|
|
2020-01-03 16:46:14 +01:00
|
|
|
if (size >= PRINTER_PACKET_SIZE) {
|
|
|
|
/* check sync */
|
|
|
|
if (ring_buffer[ring_buffer_rd] != ((char)0xFF)) {
|
|
|
|
ring_buffer_rd++; /* Drop wrong sync header */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (ring_buffer[ring_buffer_rd + 1] != ((char)0xAA)) {
|
|
|
|
ring_buffer_rd += 1; /* Drop wrong app header */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-12-27 23:13:51 +01:00
|
|
|
for (i = 0; i < PRINTER_PACKET_SIZE; ++i) {
|
2020-01-03 16:46:14 +01:00
|
|
|
uart_putc(ring_buffer[ring_buffer_rd]); // Will auto wrap at 256
|
|
|
|
ring_buffer_rd++;
|
2019-12-27 23:13:51 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-05 22:28:43 +02:00
|
|
|
void process_key_event(uint8_t col, uint8_t row, uint8_t state)
|
|
|
|
{
|
|
|
|
char c;
|
|
|
|
uint8_t keycode;
|
2019-11-01 19:52:10 +01:00
|
|
|
int event = 0;
|
2018-05-05 22:28:43 +02:00
|
|
|
|
|
|
|
keycode = keycode_translation_matrix[fn_active][col][row];
|
|
|
|
|
|
|
|
if (keycode == SKEY_FN) {
|
|
|
|
fn_active = state;
|
|
|
|
#ifdef KEYCODE_FN
|
2019-11-01 19:52:10 +01:00
|
|
|
c = KEYCODE_FN | (state << 7);
|
|
|
|
event = 1;
|
2018-05-05 22:28:43 +02:00
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
c = keycode | (state << 7);
|
2019-11-01 19:52:10 +01:00
|
|
|
event = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event) {
|
|
|
|
uart_putc(0xFF);
|
|
|
|
uart_putc(0x55);
|
|
|
|
uart_putc(c);
|
2018-05-05 22:28:43 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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 */
|
2019-12-27 23:13:51 +01:00
|
|
|
|
|
|
|
/* Set up UART */
|
|
|
|
UCSRA = 0;
|
|
|
|
UCSRB = (1 << TXEN) | (1 << RXEN) | (1 << RXCIE);
|
|
|
|
UCSRC = 0;
|
2019-10-26 22:38:51 +02:00
|
|
|
UBRRH = ((((F_CPU / BAUDRATE) / 16) - 1) >> 8);
|
|
|
|
UBRRL = (((F_CPU / BAUDRATE) / 16) - 1);
|
2018-05-05 22:28:43 +02:00
|
|
|
|
|
|
|
fn_active = 0;
|
|
|
|
|
2019-12-27 23:13:51 +01:00
|
|
|
sei();
|
|
|
|
|
2018-05-05 22:28:43 +02:00
|
|
|
/* Continuously scan matrix */
|
|
|
|
while (1) {
|
|
|
|
for (col = 0; col < 9; ++col) {
|
|
|
|
matrix_scan_col(col);
|
|
|
|
}
|
2019-12-27 23:13:51 +01:00
|
|
|
uart_forward_packets();
|
2018-05-05 22:28:43 +02:00
|
|
|
}
|
|
|
|
}
|