~ruther/qmk_firmware

9a938eecbd2b70c970992583b5c16da717d8e254 — tmk 14 years ago 2b8cd88
host interface for pjrc
M Makefile.common => Makefile.common +18 -1
@@ 1,18 1,35 @@
SRC +=	keyboard.c \
SRC +=	host.c \
	keyboard.c \
	command.c \
	layer.c \
	timer.c \
	print.c \
	util.c


# Option modules
ifdef MOUSEKEY_ENABLE
    SRC += mousekey.c
    OPT_DEFS += -DMOUSEKEY_ENABLE
endif

ifdef PS2_MOUSE_ENABLE
    SRC += ps2.c \
	   ps2_mouse.c
    OPT_DEFS += -DPS2_MOUSE_ENABLE
endif

ifdef USB_EXTRA_ENABLE
    OPT_DEFS += -DUSB_EXTRA_ENABLE
endif

ifdef USB_NKRO_ENABLE
    OPT_DEFS += -DUSB_NKRO_ENABLE
endif

ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE)
    OPT_DEFS += -DUSB_MOUSE_ENABLE
endif


include $(COMMON_DIR)/Makefile.rules

M Makefile.pjrc => Makefile.pjrc +6 -13
@@ 1,19 1,16 @@
# Following variables need to be set in <target>/Makefile:
# 	TARGET
# 	COMMON_DIR
# 	TARGET_DIR
# 	TARGET_SRC
# 	MCU
# 	F_CPU
OPT_DEFS += -DHOST_PJRC


# List C source files here. (C dependencies are automatically generated.)
SRC =	usb_keyboard.c \
	usb_debug.c \
	usb.c \
	jump_bootloader.c
SRC +=	$(TARGET_SRC)


# C source file search path
VPATH = $(TARGET_DIR):$(COMMON_DIR):$(COMMON_DIR)/pjrc


# Option modules
ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE)
    SRC += usb_mouse.c


@@ 22,7 19,3 @@ endif
ifdef USB_EXTRA_ENABLE
    SRC += usb_extra.c
endif


# C source file search path
VPATH = $(TARGET_DIR):$(COMMON_DIR):$(COMMON_DIR)/pjrc

M Makefile.rules => Makefile.rules +0 -16
@@ 78,22 78,6 @@ EXTRAINCDIRS = $(subst :, ,$(VPATH))
CSTANDARD = -std=gnu99


ifdef MOUSEKEY_ENABLE
    OPT_DEFS += -DMOUSEKEY_ENABLE
endif
ifdef PS2_MOUSE_ENABLE
    OPT_DEFS += -DPS2_MOUSE_ENABLE
endif
ifdef USB_EXTRA_ENABLE
    OPT_DEFS += -DUSB_EXTRA_ENABLE
endif
ifdef USB_NKRO_ENABLE
    OPT_DEFS += -DUSB_NKRO_ENABLE
endif
ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE)
    OPT_DEFS += -DUSB_MOUSE_ENABLE
endif

# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)UL
CDEFS += $(OPT_DEFS)

M Makefile.vusb => Makefile.vusb +1 -9
@@ 1,13 1,5 @@
# Following variables need to be set in <target>/Makefile:
# 	TARGET
# 	COMMON_DIR
# 	TARGET_DIR
# 	TARGET_SRC
# 	MCU
# 	F_CPU
OPT_DEFS += -DHOST_VUSB


# List C source files here. (C dependencies are automatically generated.)
SRC =	usbdrv.c \
	usbdrvasm.S \
	oddebug.c

A command.c => command.c +184 -0
@@ 0,0 1,184 @@
#include <stdint.h>
#include <stdbool.h>
#include <util/delay.h>
#include "usb_keycodes.h"
#include "host.h"
#include "print.h"
#include "debug.h"
#include "util.h"
#include "timer.h"
#include "layer.h"
#include "matrix_skel.h"
#include "command.h"

#ifdef HOST_PJRC
#   include "jump_bootloader.h"
#   include "usb_keyboard.h"
#   ifdef USB_EXTRA_ENABLE
#       include "usb_extra.h"
#   endif
#endif


static void help(void);
static void switch_layer(uint8_t layer);


