Change build options: Makefile and config.h. See README.tags/v1.9
timer.c \ | timer.c \ | ||||
util.c | util.c | ||||
SRC += $(TARGET_SRC) | SRC += $(TARGET_SRC) | ||||
ifdef MOUSEKEY_ENABLE | |||||
SRC += mousekey.c | |||||
endif | |||||
ifdef PS2_MOUSE_ENABLE | |||||
SRC += ps2.c \ | |||||
ps2_mouse.c | |||||
endif | |||||
# C source file search path | # C source file search path | ||||
VPATH = $(TARGET_DIR):$(COMMON_DIR) | VPATH = $(TARGET_DIR):$(COMMON_DIR) | ||||
CSTANDARD = -std=gnu99 | CSTANDARD = -std=gnu99 | ||||
# Place -D or -U options here for C sources | |||||
CDEFS = -DF_CPU=$(F_CPU)UL | |||||
CDEFS += -DDESCRIPTION=$(DESCRIPTION) | |||||
CDEFS += -DVENDOR_ID=$(VENDOR_ID) | |||||
CDEFS += -DPRODUCT_ID=$(PRODUCT_ID) | |||||
CDEFS += -DMANUFACTURER=$(MANUFACTURER) | |||||
CDEFS += -DPRODUCT=$(PRODUCT) | |||||
ifdef MOUSE_DELAY_TIME | |||||
CDEFS += -DMOUSE_DELAY_TIME=$(MOUSE_DELAY_TIME) | |||||
OPT_DEFS = | |||||
ifdef USB_NKRO_ENABLE | |||||
OPT_DEFS += -DUSB_NKRO_ENABLE | |||||
endif | |||||
ifdef MOUSEKEY_ENABLE | |||||
OPT_DEFS += -DMOUSEKEY_ENABLE | |||||
endif | endif | ||||
ifdef NKRO_ENABLE | |||||
CDEFS += -DNKRO_ENABLE | |||||
ifdef PS2_MOUSE_ENABLE | |||||
OPT_DEFS += -DPS2_MOUSE_ENABLE | |||||
endif | endif | ||||
# Place -D or -U options here for C sources | |||||
CDEFS = -DF_CPU=$(F_CPU)UL | |||||
CDEFS += $(OPT_DEFS) | |||||
# Place -D or -U options here for ASM sources | # Place -D or -U options here for ASM sources | ||||
ADEFS = -DF_CPU=$(F_CPU) | ADEFS = -DF_CPU=$(F_CPU) | ||||
ADEFS += -DDESCRIPTION=$(DESCRIPTION) | |||||
ADEFS += -DVENDOR_ID=$(VENDOR_ID) | |||||
ADEFS += -DPRODUCT_ID=$(PRODUCT_ID) | |||||
ADEFS += -DMANUFACTURER=$(MANUFACTURER) | |||||
ADEFS += -DPRODUCT=$(PRODUCT) | |||||
ifdef MOUSE_DELAY_TIME | |||||
ADEFS += -DMOUSE_DELAY_TIME=$(MOUSE_DELAY_TIME) | |||||
endif | |||||
ADEFS += $(OPT_DEFS) | |||||
# Place -D or -U options here for C++ sources | # Place -D or -U options here for C++ sources | ||||
CPPDEFS = -DF_CPU=$(F_CPU)UL -DDESCRIPTION=$(DESCRIPTION) -DVENDOR_ID=$(VENDOR_ID) -DPRODUCT_ID=$(PRODUCT_ID) | |||||
CPPDEFS = -DF_CPU=$(F_CPU)UL | |||||
#CPPDEFS += -D__STDC_LIMIT_MACROS | #CPPDEFS += -D__STDC_LIMIT_MACROS | ||||
#CPPDEFS += -D__STDC_CONSTANT_MACROS | #CPPDEFS += -D__STDC_CONSTANT_MACROS | ||||
CPPDEFS += -DDESCRIPTION=$(DESCRIPTION) | |||||
CPPDEFS += -DVENDOR_ID=$(VENDOR_ID) | |||||
CPPDEFS += -DPRODUCT_ID=$(PRODUCT_ID) | |||||
CPPDEFS += -DMANUFACTURER=$(MANUFACTURER) | |||||
CPPDEFS += -DPRODUCT=$(PRODUCT) | |||||
ifdef MOUSE_DELAY_TIME | |||||
CPPDEFS += -DMOUSE_DELAY_TIME=$(MOUSE_DELAY_TIME) | |||||
endif | |||||
CPPDEFS += $(OPT_DEFS) | |||||
CFLAGS += -Wa,-adhlns=$(@:%.o=$(OBJDIR)/%.lst) | CFLAGS += -Wa,-adhlns=$(@:%.o=$(OBJDIR)/%.lst) | ||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) | CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) | ||||
CFLAGS += $(CSTANDARD) | CFLAGS += $(CSTANDARD) | ||||
CFLAGS += -include config.h | |||||
#---------------- Compiler Options C++ ---------------- | #---------------- Compiler Options C++ ---------------- | ||||
CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst) | CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst) | ||||
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) | CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) | ||||
#CPPFLAGS += $(CSTANDARD) | #CPPFLAGS += $(CSTANDARD) | ||||
CPPFLAGS += -include config.h | |||||
#---------------- Assembler Options ---------------- | #---------------- Assembler Options ---------------- | ||||
# -listing-cont-lines: Sets the maximum number of continuation lines of hex | # -listing-cont-lines: Sets the maximum number of continuation lines of hex | ||||
# dump that will be displayed for a given single line of source input. | # dump that will be displayed for a given single line of source input. | ||||
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100 | ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100 | ||||
ASFLAGS += -include config.h | |||||
#---------------- Library Options ---------------- | #---------------- Library Options ---------------- | ||||
# Default target. | # Default target. | ||||
all: begin gccversion sizebefore build sizeafter end | all: begin gccversion sizebefore build sizeafter end | ||||
depend: tmk.c | |||||
@echo $< | |||||
@echo $(<F) | |||||
# $(CC) -E $(ALL_CFLAGS) $< | |||||
# Change the build target to build a HEX file or a library. | # Change the build target to build a HEX file or a library. | ||||
build: elf hex eep lss sym | build: elf hex eep lss sym | ||||
#build: lib | #build: lib |
http://winavr.sourceforge.net/ | http://winavr.sourceforge.net/ | ||||
Build Options | |||||
------------- | |||||
Makefile: | |||||
Comment out to disable the option | |||||
# USB NKey Rollover | |||||
USB_NKRO_ENABLE = yes | |||||
# mouse keys | |||||
MOUSEKEY_ENABLE = yes | |||||
# PS/2 mouse support | |||||
PS2_MOUSE_ENABLE = yes | |||||
config.h: | |||||
/* USB ID */ | |||||
#define VENDOR_ID 0xFEED | |||||
#define PRODUCT_ID 0xBEEF | |||||
/* device description */ | |||||
#define MANUFACTURER t.m.k. | |||||
#define PRODUCT Macway mod | |||||
#define DESCRIPTION t.m.k. keyboard firmware for Macway mod | |||||
/* matrix size */ | |||||
#define MATRIX_ROWS 8 | |||||
#define MATRIX_COLS 8 | |||||
/* mouse keys repeat delay */ | |||||
#define MOUSEKEY_DELAY_TIME 192 | |||||
/* PS/2 lines */ | |||||
#define PS2_CLOCK_PORT PORTF | |||||
#define PS2_CLOCK_PIN PINF | |||||
#define PS2_CLOCK_DDR DDRF | |||||
#define PS2_CLOCK_BIT 0 | |||||
#define PS2_DATA_PORT PORTF | |||||
#define PS2_DATA_PIN PINF | |||||
#define PS2_DATA_DDR DDRF | |||||
#define PS2_DATA_BIT 1 | |||||
Configuration | |||||
------------- | |||||
Debuging & Rescue | Debuging & Rescue | ||||
----------------- | ----------------- | ||||
Use PJRC's hid_listen.exe to see debug messages. | Use PJRC's hid_listen.exe to see debug messages. |
http://forums.anandtech.com/showpost.php?p=30873364&postcount=17 | http://forums.anandtech.com/showpost.php?p=30873364&postcount=17 | ||||
Tools for testing NKRO | |||||
---------------------- | |||||
Browser App: | |||||
http://www.microsoft.com/appliedsciences/content/projects/KeyboardGhostingDemo.aspx | |||||
http://random.xem.us/rollover.html | |||||
Windows: | |||||
AquaKeyTest.exe http://geekhack.org/showthread.php?t=6643 | |||||
Linux: | |||||
xkeycaps | |||||
xev | |||||
showkeys | |||||
EOF | EOF |
# To rebuild project do "make clean" then "make all". | # To rebuild project do "make clean" then "make all". | ||||
#---------------------------------------------------------------------------- | #---------------------------------------------------------------------------- | ||||
# TODO: use config.h for build options? | |||||
VENDOR_ID = 0xFEED | |||||
PRODUCT_ID = 0xCAFE | |||||
MANUFACTURER = 't.m.k.' | |||||
PRODUCT = 'HHKB Mod' | |||||
DESCRIPTION = 't.m.k. firmware for HHKB pro' | |||||
MOUSE_DELAY_TIME = 127 | |||||
NKRO_ENABLE = true | |||||
# Target file name (without extension). | # Target file name (without extension). | ||||
TARGET = tmk_hhkb | TARGET = tmk_hhkb | ||||
# examples use this variable to calculate timings. Do not add a "UL" here. | # examples use this variable to calculate timings. Do not add a "UL" here. | ||||
F_CPU = 16000000 | F_CPU = 16000000 | ||||
# Options | |||||
# comment out to disable | |||||
USB_NKRO_ENABLE = yes | |||||
MOUSEKEY_ENABLE = yes | |||||
#PS2_MOUSE_ENABLE = yes | |||||
include $(COMMON_DIR)/Makefile.common | include $(COMMON_DIR)/Makefile.common |
#ifndef CONFIG_H | |||||
#define CONFIG_H | |||||
#define VENDOR_ID 0xFEED | |||||
#define PRODUCT_ID 0xCAFE | |||||
#define MANUFACTURER t.m.k. | |||||
#define PRODUCT HHKB mod | |||||
#define DESCRIPTION t.m.k. keyboard firmware for HHKB mod | |||||
/* controller */ | |||||
#include "controller_teensy.h" | |||||
/* matrix size */ | |||||
#define MATRIX_ROWS 8 | |||||
#define MATRIX_COLS 8 | |||||
/* USB NKey Rollover */ | |||||
#ifdef USB_NKRO_ENABLE | |||||
#endif | |||||
/* mouse keys */ | |||||
#ifdef MOUSEKEY_ENABLE | |||||
# define MOUSEKEY_DELAY_TIME 192 | |||||
#endif | |||||
/* PS/2 mouse */ | |||||
#ifdef PS2_MOUSE_ENABLE | |||||
/* | |||||
# define PS2_CLOCK_PORT PORTF | |||||
# define PS2_CLOCK_PIN PINF | |||||
# define PS2_CLOCK_DDR DDRF | |||||
# define PS2_CLOCK_BIT 0 | |||||
# define PS2_DATA_PORT PORTF | |||||
# define PS2_DATA_PIN PINF | |||||
# define PS2_DATA_DDR DDRF | |||||
# define PS2_DATA_BIT 1 | |||||
*/ | |||||
#endif | |||||
#endif |
#ifndef CONTROLLER_H | |||||
#define CONTROLLER_H 1 | |||||
#include "controller_teensy.h" | |||||
/* matrix row size */ | |||||
#define MATRIX_ROWS 8 | |||||
/* matrix column size */ | |||||
#define MATRIX_COLS 8 | |||||
#endif |
#include "print.h" | #include "print.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
#include "util.h" | #include "util.h" | ||||
#include "controller.h" | |||||
#include "keymap_skel.h" | #include "keymap_skel.h" | ||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* |Caps | | | | | | | |Psc|Slk|Pus|Up | |Backs| | * |Caps | | | | | | | |Psc|Slk|Pus|Up | |Backs| | ||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* |Contro| | | | | | *| /|Hom|PgU|Lef|Rig|Enter | | |||||
* |Contro|VoD|VoU|Mut| | | *| /|Hom|PgU|Lef|Rig|Enter | | |||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* |Shift | | | | | | +| -|End|PgD|Dow|Shift |xxx| | * |Shift | | | | | | +| -|End|PgD|Dow|Shift |xxx| | ||||
* `-----------------------------------------------------------' | * `-----------------------------------------------------------' |
#include <util/delay.h> | #include <util/delay.h> | ||||
#include "print.h" | #include "print.h" | ||||
#include "util.h" | #include "util.h" | ||||
#include "controller.h" | |||||
#include "matrix_skel.h" | #include "matrix_skel.h" | ||||
// matrix is active low. (key on: 0/key off: 1) | // matrix is active low. (key on: 0/key off: 1) | ||||
// KEY_PREV: (on: 1/ off: 0) | // KEY_PREV: (on: 1/ off: 0) | ||||
// PE6,PE7(KEY, KEY_PREV) | // PE6,PE7(KEY, KEY_PREV) | ||||
#define COL_ENABLE (1<<6) | #define COL_ENABLE (1<<6) | ||||
#define KEY_SELELCT(ROW, COL) (PORTB = COL_ENABLE|(((COL)&0x07)<<3)|((ROW)&0x07)) | |||||
#define KEY_SELELCT(ROW, COL) (PORTB = (PORTB&(1<<7))|COL_ENABLE|(((COL)&0x07)<<3)|((ROW)&0x07)) | |||||
#define KEY_ENABLE (PORTB &= ~COL_ENABLE) | #define KEY_ENABLE (PORTB &= ~COL_ENABLE) | ||||
#define KEY_UNABLE (PORTB |= COL_ENABLE) | #define KEY_UNABLE (PORTB |= COL_ENABLE) | ||||
#define KEY_STATE (PINE&(1<<6)) | #define KEY_STATE (PINE&(1<<6)) | ||||
{ | { | ||||
// row & col output(PB0-6) | // row & col output(PB0-6) | ||||
DDRB = 0xFF; | DDRB = 0xFF; | ||||
PORTB = KEY_SELELCT(0, 0); | |||||
KEY_SELELCT(0, 0); | |||||
// KEY: input with pullup(PE6) | // KEY: input with pullup(PE6) | ||||
// KEY_PREV: output(PE7) | // KEY_PREV: output(PE7) | ||||
DDRE = 0xBF; | DDRE = 0xBF; |
UCSR1B = 0; | UCSR1B = 0; | ||||
_delay_ms(5); | _delay_ms(5); | ||||
#if defined(__AVR_AT90USB162__) // Teensy 1.0 | #if defined(__AVR_AT90USB162__) // Teensy 1.0 | ||||
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; | |||||
TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0; | |||||
DDRB = 0; DDRC = 0; DDRD = 0; | DDRB = 0; DDRC = 0; DDRD = 0; | ||||
TIMSK0 = 0; TIMSK1 = 0; | |||||
asm volatile("jmp 0x1F00"); | |||||
PORTB = 0; PORTC = 0; PORTD = 0; | |||||
asm volatile("jmp 0x3E00"); | |||||
#elif defined(__AVR_ATmega32U4__) // Teensy 2.0 | #elif defined(__AVR_ATmega32U4__) // Teensy 2.0 | ||||
DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; | |||||
TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; | |||||
ADCSRA = 0; | |||||
asm volatile("jmp 0x3F00"); | |||||
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0; | |||||
TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0; | |||||
DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0; | |||||
PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0; | |||||
asm volatile("jmp 0x7E00"); | |||||
#elif defined(__AVR_AT90USB646__) // Teensy++ 1.0 | #elif defined(__AVR_AT90USB646__) // Teensy++ 1.0 | ||||
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0; | |||||
TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0; | |||||
DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; | DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; | ||||
TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; | |||||
ADCSRA = 0; | |||||
asm volatile("jmp 0x7E00"); | |||||
PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0; | |||||
asm volatile("jmp 0xFC00"); | |||||
#elif defined(__AVR_AT90USB1286__) // Teensy++ 2.0 | #elif defined(__AVR_AT90USB1286__) // Teensy++ 2.0 | ||||
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0; | |||||
TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0; | |||||
DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; | DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; | ||||
TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; | |||||
ADCSRA = 0; | |||||
asm volatile("jmp 0xFE00"); | |||||
#endif | |||||
PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0; | |||||
asm volatile("jmp 0x1FC00"); | |||||
#endif | |||||
} | } |
#include "layer.h" | #include "layer.h" | ||||
#include "matrix_skel.h" | #include "matrix_skel.h" | ||||
#include "keymap_skel.h" | #include "keymap_skel.h" | ||||
#include "controller.h" | |||||
#include "key_process.h" | #include "key_process.h" | ||||
#define MOUSE_MOVE_UNIT 10 | |||||
#define MOUSE_MOVE_ACCEL (mouse_repeat < 50 ? mouse_repeat/5 : 10) | |||||
#ifndef MOUSE_DELAY_TIME | |||||
# define MOUSE_DELAY_TIME 255 | |||||
#ifdef MOUSEKEY_ENABLE | |||||
# include "mousekey.h" | |||||
#endif | |||||
#ifdef PS2_MOUSE_ENABLE | |||||
# include "ps2_mouse.h" | |||||
#endif | #endif | ||||
#define MOUSE_DELAY_MS (MOUSE_DELAY_TIME >> (mouse_repeat < 5 ? mouse_repeat : 4)) | |||||
// TODO: refactoring | // TODO: refactoring | ||||
void proc_matrix(void) { | void proc_matrix(void) { | ||||
static int mouse_repeat = 0; | |||||
bool modified = false; | bool modified = false; | ||||
uint8_t mouse_btn = 0; | |||||
int8_t mouse_x = 0; | |||||
int8_t mouse_y = 0; | |||||
int8_t mouse_vwheel = 0; | |||||
int8_t mouse_hwheel = 0; | |||||
uint8_t fn_bits = 0; | uint8_t fn_bits = 0; | ||||
matrix_scan(); | matrix_scan(); | ||||
} else if (IS_FN(code)) { | } else if (IS_FN(code)) { | ||||
fn_bits |= FN_BIT(code); | fn_bits |= FN_BIT(code); | ||||
} else if (IS_MOUSE(code)) { | } else if (IS_MOUSE(code)) { | ||||
if (code == MS_UP) mouse_y -= MOUSE_MOVE_UNIT + MOUSE_MOVE_ACCEL; | |||||
if (code == MS_DOWN) mouse_y += MOUSE_MOVE_UNIT + MOUSE_MOVE_ACCEL; | |||||
if (code == MS_LEFT) mouse_x -= MOUSE_MOVE_UNIT + MOUSE_MOVE_ACCEL; | |||||
if (code == MS_RGHT) mouse_x += MOUSE_MOVE_UNIT + MOUSE_MOVE_ACCEL; | |||||
if (code == MS_BTN1) mouse_btn |= BIT_BTN1; | |||||
if (code == MS_BTN2) mouse_btn |= BIT_BTN2; | |||||
if (code == MS_BTN3) mouse_btn |= BIT_BTN3; | |||||
if (code == MS_BTN4) mouse_btn |= BIT_BTN4; | |||||
if (code == MS_BTN5) mouse_btn |= BIT_BTN5; | |||||
if (code == MS_WH_U) mouse_vwheel += 1; | |||||
if (code == MS_WH_D) mouse_vwheel -= 1; | |||||
if (code == MS_WH_L) mouse_hwheel -= 1; | |||||
if (code == MS_WH_R) mouse_hwheel += 1; | |||||
#ifdef MOUSEKEY_ENABLE | |||||
mousekey_decode(code); | |||||
#endif | |||||
} | } | ||||
// audio control & system control | // audio control & system control | ||||
print("t: print timer count\n"); | print("t: print timer count\n"); | ||||
print("s: print status\n"); | print("s: print status\n"); | ||||
print("`: toggle protcol(boot/report)\n"); | print("`: toggle protcol(boot/report)\n"); | ||||
#ifdef NKRO_ENABLE | |||||
print("n: toggle NKRO\n"); | |||||
#ifdef USB_NKRO_ENABLE | |||||
print("n: toggle USB_NKRO\n"); | |||||
#endif | #endif | ||||
print("ESC: power down/wake up\n"); | print("ESC: power down/wake up\n"); | ||||
#ifdef PS2_MOUSE_ENABLE | |||||
print("1: ps2_mouse_init \n"); | |||||
print("2: ps2_mouse_read \n"); | |||||
#endif | |||||
_delay_ms(500); | _delay_ms(500); | ||||
print_enable = false; | print_enable = false; | ||||
break; | break; | ||||
#ifdef PS2_MOUSE_ENABLE | |||||
case KB_1: | |||||
usb_keyboard_clear_report(); | |||||
usb_keyboard_send(); | |||||
print_enable = true; | |||||
print("ps2_mouse_init...\n"); | |||||
_delay_ms(500); | |||||
ps2_mouse_init(); | |||||
break; | |||||
case KB_2: | |||||
usb_keyboard_clear_report(); | |||||
usb_keyboard_send(); | |||||
print_enable = true; | |||||
print("ps2_mouse_read[btn x y]: "); | |||||
_delay_ms(100); | |||||
ps2_mouse_read(); | |||||
phex(ps2_mouse_btn); print(" "); | |||||
phex(ps2_mouse_x); print(" "); | |||||
phex(ps2_mouse_y); print("\n"); | |||||
print("ps2_mouse_error_count: "); phex(ps2_mouse_error_count); print("\n"); | |||||
break; | |||||
#endif | |||||
case KB_B: // bootloader | case KB_B: // bootloader | ||||
usb_keyboard_clear_report(); | usb_keyboard_clear_report(); | ||||
usb_keyboard_send(); | usb_keyboard_send(); | ||||
print("usb_keyboard_protocol:"); phex(usb_keyboard_protocol); print("\n"); | print("usb_keyboard_protocol:"); phex(usb_keyboard_protocol); print("\n"); | ||||
print("usb_keyboard_idle_config:"); phex(usb_keyboard_idle_config); print("\n"); | print("usb_keyboard_idle_config:"); phex(usb_keyboard_idle_config); print("\n"); | ||||
print("usb_keyboard_idle_count:"); phex(usb_keyboard_idle_count); print("\n"); | print("usb_keyboard_idle_count:"); phex(usb_keyboard_idle_count); print("\n"); | ||||
print("mouse_protocol:"); phex(mouse_protocol); print("\n"); | |||||
if (usb_keyboard_nkro) print("NKRO: enabled\n"); else print("NKRO: disabled\n"); | |||||
print("usb_mouse_protocol:"); phex(usb_mouse_protocol); print("\n"); | |||||
if (usb_keyboard_nkro) print("USB_NKRO: enabled\n"); else print("USB_NKRO: disabled\n"); | |||||
_delay_ms(500); | _delay_ms(500); | ||||
break; | break; | ||||
case KB_GRV: | case KB_GRV: | ||||
usb_keyboard_clear_report(); | usb_keyboard_clear_report(); | ||||
usb_keyboard_send(); | usb_keyboard_send(); | ||||
usb_keyboard_protocol = !usb_keyboard_protocol; | usb_keyboard_protocol = !usb_keyboard_protocol; | ||||
mouse_protocol = !mouse_protocol; | |||||
usb_mouse_protocol = !usb_mouse_protocol; | |||||
print("keyboard protcol: "); | print("keyboard protcol: "); | ||||
if (usb_keyboard_protocol) print("report"); else print("boot"); | if (usb_keyboard_protocol) print("report"); else print("boot"); | ||||
print("\n"); | print("\n"); | ||||
print("mouse protcol: "); | print("mouse protcol: "); | ||||
if (mouse_protocol) print("report"); else print("boot"); | |||||
if (usb_mouse_protocol) print("report"); else print("boot"); | |||||
print("\n"); | print("\n"); | ||||
_delay_ms(1000); | _delay_ms(1000); | ||||
break; | break; | ||||
#ifdef NKRO_ENABLE | |||||
#ifdef USB_NKRO_ENABLE | |||||
case KB_N: | case KB_N: | ||||
usb_keyboard_clear_report(); | usb_keyboard_clear_report(); | ||||
usb_keyboard_send(); | usb_keyboard_send(); | ||||
usb_keyboard_nkro = !usb_keyboard_nkro; | usb_keyboard_nkro = !usb_keyboard_nkro; | ||||
if (usb_keyboard_nkro) print("NKRO: enabled\n"); else print("NKRO: disabled\n"); | |||||
if (usb_keyboard_nkro) print("USB_NKRO: enabled\n"); else print("USB_NKRO: disabled\n"); | |||||
_delay_ms(1000); | _delay_ms(1000); | ||||
break; | break; | ||||
#endif | #endif | ||||
} | } | ||||
// send mouse packet to host | |||||
if (mouse_x || mouse_y || mouse_vwheel || mouse_hwheel || mouse_btn != mouse_buttons) { | |||||
mouse_buttons = mouse_btn; | |||||
if (mouse_x && mouse_y) | |||||
usb_mouse_move(mouse_x*0.7, mouse_y*0.7, mouse_vwheel, mouse_hwheel); | |||||
else | |||||
usb_mouse_move(mouse_x, mouse_y, mouse_vwheel, mouse_hwheel); | |||||
usb_mouse_print(mouse_x, mouse_y, mouse_vwheel, mouse_hwheel); | |||||
// acceleration | |||||
_delay_ms(MOUSE_DELAY_MS); | |||||
mouse_repeat++; | |||||
} else { | |||||
mouse_repeat = 0; | |||||
} | |||||
// send key packet to host | |||||
if (modified) { | if (modified) { | ||||
usb_keyboard_send(); | usb_keyboard_send(); | ||||
} | } | ||||
#ifdef MOUSEKEY_ENABLE | |||||
// mouse keys | |||||
mousekey_usb_send(); | |||||
#endif | |||||
#ifdef PS2_MOUSE_ENABLE | |||||
// ps2 mouse | |||||
//if (ps2_mouse_error_count > 10) { | |||||
ps2_mouse_read(); | |||||
ps2_mouse_usb_send(); | |||||
//} | |||||
#endif | |||||
} | } |
# To rebuild project do "make clean" then "make all". | # To rebuild project do "make clean" then "make all". | ||||
#---------------------------------------------------------------------------- | #---------------------------------------------------------------------------- | ||||
VENDOR_ID = 0xFEED | |||||
PRODUCT_ID = 0xBEEF | |||||
MANUFACTURER = 't.m.k.' | |||||
PRODUCT = 't.m.k. Macway mod' | |||||
DESCRIPTION = 't.m.k. firmware for Macway mod' | |||||
# Target file name (without extension). | # Target file name (without extension). | ||||
TARGET = tmk_macway | TARGET = tmk_macway | ||||
# examples use this variable to calculate timings. Do not add a "UL" here. | # examples use this variable to calculate timings. Do not add a "UL" here. | ||||
F_CPU = 16000000 | F_CPU = 16000000 | ||||
# Options | |||||
# comment out to disable | |||||
#USB_NKRO_ENABLE = yes | |||||
MOUSEKEY_ENABLE = yes | |||||
PS2_MOUSE_ENABLE = yes | |||||
include $(COMMON_DIR)/Makefile.common | include $(COMMON_DIR)/Makefile.common |
#ifndef CONFIG_H | |||||
#define CONFIG_H | |||||
#define VENDOR_ID 0xFEED | |||||
#define PRODUCT_ID 0xBEEF | |||||
#define MANUFACTURER t.m.k. | |||||
#define PRODUCT Macway mod | |||||
#define DESCRIPTION t.m.k. keyboard firmware for Macway mod | |||||
/* controller */ | |||||
#include "controller_teensy.h" | |||||
/* matrix size */ | |||||
#define MATRIX_ROWS 9 | |||||
#define MATRIX_COLS 8 | |||||
/* USB NKey Rollover */ | |||||
#ifdef USB_NKRO_ENABLE | |||||
#endif | |||||
/* mouse keys */ | |||||
#ifdef MOUSEKEY_ENABLE | |||||
# define MOUSEKEY_DELAY_TIME 192 | |||||
#endif | |||||
/* PS/2 mouse */ | |||||
#ifdef PS2_MOUSE_ENABLE | |||||
# define PS2_CLOCK_PORT PORTF | |||||
# define PS2_CLOCK_PIN PINF | |||||
# define PS2_CLOCK_DDR DDRF | |||||
# define PS2_CLOCK_BIT 0 | |||||
# define PS2_DATA_PORT PORTF | |||||
# define PS2_DATA_PIN PINF | |||||
# define PS2_DATA_DDR DDRF | |||||
# define PS2_DATA_BIT 1 | |||||
#endif | |||||
#endif |
#ifndef CONTROLLER_H | |||||
#define CONTROLLER_H 1 | |||||
#include "controller_teensy.h" | |||||
/* matrix row size */ | |||||
#define MATRIX_ROWS 9 | |||||
/* matrix column size */ | |||||
#define MATRIX_COLS 8 | |||||
#endif |
#include "print.h" | #include "print.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
#include "util.h" | #include "util.h" | ||||
#include "controller.h" | |||||
#include "keymap_skel.h" | #include "keymap_skel.h" | ||||
static const uint8_t PROGMEM fn_keycode[] = { | static const uint8_t PROGMEM fn_keycode[] = { | ||||
KB_NO, // FN_0 [NOT USED] | KB_NO, // FN_0 [NOT USED] | ||||
KB_NO, // FN_1 layer 1 | KB_NO, // FN_1 layer 1 | ||||
KB_QUOTE, // FN_2 layer 2 | |||||
KB_SCOLON, // FN_3 layer 3 | |||||
KB_SPACE, // FN_4 layer 4 | |||||
KB_SLSH, // FN_2 layer 2 | |||||
KB_SCLN, // FN_3 layer 3 | |||||
KB_SPC, // FN_4 layer 4 | |||||
KB_NO, // FN_5 [NOT USED] | KB_NO, // FN_5 [NOT USED] | ||||
KB_NO, // FN_6 layer 2 | KB_NO, // FN_6 layer 2 | ||||
KB_NO // FN_7 layer 3 | KB_NO // FN_7 layer 3 | ||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| | | ||||
* |-----------------------------------------------------' | | * |-----------------------------------------------------' | | ||||
* |Contro| A| S| D| F| G| H| J| K| L|Fn3|Fn2|Return | | |||||
* |Contro| A| S| D| F| G| H| J| K| L|Fn3| '|Return | | |||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Fn1| | * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Fn1| | ||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* |Fn7|Gui |Alt |Fn4 |Fn6 |\ |` | | | | |||||
* |Fn7|Gui |Alt |Fn4 |Alt |Gui|Fn6|Fn6|Ctr| | |||||
* `-----------------------------------------------------------' | * `-----------------------------------------------------------' | ||||
*/ | */ | ||||
KEYMAP(KB_ESC, KB_1, KB_2, KB_3, KB_4, KB_5, KB_6, KB_7, KB_8, KB_9, KB_0, KB_MINS,KB_EQL, KB_BSPC, \ | KEYMAP(KB_ESC, KB_1, KB_2, KB_3, KB_4, KB_5, KB_6, KB_7, KB_8, KB_9, KB_0, KB_MINS,KB_EQL, KB_BSPC, \ | ||||
KB_TAB, KB_Q, KB_W, KB_E, KB_R, KB_T, KB_Y, KB_U, KB_I, KB_O, KB_P, KB_LBRC,KB_RBRC, \ | KB_TAB, KB_Q, KB_W, KB_E, KB_R, KB_T, KB_Y, KB_U, KB_I, KB_O, KB_P, KB_LBRC,KB_RBRC, \ | ||||
KB_LCTL,KB_A, KB_S, KB_D, KB_F, KB_G, KB_H, KB_J, KB_K, KB_L, FN_3, FN_2, KB_ENT, \ | |||||
KB_LSFT,KB_Z, KB_X, KB_C, KB_V, KB_B, KB_N, KB_M, KB_COMM,KB_DOT, KB_SLSH,KB_RSFT,FN_1, \ | |||||
FN_7, KB_LGUI,KB_LALT,FN_4, FN_6, KB_BSLS,KB_GRV, KB_NO, KB_NO), | |||||
KB_LCTL,KB_A, KB_S, KB_D, KB_F, KB_G, KB_H, KB_J, KB_K, KB_L, FN_3, KB_QUOT,KB_ENT, \ | |||||
KB_LSFT,KB_Z, KB_X, KB_C, KB_V, KB_B, KB_N, KB_M, KB_COMM,KB_DOT, FN_2, KB_RSFT,FN_1, \ | |||||
FN_7, KB_LGUI,KB_LALT,FN_4, KB_RALT,KB_RGUI,FN_6, FN_6, KB_RCTL), | |||||
/* Layer 1: HHKB mode (HHKB Fn) | /* Layer 1: HHKB mode (HHKB Fn) | ||||
* ,-----------------------------------------------------------. | * ,-----------------------------------------------------------. | ||||
* |Pow| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete | | |||||
* |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete | | |||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* |Caps | | | | | | | |Psc|Slk|Pus|Up | | | | * |Caps | | | | | | | |Psc|Slk|Pus|Up | | | | ||||
* |-----------------------------------------------------' | | * |-----------------------------------------------------' | | ||||
* |Contro| | | | | | *| /|Hom|PgU|Lef|Rig|Enter | | |||||
* |Contro|VoD|VoU|Mut| | | *| /|Hom|PgU|Lef|Rig|Enter | | |||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* |Shift | | | | | | +| -|End|PgD|Dow|Shift |xxx| | * |Shift | | | | | | +| -|End|PgD|Dow|Shift |xxx| | ||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* | |Gui |Alt | |Alt | | | | | | |||||
* | |Gui |Alt | |Alt |Gui| | |Ctr| | |||||
* `-----------------------------------------------------------' | * `-----------------------------------------------------------' | ||||
*/ | */ | ||||
KEYMAP(KB_PWR, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_DEL, \ | |||||
KEYMAP(KB_ESC, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_DEL, \ | |||||
KB_CAPS,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_PSCR,KB_SLCK,KB_BRK, KB_UP, KB_NO, \ | KB_CAPS,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_PSCR,KB_SLCK,KB_BRK, KB_UP, KB_NO, \ | ||||
KB_LCTL,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KP_ASTR,KP_SLSH,KB_HOME,KB_PGUP,KB_LEFT,KB_RGHT,KB_ENT, \ | |||||
KB_LCTL,KB_VOLD,KB_VOLU,KB_MUTE,KB_NO, KB_NO, KP_ASTR,KP_SLSH,KB_HOME,KB_PGUP,KB_LEFT,KB_RGHT,KB_ENT, \ | |||||
KB_LSFT,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KP_PLUS,KP_MINS,KB_END, KB_PGDN,KB_DOWN,KB_RSFT,FN_1, \ | KB_LSFT,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KP_PLUS,KP_MINS,KB_END, KB_PGDN,KB_DOWN,KB_RSFT,FN_1, \ | ||||
KB_NO, KB_LGUI,KB_LALT,KB_SPC, KB_RALT,KB_NO, KB_NO, KB_NO, KB_NO), | |||||
KB_NO, KB_LGUI,KB_LALT,KB_SPC, KB_RALT,KB_NO, KB_NO, KB_NO, KB_RCTL), | |||||
/* Layer 2: Vi mode (Quote/Rmeta) | /* Layer 2: Vi mode (Quote/Rmeta) | ||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* | \ |Hom|PgD|Up |PgU|End|Hom|PgD|PgU|End| | | | | | * | \ |Hom|PgD|Up |PgU|End|Hom|PgD|PgU|End| | | | | | ||||
* |-----------------------------------------------------' | | * |-----------------------------------------------------' | | ||||
* |Contro| |Lef|Dow|Rig| |Lef|Dow|Up |Rig| |xxx| \ | | |||||
* |Contro| |Lef|Dow|Rig| |Lef|Dow|Up |Rig| | | \ | | |||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* |Shift | | | | | |Hom|PgD|PgU|End| |Shift | | | |||||
* |Shift | | | | | |Hom|PgD|PgU|End|xxx|Shift | | | |||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* | |Gui |Alt |Space |xxxxx| | | | | | |||||
* | |Gui |Alt |Space |Alt |Gui|Fn6|Fn6|Ctr| | |||||
* `-----------------------------------------------------------' | * `-----------------------------------------------------------' | ||||
*/ | */ | ||||
KEYMAP(KB_GRV, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_GRV, \ | KEYMAP(KB_GRV, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_GRV, \ | ||||
KB_BSLS,KB_HOME,KB_PGDN,KB_UP, KB_PGUP,KB_END, KB_HOME,KB_PGDN,KB_PGUP,KB_END, KB_NO, KB_NO, KB_NO, \ | KB_BSLS,KB_HOME,KB_PGDN,KB_UP, KB_PGUP,KB_END, KB_HOME,KB_PGDN,KB_PGUP,KB_END, KB_NO, KB_NO, KB_NO, \ | ||||
KB_LCTL,KB_NO, KB_LEFT,KB_DOWN,KB_RGHT,KB_NO, KB_LEFT,KB_DOWN,KB_UP, KB_RGHT,KB_NO, FN_2, KB_BSLS, \ | |||||
KB_LSFT,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_RSFT,KB_NO, \ | |||||
KB_NO, KB_LGUI,KB_LALT,KB_SPC, FN_6, KB_NO, KB_NO, KB_NO, KB_NO), | |||||
KB_LCTL,KB_NO, KB_LEFT,KB_DOWN,KB_RGHT,KB_NO, KB_LEFT,KB_DOWN,KB_UP, KB_RGHT,KB_NO, KB_NO, KB_BSLS, \ | |||||
KB_LSFT,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, FN_2, KB_RSFT,KB_NO, \ | |||||
KB_NO, KB_LGUI,KB_LALT,KB_SPC, KB_RALT,KB_RGUI,FN_6, FN_6, KB_RCTL), | |||||
/* Layer 3: Mouse mode (Semicolon) | /* Layer 3: Mouse mode (Semicolon) | ||||
* ,-------------------------------------------------------- --. | |||||
* |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Delete | | |||||
* ,-----------------------------------------------------------. | |||||
* | `| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12| ` | | |||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* |Tab |MwL|MwD|McU|MwU|MwR|MwL|MwD|MwU|MwR| | | | | | |||||
* | \ |MwL|MwD|McU|MwU|MwR|MwL|MwD|MwU|MwR| | | | | | |||||
* |-----------------------------------------------------' | | * |-----------------------------------------------------' | | ||||
* |Contro| |McL|McD|McR| |McL|McD|McU|McR|xxx| |Return | | |||||
* |Contro| |McL|McD|McR| |McL|McD|McU|McR|xxx| | \ | | |||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* |Shift | | |Mb1|Mb2|Mb3|Mb2|Mb1| | | |Shift | | | * |Shift | | |Mb1|Mb2|Mb3|Mb2|Mb1| | | |Shift | | | ||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* `-----------------------------------------------------------' | * `-----------------------------------------------------------' | ||||
* Mc: Mouse Cursor / Mb: Mouse Button / Mw: Mouse Wheel | * Mc: Mouse Cursor / Mb: Mouse Button / Mw: Mouse Wheel | ||||
*/ | */ | ||||
KEYMAP(KB_ESC, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_DEL, \ | |||||
KB_TAB, MS_WH_L,MS_WH_D,MS_UP, MS_WH_U,MS_WH_R,MS_WH_L,MS_WH_D,MS_WH_U,MS_WH_R,KB_NO, KB_NO, KB_NO, \ | |||||
KB_LCTL,KB_NO, MS_LEFT,MS_DOWN,MS_RGHT,KB_NO, MS_LEFT,MS_DOWN,MS_UP, MS_RGHT,FN_3, KB_NO, KB_ENT, \ | |||||
KEYMAP(KB_GRV, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_GRV, \ | |||||
KB_BSLS,MS_WH_L,MS_WH_D,MS_UP, MS_WH_U,MS_WH_R,MS_WH_L,MS_WH_D,MS_WH_U,MS_WH_R,KB_NO, KB_NO, KB_NO, \ | |||||
KB_LCTL,KB_NO, MS_LEFT,MS_DOWN,MS_RGHT,KB_NO, MS_LEFT,MS_DOWN,MS_UP, MS_RGHT,FN_3, KB_NO, KB_BSLS, \ | |||||
KB_LSFT,KB_NO, KB_NO, MS_BTN1,MS_BTN2,MS_BTN3,MS_BTN2,MS_BTN1,KB_NO, KB_NO, KB_NO, KB_RSFT,KB_NO, \ | KB_LSFT,KB_NO, KB_NO, MS_BTN1,MS_BTN2,MS_BTN3,MS_BTN2,MS_BTN1,KB_NO, KB_NO, KB_NO, KB_RSFT,KB_NO, \ | ||||
FN_7, KB_LGUI,KB_LALT,MS_BTN1,KB_RALT,KB_NO, KB_NO, KB_NO, KB_NO), | FN_7, KB_LGUI,KB_LALT,MS_BTN1,KB_RALT,KB_NO, KB_NO, KB_NO, KB_NO), | ||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* |Shift | /| .| ,| M| N| B| V| C| X| Z|Shift | | | * |Shift | /| .| ,| M| N| B| V| C| X| Z|Shift | | | ||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* | |Gui |Alt |xxxxxxxxxxxxxxxxxxxxxx|Alt | | | | | | |||||
* | |Gui |Alt |xxxxxxxxxxxxxxxxxxxxxx|Alt |Gui| | |Ctr| | |||||
* `-----------------------------------------------------------' | * `-----------------------------------------------------------' | ||||
*/ | */ | ||||
KEYMAP(KB_MINS,KB_0, KB_9, KB_8, KB_7, KB_6, KB_5, KB_4, KB_3, KB_2, KB_1, KB_NO, KB_NO, KB_ESC, \ | KEYMAP(KB_MINS,KB_0, KB_9, KB_8, KB_7, KB_6, KB_5, KB_4, KB_3, KB_2, KB_1, KB_NO, KB_NO, KB_ESC, \ | ||||
KB_BSPC,KB_P, KB_O, KB_I, KB_U, KB_Y, KB_T, KB_R, KB_E, KB_W, KB_Q, KB_TAB, KB_TAB, \ | KB_BSPC,KB_P, KB_O, KB_I, KB_U, KB_Y, KB_T, KB_R, KB_E, KB_W, KB_Q, KB_TAB, KB_TAB, \ | ||||
KB_LCTL,KB_SCLN,KB_L, KB_K, KB_J, KB_H, KB_G, KB_F, KB_D, KB_S, KB_A, KB_RCTL,KB_RCTL, \ | KB_LCTL,KB_SCLN,KB_L, KB_K, KB_J, KB_H, KB_G, KB_F, KB_D, KB_S, KB_A, KB_RCTL,KB_RCTL, \ | ||||
KB_LSFT,KB_SLSH,KB_DOT, KB_COMM,KB_M, KB_N, KB_B, KB_V, KB_C, KB_X, KB_Z, KB_RSFT,KB_NO, \ | KB_LSFT,KB_SLSH,KB_DOT, KB_COMM,KB_M, KB_N, KB_B, KB_V, KB_C, KB_X, KB_Z, KB_RSFT,KB_NO, \ | ||||
KB_NO, KB_LGUI,KB_LALT,FN_4, KB_RALT,KB_NO, KB_NO, KB_NO, KB_NO), | |||||
KB_NO, KB_LGUI,KB_LALT,FN_4, KB_RALT,KB_RGUI,KB_NO, KB_NO, KB_RCTL), | |||||
}; | }; | ||||
bool keymap_is_special_mode(uint8_t fn_bits) | bool keymap_is_special_mode(uint8_t fn_bits) | ||||
{ | { | ||||
return (usb_keyboard_mods == (BIT_LCTRL | BIT_LSHIFT | BIT_LALT | BIT_LGUI)); | |||||
//return (usb_keyboard_mods == (BIT_LCTRL | BIT_LSHIFT | BIT_LALT | BIT_LGUI)); | |||||
return (usb_keyboard_mods == (BIT_RSHIFT)); | |||||
} | } |
#include <util/delay.h> | #include <util/delay.h> | ||||
#include "print.h" | #include "print.h" | ||||
#include "util.h" | #include "util.h" | ||||
#include "controller.h" | |||||
#include "matrix_skel.h" | #include "matrix_skel.h" | ||||
// matrix is active low. (key on: 0/key off: 1) | |||||
// row: Hi-Z(unselected)/low output(selected) | |||||
// PD0, PC7, PD7, PF6, PD6, PD1, PD2, PC6, PF7 | |||||
// col: input w/pullup | |||||
// PB0-PB7 | |||||
// matrix state buffer | |||||
// matrix state buffer (key on: 1/key off: 0) | |||||
static uint8_t *matrix; | static uint8_t *matrix; | ||||
static uint8_t *matrix_prev; | static uint8_t *matrix_prev; | ||||
static uint8_t _matrix0[MATRIX_ROWS]; | static uint8_t _matrix0[MATRIX_ROWS]; | ||||
{ | { | ||||
// initialize row and col | // initialize row and col | ||||
unselect_rows(); | unselect_rows(); | ||||
// Input with pull-up(DDR:0, PORT:1) | |||||
DDRB = 0x00; | DDRB = 0x00; | ||||
PORTB = 0xFF; | PORTB = 0xFF; | ||||
matrix = tmp; | matrix = tmp; | ||||
for (int i = 0; i < MATRIX_ROWS; i++) { | for (int i = 0; i < MATRIX_ROWS; i++) { | ||||
unselect_rows(); | |||||
select_row(i); | select_row(i); | ||||
_delay_us(30); // without this wait read unstable value. | _delay_us(30); // without this wait read unstable value. | ||||
matrix[i] = ~read_col(); | matrix[i] = ~read_col(); | ||||
unselect_rows(); | |||||
} | } | ||||
unselect_rows(); | |||||
return 1; | return 1; | ||||
} | } | ||||
static void unselect_rows(void) | static void unselect_rows(void) | ||||
{ | { | ||||
DDRD = 0x00; | |||||
PORTD = 0x00; | |||||
DDRC = 0x00; | |||||
PORTC = 0x00; | |||||
DDRF = 0x00; | |||||
PORTF = 0x00; | |||||
// Hi-Z(DDR:0, PORT:0) to unselect | |||||
DDRC &= ~0b11000000; // PC: 7,6 | |||||
PORTC &= ~0b11000000; | |||||
DDRD &= ~0b11000111; // PD: 7,6,2,1,0 | |||||
PORTD &= ~0b11000111; | |||||
DDRF &= ~0b11000000; // PF: 7,6 | |||||
PORTF &= ~0b11000000; | |||||
} | } | ||||
static void select_row(uint8_t row) | static void select_row(uint8_t row) | ||||
{ | { | ||||
// Output low(DDR:1, PORT:0) to select | |||||
// row: 0 1 2 3 4 5 6 7 8 | |||||
// pin: PD0, PC7, PD7, PF6, PD6, PD1, PD2, PC6, PF7 | |||||
switch (row) { | switch (row) { | ||||
case 0: | case 0: | ||||
DDRD = (1<<0); | |||||
PORTD = 0x00; | |||||
DDRC = 0x00; | |||||
PORTC = 0x00; | |||||
DDRF = 0x00; | |||||
PORTF = 0x00; | |||||
DDRD |= (1<<0); | |||||
PORTD &= ~(1<<0); | |||||
break; | break; | ||||
case 1: | case 1: | ||||
DDRD = 0x00; | |||||
PORTD = 0x00; | |||||
DDRC = (1<<7); | |||||
PORTC = 0x00; | |||||
DDRF = 0x00; | |||||
PORTF = 0x00; | |||||
DDRC |= (1<<7); | |||||
PORTC &= ~(1<<7); | |||||
break; | break; | ||||
case 2: | case 2: | ||||
DDRD = (1<<7); | |||||
PORTD = 0x00; | |||||
DDRC = 0x00; | |||||
PORTC = 0x00; | |||||
DDRF = 0x00; | |||||
PORTF = 0x00; | |||||
DDRD |= (1<<7); | |||||
PORTD &= ~(1<<7); | |||||
break; | break; | ||||
case 3: | case 3: | ||||
DDRD = 0x00; | |||||
PORTD = 0x00; | |||||
DDRC = 0x00; | |||||
PORTC = 0x00; | |||||
DDRF = (1<<6); | |||||
PORTF = 0x00; | |||||
DDRF |= (1<<6); | |||||
PORTF &= ~(1<<6); | |||||
break; | break; | ||||
case 4: | case 4: | ||||
DDRD = (1<<6); | |||||
PORTD = 0x00; | |||||
DDRC = 0x00; | |||||
PORTC = 0x00; | |||||
DDRF = 0x00; | |||||
PORTF = 0x00; | |||||
DDRD |= (1<<6); | |||||
PORTD &= ~(1<<6); | |||||
break; | break; | ||||
case 5: | case 5: | ||||
DDRD = (1<<1); | |||||
PORTD = 0x00; | |||||
DDRC = 0x00; | |||||
PORTC = 0x00; | |||||
DDRF = 0x00; | |||||
PORTF = 0x00; | |||||
DDRD |= (1<<1); | |||||
PORTD &= ~(1<<1); | |||||
break; | break; | ||||
case 6: | case 6: | ||||
DDRD = (1<<2); | |||||
PORTD = 0x00; | |||||
DDRC = 0x00; | |||||
PORTC = 0x00; | |||||
DDRF = 0x00; | |||||
PORTF = 0x00; | |||||
DDRD |= (1<<2); | |||||
PORTD &= ~(1<<2); | |||||
break; | break; | ||||
case 7: | case 7: | ||||
DDRD = 0x00; | |||||
PORTD = 0x00; | |||||
DDRC = (1<<6); | |||||
PORTC = 0x00; | |||||
DDRF = 0x00; | |||||
PORTF = 0x00; | |||||
DDRC |= (1<<6); | |||||
PORTC &= ~(1<<6); | |||||
break; | break; | ||||
case 8: | case 8: | ||||
DDRD = 0x00; | |||||
PORTD = 0x00; | |||||
DDRC = 0x00; | |||||
PORTC = 0x00; | |||||
DDRF = (1<<7); | |||||
PORTF = 0x00; | |||||
DDRF |= (1<<7); | |||||
PORTF &= ~(1<<7); | |||||
break; | break; | ||||
} | } | ||||
} | } |
#include <stdint.h> | |||||
#include <util/delay.h> | |||||
#include "usb_keycodes.h" | |||||
#include "usb_mouse.h" | |||||
#include "mousekey.h" | |||||
static int8_t mousekey_x = 0; | |||||
static int8_t mousekey_y = 0; | |||||
static int8_t mousekey_v = 0; | |||||
static int8_t mousekey_h = 0; | |||||
static uint8_t mousekey_btn = 0; | |||||
static uint8_t mousekey_btn_prev = 0; | |||||
static uint8_t mousekey_repeat = 0; | |||||
/* | |||||
* TODO: fix acceleration algorithm | |||||
* see wikipedia http://en.wikipedia.org/wiki/Mouse_keys | |||||
*/ | |||||
#ifndef MOUSEKEY_DELAY_TIME | |||||
# define MOUSEKEY_DELAY_TIME 255 | |||||
#endif | |||||
static inline uint8_t move_unit(void) | |||||
{ | |||||
return 10 + (mousekey_repeat < 50 ? mousekey_repeat/5 : 10); | |||||
} | |||||
void mousekey_decode(uint8_t code) | |||||
{ | |||||
if (code == MS_UP) mousekey_y -= move_unit(); | |||||
else if (code == MS_DOWN) mousekey_y += move_unit(); | |||||
else if (code == MS_LEFT) mousekey_x -= move_unit(); | |||||
else if (code == MS_RGHT) mousekey_x += move_unit(); | |||||
else if (code == MS_BTN1) mousekey_btn |= MOUSE_BTN1; | |||||
else if (code == MS_BTN2) mousekey_btn |= MOUSE_BTN2; | |||||
else if (code == MS_BTN3) mousekey_btn |= MOUSE_BTN3; | |||||
else if (code == MS_BTN4) mousekey_btn |= MOUSE_BTN4; | |||||
else if (code == MS_BTN5) mousekey_btn |= MOUSE_BTN5; | |||||
else if (code == MS_WH_U) mousekey_v += 1; | |||||
else if (code == MS_WH_D) mousekey_v -= 1; | |||||
else if (code == MS_WH_L) mousekey_h -= 1; | |||||
else if (code == MS_WH_R) mousekey_h += 1; | |||||
} | |||||
bool mousekey_changed(void) | |||||
{ | |||||
return (mousekey_x || mousekey_y || mousekey_v || mousekey_h || mousekey_btn != mousekey_btn_prev); | |||||
} | |||||
void mousekey_usb_send(void) | |||||
{ | |||||
if (mousekey_changed()) { | |||||
mousekey_btn_prev = mousekey_btn; | |||||
if (mousekey_x && mousekey_y) | |||||
usb_mouse_send(mousekey_x*0.7, mousekey_y*0.7, mousekey_v, mousekey_h, mousekey_btn); | |||||
else | |||||
usb_mouse_send(mousekey_x, mousekey_y, mousekey_v, mousekey_h, mousekey_btn); | |||||
usb_mouse_print(mousekey_x, mousekey_y, mousekey_v, mousekey_h, mousekey_btn); | |||||
_delay_ms(MOUSEKEY_DELAY_TIME >> (mousekey_repeat < 5 ? mousekey_repeat : 4)); | |||||
mousekey_repeat++; | |||||
} else { | |||||
mousekey_repeat = 0; | |||||
} | |||||
mousekey_x = 0; | |||||
mousekey_y = 0; | |||||
mousekey_v = 0; | |||||
mousekey_h = 0; | |||||
mousekey_btn = 0; | |||||
} |
#ifndef MOUSEKEY_H | |||||
#define MOUSEKEY_H | |||||
#include <stdbool.h> | |||||
void mousekey_decode(uint8_t code); | |||||
bool mousekey_changed(void); | |||||
void mousekey_usb_send(void); | |||||
#endif | |||||
/* | |||||
Copyright (c) 2010 Jun WAKO <[email protected]> | |||||
This software is licensed with a Modified BSD License. | |||||
All of this is supposed to be Free Software, Open Source, DFSG-free, | |||||
GPL-compatible, and OK to use in both free and proprietary applications. | |||||
Additions and corrections to this file are welcome. | |||||
Redistribution and use in source and binary forms, with or without | |||||
modification, are permitted provided that the following conditions are met: | |||||
* Redistributions of source code must retain the above copyright | |||||
notice, this list of conditions and the following disclaimer. | |||||
* Redistributions in binary form must reproduce the above copyright | |||||
notice, this list of conditions and the following disclaimer in | |||||
the documentation and/or other materials provided with the | |||||
distribution. | |||||
* Neither the name of the copyright holders nor the names of | |||||
contributors may be used to endorse or promote products derived | |||||
from this software without specific prior written permission. | |||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#include <stdbool.h> | |||||
#include <avr/io.h> | |||||
#include <util/delay.h> | |||||
#include "ps2.h" | |||||
#include "print.h" | |||||
#include "debug.h" | |||||
static inline void clock_lo(void); | |||||
static inline void clock_hi(void); | |||||
static inline bool clock_in(void); | |||||
static inline void data_lo(void); | |||||
static inline void data_hi(void); | |||||
static inline bool data_in(void); | |||||
static inline uint16_t wait_clock_lo(uint16_t us); | |||||
static inline uint16_t wait_clock_hi(uint16_t us); | |||||
static inline uint16_t wait_data_lo(uint16_t us); | |||||
static inline uint16_t wait_data_hi(uint16_t us); | |||||
/* | |||||
Primitive PS/2 Library for AVR | |||||
============================== | |||||
Host side is only supported now. | |||||
I/O control | |||||
----------- | |||||
High state is asserted by input with pull up. | |||||
PS/2 References | |||||
--------------- | |||||
http://www.computer-engineering.org/ps2protocol/ | |||||
http://www.mcamafia.de/pdf/ibm_hitrc07.pdf | |||||
*/ | |||||
#define WAIT(stat, us, err) do { \ | |||||
if (!wait_##stat(us)) { \ | |||||
ps2_error = err; \ | |||||
goto ERROR; \ | |||||
} \ | |||||
} while (0) | |||||
#define WAIT_NORETRY(stat, us, err) do { \ | |||||
if (!wait_##stat(us)) { \ | |||||
ps2_error = err; \ | |||||
return 0; \ | |||||
} \ | |||||
} while (0) | |||||
uint8_t ps2_error = PS2_ERR_NONE; | |||||
void ps2_host_init(void) | |||||
{ | |||||
/* inhibit */ | |||||
clock_lo(); | |||||
data_hi(); | |||||
} | |||||
uint8_t ps2_host_send(uint8_t data) | |||||
{ | |||||
bool parity = true; | |||||
ps2_error = 0; | |||||
/* request to send */ | |||||
clock_lo(); | |||||
data_lo(); | |||||
_delay_us(100); | |||||
/* start bit [1] */ | |||||
clock_hi(); | |||||
WAIT(clock_lo, 15000, 1); | |||||
/* data [2-9] */ | |||||
for (uint8_t i = 0; i < 8; i++) { | |||||
if (data&(1<<i)) { | |||||
parity = !parity; | |||||
data_hi(); | |||||
} else { | |||||
data_lo(); | |||||
} | |||||
WAIT(clock_hi, 50, 2); | |||||
WAIT(clock_lo, 50, 3); | |||||
} | |||||
/* parity [10] */ | |||||
if (parity) { data_hi(); } else { data_lo(); } | |||||
WAIT(clock_hi, 50, 4); | |||||
WAIT(clock_lo, 50, 5); | |||||
/* stop bit [11] */ | |||||
data_hi(); | |||||
/* ack [12] */ | |||||
WAIT(data_lo, 50, 6); | |||||
WAIT(clock_lo, 50, 7); | |||||
WAIT(clock_hi, 50, 8); | |||||
WAIT(data_hi, 50, 9); | |||||
/* inhibit device to send */ | |||||
clock_lo(); | |||||
return 1; | |||||
ERROR: | |||||
return 0; | |||||
} | |||||
uint8_t ps2_host_recv(void) | |||||
{ | |||||
uint8_t data = 0; | |||||
bool parity = true; | |||||
ps2_error = 0; | |||||
/* cancel to sync */ | |||||
clock_lo(); | |||||
_delay_us(100); | |||||
/* release lines(idle state) */ | |||||
clock_hi(); | |||||
data_hi(); | |||||
/* start bit [1] */ | |||||
WAIT(clock_lo, 20000, 1); | |||||
WAIT(data_lo, 1, 2); | |||||
WAIT(clock_hi, 50, 3); | |||||
/* data [2-9] */ | |||||
for (uint8_t i = 0; i < 8; i++) { | |||||
WAIT(clock_lo, 50, 4); | |||||
if (data_in()) { | |||||
parity = !parity; | |||||
data |= (1<<i); | |||||
} | |||||
WAIT(clock_hi, 50, 5); | |||||
} | |||||
/* parity [10] */ | |||||
WAIT(clock_lo, 50, 6); | |||||
if (data_in() != parity) { | |||||
ps2_error = PS2_ERR_PARITY; | |||||
goto ERROR; | |||||
} | |||||
WAIT(clock_hi, 50, 7); | |||||
/* stop bit [11] */ | |||||
WAIT(clock_lo, 50, 8); | |||||
WAIT(data_hi, 1, 9); | |||||
WAIT(clock_hi, 50, 10); | |||||
/* inhibit device to send */ | |||||
clock_lo(); | |||||
return data; | |||||
ERROR: | |||||
return 0; | |||||
} | |||||
static inline void clock_lo() | |||||
{ | |||||
PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT); | |||||
PS2_CLOCK_DDR |= (1<<PS2_CLOCK_BIT); | |||||
} | |||||
static inline void clock_hi() | |||||
{ | |||||
/* input with pull up */ | |||||
PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT); | |||||
PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT); | |||||
} | |||||
static inline bool clock_in() | |||||
{ | |||||
PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT); | |||||
PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT); | |||||
return PS2_CLOCK_PIN&(1<<PS2_CLOCK_BIT); | |||||
} | |||||
static inline void data_lo() | |||||
{ | |||||
PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT); | |||||
PS2_DATA_DDR |= (1<<PS2_DATA_BIT); | |||||
} | |||||
static inline void data_hi() | |||||
{ | |||||
/* input with pull up */ | |||||
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); | |||||
PS2_DATA_PORT |= (1<<PS2_DATA_BIT); | |||||
} | |||||
static inline bool data_in() | |||||
{ | |||||
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); | |||||
PS2_DATA_PORT |= (1<<PS2_DATA_BIT); | |||||
return PS2_DATA_PIN&(1<<PS2_DATA_BIT); | |||||
} | |||||
static inline uint16_t wait_clock_lo(uint16_t us) | |||||
{ | |||||
while (clock_in() && us) { asm(""); _delay_us(1); us--; } | |||||
return us; | |||||
} | |||||
static inline uint16_t wait_clock_hi(uint16_t us) | |||||
{ | |||||
while (!clock_in() && us) { asm(""); _delay_us(1); us--; } | |||||
return us; | |||||
} | |||||
static inline uint16_t wait_data_lo(uint16_t us) | |||||
{ | |||||
while (data_in() && us) { asm(""); _delay_us(1); us--; } | |||||
return us; | |||||
} | |||||
static inline uint16_t wait_data_hi(uint16_t us) | |||||
{ | |||||
while (!data_in() && us) { asm(""); _delay_us(1); us--; } | |||||
return us; | |||||
} |
/* | |||||
Copyright (c) 2010 Jun WAKO <[email protected]> | |||||
This software is licensed with a Modified BSD License. | |||||
All of this is supposed to be Free Software, Open Source, DFSG-free, | |||||
GPL-compatible, and OK to use in both free and proprietary applications. | |||||
Additions and corrections to this file are welcome. | |||||
Redistribution and use in source and binary forms, with or without | |||||
modification, are permitted provided that the following conditions are met: | |||||
* Redistributions of source code must retain the above copyright | |||||
notice, this list of conditions and the following disclaimer. | |||||
* Redistributions in binary form must reproduce the above copyright | |||||
notice, this list of conditions and the following disclaimer in | |||||
the documentation and/or other materials provided with the | |||||
distribution. | |||||
* Neither the name of the copyright holders nor the names of | |||||
contributors may be used to endorse or promote products derived | |||||
from this software without specific prior written permission. | |||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||||
POSSIBILITY OF SUCH DAMAGE. | |||||
*/ | |||||
#ifndef PS2_H | |||||
#define PS2_H | |||||
/* | |||||
* Primitive PS/2 Library for AVR | |||||
*/ | |||||
/* port settings for clock and data line */ | |||||
#if !(defined(PS2_CLOCK_PORT) && \ | |||||
defined(PS2_CLOCK_PIN) && \ | |||||
defined(PS2_CLOCK_DDR) && \ | |||||
defined(PS2_CLOCK_BIT)) | |||||
# error "PS/2 clock port setting is required in config.h" | |||||
#endif | |||||
#if !(defined(PS2_DATA_PORT) && \ | |||||
defined(PS2_DATA_PIN) && \ | |||||
defined(PS2_DATA_DDR) && \ | |||||
defined(PS2_DATA_BIT)) | |||||
# error "PS/2 data port setting is required in config.h" | |||||
#endif | |||||
#define PS2_ERR_NONE 0 | |||||
#define PS2_ERR_PARITY 0x10 | |||||
extern uint8_t ps2_error; | |||||
/* host side */ | |||||
void ps2_host_init(void); | |||||
uint8_t ps2_host_send(uint8_t); | |||||
uint8_t ps2_host_recv(void); | |||||
/* TODO: device side */ | |||||
#endif |
#include <stdbool.h> | |||||
#include<avr/io.h> | |||||
#include<util/delay.h> | |||||
#include "ps2.h" | |||||
#include "ps2_mouse.h" | |||||
#include "usb_mouse.h" | |||||
#define PS2_MOUSE_DEBUG | |||||
#ifdef PS2_MOUSE_DEBUG | |||||
# include "print.h" | |||||
# include "debug.h" | |||||
#else | |||||
# define print(s) | |||||
# define phex(h) | |||||
# define phex16(h) | |||||
#endif | |||||
/* | |||||
TODO | |||||
---- | |||||
- Error handling | |||||
- Stream mode | |||||
- Tracpoint command support: needed | |||||
- Middle button + move = Wheel traslation | |||||
*/ | |||||
uint8_t ps2_mouse_x = 0; | |||||
uint8_t ps2_mouse_y = 0; | |||||
uint8_t ps2_mouse_btn = 0; | |||||
uint8_t ps2_mouse_error_count = 0; | |||||
static uint8_t ps2_mouse_btn_prev = 0; | |||||
void ps2_mouse_init(void) { | |||||
uint8_t rcv; | |||||
// Reset | |||||
rcv = ps2_host_send(0xFF); | |||||
print("ps2_mouse_init: send 0xFF: "); | |||||
phex(ps2_error); print("\n"); | |||||
// ACK | |||||
rcv = ps2_host_recv(); | |||||
print("ps2_mouse_init: read ACK: "); | |||||
phex(rcv); phex(ps2_error); print("\n"); | |||||
// BAT takes some time | |||||
_delay_ms(100); | |||||
rcv = ps2_host_recv(); | |||||
print("ps2_mouse_init: read BAT: "); | |||||
phex(rcv); phex(ps2_error); print("\n"); | |||||
// Device ID | |||||
rcv = ps2_host_recv(); | |||||
print("ps2_mouse_init: read DevID: "); | |||||
phex(rcv); phex(ps2_error); print("\n"); | |||||
// Enable data reporting | |||||
ps2_host_send(0xF4); | |||||
print("ps2_mouse_init: send 0xF4: "); | |||||
phex(ps2_error); print("\n"); | |||||
// ACK | |||||
rcv = ps2_host_recv(); | |||||
print("ps2_mouse_init: read ACK: "); | |||||
phex(rcv); phex(ps2_error); print("\n"); | |||||
// Set Remote mode | |||||
ps2_host_send(0xF0); | |||||
print("ps2_mouse_init: send 0xF0: "); | |||||
phex(ps2_error); print("\n"); | |||||
// ACK | |||||
rcv = ps2_host_recv(); | |||||
print("ps2_mouse_init: read ACK: "); | |||||
phex(rcv); phex(ps2_error); print("\n"); | |||||
if (ps2_error) ps2_mouse_error_count++; | |||||
} | |||||
/* | |||||
Data format: | |||||
bit: 7 6 5 4 3 2 1 0 | |||||
----------------------------------------------------------------------- | |||||
0 btn: Yovflw Xovflw Ysign Xsign 1 Middle Right Left | |||||
1 x: X movement(0-255) | |||||
2 y: Y movement(0-255) | |||||
*/ | |||||
void ps2_mouse_read(void) | |||||
{ | |||||
uint8_t rcv; | |||||
ps2_host_send(0xEB); | |||||
rcv=ps2_host_recv(); | |||||
if(rcv==0xFA) { | |||||
ps2_mouse_btn = ps2_host_recv(); | |||||
ps2_mouse_x = ps2_host_recv(); | |||||
ps2_mouse_y = ps2_host_recv(); | |||||
} | |||||
if (ps2_error) ps2_mouse_error_count++; | |||||
} | |||||
bool ps2_mouse_changed(void) | |||||
{ | |||||
return (ps2_mouse_x || ps2_mouse_y || (ps2_mouse_btn & PS2_MOUSE_BTN_MASK) != ps2_mouse_btn_prev); | |||||
} | |||||
#define PS2_MOUSE_SCROLL_BUTTON 0x04 | |||||
void ps2_mouse_usb_send(void) | |||||
{ | |||||
static bool scrolled = false; | |||||
if (ps2_mouse_changed()) { | |||||
int8_t x, y, v, h; | |||||
x = y = v = h = 0; | |||||
// convert scale of X, Y: PS/2(-256/255) -> USB(-127/127) | |||||
if (ps2_mouse_btn & (1<<PS2_MOUSE_X_SIGN)) | |||||
x = ps2_mouse_x > 128 ? (int8_t)ps2_mouse_x : -127; | |||||
else | |||||
x = ps2_mouse_x < 128 ? (int8_t)ps2_mouse_x : 127; | |||||
if (ps2_mouse_btn & (1<<PS2_MOUSE_Y_SIGN)) | |||||
y = ps2_mouse_y > 128 ? (int8_t)ps2_mouse_y : -127; | |||||
else | |||||
y = ps2_mouse_y < 128 ? (int8_t)ps2_mouse_y : 127; | |||||
// Y is needed to reverse | |||||
y = -y; | |||||
if (ps2_mouse_btn & PS2_MOUSE_SCROLL_BUTTON) { | |||||
// scroll | |||||
if (x > 0 || x < 0) h = (x > 64 ? 64 : (x < -64 ? -64 :x)); | |||||
if (y > 0 || y < 0) v = (y > 64 ? 64 : (y < -64 ? -64 :y)); | |||||
if (h || v) { | |||||
scrolled = true; | |||||
usb_mouse_send(0,0, -v/16, h/16, 0); | |||||
_delay_ms(100); | |||||
} | |||||
} else if (!scrolled && (ps2_mouse_btn_prev & PS2_MOUSE_SCROLL_BUTTON)) { | |||||
usb_mouse_send(0,0,0,0, PS2_MOUSE_SCROLL_BUTTON); | |||||
_delay_ms(100); | |||||
usb_mouse_send(0,0,0,0, 0); | |||||
} else { | |||||
scrolled = false; | |||||
usb_mouse_send(x, y, 0, 0, ps2_mouse_btn & PS2_MOUSE_BTN_MASK); | |||||
} | |||||
ps2_mouse_btn_prev = (ps2_mouse_btn & PS2_MOUSE_BTN_MASK); | |||||
ps2_mouse_print(); | |||||
} | |||||
ps2_mouse_x = 0; | |||||
ps2_mouse_y = 0; | |||||
ps2_mouse_btn = 0; | |||||
} | |||||
void ps2_mouse_print(void) | |||||
{ | |||||
if (!debug_mouse) return; | |||||
print("ps2_mouse[btn|x y]: "); | |||||
phex(ps2_mouse_btn); print("|"); | |||||
phex(ps2_mouse_x); print(" "); | |||||
phex(ps2_mouse_y); print("\n"); | |||||
} |
#ifndef PS2_MOUSE_H | |||||
#define PS2_MOUSE_H | |||||
#include <stdbool.h> | |||||
#define PS2_MOUSE_BTN_MASK 0x07 | |||||
#define PS2_MOUSE_BTN_LEFT 0 | |||||
#define PS2_MOUSE_BTN_RIGHT 1 | |||||
#define PS2_MOUSE_BTN_MIDDLE 2 | |||||
#define PS2_MOUSE_X_SIGN 4 | |||||
#define PS2_MOUSE_Y_SIGN 5 | |||||
#define PS2_MOUSE_X_OVFLW 6 | |||||
#define PS2_MOUSE_Y_OVFLW 7 | |||||
extern uint8_t ps2_mouse_x; | |||||
extern uint8_t ps2_mouse_y; | |||||
extern uint8_t ps2_mouse_btn; | |||||
extern uint8_t ps2_mouse_error_count; | |||||
void ps2_mouse_init(void); | |||||
void ps2_mouse_read(void); | |||||
bool ps2_mouse_changed(void); | |||||
void ps2_mouse_usb_send(void); | |||||
void ps2_mouse_print(void); | |||||
#endif |
#include "print.h" | #include "print.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
#include "util.h" | #include "util.h" | ||||
#include "controller.h" | |||||
#include "timer.h" | #include "timer.h" | ||||
#include "jump_bootloader.h" | #include "jump_bootloader.h" | ||||
#ifdef PS2_MOUSE_ENABLE | |||||
# include "ps2.h" | |||||
# include "ps2_mouse.h" | |||||
#endif | |||||
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) | #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) | ||||
jump_bootloader(); // not return | jump_bootloader(); // not return | ||||
} | } | ||||
#ifdef PS2_MOUSE_ENABLE | |||||
ps2_host_init(); | |||||
ps2_mouse_init(); | |||||
#endif | |||||
while (1) { | while (1) { | ||||
proc_matrix(); | proc_matrix(); | ||||
_delay_ms(2); | |||||
} | } | ||||
} | } |
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(MOUSE_SIZE) | MOUSE_BUFFER, // 2 | 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(MOUSE_SIZE) | MOUSE_BUFFER, // 2 | ||||
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER, // 3 | 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER, // 3 | ||||
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(EXTRA_SIZE) | EXTRA_BUFFER, // 4 | 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(EXTRA_SIZE) | EXTRA_BUFFER, // 4 | ||||
#ifdef NKRO_ENABLE | |||||
#ifdef USB_NKRO_ENABLE | |||||
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KBD2_SIZE) | KBD2_BUFFER, // 5 | 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KBD2_SIZE) | KBD2_BUFFER, // 5 | ||||
#else | #else | ||||
0, // 5 | 0, // 5 | ||||
0x81, 0x00, // Input (Data, Array), | 0x81, 0x00, // Input (Data, Array), | ||||
0xc0 // End Collection | 0xc0 // End Collection | ||||
}; | }; | ||||
#ifdef NKRO_ENABLE | |||||
#ifdef USB_NKRO_ENABLE | |||||
static uint8_t PROGMEM keyboard2_hid_report_desc[] = { | static uint8_t PROGMEM keyboard2_hid_report_desc[] = { | ||||
0x05, 0x01, // Usage Page (Generic Desktop), | 0x05, 0x01, // Usage Page (Generic Desktop), | ||||
0x09, 0x06, // Usage (Keyboard), | 0x09, 0x06, // Usage (Keyboard), | ||||
#define MOUSE_HID_DESC_OFFSET (9+(9+9+7)*1+9) | #define MOUSE_HID_DESC_OFFSET (9+(9+9+7)*1+9) | ||||
#define DEBUG_HID_DESC_OFFSET (9+(9+9+7)*2+9) | #define DEBUG_HID_DESC_OFFSET (9+(9+9+7)*2+9) | ||||
#define EXTRA_HID_DESC_OFFSET (9+(9+9+7)*3+9) | #define EXTRA_HID_DESC_OFFSET (9+(9+9+7)*3+9) | ||||
#ifdef NKRO_ENABLE | |||||
#ifdef USB_NKRO_ENABLE | |||||
# define NUM_INTERFACES 5 | # define NUM_INTERFACES 5 | ||||
# define KBD2_HID_DESC_OFFSET (9+(9+9+7)*4+9) | # define KBD2_HID_DESC_OFFSET (9+(9+9+7)*4+9) | ||||
#else | #else | ||||
EXTRA_SIZE, 0, // wMaxPacketSize | EXTRA_SIZE, 0, // wMaxPacketSize | ||||
10, // bInterval | 10, // bInterval | ||||
#ifdef NKRO_ENABLE | |||||
#ifdef USB_NKRO_ENABLE | |||||
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 | // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 | ||||
9, // bLength | 9, // bLength | ||||
4, // bDescriptorType | 4, // bDescriptorType | ||||
{0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)}, | {0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)}, | ||||
{0x2100, EXTRA_INTERFACE, config1_descriptor+EXTRA_HID_DESC_OFFSET, 9}, | {0x2100, EXTRA_INTERFACE, config1_descriptor+EXTRA_HID_DESC_OFFSET, 9}, | ||||
{0x2200, EXTRA_INTERFACE, extra_hid_report_desc, sizeof(extra_hid_report_desc)}, | {0x2200, EXTRA_INTERFACE, extra_hid_report_desc, sizeof(extra_hid_report_desc)}, | ||||
#ifdef NKRO_ENABLE | |||||
#ifdef USB_NKRO_ENABLE | |||||
{0x2100, KBD2_INTERFACE, config1_descriptor+KBD2_HID_DESC_OFFSET, 9}, | {0x2100, KBD2_INTERFACE, config1_descriptor+KBD2_HID_DESC_OFFSET, 9}, | ||||
{0x2200, KBD2_INTERFACE, keyboard2_hid_report_desc, sizeof(keyboard2_hid_report_desc)}, | {0x2200, KBD2_INTERFACE, keyboard2_hid_report_desc, sizeof(keyboard2_hid_report_desc)}, | ||||
#endif | #endif | ||||
if (bRequest == HID_GET_REPORT) { | if (bRequest == HID_GET_REPORT) { | ||||
if (wValue == HID_REPORT_INPUT) { | if (wValue == HID_REPORT_INPUT) { | ||||
usb_wait_in_ready(); | usb_wait_in_ready(); | ||||
UEDATX = mouse_buttons; | |||||
UEDATX = 0; | |||||
UEDATX = 0; | UEDATX = 0; | ||||
UEDATX = 0; | UEDATX = 0; | ||||
UEDATX = 0; | UEDATX = 0; | ||||
} | } | ||||
if (bRequest == HID_GET_PROTOCOL) { | if (bRequest == HID_GET_PROTOCOL) { | ||||
usb_wait_in_ready(); | usb_wait_in_ready(); | ||||
UEDATX = mouse_protocol; | |||||
UEDATX = usb_mouse_protocol; | |||||
usb_send_in(); | usb_send_in(); | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
if (bmRequestType == 0x21) { | if (bmRequestType == 0x21) { | ||||
if (bRequest == HID_SET_PROTOCOL) { | if (bRequest == HID_SET_PROTOCOL) { | ||||
mouse_protocol = wValue; | |||||
usb_mouse_protocol = wValue; | |||||
usb_send_in(); | usb_send_in(); | ||||
return; | return; | ||||
} | } |
// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana | // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana | ||||
volatile uint8_t usb_keyboard_leds=0; | volatile uint8_t usb_keyboard_leds=0; | ||||
// enable NKRO | |||||
// enable USB NKRO | |||||
bool usb_keyboard_nkro = false; | bool usb_keyboard_nkro = false; | ||||
{ | { | ||||
int8_t result = 0; | int8_t result = 0; | ||||
#ifdef NKRO_ENABLE | |||||
#ifdef USB_NKRO_ENABLE | |||||
if (usb_keyboard_nkro) | if (usb_keyboard_nkro) | ||||
result = _send_report(report, KBD2_ENDPOINT, 0, KBD2_REPORT_KEYS); | result = _send_report(report, KBD2_ENDPOINT, 0, KBD2_REPORT_KEYS); | ||||
else | else | ||||
static inline void _add_key_bit(uint8_t code); | static inline void _add_key_bit(uint8_t code); | ||||
void usb_keyboard_add_key(uint8_t code) | void usb_keyboard_add_key(uint8_t code) | ||||
{ | { | ||||
#ifdef NKRO_ENABLE | |||||
#ifdef USB_NKRO_ENABLE | |||||
if (usb_keyboard_nkro) { | if (usb_keyboard_nkro) { | ||||
_add_key_bit(code); | _add_key_bit(code); | ||||
return; | return; | ||||
void usb_keyboard_del_key(uint8_t code) | void usb_keyboard_del_key(uint8_t code) | ||||
{ | { | ||||
#ifdef NKRO_ENABLE | |||||
#ifdef USB_NKRO_ENABLE | |||||
if ((code>>3) < KEYS_MAX) { | if ((code>>3) < KEYS_MAX) { | ||||
usb_keyboard_keys[code>>3] &= ~(1<<(code&7)); | usb_keyboard_keys[code>>3] &= ~(1<<(code&7)); | ||||
} | } | ||||
uint8_t usb_keyboard_get_key(void) | uint8_t usb_keyboard_get_key(void) | ||||
{ | { | ||||
#ifdef NKRO_ENABLE | |||||
#ifdef USB_NKRO_ENABLE | |||||
if (usb_keyboard_nkro) { | if (usb_keyboard_nkro) { | ||||
uint8_t i = 0; | uint8_t i = 0; | ||||
for (; i < KEYS_MAX && !usb_keyboard_keys[i]; i++); | for (; i < KEYS_MAX && !usb_keyboard_keys[i]; i++); |
#define KBD_REPORT_KEYS (KBD_SIZE - 2) | #define KBD_REPORT_KEYS (KBD_SIZE - 2) | ||||
// secondary keyboard | // secondary keyboard | ||||
#ifdef NKRO_ENABLE | |||||
#ifdef USB_NKRO_ENABLE | |||||
#define KBD2_INTERFACE 4 | #define KBD2_INTERFACE 4 | ||||
#define KBD2_ENDPOINT 5 | #define KBD2_ENDPOINT 5 | ||||
#define KBD2_SIZE 16 | #define KBD2_SIZE 16 |
#include "debug.h" | #include "debug.h" | ||||
static bool is_sent = false; | |||||
uint8_t usb_mouse_protocol=1; | |||||
// which buttons are currently pressed | |||||
uint8_t mouse_buttons=0; | |||||
// protocol setting from the host. We use exactly the same report | |||||
// either way, so this variable only stores the setting since we | |||||
// are required to be able to report which setting is in use. | |||||
uint8_t mouse_protocol=1; | |||||
// Set the mouse buttons. To create a "click", 2 calls are needed, | |||||
// one to push the button down and the second to release it | |||||
int8_t usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right) | |||||
{ | |||||
uint8_t mask=0; | |||||
if (left) mask |= 1; | |||||
if (middle) mask |= 4; | |||||
if (right) mask |= 2; | |||||
mouse_buttons = mask; | |||||
return usb_mouse_move(0, 0, 0, 0); | |||||
} | |||||
// Move the mouse. x, y and wheel are -127 to 127. Use 0 for no movement. | |||||
int8_t usb_mouse_move(int8_t x, int8_t y, int8_t wheel, int8_t hwheel) | |||||
int8_t usb_mouse_send(int8_t x, int8_t y, int8_t wheel_v, int8_t wheel_h, uint8_t buttons) | |||||
{ | { | ||||
uint8_t intr_state, timeout; | uint8_t intr_state, timeout; | ||||
if (!usb_configured()) return -1; | if (!usb_configured()) return -1; | ||||
if (x == -128) x = -127; | if (x == -128) x = -127; | ||||
if (y == -128) y = -127; | if (y == -128) y = -127; | ||||
if (wheel == -128) wheel = -127; | |||||
if (hwheel == -128) hwheel = -127; | |||||
if (wheel_v == -128) wheel_v = -127; | |||||
if (wheel_h == -128) wheel_h = -127; | |||||
intr_state = SREG; | intr_state = SREG; | ||||
cli(); | cli(); | ||||
UENUM = MOUSE_ENDPOINT; | UENUM = MOUSE_ENDPOINT; | ||||
cli(); | cli(); | ||||
UENUM = MOUSE_ENDPOINT; | UENUM = MOUSE_ENDPOINT; | ||||
} | } | ||||
UEDATX = mouse_buttons; | |||||
UEDATX = buttons; | |||||
UEDATX = x; | UEDATX = x; | ||||
UEDATX = y; | UEDATX = y; | ||||
if (mouse_protocol) { | |||||
UEDATX = wheel; | |||||
UEDATX = hwheel; | |||||
if (usb_mouse_protocol) { | |||||
UEDATX = wheel_v; | |||||
UEDATX = wheel_h; | |||||
} | } | ||||
UEINTX = 0x3A; | UEINTX = 0x3A; | ||||
SREG = intr_state; | SREG = intr_state; | ||||
is_sent = true; | |||||
return 0; | return 0; | ||||
} | } | ||||
void usb_mouse_clear(void) { | |||||
is_sent = false; | |||||
} | |||||
bool usb_mouse_is_sent(void) { | |||||
return is_sent; | |||||
} | |||||
void usb_mouse_print(int8_t mouse_x, int8_t mouse_y, int8_t wheel_v, int8_t wheel_h) { | |||||
void usb_mouse_print(int8_t x, int8_t y, int8_t wheel_v, int8_t wheel_h, uint8_t buttons) { | |||||
if (!debug_mouse) return; | if (!debug_mouse) return; | ||||
print("mouse btn|x y v h: "); | |||||
phex(mouse_buttons); print("|"); | |||||
phex(mouse_x); print(" "); | |||||
phex(mouse_y); print(" "); | |||||
print("usb_mouse[btn|x y v h]: "); | |||||
phex(buttons); print("|"); | |||||
phex(x); print(" "); | |||||
phex(y); print(" "); | |||||
phex(wheel_v); print(" "); | phex(wheel_v); print(" "); | ||||
phex(wheel_h); print("\n"); | phex(wheel_h); print("\n"); | ||||
} | } |
#define MOUSE_SIZE 8 | #define MOUSE_SIZE 8 | ||||
#define MOUSE_BUFFER EP_DOUBLE_BUFFER | #define MOUSE_BUFFER EP_DOUBLE_BUFFER | ||||
#define BIT_BTN1 (1<<0) | |||||
#define BIT_BTN2 (1<<1) | |||||
#define BIT_BTN3 (1<<2) | |||||
#define BIT_BTN4 (1<<3) | |||||
#define BIT_BTN5 (1<<4) | |||||
#define MOUSE_BTN1 (1<<0) | |||||
#define MOUSE_BTN2 (1<<1) | |||||
#define MOUSE_BTN3 (1<<2) | |||||
#define MOUSE_BTN4 (1<<3) | |||||
#define MOUSE_BTN5 (1<<4) | |||||
extern uint8_t mouse_buttons; | |||||
extern uint8_t mouse_protocol; | |||||
extern uint8_t usb_mouse_protocol; | |||||
int8_t usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right); | |||||
int8_t usb_mouse_move(int8_t x, int8_t y, int8_t wheel, int8_t hwheel); | |||||
void usb_mouse_clear(void); | |||||
bool usb_mouse_is_sent(void); | |||||
void usb_mouse_print(int8_t mouse_x, int8_t mouse_y, int8_t wheel_v, int8_t wheel_h); | |||||
int8_t usb_mouse_send(int8_t x, int8_t y, int8_t wheel_v, int8_t wheel_h, uint8_t buttons); | |||||
void usb_mouse_print(int8_t x, int8_t y, int8_t wheel_v, int8_t wheel_h, uint8_t buttons); | |||||
#endif | #endif |