Initial commit
This commit is contained in:
commit
bec3721e46
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
.build/
|
||||||
|
.clangd
|
||||||
|
compile_commands.json
|
39
Makefile
Normal file
39
Makefile
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
OBJCOPY = avr-objcopy
|
||||||
|
CC = avr-gcc
|
||||||
|
BUILD = .build
|
||||||
|
TARGET = main
|
||||||
|
|
||||||
|
OPT = s
|
||||||
|
CFLAGS = -Wall -Wextra -std=c18 -O$(OPT) -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects -mmcu=atmega328p -DF_CPU=16000000L -Iinclude
|
||||||
|
LDFLAGS = -Wall -Wextra -O$(OPT) -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p
|
||||||
|
|
||||||
|
SRC = \
|
||||||
|
src/main.c \
|
||||||
|
src/keyboard.c \
|
||||||
|
src/fifo.c \
|
||||||
|
src/scancode.c
|
||||||
|
|
||||||
|
OBJ = $(addprefix $(BUILD)/, $(notdir $(SRC:.c=.o)))
|
||||||
|
vpath %.c $(sort $(dir $(SRC)))
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
all: $(BUILD) $(BUILD)/$(TARGET).bin
|
||||||
|
|
||||||
|
%.hex: %.elf | $(BUILD)
|
||||||
|
$(OBJCOPY) -O ihex -R .eeprom $< $@
|
||||||
|
|
||||||
|
%.bin: %.hex | $(BUILD)
|
||||||
|
$(OBJCOPY) -I ihex -O binary $< $@
|
||||||
|
|
||||||
|
$(BUILD)/%.o: %.c Makefile | $(BUILD)
|
||||||
|
$(CC) -c $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
|
$(BUILD)/$(TARGET).elf: $(OBJ) Makefile
|
||||||
|
$(CC) $(LDFLAGS) $(OBJ) -o $@
|
||||||
|
|
||||||
|
$(BUILD):
|
||||||
|
mkdir $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -fr $(BUILD)
|
147
generate_scancode.py
Normal file
147
generate_scancode.py
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
scancode = [[0]*128, [0]*128]
|
||||||
|
|
||||||
|
scancode[0][0x0D] = '\t'
|
||||||
|
scancode[0][0x0E] = '`'
|
||||||
|
scancode[0][0x15] = 'q'
|
||||||
|
scancode[0][0x16] = '1'
|
||||||
|
scancode[0][0x1A] = 'z'
|
||||||
|
scancode[0][0x1B] = 's'
|
||||||
|
scancode[0][0x1C] = 'a'
|
||||||
|
scancode[0][0x1D] = 'w'
|
||||||
|
scancode[0][0x1E] = '2'
|
||||||
|
scancode[0][0x21] = 'c'
|
||||||
|
scancode[0][0x22] = 'x'
|
||||||
|
scancode[0][0x23] = 'd'
|
||||||
|
scancode[0][0x24] = 'e'
|
||||||
|
scancode[0][0x25] = '4'
|
||||||
|
scancode[0][0x26] = '3'
|
||||||
|
scancode[0][0x29] = ' '
|
||||||
|
scancode[0][0x2A] = 'v'
|
||||||
|
scancode[0][0x2B] = 'f'
|
||||||
|
scancode[0][0x2C] = 't'
|
||||||
|
scancode[0][0x2D] = 'r'
|
||||||
|
scancode[0][0x2E] = '5'
|
||||||
|
scancode[0][0x31] = 'n'
|
||||||
|
scancode[0][0x32] = 'b'
|
||||||
|
scancode[0][0x33] = 'h'
|
||||||
|
scancode[0][0x34] = 'g'
|
||||||
|
scancode[0][0x35] = 'y'
|
||||||
|
scancode[0][0x36] = '6'
|
||||||
|
scancode[0][0x3A] = 'm'
|
||||||
|
scancode[0][0x3B] = 'j'
|
||||||
|
scancode[0][0x3C] = 'u'
|
||||||
|
scancode[0][0x3D] = '7'
|
||||||
|
scancode[0][0x3E] = '8'
|
||||||
|
scancode[0][0x41] = ','
|
||||||
|
scancode[0][0x42] = 'k'
|
||||||
|
scancode[0][0x43] = 'i'
|
||||||
|
scancode[0][0x44] = 'o'
|
||||||
|
scancode[0][0x45] = '0'
|
||||||
|
scancode[0][0x46] = '9'
|
||||||
|
scancode[0][0x49] = '.'
|
||||||
|
scancode[0][0x4A] = '/'
|
||||||
|
scancode[0][0x4B] = 'l'
|
||||||
|
scancode[0][0x4C] = ';'
|
||||||
|
scancode[0][0x4D] = 'p'
|
||||||
|
scancode[0][0x4E] = '-'
|
||||||
|
scancode[0][0x52] = '\''
|
||||||
|
scancode[0][0x54] = '['
|
||||||
|
scancode[0][0x55] = '='
|
||||||
|
scancode[0][0x5A] = '\r'
|
||||||
|
scancode[0][0x5B] = ']'
|
||||||
|
scancode[0][0x5D] = '\\'
|
||||||
|
scancode[0][0x66] = 0x08
|
||||||
|
scancode[0][0x69] = '1'
|
||||||
|
scancode[0][0x6B] = '2'
|
||||||
|
scancode[0][0x6C] = '7'
|
||||||
|
scancode[0][0x70] = '0'
|
||||||
|
scancode[0][0x71] = '.'
|
||||||
|
scancode[0][0x72] = '2'
|
||||||
|
scancode[0][0x73] = '5'
|
||||||
|
scancode[0][0x74] = '6'
|
||||||
|
scancode[0][0x75] = '8'
|
||||||
|
scancode[0][0x76] = 0x1B
|
||||||
|
scancode[0][0x79] = '+'
|
||||||
|
scancode[0][0x7A] = '3'
|
||||||
|
scancode[0][0x7B] = '-'
|
||||||
|
scancode[0][0x7C] = '*'
|
||||||
|
scancode[0][0x7D] = '9'
|
||||||
|
|
||||||
|
scancode[1][0x0D] = '\t'
|
||||||
|
scancode[1][0x0E] = '~'
|
||||||
|
scancode[1][0x15] = 'Q'
|
||||||
|
scancode[1][0x16] = '!'
|
||||||
|
scancode[1][0x1A] = 'Z'
|
||||||
|
scancode[1][0x1B] = 'S'
|
||||||
|
scancode[1][0x1C] = 'A'
|
||||||
|
scancode[1][0x1D] = 'W'
|
||||||
|
scancode[1][0x1E] = '@'
|
||||||
|
scancode[1][0x21] = 'C'
|
||||||
|
scancode[1][0x22] = 'X'
|
||||||
|
scancode[1][0x23] = 'D'
|
||||||
|
scancode[1][0x24] = 'E'
|
||||||
|
scancode[1][0x25] = '$'
|
||||||
|
scancode[1][0x26] = '#'
|
||||||
|
scancode[1][0x29] = ' '
|
||||||
|
scancode[1][0x2A] = 'V'
|
||||||
|
scancode[1][0x2B] = 'F'
|
||||||
|
scancode[1][0x2C] = 'T'
|
||||||
|
scancode[1][0x2D] = 'R'
|
||||||
|
scancode[1][0x2E] = '%'
|
||||||
|
scancode[1][0x31] = 'N'
|
||||||
|
scancode[1][0x32] = 'B'
|
||||||
|
scancode[1][0x33] = 'H'
|
||||||
|
scancode[1][0x34] = 'G'
|
||||||
|
scancode[1][0x35] = 'Y'
|
||||||
|
scancode[1][0x36] = '^'
|
||||||
|
scancode[1][0x3A] = 'M'
|
||||||
|
scancode[1][0x3B] = 'J'
|
||||||
|
scancode[1][0x3C] = 'U'
|
||||||
|
scancode[1][0x3D] = '&'
|
||||||
|
scancode[1][0x3E] = '*'
|
||||||
|
scancode[1][0x41] = '<'
|
||||||
|
scancode[1][0x42] = 'K'
|
||||||
|
scancode[1][0x43] = 'I'
|
||||||
|
scancode[1][0x44] = 'O'
|
||||||
|
scancode[1][0x45] = ')'
|
||||||
|
scancode[1][0x46] = '('
|
||||||
|
scancode[1][0x49] = '>'
|
||||||
|
scancode[1][0x4A] = '?'
|
||||||
|
scancode[1][0x4B] = 'L'
|
||||||
|
scancode[1][0x4C] = ':'
|
||||||
|
scancode[1][0x4D] = 'P'
|
||||||
|
scancode[1][0x4E] = '_'
|
||||||
|
scancode[1][0x52] = '"'
|
||||||
|
scancode[1][0x54] = '{'
|
||||||
|
scancode[1][0x55] = '+'
|
||||||
|
scancode[1][0x5A] = '\r'
|
||||||
|
scancode[1][0x5B] = '}'
|
||||||
|
scancode[1][0x5D] = '|'
|
||||||
|
scancode[1][0x66] = 0X08
|
||||||
|
scancode[1][0x69] = '1'
|
||||||
|
scancode[1][0x6B] = '2'
|
||||||
|
scancode[1][0x6C] = '7'
|
||||||
|
scancode[1][0x70] = '0'
|
||||||
|
scancode[1][0x71] = '.'
|
||||||
|
scancode[1][0x72] = '2'
|
||||||
|
scancode[1][0x73] = '5'
|
||||||
|
scancode[1][0x74] = '6'
|
||||||
|
scancode[1][0x75] = '8'
|
||||||
|
scancode[1][0x76] = 0X1B
|
||||||
|
scancode[1][0x79] = '+'
|
||||||
|
scancode[1][0x7A] = '3'
|
||||||
|
scancode[1][0x7B] = '-'
|
||||||
|
scancode[1][0x7C] = '*'
|
||||||
|
scancode[1][0x7D] = '9'
|
||||||
|
|
||||||
|
print("char scancode[2][128] = {")
|
||||||
|
for i in scancode:
|
||||||
|
print("\t{", end="")
|
||||||
|
for j in i:
|
||||||
|
if (type(j) == str):
|
||||||
|
j = ord(j)
|
||||||
|
print(f"0x{j:02x},", end="")
|
||||||
|
print("},")
|
||||||
|
print("};")
|
19
include/fifo.h
Normal file
19
include/fifo.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef FIFO_h
|
||||||
|
#define FIFO_h
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define FIFO_SIZE 64
|
||||||
|
|
||||||
|
struct FIFO {
|
||||||
|
int head;
|
||||||
|
int tail;
|
||||||
|
int size;
|
||||||
|
uint8_t buffer[FIFO_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
void FIFO_push(volatile struct FIFO* fifo, uint8_t value);
|
||||||
|
uint8_t FIFO_pop(volatile struct FIFO* fifo);
|
||||||
|
int FIFO_size(volatile struct FIFO* fifo);
|
||||||
|
|
||||||
|
#endif
|
15
include/keyboard.h
Normal file
15
include/keyboard.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef KEYBOARD_h
|
||||||
|
#define KEYBOARD_h
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define KEYBOARD_CLK 2
|
||||||
|
#define KEYBOARD_DATA 7
|
||||||
|
|
||||||
|
void send_keyboard_cmd(uint8_t value);
|
||||||
|
void queue_keyboard_cmd(uint8_t value);
|
||||||
|
void send_keyboard_cmd_queue();
|
||||||
|
|
||||||
|
void keyboard_interrupt(void (*callback)(uint8_t));
|
||||||
|
|
||||||
|
#endif
|
9
include/scancode.h
Normal file
9
include/scancode.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef SCANCODE_H
|
||||||
|
#define SCANCODE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void setup_scancode();
|
||||||
|
// uint8_t convert_scancode(uint8_t shift, uint8_t code);
|
||||||
|
|
||||||
|
#endif
|
37
src/fifo.c
Normal file
37
src/fifo.c
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#include "fifo.h"
|
||||||
|
|
||||||
|
void FIFO_push(volatile struct FIFO* fifo, uint8_t value) {
|
||||||
|
if (fifo->size == FIFO_SIZE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fifo->size++;
|
||||||
|
|
||||||
|
if (fifo->size > 1) {
|
||||||
|
fifo->tail++;
|
||||||
|
fifo->tail %= FIFO_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fifo->buffer[fifo->tail] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t FIFO_pop(volatile struct FIFO* fifo) {
|
||||||
|
if (fifo->size == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fifo->size--;
|
||||||
|
|
||||||
|
uint8_t data = fifo->buffer[fifo->head];
|
||||||
|
|
||||||
|
if (fifo->size >= 1) {
|
||||||
|
fifo->head++;
|
||||||
|
fifo->head %= FIFO_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FIFO_size(volatile struct FIFO* fifo) {
|
||||||
|
return fifo->size;
|
||||||
|
}
|
231
src/keyboard.c
Normal file
231
src/keyboard.c
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
#include "keyboard.h"
|
||||||
|
#include "scancode.h"
|
||||||
|
#include "fifo.h"
|
||||||
|
|
||||||
|
volatile struct {
|
||||||
|
struct FIFO buffer;
|
||||||
|
|
||||||
|
uint8_t sending : 1;
|
||||||
|
uint16_t value;
|
||||||
|
uint8_t counter;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t shift : 1;
|
||||||
|
uint8_t caps_lock : 1;
|
||||||
|
uint8_t ctrl : 1;
|
||||||
|
} modifier;
|
||||||
|
|
||||||
|
uint8_t released : 1;
|
||||||
|
} keyboard = {0};
|
||||||
|
|
||||||
|
// Send a command to the keyboard (BLOCKS)
|
||||||
|
void send_keyboard_cmd(uint8_t value) {
|
||||||
|
// Pull clock low
|
||||||
|
DDRD |= (1<<KEYBOARD_CLK);
|
||||||
|
PORTD &= ~(1<<KEYBOARD_CLK);
|
||||||
|
|
||||||
|
_delay_ms(1);
|
||||||
|
|
||||||
|
// Pull data low
|
||||||
|
DDRD |= (1<<KEYBOARD_DATA);
|
||||||
|
PORTD &= ~(1<<KEYBOARD_DATA);
|
||||||
|
|
||||||
|
// Release clock
|
||||||
|
DDRD &= ~(1<<KEYBOARD_CLK);
|
||||||
|
|
||||||
|
keyboard.sending = 1;
|
||||||
|
keyboard.value = value;
|
||||||
|
|
||||||
|
while (keyboard.sending) {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add keyboard command to the queue
|
||||||
|
void queue_keyboard_cmd(uint8_t value) {
|
||||||
|
FIFO_push(&keyboard.buffer, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send queued command
|
||||||
|
void send_keyboard_cmd_queue() {
|
||||||
|
while (FIFO_size(&keyboard.buffer)) {
|
||||||
|
send_keyboard_cmd(FIFO_pop(&keyboard.buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate parity
|
||||||
|
uint8_t parity(uint8_t value) {
|
||||||
|
value ^= value >> 4;
|
||||||
|
value ^= value >> 2;
|
||||||
|
value ^= value >> 1;
|
||||||
|
|
||||||
|
return (~value) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void receive_scancode_bit(void (*callback)(uint8_t)) {
|
||||||
|
keyboard.value |= ((PIND >> KEYBOARD_DATA) & 1) << keyboard.counter;
|
||||||
|
keyboard.counter++;
|
||||||
|
|
||||||
|
// Check that the first bit is 0
|
||||||
|
if (keyboard.counter == 1 && keyboard.value & 1) {
|
||||||
|
keyboard.counter = 0;
|
||||||
|
keyboard.value = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the parity
|
||||||
|
if (keyboard.counter == 10 && parity(keyboard.value >> 1) != ((keyboard.value >> 9) & 1)) {
|
||||||
|
keyboard.counter = 0;
|
||||||
|
keyboard.value = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that the last bit is 1
|
||||||
|
if (keyboard.counter == 11 && !((keyboard.value >> 10) & 1)) {
|
||||||
|
keyboard.counter = 0;
|
||||||
|
keyboard.value = 0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the scancode
|
||||||
|
if (keyboard.counter == 11) {
|
||||||
|
uint8_t value = keyboard.value >> 1;
|
||||||
|
|
||||||
|
keyboard.counter = 0;
|
||||||
|
keyboard.value = 0;
|
||||||
|
|
||||||
|
switch (value) {
|
||||||
|
// Left and right shift
|
||||||
|
case 18:
|
||||||
|
case 89:
|
||||||
|
keyboard.modifier.shift = !keyboard.released;
|
||||||
|
keyboard.released = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Caps lock
|
||||||
|
case 0x58:
|
||||||
|
if (!keyboard.released) {
|
||||||
|
keyboard.modifier.caps_lock = !keyboard.modifier.caps_lock;
|
||||||
|
|
||||||
|
queue_keyboard_cmd(0xED);
|
||||||
|
queue_keyboard_cmd(keyboard.modifier.caps_lock << 2);
|
||||||
|
}
|
||||||
|
keyboard.released = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Left ctrl
|
||||||
|
case 0x14:
|
||||||
|
keyboard.modifier.ctrl = !keyboard.released;
|
||||||
|
keyboard.released = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 240:
|
||||||
|
keyboard.released = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (!keyboard.released) {
|
||||||
|
char c = convert_scancode(keyboard.modifier.shift, value & 127);
|
||||||
|
|
||||||
|
if (keyboard.modifier.caps_lock && !keyboard.modifier.shift && c >= 'a' && c <= 'z') {
|
||||||
|
c -= 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyboard.modifier.ctrl) {
|
||||||
|
switch (c) {
|
||||||
|
case 'c':
|
||||||
|
c = 0x03;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'e':
|
||||||
|
c = 0x05;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
c = 0x10;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'r':
|
||||||
|
c = 0x12;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
c = 0x13;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'u':
|
||||||
|
c = 0x15;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'x':
|
||||||
|
c = 0x18;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'z':
|
||||||
|
c = 0x1A;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
c = 0x00;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c) {
|
||||||
|
callback(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keyboard.released = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_cmd_bit() {
|
||||||
|
if (keyboard.counter == 8) {
|
||||||
|
// Send parity
|
||||||
|
if (parity(keyboard.value)) {
|
||||||
|
PORTD |= (1<<KEYBOARD_DATA);
|
||||||
|
} else {
|
||||||
|
PORTD &= ~(1<<KEYBOARD_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
++keyboard.counter;
|
||||||
|
} else if (keyboard.counter == 9) {
|
||||||
|
// Release data line
|
||||||
|
PORTD &= ~(1<<KEYBOARD_DATA);
|
||||||
|
DDRD &= ~(1<<KEYBOARD_DATA);
|
||||||
|
|
||||||
|
++keyboard.counter;
|
||||||
|
} else if (keyboard.counter == 10) {
|
||||||
|
// Wait for data to go low as ack
|
||||||
|
if (!((PIND >> KEYBOARD_DATA) & 1)) {
|
||||||
|
keyboard.counter = 0;
|
||||||
|
keyboard.value = 0;
|
||||||
|
keyboard.sending = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Send bit
|
||||||
|
if ((keyboard.value >> keyboard.counter) & 1) {
|
||||||
|
PORTD |= (1<<KEYBOARD_DATA);
|
||||||
|
} else {
|
||||||
|
PORTD &= ~(1<<KEYBOARD_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
++keyboard.counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void keyboard_interrupt(void (*callback)(uint8_t)) {
|
||||||
|
if (!keyboard.sending && PIND & (1<<KEYBOARD_CLK)) {
|
||||||
|
receive_scancode_bit(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyboard.sending && !(PIND>>KEYBOARD_CLK & 1)) {
|
||||||
|
send_cmd_bit();
|
||||||
|
}
|
||||||
|
}
|
53
src/main.c
Normal file
53
src/main.c
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "scancode.h"
|
||||||
|
#include "keyboard.h"
|
||||||
|
|
||||||
|
#define CLK 4
|
||||||
|
#define DATA 5
|
||||||
|
|
||||||
|
// Clock the value to 74164
|
||||||
|
void write_value(uint8_t value) {
|
||||||
|
for (uint8_t i = 0; i < 8; ++i) {
|
||||||
|
uint8_t bit = (value >> i) & 1;
|
||||||
|
PORTD |= (1<<CLK) | (bit<<DATA);
|
||||||
|
PORTD &= ~((1<<CLK) | (bit<<DATA));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(PCINT2_vect) {
|
||||||
|
keyboard_interrupt(write_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// Configure pins as output
|
||||||
|
DDRD |= (1<<CLK) | (1<<DATA);
|
||||||
|
|
||||||
|
DDRD &= ~((1<<KEYBOARD_CLK) | (1<<KEYBOARD_DATA));
|
||||||
|
|
||||||
|
// interrupt
|
||||||
|
PCMSK2 |= (1<<PCINT18);
|
||||||
|
PCICR |= (1<<PCIE2);
|
||||||
|
|
||||||
|
write_value(0);
|
||||||
|
|
||||||
|
sei();
|
||||||
|
|
||||||
|
// Wait for the keyboard to be ready
|
||||||
|
_delay_ms(1000);
|
||||||
|
// Reset the keyboard
|
||||||
|
send_keyboard_cmd(0xFF);
|
||||||
|
|
||||||
|
_delay_ms(1000);
|
||||||
|
|
||||||
|
// Set the keyboard repeat rate (and delay)
|
||||||
|
send_keyboard_cmd(0xF3);
|
||||||
|
send_keyboard_cmd(0x00 | (1<<5) | (1<<4));
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
send_keyboard_cmd_queue();
|
||||||
|
}
|
||||||
|
}
|
10
src/scancode.c
Normal file
10
src/scancode.c
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#include "scancode.h"
|
||||||
|
|
||||||
|
char scancode[2][128] = {
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x71,0x31,0x00,0x00,0x00,0x7a,0x73,0x61,0x77,0x32,0x00,0x00,0x63,0x78,0x64,0x65,0x34,0x33,0x00,0x00,0x20,0x76,0x66,0x74,0x72,0x35,0x00,0x00,0x6e,0x62,0x68,0x67,0x79,0x36,0x00,0x00,0x00,0x6d,0x6a,0x75,0x37,0x38,0x00,0x00,0x2c,0x6b,0x69,0x6f,0x30,0x39,0x00,0x00,0x2e,0x2f,0x6c,0x3b,0x70,0x2d,0x00,0x00,0x00,0x27,0x00,0x5b,0x3d,0x00,0x00,0x00,0x00,0x0d,0x5d,0x00,0x5c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x31,0x00,0x32,0x37,0x00,0x00,0x00,0x30,0x2e,0x32,0x35,0x36,0x38,0x1b,0x00,0x00,0x2b,0x33,0x2d,0x2a,0x39,0x00,0x00,},
|
||||||
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0x21,0x00,0x00,0x00,0x5a,0x53,0x41,0x57,0x40,0x00,0x00,0x43,0x58,0x44,0x45,0x24,0x23,0x00,0x00,0x20,0x56,0x46,0x54,0x52,0x25,0x00,0x00,0x4e,0x42,0x48,0x47,0x59,0x5e,0x00,0x00,0x00,0x4d,0x4a,0x55,0x26,0x2a,0x00,0x00,0x3c,0x4b,0x49,0x4f,0x29,0x28,0x00,0x00,0x3e,0x3f,0x4c,0x3a,0x50,0x5f,0x00,0x00,0x00,0x22,0x00,0x7b,0x2b,0x00,0x00,0x00,0x00,0x0d,0x7d,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x31,0x00,0x32,0x37,0x00,0x00,0x00,0x30,0x2e,0x32,0x35,0x36,0x38,0x1b,0x00,0x00,0x2b,0x33,0x2d,0x2a,0x39,0x00,0x00,},
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t convert_scancode(uint8_t shift, uint8_t code) {
|
||||||
|
return scancode[shift][code];
|
||||||
|
}
|
Reference in New Issue
Block a user