uint8_t command_proc(void)
{
    if (!IS_COMMAND())
        return 0;

    uint8_t processed = 1;
    bool last_print_enable = print_enable;
    print_enable = true;
    switch (keyboard_report->keys[0]) {
        case KB_H:
            help();
            break;
        case KB_B:
#ifdef HOST_PJRC
            host_clear_keyboard_report();
            host_send_keyboard_report();
            print("jump to bootloader...\n");
            _delay_ms(1000);
            jump_bootloader(); // not return
#endif
            break;
        case KB_D:
            debug_enable = !debug_enable;
            if (debug_enable) {
                last_print_enable = true;
                print("debug enabled.\n");
                debug_matrix = true;
                debug_keyboard = true;
                debug_mouse = true;
            } else {
                print("debug disabled.\n");
                last_print_enable = false;
                debug_matrix = false;
                debug_keyboard = false;
                debug_mouse = false;
            }
            break;
        case KB_X: // debug matrix toggle
            debug_matrix = !debug_matrix;
            if (debug_matrix)
                print("debug matrix enabled.\n");
            else
                print("debug matrix disabled.\n");
            break;
        case KB_K: // debug keyboard toggle
            debug_keyboard = !debug_keyboard;
            if (debug_keyboard)
                print("debug keyboard enabled.\n");
            else
                print("debug keyboard disabled.\n");
            break;
        case KB_M: // debug mouse toggle
            debug_mouse = !debug_mouse;
            if (debug_mouse)
                print("debug mouse enabled.\n");
            else
                print("debug mouse disabled.\n");
            break;
        case KB_V: // print version & information
            print(STR(DESCRIPTION) "\n");
            break;
        case KB_T: // print timer
            print("timer: "); phex16(timer_count); print("\n");
            break;
        case KB_P: // print toggle
            if (print_enable) {
                print("print disabled.\n");
                last_print_enable = false;
            } else {
                last_print_enable = true;
                print("print enabled.\n");
            }
            break;
        case KB_S:
#ifdef HOST_PJRC
            print("UDCON: "); phex(UDCON); print("\n");
            print("UDIEN: "); phex(UDIEN); print("\n");
            print("UDINT: "); phex(UDINT); print("\n");
            print("host_keyboard_leds:"); phex(host_keyboard_leds()); print("\n");
#endif
            break;
#ifdef USB_NKRO_ENABLE
        case KB_N:
            keyboard_nkro = !keyboard_nkro;
            if (keyboard_nkro)
                print("USB_NKRO: enabled\n");
            else
                print("USB_NKRO: disabled\n");
            break;
#endif
#ifdef USB_EXTRA_ENABLE
        case KB_ESC:
            if (suspend && remote_wakeup) {
                usb_remote_wakeup();
            } else {
                usb_extra_system_send(SYSTEM_POWER_DOWN);
            }
            break;
#endif
        case KB_BSPC:
            matrix_init();
            print("clear matrix\n");
            break;
        case KB_0:
            switch_layer(0);
            break;
        case KB_1:
            switch_layer(1);
            break;
        case KB_2:
            switch_layer(2);
            break;
        case KB_3:
            switch_layer(3);
            break;
        case KB_4:
            switch_layer(4);
            break;
        default:
            processed = 0;
    }
    if (processed)
        _delay_ms(500);
    print_enable = last_print_enable;
    return processed;
}

static void help(void)
{
    print("b: jump to bootloader\n");
    print("d: toggle debug enable\n");
    print("x: toggle matrix debug\n");
    print("k: toggle keyboard debug\n");
    print("m: toggle mouse debug\n");
    print("p: toggle print enable\n");
    print("v: print version\n");
    print("t: print timer count\n");
    print("s: print status\n");
#ifdef USB_NKRO_ENABLE
    print("n: toggle USB_NKRO\n");
#endif
    print("Backspace: clear matrix\n");
    print("ESC: power down/wake up\n");
    print("0: switch to Layer0 \n");
    print("1: switch to Layer1 \n");
    print("2: switch to Layer2 \n");
    print("3: switch to Layer3 \n");
    print("4: switch to Layer4 \n");
}

static void switch_layer(uint8_t layer)
{
    print("current_layer: "); phex(current_layer); print("\n");
    print("default_layer: "); phex(default_layer); print("\n");
    current_layer = layer;
    default_layer = layer;
    print("switch to Layer: "); phex(layer); print("\n");
}

A command.h => command.h +6 -0
@@ 0,0 1,6 @@
#ifndef COMMAND_H
#define COMMAND

uint8_t command_proc(void);

#endif

M hhkb/Makefile => hhkb/Makefile +0 -1
@@ 9,7 9,6 @@ TARGET_DIR = .

# keyboard dependent files
TARGET_SRC =	tmk.c \
		host_pjrc.c \
		keymap.c \
  	        matrix.c \
		led.c

M hhkb/config.h => hhkb/config.h +5 -0
@@ 13,9 13,14 @@
/* matrix size */
#define MATRIX_ROWS 8
#define MATRIX_COLS 8

/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST

/* key combination for command */
#define IS_COMMAND() (keyboard_report->mods == (BIT_LSHIFT | BIT_RSHIFT))


/* USB NKey Rollover */
#ifdef USB_NKRO_ENABLE
#endif

A hhkb/led.c => hhkb/led.c +9 -0
@@ 0,0 1,9 @@
#include "stdint.h"
#include "led.h"


/* HHKB has no LEDs */
void led_set(uint8_t usb_led)
{
}


M host.h => host.h +17 -4
@@ 26,7 26,17 @@
#define MOUSE_BTN5 (1<<4)


#define REPORT_KEYS 6
#if defined(HOST_PJRC)
#   include "usb.h"
#   if defined(KBD2_REPORT_KEYS) && KBD2_REPORT_KEYS > KBD_REPORT_KEYS
#       define REPORT_KEYS KBD2_REPORT_KEYS
#   else
#       define REPORT_KEYS KBD_REPORT_KEYS
#   endif
#elif defined(HOST_VUSB)
#   define REPORT_KEYS 6
#endif

typedef struct {
    uint8_t mods;
    uint8_t rserved;


@@ 37,17 47,21 @@ typedef struct {
    uint8_t buttons;
    int8_t x;
    int8_t y;
/*
    int8_t v;
    int8_t h;
 */
} report_mouse_t;


#ifdef USB_NKRO_ENABLE
extern bool keyboard_nkro;
#endif

extern report_keyboard_t *keyboard_report;
extern report_keyboard_t *keyboard_report_prev;


uint8_t host_keyboard_leds(void);

/* keyboard report operations */
void host_add_key(uint8_t key);
void host_add_mod_bit(uint8_t mod);


@@ 61,7 75,6 @@ uint8_t host_get_mods(void);


void host_send_keyboard_report(void);
void host_send_mouse_report(void);
void host_mouse_send(report_mouse_t *report);

#endif

M keyboard.c => keyboard.c +9 -4
@@ 13,7 13,7 @@
#endif


static uint8_t last_led = 0;
static uint8_t last_leds = 0;


void keyboard_init(void)


@@ 125,8 125,13 @@ void keyboard_proc(void)
        ps2_mouse_usb_send();
#endif

    if (last_led != host_keyboard_led()) {
        led_set(host_keyboard_led());
        last_led = host_keyboard_led();
    if (last_leds != host_keyboard_leds()) {
        keyboard_set_leds(host_keyboard_leds());
        last_leds = host_keyboard_leds();
    }
}

void keyboard_set_leds(uint8_t leds)
{
    led_set(leds);
}

M keyboard.h => keyboard.h +3 -2
@@ 1,10 1,11 @@
#ifndef KEYBOARD_H
#define KEYBOARD_H

#include <stdint.h>


void keyboard_init(void);
void keyboard_proc(void);
void keyboard_set_leds(uint8_t leds);

#endif



M layer.c => layer.c +1 -0
@@ 4,6 4,7 @@
#include "timer.h"
#include "layer.h"


/*
 * Parameters:
 *     ENTER_DELAY         |=======|

M mousekey.c => mousekey.c +18 -24
@@ 24,11 24,15 @@ static void mousekey_debug(void);
#   define MOUSEKEY_DELAY_TIME 255
#endif

// acceleration parameters
uint8_t mousekey_move_unit = 2;
uint8_t mousekey_resolution = 5;


static inline uint8_t move_unit(void)
{
    uint16_t unit = 10 + (mousekey_repeat);
    return (unit > 127 ? 127 : unit);
    uint16_t unit = 5 + mousekey_repeat*2;
    return (unit > 63 ? 63 : unit);
}

void mousekey_decode(uint8_t code)


@@ 40,23 44,18 @@ void mousekey_decode(uint8_t code)
    else if (code == KB_MS_BTN1)    report.buttons |= MOUSE_BTN1;
    else if (code == KB_MS_BTN2)    report.buttons |= MOUSE_BTN2;
    else if (code == KB_MS_BTN3)    report.buttons |= MOUSE_BTN3;
/*
    else if (code == KB_MS_BTN4)    report.buttons |= MOUSE_BTN4;
    else if (code == KB_MS_BTN5)    report.buttons |= MOUSE_BTN5;
    else if (code == KB_MS_WH_UP)   report.v += 1;
    else if (code == KB_MS_WH_DOWN) report.v -= 1;
    else if (code == KB_MS_WH_LEFT) report.h -= 1;
    else if (code == KB_MS_WH_RIGHT)report.h += 1;
*/
}

bool mousekey_changed(void)
{
    return (report.buttons != report_prev.buttons ||
            report.x != report_prev.x ||
            report.y != report_prev.y ||
            report.x || report.y);
    //return (report.buttons != report_prev.buttons || report.x || report.y);
            report.x || report.y || report.v || report.h);
}

void mousekey_send(void)


@@ 65,36 64,30 @@ void mousekey_send(void)

    if (!mousekey_changed()) {
        mousekey_repeat = 0;
        mousekey_clear_report();
        return;
    }

    // send immediately when buttun state is changed
    if (report.buttons == report_prev.buttons) {
        // TODO: delay parameter setting
        if ((timer_elapsed(last_timer) < (mousekey_repeat == 1 ? 20 : 5))) {
        if (timer_elapsed(last_timer) < 5) {
            mousekey_clear_report();
            return;
        }
    }

    if (mousekey_repeat != 0xFF) {
        mousekey_repeat++;
    }

    if (report.x && report.y) {
        report.x *= 0.7;
        report.y *= 0.7;
    }

    /*
    print("mousekey_repeat: "); phex(mousekey_repeat); print("\n");
    print("timer: "); phex16(timer_read()); print("\n");
    print("last_timer: "); phex16(last_timer); print("\n");
    print("mousekey: "); phex(report.buttons); print(" "); phex(report.x); print(" "); phex(report.y); print("\n");
    */

    mousekey_debug();

    host_mouse_send(&report);
    report_prev.buttons = report.buttons;
    report_prev.x = report.x;
    report_prev.y = report.y;
    if (mousekey_repeat != 0xFF) mousekey_repeat++;
    report_prev = report;
    last_timer = timer_read();
    mousekey_clear_report();
}


@@ 104,6 97,8 @@ void mousekey_clear_report(void)
    report.buttons = 0;
    report.x = 0;
    report.y = 0;
    report.v = 0;
    report.h = 0;
}

static void mousekey_debug(void)


@@ 113,9 108,8 @@ static void mousekey_debug(void)
    phex(report.buttons); print("|");
    phex(report.x); print(" ");
    phex(report.y); print(" ");
/*
    phex(report.v); print(" ");
    phex(report.h);
*/
    phex(mousekey_repeat);
    print("\n");
}

A pjrc/host.c => pjrc/host.c +135 -0
@@ 0,0 1,135 @@
#include <stdint.h>
#include "usb_keycodes.h"
#include "usb_keyboard.h"
#include "usb_mouse.h"
#include "debug.h"
#include "host.h"


#ifdef USB_NKRO_ENABLE
bool keyboard_nkro = false;
#endif

static report_keyboard_t report0;
static report_keyboard_t report1;
report_keyboard_t *keyboard_report = &report0;
report_keyboard_t *keyboard_report_prev = &report1;

static inline void add_key_byte(uint8_t code);
static inline void add_key_bit(uint8_t code);


uint8_t host_keyboard_leds(void)
{
    return usb_keyboard_leds;
}

/* keyboard report operations */
void host_add_key(uint8_t key)
{
#ifdef USB_NKRO_ENABLE
    if (keyboard_nkro) {
        add_key_bit(key);
        return;
    }
#endif
    add_key_byte(key);
}

void host_add_mod_bit(uint8_t mod)
{
    keyboard_report->mods |= mod;
}

void host_set_mods(uint8_t mods)
{
    keyboard_report->mods = mods;
}

void host_add_code(uint8_t code)
{
    if (IS_MOD(code)) {
        host_add_mod_bit(MOD_BIT(code));
    } else {
        host_add_key(code);
    }
}

void host_swap_keyboard_report(void)
{
    report_keyboard_t *tmp = keyboard_report_prev;
    keyboard_report_prev = keyboard_report;
    keyboard_report = tmp;
}

void host_clear_keyboard_report(void)
{
    keyboard_report->mods = 0;
    for (int8_t i = 0; i < REPORT_KEYS; i++) {
        keyboard_report->keys[i] = 0;
    }
}

uint8_t host_has_anykey(void)
{
    uint8_t cnt = 0;
    for (int i = 0; i < REPORT_KEYS; i++) {
        if (keyboard_report->keys[i])
            cnt++;
    }
    return cnt;
}

uint8_t *host_get_keys(void)
{
    return keyboard_report->keys;
}

uint8_t host_get_mods(void)
{
    return keyboard_report->mods;
}


void host_send_keyboard_report(void)
{
    usb_keyboard_send_report(keyboard_report);
}

void host_mouse_send(report_mouse_t *report)
{
    usb_mouse_send(report->x, report->y, report->v, report->h, report->buttons);
}


static inline void add_key_byte(uint8_t code)
{
    // TODO: fix ugly code
    int8_t i = 0;
    int8_t empty = -1;
    for (; i < REPORT_KEYS; i++) {
        if (keyboard_report_prev->keys[i] == code) {
            keyboard_report->keys[i] = code;
            break;
        }
        if (empty == -1 &&
                keyboard_report_prev->keys[i] == 0 &&
                keyboard_report->keys[i] == 0) {
            empty = i;
        }
    }
    if (i == REPORT_KEYS) {
        if (empty != -1) {
            keyboard_report->keys[empty] = code;
        }
    }
}

static inline void add_key_bit(uint8_t code)
{
    if ((code>>3) < REPORT_KEYS) {
        keyboard_report->keys[code>>3] |= 1<<(code&7);
    } else {
        debug("add_key_bit: can't add: "); phex(code); debug("\n");
    }
}

M pjrc/usb.c => pjrc/usb.c +4 -4
@@ 687,10 687,10 @@ ISR(USB_GEN_vect)
				usb_keyboard_idle_count++;
				if (usb_keyboard_idle_count == usb_keyboard_idle_config) {
					usb_keyboard_idle_count = 0;
					UEDATX = usb_keyboard_mods;
					UEDATX = keyboard_report->mods;
					UEDATX = 0;
					for (i=0; i<6; i++) {
						UEDATX = usb_keyboard_keys[i];
						UEDATX = keyboard_report->keys[i];
					}
					UEINTX = 0x3A;
				}


@@ 873,10 873,10 @@ ISR(USB_COM_vect)
			if (bmRequestType == 0xA1) {
				if (bRequest == HID_GET_REPORT) {
					usb_wait_in_ready();
					UEDATX = usb_keyboard_mods;
					UEDATX = keyboard_report->mods;
					UEDATX = 0;
					for (i=0; i<6; i++) {
						UEDATX = usb_keyboard_keys[i];
						UEDATX = keyboard_report->keys[i];
					}
					usb_send_in();
					return;

M pjrc/usb.h => pjrc/usb.h +19 -2
@@ 14,8 14,6 @@ uint8_t usb_configured(void);		// is the USB port configured
void usb_remote_wakeup(void);




#define EP_TYPE_CONTROL			0x00
#define EP_TYPE_BULK_IN			0x81
#define EP_TYPE_BULK_OUT		0x80


@@ 88,4 86,23 @@ void usb_remote_wakeup(void);
#define ENDPOINT_HALT			0
#define TEST_MODE			2


/*------------------------------------------------------------------*
 * Keyboard descriptor setting
 *------------------------------------------------------------------*/
#define KBD_INTERFACE		0
#define KBD_ENDPOINT		1
#define KBD_SIZE		8
#define KBD_BUFFER		EP_DOUBLE_BUFFER
#define KBD_REPORT_KEYS		(KBD_SIZE - 2)

// secondary keyboard
#ifdef USB_NKRO_ENABLE
#define KBD2_INTERFACE		4
#define KBD2_ENDPOINT		5
#define KBD2_SIZE		16
#define KBD2_BUFFER		EP_DOUBLE_BUFFER
#define KBD2_REPORT_KEYS	(KBD2_SIZE - 1)
#endif

#endif

M pjrc/usb_keyboard.c => pjrc/usb_keyboard.c +11 -172
@@ 5,14 5,9 @@
#include "print.h"
#include "debug.h"
#include "util.h"
#include "host.h"


// keyboard report.
static usb_keyboard_report_t _report0 = { {0}, 0, false };
static usb_keyboard_report_t _report1 = { {0}, 0, false };
usb_keyboard_report_t *usb_keyboard_report = &_report0;
usb_keyboard_report_t *usb_keyboard_report_prev = &_report1;

// 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.


@@ 28,167 23,42 @@ uint8_t usb_keyboard_idle_count=0;
// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
volatile uint8_t usb_keyboard_leds=0;

// enable USB NKRO
bool usb_keyboard_nkro = false;

static inline int8_t send_report(report_keyboard_t *report, uint8_t endpoint, uint8_t keys_start, uint8_t keys_end);

int8_t usb_keyboard_send(void)
{
    return usb_keyboard_send_report(usb_keyboard_report);
}

static inline int8_t _send_report(usb_keyboard_report_t *report, uint8_t endpoint, uint8_t keys_start, uint8_t keys_end);
int8_t usb_keyboard_send_report(usb_keyboard_report_t *report)
int8_t usb_keyboard_send_report(report_keyboard_t *report)
{
    int8_t result = 0;

#ifdef USB_NKRO_ENABLE
    if (usb_keyboard_nkro)
        result = _send_report(report, KBD2_ENDPOINT, 0, KBD2_REPORT_KEYS);
    if (keyboard_nkro)
        result = send_report(report, KBD2_ENDPOINT, 0, KBD2_REPORT_KEYS);
    else
#endif
    {
        if (usb_keyboard_protocol)
            result = _send_report(report, KBD_ENDPOINT, 0, KBD_REPORT_KEYS);
            result = send_report(report, KBD_ENDPOINT, 0, KBD_REPORT_KEYS);
        else
            result = _send_report(report, KBD_ENDPOINT, 0, 6);
            result = send_report(report, KBD_ENDPOINT, 0, 6);
    }

    if (result) return result;
    usb_keyboard_idle_count = 0;
    report->is_sent =true;
    usb_keyboard_print_report(report);
    return 0;
}

void usb_keyboard_swap_report(void) {
    usb_keyboard_report_t *tmp = usb_keyboard_report_prev;
    usb_keyboard_report_prev = usb_keyboard_report;
    usb_keyboard_report = tmp;
}

void usb_keyboard_clear_report(void) {
    usb_keyboard_clear_keys();
    usb_keyboard_clear_mods();
    usb_keyboard_report->is_sent = false;
}

void usb_keyboard_clear_keys(void) {
    for (int i = 0; i < KEYS_MAX; i++) usb_keyboard_report->keys[i] = 0;
}

void usb_keyboard_clear_mods(void)
{
    usb_keyboard_report->mods = 0;
}

void usb_keyboard_set_keys(uint8_t *keys)
{
    for (int i = 0; i < KEYS_MAX; i++)
        usb_keyboard_report->keys[i] = keys[i];
}

void usb_keyboard_set_mods(uint8_t mods)
{
    usb_keyboard_report->mods = mods;
}

void usb_keyboard_add_code(uint8_t code)
{
    if (IS_MOD(code)) {
        usb_keyboard_add_mod(code);
    } else {
        usb_keyboard_add_key(code);
    }
}

static inline void _add_key_byte(uint8_t code);
static inline void _add_key_bit(uint8_t code);
void usb_keyboard_add_key(uint8_t code)
{
#ifdef USB_NKRO_ENABLE
    if (usb_keyboard_nkro) {
        _add_key_bit(code);
        return;
    }
#endif
    _add_key_byte(code);
}

void usb_keyboard_add_mod(uint8_t code)
{
    usb_keyboard_report->mods |= MOD_BIT(code);
}

void usb_keyboard_del_code(uint8_t code)
{
    if (IS_MOD(code)) {
        usb_keyboard_del_mod(code);
    } else {
        usb_keyboard_del_key(code);
    }
}

void usb_keyboard_del_key(uint8_t code)
{
#ifdef USB_NKRO_ENABLE
    if ((code>>3) < KEYS_MAX) {
        usb_keyboard_keys[code>>3] &= ~(1<<(code&7));
    }
#else
    for (int i = 0; i < KEYS_MAX; i++) {
        if (usb_keyboard_report->keys[i] == code) {
            usb_keyboard_report->keys[i] = KB_NO;
            return;
        }
    }
#endif
}

void usb_keyboard_del_mod(uint8_t code)
{
    usb_keyboard_report->mods &= ~MOD_BIT(code);
}

bool usb_keyboard_is_sent(void)
{
    return usb_keyboard_report->is_sent;
}

bool usb_keyboard_has_key(void)
{
    uint8_t keys = 0;    
    for (int i = 0; i < KEYS_MAX; i++) keys |= usb_keyboard_report->keys[i];
    return keys ? true : false;
}

bool usb_keyboard_has_mod(void)
{
    return usb_keyboard_report->mods ? true : false;
}

uint8_t usb_keyboard_get_key(void)
{
#ifdef USB_NKRO_ENABLE
    if (usb_keyboard_nkro) {
        uint8_t i = 0;
        for (; i < KEYS_MAX && !usb_keyboard_keys[i]; i++);
        return i<<3 | biton(usb_keyboard_keys[i]);
    }
#endif
    return usb_keyboard_keys[0];
}

void usb_keyboard_print_report(usb_keyboard_report_t *report)
void usb_keyboard_print_report(report_keyboard_t *report)
{
    if (!debug_keyboard) return;
    print("keys: ");
    for (int i = 0; i < KEYS_MAX; i++) { phex(report->keys[i]); print(" "); }
    for (int i = 0; i < REPORT_KEYS; i++) { phex(report->keys[i]); print(" "); }
    print(" mods: "); phex(report->mods); print("\n");
}


static inline int8_t _send_report(usb_keyboard_report_t *report, uint8_t endpoint, uint8_t keys_start, uint8_t keys_end)
static inline int8_t send_report(report_keyboard_t *report, uint8_t endpoint, uint8_t keys_start, uint8_t keys_end)
{
    uint8_t intr_state, timeout;



@@ 211,7 81,7 @@ static inline int8_t _send_report(usb_keyboard_report_t *report, uint8_t endpoin
            UENUM = endpoint;
    }
    UEDATX = report->mods;
    if (!usb_keyboard_nkro)
    if (!keyboard_nkro)
        UEDATX = 0;
    for (uint8_t i = keys_start; i < keys_end; i++) {
            UEDATX = report->keys[i];


@@ 220,34 90,3 @@ static inline int8_t _send_report(usb_keyboard_report_t *report, uint8_t endpoin
    SREG = intr_state;
    return 0;
}

static inline void _add_key_byte(uint8_t code)
{
    // TODO: fix ugly code
    int8_t i = 0;
    int8_t empty = -1;
    for (; i < KEYS_MAX; i++) {
        if (usb_keyboard_keys_prev[i] == code) {
            usb_keyboard_keys[i] = code;
            break;
        }
        if (empty == -1 &&
                usb_keyboard_keys_prev[i] == 0 &&
                usb_keyboard_keys[i] == 0) {
            empty = i;
        }
    }
    if (i == KEYS_MAX) {
        if (empty != -1) {
            usb_keyboard_keys[empty] = code;
        }
    }
}

static inline void _add_key_bit(uint8_t code)
{
    if ((code>>3) < KEYS_MAX) {
        usb_keyboard_keys[code>>3] |= 1<<(code&7);
    }
}


M pjrc/usb_keyboard.h => pjrc/usb_keyboard.h +3 -65
@@ 4,78 4,16 @@
#include <stdint.h>
#include <stdbool.h>
#include "usb.h"
#include "host.h"


#define KBD_INTERFACE		0
#define KBD_ENDPOINT		1
#define KBD_SIZE		8
#define KBD_BUFFER		EP_DOUBLE_BUFFER
#define KBD_REPORT_KEYS		(KBD_SIZE - 2)

// secondary keyboard
#ifdef USB_NKRO_ENABLE
#define KBD2_INTERFACE		4
#define KBD2_ENDPOINT		5
#define KBD2_SIZE		16
#define KBD2_BUFFER		EP_DOUBLE_BUFFER
#define KBD2_REPORT_KEYS	(KBD2_SIZE - 1)
#endif

#if defined(KBD2_REPORT_KEYS) && KBD2_REPORT_KEYS > KBD_REPORT_KEYS
#define KEYS_MAX KBD2_REPORT_KEYS
#else
#define KEYS_MAX KBD_REPORT_KEYS
#endif


typedef struct report {
    uint8_t keys[KEYS_MAX];
    uint8_t mods;
    bool is_sent;
} usb_keyboard_report_t;


#define usb_keyboard_keys usb_keyboard_report->keys
#define usb_keyboard_mods usb_keyboard_report->mods
#define usb_keyboard_keys_prev usb_keyboard_report_prev->keys
#define usb_keyboard_mods_prev usb_keyboard_report_prev->mods


extern usb_keyboard_report_t *usb_keyboard_report;
extern usb_keyboard_report_t *usb_keyboard_report_prev;
extern uint8_t usb_keyboard_protocol;
extern uint8_t usb_keyboard_idle_config;
extern uint8_t usb_keyboard_idle_count;
extern volatile uint8_t usb_keyboard_leds;
extern bool usb_keyboard_nkro;


int8_t usb_keyboard_send(void);
int8_t usb_keyboard_send_report(usb_keyboard_report_t *report);

void usb_keyboard_swap_report(void);

void usb_keyboard_clear_report(void);
void usb_keyboard_clear_keys(void);
void usb_keyboard_clear_mods(void);

void usb_keyboard_set_keys(uint8_t *keys);
void usb_keyboard_set_mods(uint8_t mods);

void usb_keyboard_add_code(uint8_t code);
void usb_keyboard_add_key(uint8_t code);
void usb_keyboard_add_mod(uint8_t code);

void usb_keyboard_del_code(uint8_t code);
void usb_keyboard_del_key(uint8_t code);
void usb_keyboard_del_mod(uint8_t code);

bool usb_keyboard_is_sent(void);
bool usb_keyboard_has_key(void);
bool usb_keyboard_has_mod(void);

uint8_t usb_keyboard_get_key(void);

void usb_keyboard_print_report(usb_keyboard_report_t *report);
int8_t usb_keyboard_send_report(report_keyboard_t *report);
void usb_keyboard_print_report(report_keyboard_t *report);

#endif

M ps2_vusb/Makefile => ps2_vusb/Makefile +0 -1
@@ 13,7 13,6 @@ TARGET_SRC =	main.c \
		matrix.c \
		led.c \
		ps2.c \
		host_vusb.c \
		usart_print.c

OPT_DEFS = -DDEBUG_LEVEL=0

A ps2_vusb/README => ps2_vusb/README +12 -0
@@ 0,0 1,12 @@
PS/2 to USB keyboard converter with V-USB
=========================================
2011/02/07

NOT COMPLETED
development was suspended.

TODO:
PS/2 library:   losts data from keyboard occasionally,
                should use interrupt thoroughly for communication.

Code cleaning:  merge code changed here to other subprojects and common modules.

M ps2_vusb/config.h => ps2_vusb/config.h +7 -7
@@ 11,8 11,13 @@
/* matrix size */
#define MATRIX_ROWS 32  // keycode bit: 3-0
#define MATRIX_COLS 8   // keycode bit: 6-4
/* define if matrix has ghost */
//#define MATRIX_HAS_GHOST

/* key combination for command */
#define IS_COMMAND() ( \
    keyboard_report->mods == (BIT_LSHIFT | BIT_RSHIFT) || \
    keyboard_report->mods == (BIT_LCTRL | BIT_RSHIFT) \
)


/* USB NKey Rollover */
#ifdef USB_NKRO_ENABLE


@@ 23,11 28,6 @@
#   define MOUSEKEY_DELAY_TIME 255
#endif

#define IS_COMMAND() ( \
    keyboard_report->mods == (BIT_LSHIFT | BIT_RSHIFT) || \
    keyboard_report->mods == (BIT_LCTRL | BIT_RSHIFT) \
)


/* PS/2 lines */
#define PS2_CLOCK_PORT  PORTD

R ps2_vusb/host_vusb.c => vusb/host.c +4 -4
@@ 12,12 12,12 @@ static report_keyboard_t report1;
report_keyboard_t *keyboard_report = &report0;
report_keyboard_t *keyboard_report_prev = &report1;

static uint8_t keyboard_led = 0;
static uint8_t keyboard_leds = 0;
static uchar   idleRate = 0;

uint8_t host_keyboard_led(void)
uint8_t host_keyboard_leds(void)
{
    return keyboard_led;
    return keyboard_leds;
}




@@ 190,7 190,7 @@ uchar usbFunctionWrite(uchar *data, uchar len)
    switch (last_req.kind) {
        case SET_LED:
            //debug("SET_LED\n");
            keyboard_led = data[0];
            keyboard_leds = data[0];
            last_req.len = 0;
            return 1;
            break;

R ps2_vusb/host_vusb.h => vusb/host_vusb.h +0 -0