# Object files directory
# To put object files in current directory, use a dot (.), do NOT make
# this an empty or blank macro!
-OBJDIR = obj
+OBJDIR = obj_$(TARGET)
# Optimization level, can be [0, 1, 2, 3, s].
CFLAGS += -Wa,-adhlns=$(@:%.o=%.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)
-CFLAGS += -include config.h
+CFLAGS += -include $(CONFIG_H)
#---------------- Compiler Options C++ ----------------
CPPFLAGS += -Wa,-adhlns=$(@:%.o=%.lst)
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
#CPPFLAGS += $(CSTANDARD)
-CPPFLAGS += -include config.h
+CPPFLAGS += -include $(CONFIG_H)
#---------------- Assembler Options ----------------
# -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.
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(@:%.o=%.lst),-gstabs,--listing-cont-lines=100
-ASFLAGS += -include config.h
+ASFLAGS += -include $(CONFIG_H)
#---------------- Library Options ----------------
SIZE = avr-size
AR = avr-ar rcs
NM = avr-nm
-AVRDUDE = avrdude
REMOVE = rm -f
REMOVEDIR = rmdir
COPY = cp
# Program the device.
program: $(TARGET).hex $(TARGET).eep
- $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
+ $(PROGRAM_CMD)
# Generate avr-gdb config/init file which does the following:
#include "util.h"
#include "timer.h"
#include "layer.h"
-#include "matrix_skel.h"
+#include "matrix.h"
#include "command.h"
#ifdef HOST_PJRC
break;
#ifdef USB_NKRO_ENABLE
case KB_N:
+ host_clear_keyboard_report();
+ host_send_keyboard_report();
keyboard_nkro = !keyboard_nkro;
if (keyboard_nkro)
print("USB_NKRO: enabled\n");
+++ /dev/null
-#include <stdbool.h>
-#include <avr/io.h>
-#include <avr/interrupt.h>
-#include <util/delay.h>
-#include "print.h"
-#include "debug.h"
-#include "timer.h"
-#include "util.h"
-#include "jump_bootloader.h"
-#include "usb_keyboard.h"
-#include "usb_keycodes.h"
-#include "usb.h"
-#include "layer.h"
-#include "matrix_skel.h"
-#include "keymap_skel.h"
-#include "key_process.h"
-#ifdef MOUSEKEY_ENABLE
-# include "mousekey.h"
-#endif
-#ifdef PS2_MOUSE_ENABLE
-# include "ps2_mouse.h"
-#endif
-#ifdef USB_EXTRA_ENABLE
-# include "usb_extra.h"
-#endif
-#ifdef USB_MOUSE_ENABLE
-# include "usb_mouse.h"
-#endif
-
-
-// TODO: refactoring
-void proc_matrix(void) {
- bool modified = false;
- uint8_t fn_bits = 0;
-
- matrix_scan();
- modified = matrix_is_modified();
-
- if (modified) {
- if (debug_matrix) matrix_print();
-#ifdef DEBUG_LED
- // LED flash for debug
- DEBUG_LED_CONFIG;
- DEBUG_LED_ON;
-#endif
- }
-
- if (matrix_has_ghost()) {
- // should send error?
- debug("matrix has ghost!!\n");
- return;
- }
-
- usb_keyboard_swap_report();
- usb_keyboard_clear_report();
- for (int row = 0; row < matrix_rows(); row++) {
- for (int col = 0; col < matrix_cols(); col++) {
- if (!matrix_is_on(row, col)) continue;
-
- uint8_t code = layer_get_keycode(row, col);
- if (code == KB_NO) {
- // do nothing
- } else if (IS_MOD(code)) {
- usb_keyboard_add_mod(code);
- } else if (IS_FN(code)) {
- fn_bits |= FN_BIT(code);
- }
-#ifdef MOUSEKEY_ENABLE
- else if (IS_MOUSEKEY(code)) {
- mousekey_decode(code);
- }
-#endif
-#ifdef USB_EXTRA_ENABLE
- // audio control & system control
- else if (code == KB_MUTE) {
- usb_extra_audio_send(AUDIO_MUTE);
- usb_extra_audio_send(0);
- _delay_ms(500);
- } else if (code == KB_VOLU) {
- usb_extra_audio_send(AUDIO_VOL_UP);
- usb_extra_audio_send(0);
- _delay_ms(200);
- } else if (code == KB_VOLD) {
- usb_extra_audio_send(AUDIO_VOL_DOWN);
- usb_extra_audio_send(0);
- _delay_ms(200);
- } else if (code == KB_PWR) {
- if (suspend && remote_wakeup) {
- usb_remote_wakeup();
- } else {
- usb_extra_system_send(SYSTEM_POWER_DOWN);
- }
- _delay_ms(1000);
- }
-#endif
- // normal key
- else if (IS_KEY(code)) {
- usb_keyboard_add_key(code);
- } else {
- debug("ignore keycode: "); debug_hex(code); debug("\n");
- }
- }
- }
-
- if (modified) {
-#ifdef DEBUG_LED
- // LED flash for debug
- DEBUG_LED_CONFIG;
- DEBUG_LED_OFF;
-#endif
- }
-
- layer_switching(fn_bits);
-
- // TODO: clean code
- // special mode for control, develop and debug
- if (keymap_is_special_mode(fn_bits)) {
- switch (usb_keyboard_get_key()) {
- case KB_H: // help
- usb_keyboard_clear_report();
- usb_keyboard_send();
- print_enable = true;
- 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");
- print("`: toggle protcol(boot/report)\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");
-#ifdef PS2_MOUSE_ENABLE
- print("[: ps2_mouse_init \n");
- print("]: ps2_mouse_read \n");
- print("\: ps2_mouse: on/off toggle \n");
-#endif
- _delay_ms(500);
- print_enable = false;
- break;
- case KB_BSPC:
- usb_keyboard_clear_report();
- usb_keyboard_send();
- matrix_init();
- print("clear matrix\n");
- _delay_ms(500);
- break;
- case KB_0:
- usb_keyboard_clear_report();
- usb_keyboard_send();
- print("current_layer: "); phex(current_layer); print("\n");
- print("default_layer: "); phex(default_layer); print("\n");
- current_layer = 0;
- default_layer = 0;
- print("switch to Layer0 \n");
- _delay_ms(500);
- break;
- case KB_1:
- usb_keyboard_clear_report();
- usb_keyboard_send();
- print("current_layer: "); phex(current_layer); print("\n");
- print("default_layer: "); phex(default_layer); print("\n");
- current_layer = 1;
- default_layer = 1;
- print("switch to Layer1 \n");
- _delay_ms(500);
- break;
- case KB_2:
- usb_keyboard_clear_report();
- usb_keyboard_send();
- print("current_layer: "); phex(current_layer); print("\n");
- print("default_layer: "); phex(default_layer); print("\n");
- current_layer = 2;
- default_layer = 2;
- print("switch to Layer2 \n");
- _delay_ms(500);
- break;
- case KB_3:
- usb_keyboard_clear_report();
- usb_keyboard_send();
- print("current_layer: "); phex(current_layer); print("\n");
- print("default_layer: "); phex(default_layer); print("\n");
- current_layer = 3;
- default_layer = 3;
- print("switch to Layer3 \n");
- _delay_ms(500);
- break;
- case KB_4:
- usb_keyboard_clear_report();
- usb_keyboard_send();
- print("current_layer: "); phex(current_layer); print("\n");
- print("default_layer: "); phex(default_layer); print("\n");
- current_layer = 4;
- default_layer = 4;
- print("switch to Layer4 \n");
- _delay_ms(500);
- break;
-#ifdef PS2_MOUSE_ENABLE
- case KB_LBRC:
- usb_keyboard_clear_report();
- usb_keyboard_send();
- print_enable = true;
- print("ps2_mouse_init...\n");
- _delay_ms(500);
- ps2_mouse_init();
- break;
- case KB_RBRC:
- 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;
- case KB_BSLS:
- ps2_mouse_enable = !ps2_mouse_enable;
- print("ps2_mouse: ");
- if (ps2_mouse_enable)
- print("on");
- else
- print("off");
- print("\n");
- _delay_ms(500);
- break;
-#endif
- case KB_B: // bootloader
- usb_keyboard_clear_report();
- usb_keyboard_send();
- print_enable = true;
- print("jump to bootloader...\n");
- _delay_ms(1000);
- jump_bootloader(); // not return
- break;
- case KB_D: // debug all toggle
- usb_keyboard_clear_report();
- usb_keyboard_send();
- debug_enable = !debug_enable;
- if (debug_enable) {
- print_enable = true;
- print("debug enabled.\n");
- //debug_matrix = true;
- //debug_keyboard = true;
- //debug_mouse = true;
- } else {
- print("debug disabled.\n");
- print_enable = false;
- //debug_matrix = false;
- //debug_keyboard = false;
- //debug_mouse = false;
- }
- _delay_ms(1000);
- break;
- case KB_X: // debug matrix toggle
- usb_keyboard_clear_report();
- usb_keyboard_send();
- debug_matrix = !debug_matrix;
- if (debug_matrix)
- print("debug matrix enabled.\n");
- else
- print("debug matrix disabled.\n");
- _delay_ms(1000);
- break;
- case KB_K: // debug keyboard toggle
- usb_keyboard_clear_report();
- usb_keyboard_send();
- debug_keyboard = !debug_keyboard;
- if (debug_keyboard)
- print("debug keyboard enabled.\n");
- else
- print("debug keyboard disabled.\n");
- _delay_ms(1000);
- break;
- case KB_M: // debug mouse toggle
- usb_keyboard_clear_report();
- usb_keyboard_send();
- debug_mouse = !debug_mouse;
- if (debug_mouse)
- print("debug mouse enabled.\n");
- else
- print("debug mouse disabled.\n");
- _delay_ms(1000);
- break;
- case KB_V: // print version & information
- usb_keyboard_clear_report();
- usb_keyboard_send();
- print_enable = true;
- print(STR(DESCRIPTION) "\n");
- _delay_ms(1000);
- break;
- case KB_T: // print timer
- usb_keyboard_clear_report();
- usb_keyboard_send();
- print_enable = true;
- print("timer: "); phex16(timer_count); print("\n");
- _delay_ms(500);
- break;
- case KB_P: // print toggle
- usb_keyboard_clear_report();
- usb_keyboard_send();
- if (print_enable) {
- print("print disabled.\n");
- print_enable = false;
- } else {
- print_enable = true;
- print("print enabled.\n");
- }
- _delay_ms(1000);
- break;
- case KB_S:
- usb_keyboard_clear_report();
- usb_keyboard_send();
- print("UDCON: "); phex(UDCON); print("\n");
- print("UDIEN: "); phex(UDIEN); print("\n");
- print("UDINT: "); phex(UDINT); print("\n");
- print("usb_keyboard_leds:"); phex(usb_keyboard_leds); 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_count:"); phex(usb_keyboard_idle_count); print("\n");
-#ifdef USB_MOUSE_ENABLE
- print("usb_mouse_protocol:"); phex(usb_mouse_protocol); print("\n");
-#endif
- if (usb_keyboard_nkro) print("USB_NKRO: enabled\n"); else print("USB_NKRO: disabled\n");
- _delay_ms(500);
- break;
- case KB_GRV:
- usb_keyboard_clear_report();
- usb_keyboard_send();
- usb_keyboard_protocol = !usb_keyboard_protocol;
- print("keyboard protcol: ");
- if (usb_keyboard_protocol) print("report"); else print("boot");
- print("\n");
-
-#ifdef USB_MOUSE_ENABLE
- usb_mouse_protocol = !usb_mouse_protocol;
- print("mouse protcol: ");
- if (usb_mouse_protocol) print("report"); else print("boot");
- print("\n");
-#endif
- _delay_ms(1000);
- break;
-#ifdef USB_NKRO_ENABLE
- case KB_N:
- usb_keyboard_clear_report();
- usb_keyboard_send();
- usb_keyboard_nkro = !usb_keyboard_nkro;
- if (usb_keyboard_nkro) print("USB_NKRO: enabled\n"); else print("USB_NKRO: disabled\n");
- _delay_ms(1000);
- break;
-#endif
-#ifdef USB_EXTRA_ENABLE
- case KB_ESC:
- usb_keyboard_clear_report();
- usb_keyboard_send();
- if (suspend && remote_wakeup) {
- usb_remote_wakeup();
- } else {
- usb_extra_system_send(SYSTEM_POWER_DOWN);
- }
- _delay_ms(1000);
- break;
-#endif
- }
- }
-
-
- if (modified) {
- usb_keyboard_send();
- }
-
-#ifdef MOUSEKEY_ENABLE
- mousekey_usb_send();
-#endif
-
-#ifdef PS2_MOUSE_ENABLE
- if (ps2_mouse_read() == 0)
- ps2_mouse_usb_send();
-#endif
-}
+++ /dev/null
-#ifndef KEY_PROCESS_H
-#define KEY_PROCESS_H 1
-
-
-void proc_matrix(void);
-
-#endif
#include "keyboard.h"
#include "host.h"
#include "layer.h"
-#include "matrix_skel.h"
+#include "matrix.h"
#include "led.h"
#include "usb_keycodes.h"
#include "timer.h"
#ifdef MOUSEKEY_ENABLE
#include "mousekey.h"
#endif
+/* TODO: shoud make new API */
+#ifdef USB_EXTRA_ENABLE
+#include "usb_extra.h"
+#include <util/delay.h>
+#endif
static uint8_t last_leds = 0;
fn_bits |= FN_BIT(code);
}
#ifdef USB_EXTRA_ENABLE
-/* TODO: use new API
// audio control & system control
else if (code == KB_MUTE) {
usb_extra_audio_send(AUDIO_MUTE);
}
_delay_ms(1000);
}
-*/
#endif
else if (IS_KEY(code)) {
host_add_key(code);
layer_switching(fn_bits);
if (command_proc()) {
- // not send report
return;
}
--- /dev/null
+#ifndef KEYMAP_H
+#define KEYMAP_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "usb_keycodes.h"
+
+
+/* keycode in specific layer */
+uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col);
+
+/* layer to move during press Fn key */
+uint8_t keymap_fn_layer(uint8_t fn_bits);
+
+/* keycode to send when release Fn key without using */
+uint8_t keymap_fn_keycode(uint8_t fn_bits);
+
+#endif
+++ /dev/null
-#ifndef KEYMAP_SKEL_H
-#define KEYMAP_SKEL_H 1
-
-#include <stdint.h>
-#include <stdbool.h>
-#include "usb_keycodes.h"
-
-
-/* keycode in specific layer */
-uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col);
-
-/* layer to move during press Fn key */
-uint8_t keymap_fn_layer(uint8_t fn_bits);
-
-/* keycode to send when release Fn key without using */
-uint8_t keymap_fn_keycode(uint8_t fn_bits);
-
-/* whether special key combination */
-bool keymap_is_special_mode(uint8_t fn_bits);
-
-#endif
-#include "keymap_skel.h"
+#include "keymap.h"
#include "host.h"
#include "debug.h"
#include "timer.h"
--- /dev/null
+/* 2010/08/23 noname
+ * keyboard firmware based on PJRC USB keyboard example
+ */
+/* Keyboard example with debug channel, for Teensy USB Development Board
+ * http://www.pjrc.com/teensy/usb_keyboard.html
+ * Copyright (c) 2008 PJRC.COM, LLC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdbool.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <util/delay.h>
+#include "keyboard.h"
+#include "usb.h"
+#include "matrix.h"
+#include "print.h"
+#include "debug.h"
+#include "util.h"
+#include "jump_bootloader.h"
+#ifdef PS2_MOUSE_ENABLE
+# include "ps2_mouse.h"
+#endif
+
+
+#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
+
+
+bool debug_enable = false;
+bool debug_matrix = false;
+bool debug_keyboard = false;
+bool debug_mouse = false;
+
+
+int main(void)
+{
+ DEBUG_LED_CONFIG;
+ DEBUG_LED_OFF;
+
+ // set for 16 MHz clock
+ CPU_PRESCALE(0);
+
+ // Initialize the USB, and then wait for the host to set configuration.
+ // If the Teensy is powered without a PC connected to the USB port,
+ // this will wait forever.
+ usb_init();
+ while (!usb_configured()) /* wait */ ;
+
+ keyboard_init();
+ matrix_scan();
+ if (matrix_key_count() >= 3) {
+#ifdef DEBUG_LED
+ for (int i = 0; i < 6; i++) {
+ DEBUG_LED_CONFIG;
+ DEBUG_LED_ON;
+ _delay_ms(500);
+ DEBUG_LED_OFF;
+ _delay_ms(500);
+ }
+#else
+ _delay_ms(5000);
+#endif
+ print_enable = true;
+ debug_enable = true;
+ debug_matrix = true;
+ debug_keyboard = true;
+ debug_mouse = true;
+ print("debug enabled.\n");
+ }
+ if (matrix_key_count() >= 4) {
+ print("jump to bootloader...\n");
+ _delay_ms(1000);
+ jump_bootloader(); // not return
+ }
+
+
+ while (1) {
+ keyboard_proc();
+ }
+}
--- /dev/null
+#ifndef MATRIX_H
+#define MATRIX_H
+
+#include <stdbool.h>
+
+/* number of matrix rows */
+uint8_t matrix_rows(void);
+/* number of matrix columns */
+uint8_t matrix_cols(void);
+/* intialize matrix for scaning. should be called once. */
+void matrix_init(void);
+/* scan all key states on matrix */
+uint8_t matrix_scan(void);
+/* whether modified from previous scan. used after matrix_scan. */
+bool matrix_is_modified(void);
+/* whether ghosting occur on matrix. */
+bool matrix_has_ghost(void);
+/* whether a swtich is on */
+bool matrix_is_on(uint8_t row, uint8_t col);
+/* matrix state on row */
+#if (MATRIX_COLS <= 8)
+uint8_t matrix_get_row(uint8_t row);
+#else
+uint16_t matrix_get_row(uint8_t row);
+#endif
+/* count keys pressed */
+uint8_t matrix_key_count(void);
+/* print matrix for debug */
+void matrix_print(void);
+
+
+#endif
+++ /dev/null
-#ifndef MATRIX_SKEL_H
-#define MATRIX_SKEL_H 1
-
-#include <stdbool.h>
-
-/* number of matrix rows */
-uint8_t matrix_rows(void);
-/* number of matrix columns */
-uint8_t matrix_cols(void);
-/* intialize matrix for scaning. should be called once. */
-void matrix_init(void);
-/* scan all key states on matrix */
-uint8_t matrix_scan(void);
-/* whether modified from previous scan. used after matrix_scan. */
-bool matrix_is_modified(void);
-/* whether ghosting occur on matrix. */
-bool matrix_has_ghost(void);
-/* whether a swtich is on */
-bool matrix_is_on(uint8_t row, uint8_t col);
-/* matrix state on row */
-#if (MATRIX_COLS <= 8)
-uint8_t matrix_get_row(uint8_t row);
-#else
-uint16_t matrix_get_row(uint8_t row);
-#endif
-/* count keys pressed */
-uint8_t matrix_key_count(void);
-/* print matrix for debug */
-void matrix_print(void);
-
-
-#endif
{
if (!data)
return;
+
+ uint8_t sreg = SREG;
+ cli();
uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
if (next != pbuf_tail) {
pbuf[pbuf_head] = data;
} else {
debug("pbuf: full\n");
}
+ SREG = sreg;
}
static inline uint8_t pbuf_dequeue(void)
{
uint8_t val = 0;
+
uint8_t sreg = SREG;
cli();
if (pbuf_head != pbuf_tail) {
pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
}
SREG = sreg;
+
return val;
}
/* get data received by interrupt */
uint8_t ps2_host_recv(void)
{
- // TODO: release clock line after 100us when inhibited by error
if (ps2_error) {
+ print("x");
+ phex(ps2_error);
ps2_host_send(0xFE); // request to resend
ps2_error = PS2_ERR_NONE;
}
+ idle();
return pbuf_dequeue();
}
}
goto RETURN;
ERROR:
- DEBUGP(0xFF);
+ DEBUGP(0x0F);
inhibit();
ps2_error = state;
DONE:
-# Hey Emacs, this is a -*- makefile -*-
-#----------------------------------------------------------------------------
-# WinAVR Makefile Template written by Eric B. Weddington, Jörg Wunsch, et al.
-#
-# Released to the Public Domain
-#
-# Additional material for this makefile was written by:
-# Peter Fleury
-# Tim Henigan
-# Colin O'Flynn
-# Reiner Patommel
-# Markus Pfaff
-# Sander Pool
-# Frederik Rouleau
-# Carlos Lamas
-#
-#----------------------------------------------------------------------------
-# On command line:
-#
-# make all = Make software.
-#
-# make clean = Clean out built project files.
-#
-# make coff = Convert ELF to AVR COFF.
-#
-# make extcoff = Convert ELF to AVR Extended COFF.
-#
-# make program = Download the hex file to the device, using avrdude.
-# Please customize the avrdude settings below first!
-#
-# make debug = Start either simulavr or avarice as specified for debugging,
-# with avr-gdb or avr-insight as the front end for debugging.
-#
-# make filename.s = Just compile filename.c into the assembler code only.
-#
-# make filename.i = Create a preprocessed source file for use in submitting
-# bug reports to the GCC project.
-#
-# To rebuild project do "make clean" then "make all".
-#----------------------------------------------------------------------------
-
# Target file name (without extension).
-TARGET = tmk_ps2_usb
+TARGET = ps2_usb
# Directory common source filess exist
COMMON_DIR = ..
TARGET_DIR = .
# keyboard dependent files
-TARGET_SRC = keymap.c \
+TARGET_SRC = main_pjrc.c \
+ keymap.c \
matrix.c \
+ led.c \
ps2.c
+CONFIG_H = config_pjrc.h
+
# MCU name, you MUST set this to match the board you are using
# type "make clean" after changing this, so all files will be rebuilt
USB_NKRO_ENABLE = yes # USB Nkey Rollover
+
+#---------------- Programming Options --------------------------
+PROGRAM_CMD = teensy_loader_cli.exe -mmcu=$(MCU) -w -v $(TARGET).hex
+
+
+
+include $(COMMON_DIR)/Makefile.pjrc
include $(COMMON_DIR)/Makefile.common
--- /dev/null
+# Target file name (without extension).
+TARGET = ps2_vusb
+
+# Directory common source filess exist
+COMMON_DIR = ..
+
+# Directory keyboard dependent files exist
+TARGET_DIR = .
+
+# keyboard dependent files
+TARGET_SRC = main_vusb.c \
+ keymap.c \
+ matrix.c \
+ led.c \
+ ps2_usart.c \
+ sendchar_dummy.c
+# sendchar_usart.c
+
+CONFIG_H = config_vusb.h
+
+
+OPT_DEFS = -DDEBUG_LEVEL=0
+
+
+# MCU name, you MUST set this to match the board you are using
+# type "make clean" after changing this, so all files will be rebuilt
+#MCU = at90usb162 # Teensy 1.0
+#MCU = atmega32u4 # Teensy 2.0
+#MCU = at90usb646 # Teensy++ 1.0
+#MCU = at90usb1286 # Teensy++ 2.0
+MCU = atmega168
+
+
+# Processor frequency.
+# Normally the first thing your program should do is set the clock prescaler,
+# so your program will run at the correct speed. You should also set this
+# variable to same clock speed. The _delay_ms() macro uses this, and many
+# examples use this variable to calculate timings. Do not add a "UL" here.
+F_CPU = 20000000
+
+
+# Build Options
+# comment out to disable the options.
+#
+MOUSEKEY_ENABLE = yes # Mouse keys
+#USB_EXTRA_ENABLE = yes # Enhanced feature for Windows(Audio control and System control)
+#USB_NKRO_ENABLE = yes # USB Nkey Rollover
+
+
+
+#---------------- Programming Options --------------------------
+AVRDUDE = avrdude
+# Type: avrdude -c ? to get a full listing.
+AVRDUDE_PROGRAMMER = usbasp
+AVRDUDE_PORT =
+AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
+#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
+
+# Uncomment the following if you want avrdude's erase cycle counter.
+# Note that this counter needs to be initialized first using -Yn,
+# see avrdude manual.
+#AVRDUDE_ERASE_COUNTER = -y
+
+# Uncomment the following if you do /not/ wish a verification to be
+# performed after programming the device.
+#AVRDUDE_NO_VERIFY = -V
+
+# Increase verbosity level. Please use this when submitting bug
+# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
+# to submit bug reports.
+#AVRDUDE_VERBOSE = -v -v
+
+#AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
+AVRDUDE_FLAGS = -p $(MCU) -c $(AVRDUDE_PROGRAMMER)
+AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
+AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
+AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
+
+PROGRAM_CMD = $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
+
+
+
+include $(COMMON_DIR)/Makefile.vusb
+include $(COMMON_DIR)/Makefile.common
You can customize keymaps easily by editing source code.
-Build
------
+Build for Teensy
+----------------
0. Connect PS/2 keyboard to Teensy by 4 lines(Vcc, GND, Data, Clock).
-1. Define following macros for PS/2 connection in config.h:
+1. Define following macros for PS/2 connection in config_pjrc.h:
PS2_DATA_PORT
PS2_DATA_PIN
PS2_DATA_DDR
http://www.pjrc.com/teensy/loader.html
+Build for V-USB
+---------------
+0. Build V-USB controller board and connect PS/2 keyboard.
+1. Define macros in config_vusb.h if needed.
+2. Edit Makefile.vusb for build options and MCU setting.
+3. make -f Makefile.vusb
+4. program your V-USB controller.
+
+
Keymap
------
You can change a keymap by editing code of keymap.c like following.
+++ /dev/null
-#ifndef CONFIG_H
-#define CONFIG_H
-
-/* controller configuration */
-#include "controller_teensy.h"
-
-#define VENDOR_ID 0xFEED
-#define PRODUCT_ID 0x6512
-#define MANUFACTURER t.m.k.
-#define PRODUCT PS/2 keyboard converter
-#define DESCRIPTION convert PS/2 keyboard to USB
-
-/* 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
-
-/* USB NKey Rollover */
-#ifdef USB_NKRO_ENABLE
-#endif
-
-/* mouse keys */
-#ifdef MOUSEKEY_ENABLE
-# define MOUSEKEY_DELAY_TIME 255
-#endif
-
-/* PS/2 mouse */
-#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
--- /dev/null
+#ifndef CONFIG_H
+#define CONFIG_H
+
+/* controller configuration */
+#include "controller_teensy.h"
+
+#define VENDOR_ID 0xFEED
+#define PRODUCT_ID 0x6512
+#define MANUFACTURER t.m.k.
+#define PRODUCT PS/2 keyboard converter
+#define DESCRIPTION convert PS/2 keyboard to USB
+
+
+/* matrix size */
+#define MATRIX_ROWS 32 // keycode bit: 3-0
+#define MATRIX_COLS 8 // keycode bit: 6-4
+
+
+/* key combination for command */
+#define IS_COMMAND() ( \
+ keyboard_report->mods == (BIT_LSHIFT | BIT_RSHIFT) || \
+ keyboard_report->mods == (BIT_LCTRL | BIT_RSHIFT) \
+)
+
+
+/* mouse keys */
+#ifdef MOUSEKEY_ENABLE
+# define MOUSEKEY_DELAY_TIME 255
+#endif
+
+
+/* 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
+
+#endif
--- /dev/null
+#ifndef CONFIG_H
+#define CONFIG_H
+
+
+#define VENDOR_ID 0xFEED
+#define PRODUCT_ID 0x2233
+// TODO: share these strings with usbconfig.h
+// Edit usbconfig.h to change these.
+#define MANUFACTURER t.m.k.
+#define PRODUCT PS/2 keyboard converter
+#define DESCRIPTION convert PS/2 keyboard to USB
+
+
+/* matrix size */
+#define MATRIX_ROWS 32 // keycode bit: 3-0
+#define MATRIX_COLS 8 // keycode bit: 6-4
+
+
+/* key combination for command */
+#define IS_COMMAND() ( \
+ keyboard_report->mods == (BIT_LSHIFT | BIT_RSHIFT) || \
+ keyboard_report->mods == (BIT_LCTRL | BIT_RSHIFT) \
+)
+
+
+/* mouse keys */
+#ifdef MOUSEKEY_ENABLE
+# define MOUSEKEY_DELAY_TIME 255
+#endif
+
+
+/* PS/2 lines */
+#define PS2_CLOCK_PORT PORTD
+#define PS2_CLOCK_PIN PIND
+#define PS2_CLOCK_DDR DDRD
+#define PS2_CLOCK_BIT 4
+#define PS2_DATA_PORT PORTD
+#define PS2_DATA_PIN PIND
+#define PS2_DATA_DDR DDRD
+#define PS2_DATA_BIT 0
+
+
+// Synchronous USART is used to receive data from keyboard.
+// Use RXD pin for PS/2 DATA line and XCK for PS/2 CLOCK.
+// NOTE: This is recomended strongly if you use V-USB library.
+#define PS2_USE_USART
+
+// External or Pin Change Interrupt is used to receive data from keyboard.
+// Use INT1 or PCINTxx for PS/2 CLOCK line. see below.
+//#define PS2_USE_INT
+
+
+#ifdef PS2_USE_USART
+// synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge
+// set DDR of CLOCK as input to be slave
+#define PS2_USART_INIT() do { \
+ PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT); \
+ PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); \
+ UCSR0C = ((1 << UMSEL00) | \
+ (3 << UPM00) | \
+ (0 << USBS0) | \
+ (3 << UCSZ00) | \
+ (0 << UCPOL0)); \
+ UCSR0A = 0; \
+ UBRR0H = 0; \
+ UBRR0L = 0; \
+} while (0)
+#define PS2_USART_RX_INT_ON() do { \
+ UCSR0B = ((1 << RXCIE0) | \
+ (1 << RXEN0)); \
+} while (0)
+#define PS2_USART_RX_POLL_ON() do { \
+ UCSR0B = (1 << RXEN0); \
+} while (0)
+#define PS2_USART_OFF() do { \
+ UCSR0C = 0; \
+ UCSR0B &= ~((1 << RXEN0) | \
+ (1 << TXEN0)); \
+} while (0)
+#define PS2_USART_RX_READY (UCSR0A & (1<<RXC0))
+#define PS2_USART_RX_DATA UDR0
+#define PS2_USART_ERROR (UCSR0A & ((1<<FE0) | (1<<DOR0) | (1<<UPE0)))
+#define PS2_USART_RX_VECT USART_RX_vect
+#endif
+
+
+#ifdef PS2_USE_INT
+/* INT1
+#define PS2_INT_INIT() do { \
+ EICRA |= ((1<<ISC11) | \
+ (0<<ISC10)); \
+} while (0)
+#define PS2_INT_ON() do { \
+ EIMSK |= (1<<INT1); \
+} while (0)
+#define PS2_INT_OFF() do { \
+ EIMSK &= ~(1<<INT1); \
+} while (0)
+#define PS2_INT_VECT INT1_vect
+*/
+
+/* PCINT20 */
+#define PS2_INT_INIT() do { \
+ PCICR |= (1<<PCIE2); \
+} while (0)
+#define PS2_INT_ON() do { \
+ PCMSK2 |= (1<<PCINT20); \
+} while (0)
+#define PS2_INT_OFF() do { \
+ PCMSK2 &= ~(1<<PCINT20); \
+ PCICR &= ~(1<<PCIE2); \
+} while (0)
+#define PS2_INT_VECT PCINT2_vect
+#endif
+
+#endif
#include <stdint.h>
#include <stdbool.h>
#include <avr/pgmspace.h>
-#include "usb_keyboard.h"
#include "usb_keycodes.h"
#include "print.h"
#include "debug.h"
#include "util.h"
-#include "keymap_skel.h"
+#include "keymap.h"
#define KEYCODE(layer, row, col) (pgm_read_byte(&keymaps[(layer)][(row)][(col)]))
{
return pgm_read_byte(&fn_keycode[(biton(fn_bits))]);
}
-
-// define a condition to enter special function mode
-bool keymap_is_special_mode(uint8_t fn_bits)
-{
- return usb_keyboard_mods == (BIT_LSHIFT | BIT_RSHIFT) || usb_keyboard_mods == (BIT_LCTRL | BIT_RSHIFT);
-}
--- /dev/null
+#include "stdint.h"
+#include "ps2.h"
+#include "led.h"
+
+
+void led_set(uint8_t usb_led)
+{
+ uint8_t ps2_led = 0;
+ if (usb_led & (1<<USB_LED_SCROLL_LOCK))
+ ps2_led |= (1<<PS2_LED_SCROLL_LOCK);
+ if (usb_led & (1<<USB_LED_NUM_LOCK))
+ ps2_led |= (1<<PS2_LED_NUM_LOCK);
+ if (usb_led & (1<<USB_LED_CAPS_LOCK))
+ ps2_led |= (1<<PS2_LED_CAPS_LOCK);
+ ps2_host_set_led(ps2_led);
+}
--- /dev/null
+/* PS/2 to USB keyboard converter
+ * 2011/02/20
+ * Copyright (c) 2011 tmk
+ */
+/* Name: main.c
+ * Project: hid-mouse, a very simple HID example
+ * Author: Christian Starkjohann
+ * Creation Date: 2008-04-07
+ * Tabsize: 4
+ * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: main.c 790 2010-05-30 21:00:26Z cs $
+ */
+#include <stdint.h>
+#include <avr/wdt.h>
+#include <avr/interrupt.h>
+#include <util/delay.h>
+#include "usbdrv.h"
+#include "oddebug.h"
+#include "host_vusb.h"
+#include "keyboard.h"
+
+
+#if 0
+#define DEBUGP_INIT() do { DDRC = 0xFF; } while (0)
+#define DEBUGP(x) do { PORTC = x; } while (0)
+#else
+#define DEBUGP_INIT()
+#define DEBUGP(x)
+#endif
+
+
+int main(void)
+{
+ DEBUGP_INIT();
+ wdt_enable(WDTO_1S);
+ odDebugInit();
+ usbInit();
+
+ /* enforce re-enumeration, do this while interrupts are disabled! */
+ usbDeviceDisconnect();
+ uint8_t i = 0;
+ /* fake USB disconnect for > 250 ms */
+ while(--i){
+ wdt_reset();
+ _delay_ms(1);
+ }
+ usbDeviceConnect();
+
+ keyboard_init();
+
+ sei();
+ while (1) {
+ DEBUGP(0x1);
+ wdt_reset();
+ usbPoll();
+ DEBUGP(0x2);
+ keyboard_proc();
+ DEBUGP(0x3);
+ host_vusb_keyboard_send();
+ }
+}
#include "util.h"
#include "debug.h"
#include "ps2.h"
-#include "usb_keyboard.h"
-#include "matrix_skel.h"
+#include "matrix.h"
#if (MATRIX_COLS > 16)
#endif
static void matrix_make(uint8_t code);
static void matrix_break(uint8_t code);
-static void ps2_reset(void);
-static void ps2_set_leds(uint8_t leds);
inline
void matrix_init(void)
{
- print_enable = true;
ps2_host_init();
- ps2_reset();
-
- // flush LEDs
- ps2_set_leds(1<<PS2_LED_NUM_LOCK);
- _delay_ms(100);
- ps2_set_leds(1<<PS2_LED_NUM_LOCK|1<<PS2_LED_CAPS_LOCK);
- _delay_ms(100);
- ps2_set_leds(1<<PS2_LED_NUM_LOCK|1<<PS2_LED_CAPS_LOCK|1<<PS2_LED_SCROLL_LOCK);
- _delay_ms(300);
- ps2_set_leds(0x00);
-
// initialize matrix state: all keys off
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
uint8_t code;
while ((code = ps2_host_recv())) {
-debug_hex(code); debug(" ");
switch (state) {
case INIT:
switch (code) {
state = INIT;
}
}
-
- // handle LED indicators
- static uint8_t prev_leds = 0;
- if (prev_leds != usb_keyboard_leds) {
- uint8_t leds = 0;
- if (usb_keyboard_leds&(1<<USB_LED_SCROLL_LOCK))
- leds |= (1<<PS2_LED_SCROLL_LOCK);
- if (usb_keyboard_leds&(1<<USB_LED_NUM_LOCK))
- leds |= (1<<PS2_LED_NUM_LOCK);
- if (usb_keyboard_leds&(1<<USB_LED_CAPS_LOCK))
- leds |= (1<<PS2_LED_CAPS_LOCK);
-
- ps2_set_leds(leds);
- prev_leds = usb_keyboard_leds;
- }
-
return 1;
}
is_modified = true;
}
}
-
-static void ps2_reset(void)
-{
- ps2_host_send(0xFF);
- ps2_host_recv(); // 0xFA
- ps2_host_recv(); // 0xAA
- _delay_ms(1000);
-}
-
-static void ps2_set_leds(uint8_t leds)
-{
- ps2_host_send(0xED);
- ps2_host_recv(); // 0xFA
- ps2_host_send(leds);
- ps2_host_recv(); // 0xFA
-}
--- /dev/null
+/*
+Copyright (c) 2010,2011 Jun WAKO <wakojun@gmail.com>
+
+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.
+*/
+/*
+Primitive PS/2 Library for AVR
+==============================
+Host side is only supported now.
+Synchronous USART is used to receive data by hardware process
+rather than interrupt. During V-USB interrupt runs, CLOCK interrupt
+cannot interpose. In the result it is prone to lost CLOCK edge.
+
+
+I/O control
+-----------
+High state is asserted by internal pull-up.
+If you have a signaling problem, you may need to have
+external pull-up resisters on CLOCK and DATA line.
+
+
+PS/2 References
+---------------
+http://www.computer-engineering.org/ps2protocol/
+http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
+*/
+#include <stdbool.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <util/delay.h>
+#include "ps2.h"
+#include "debug.h"
+
+
+#if 0
+#define DEBUGP_INIT() do { DDRC = 0xFF; } while (0)
+#define DEBUGP(x) do { PORTC = x; } while (0)
+#else
+#define DEBUGP_INIT()
+#define DEBUGP(x)
+#endif
+
+#define WAIT(stat, us, err) do { \
+ if (!wait_##stat(us)) { \
+ ps2_error = err; \
+ goto ERROR; \
+ } \
+} while (0)
+
+
+uint8_t ps2_error = PS2_ERR_NONE;
+
+
+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);
+static inline void idle(void);
+static inline void inhibit(void);
+#if defined PS2_USE_INT || defined PS2_USE_USART
+static inline uint8_t pbuf_dequeue(void);
+static inline void pbuf_enqueue(uint8_t data);
+#endif
+
+
+void ps2_host_init(void)
+{
+ DEBUGP_INIT();
+ DEBUGP(0x1);
+ idle();
+ PS2_USART_INIT();
+ PS2_USART_RX_INT_ON();
+}
+
+uint8_t ps2_host_send(uint8_t data)
+{
+ uint8_t res = 0;
+ bool parity = true;
+ ps2_error = PS2_ERR_NONE;
+
+ DEBUGP(0x6);
+ PS2_USART_OFF();
+
+ /* terminate a transmission if we have */
+ inhibit();
+ _delay_us(100);
+
+ /* start bit [1] */
+ data_lo();
+ clock_hi();
+ WAIT(clock_lo, 15000, 1);
+ /* data [2-9] */
+ for (uint8_t i = 0; i < 8; i++) {
+ _delay_us(15);
+ if (data&(1<<i)) {
+ parity = !parity;
+ data_hi();
+ } else {
+ data_lo();
+ }
+ WAIT(clock_hi, 50, 2);
+ WAIT(clock_lo, 50, 3);
+ }
+ /* parity [10] */
+ _delay_us(15);
+ if (parity) { data_hi(); } else { data_lo(); }
+ WAIT(clock_hi, 50, 4);
+ WAIT(clock_lo, 50, 5);
+ /* stop bit [11] */
+ _delay_us(15);
+ data_hi();
+ /* ack [12] */
+ WAIT(data_lo, 50, 6);
+ WAIT(clock_lo, 50, 7);
+
+ /* wait for idle state */
+ WAIT(clock_hi, 50, 8);
+ WAIT(data_hi, 50, 9);
+
+ res = ps2_host_recv_response();
+ERROR:
+ idle();
+ PS2_USART_INIT();
+ PS2_USART_RX_INT_ON();
+ return res;
+}
+
+// Do polling data from keyboard to get response to last command.
+uint8_t ps2_host_recv_response(void)
+{
+ uint8_t data = 0;
+ PS2_USART_INIT();
+ PS2_USART_RX_POLL_ON();
+ while (!PS2_USART_RX_READY)
+ ;
+ data = PS2_USART_RX_DATA;
+ PS2_USART_OFF();
+ DEBUGP(0x9);
+ return data;
+}
+
+uint8_t ps2_host_recv(void)
+{
+ return pbuf_dequeue();
+}
+
+ISR(PS2_USART_RX_VECT)
+{
+ DEBUGP(0x7);
+ uint8_t error = PS2_USART_ERROR;
+ uint8_t data = PS2_USART_RX_DATA;
+ if (error) {
+ DEBUGP(error>>2);
+ } else {
+ pbuf_enqueue(data);
+ }
+ DEBUGP(0x8);
+}
+
+/* send LED state to keyboard */
+void ps2_host_set_led(uint8_t led)
+{
+ // send 0xED then keyboard keeps waiting for next LED data
+ // and keyboard does not send any scan codes during waiting.
+ // If fail to send LED data keyboard looks like being freezed.
+ uint8_t retry = 3;
+ while (retry-- && ps2_host_send(PS2_SET_LED) != PS2_ACK)
+ ;
+ retry = 3;
+ while (retry-- && ps2_host_send(led) != PS2_ACK)
+ ;
+}
+
+
+/*--------------------------------------------------------------------
+ * static functions
+ *------------------------------------------------------------------*/
+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);
+ _delay_us(1);
+ 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);
+ _delay_us(1);
+ 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;
+}
+
+/* idle state that device can send */
+static inline void idle(void)
+{
+ clock_hi();
+ data_hi();
+}
+
+/* inhibit device to send */
+static inline void inhibit(void)
+{
+ clock_lo();
+ data_hi();
+}
+
+
+/*--------------------------------------------------------------------
+ * Ring buffer to store scan codes from keyboard
+ *------------------------------------------------------------------*/
+#define PBUF_SIZE 8
+static uint8_t pbuf[PBUF_SIZE];
+static uint8_t pbuf_head = 0;
+static uint8_t pbuf_tail = 0;
+static inline void pbuf_enqueue(uint8_t data)
+{
+ if (!data)
+ return;
+
+ uint8_t sreg = SREG;
+ cli();
+ uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
+ if (next != pbuf_tail) {
+ pbuf[pbuf_head] = data;
+ pbuf_head = next;
+ } else {
+ debug("pbuf: full\n");
+ }
+ SREG = sreg;
+}
+
+static inline uint8_t pbuf_dequeue(void)
+{
+ uint8_t val = 0;
+
+ uint8_t sreg = SREG;
+ cli();
+ if (pbuf_head != pbuf_tail) {
+ val = pbuf[pbuf_tail];
+ pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
+ }
+ SREG = sreg;
+
+ return val;
+}
--- /dev/null
+#include <stdint.h>
+#include "sendchar.h"
+
+
+int8_t sendchar(uint8_t c)
+{
+ return 1;
+}
--- /dev/null
+#include <stdint.h>
+#include "oddebug.h"
+#include "sendchar.h"
+
+
+/* from oddebug.h */
+#if defined UBRR
+# define ODDBG_UBRR UBRR
+#elif defined UBRRL
+# define ODDBG_UBRR UBRRL
+#elif defined UBRR0
+# define ODDBG_UBRR UBRR0
+#elif defined UBRR0L
+# define ODDBG_UBRR UBRR0L
+#endif
+
+#if defined UCR
+# define ODDBG_UCR UCR
+#elif defined UCSRB
+# define ODDBG_UCR UCSRB
+#elif defined UCSR0B
+# define ODDBG_UCR UCSR0B
+#endif
+
+#if defined TXEN
+# define ODDBG_TXEN TXEN
+#else
+# define ODDBG_TXEN TXEN0
+#endif
+
+#if defined USR
+# define ODDBG_USR USR
+#elif defined UCSRA
+# define ODDBG_USR UCSRA
+#elif defined UCSR0A
+# define ODDBG_USR UCSR0A
+#endif
+
+#if defined UDRE
+# define ODDBG_UDRE UDRE
+#else
+# define ODDBG_UDRE UDRE0
+#endif
+
+#if defined UDR
+# define ODDBG_UDR UDR
+#elif defined UDR0
+# define ODDBG_UDR UDR0
+#endif
+
+
+/* from oddebug.c */
+int8_t sendchar(uint8_t c)
+{
+ while(!(ODDBG_USR & (1 << ODDBG_UDRE))); /* wait for data register empty */
+ ODDBG_UDR = c;
+ return 1;
+}
--- /dev/null
+/* Name: usbconfig.h
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2005-04-01
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: usbconfig-prototype.h 785 2010-05-30 17:57:07Z cs $
+ */
+
+#ifndef __usbconfig_h_included__
+#define __usbconfig_h_included__
+
+#include "config_vusb.h"
+
+/*
+General Description:
+This file is an example configuration (with inline documentation) for the USB
+driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
+also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
+wire the lines to any other port, as long as D+ is also wired to INT0 (or any
+other hardware interrupt, as long as it is the highest level interrupt, see
+section at the end of this file).
+*/
+
+/* ---------------------------- Hardware Config ---------------------------- */
+
+#define USB_CFG_IOPORTNAME D
+/* This is the port where the USB bus is connected. When you configure it to
+ * "B", the registers PORTB, PINB and DDRB will be used.
+ */
+#define USB_CFG_DMINUS_BIT 3
+/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
+ * This may be any bit in the port.
+ */
+#define USB_CFG_DPLUS_BIT 2
+/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
+ * This may be any bit in the port. Please note that D+ must also be connected
+ * to interrupt pin INT0! [You can also use other interrupts, see section
+ * "Optional MCU Description" below, or you can connect D- to the interrupt, as
+ * it is required if you use the USB_COUNT_SOF feature. If you use D- for the
+ * interrupt, the USB interrupt will also be triggered at Start-Of-Frame
+ * markers every millisecond.]
+ */
+#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
+/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000,
+ * 16500, 18000 and 20000. The 12.8 MHz and 16.5 MHz versions of the code
+ * require no crystal, they tolerate +/- 1% deviation from the nominal
+ * frequency. All other rates require a precision of 2000 ppm and thus a
+ * crystal!
+ * Since F_CPU should be defined to your actual clock rate anyway, you should
+ * not need to modify this setting.
+ */
+#define USB_CFG_CHECK_CRC 0
+/* Define this to 1 if you want that the driver checks integrity of incoming
+ * data packets (CRC checks). CRC checks cost quite a bit of code size and are
+ * currently only available for 18 MHz crystal clock. You must choose
+ * USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
+ */
+
+/* ----------------------- Optional Hardware Config ------------------------ */
+
+/* #define USB_CFG_PULLUP_IOPORTNAME D */
+/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
+ * V+, you can connect and disconnect the device from firmware by calling
+ * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
+ * This constant defines the port on which the pullup resistor is connected.
+ */
+/* #define USB_CFG_PULLUP_BIT 4 */
+/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
+ * above) where the 1.5k pullup resistor is connected. See description
+ * above for details.
+ */
+
+/* --------------------------- Functional Range ---------------------------- */
+
+#define USB_CFG_HAVE_INTRIN_ENDPOINT 1
+/* Define this to 1 if you want to compile a version with two endpoints: The
+ * default control endpoint 0 and an interrupt-in endpoint (any other endpoint
+ * number).
+ */
+#define USB_CFG_HAVE_INTRIN_ENDPOINT3 1
+/* Define this to 1 if you want to compile a version with three endpoints: The
+ * default control endpoint 0, an interrupt-in endpoint 3 (or the number
+ * configured below) and a catch-all default interrupt-in endpoint as above.
+ * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
+ */
+#define USB_CFG_EP3_NUMBER 3
+/* If the so-called endpoint 3 is used, it can now be configured to any other
+ * endpoint number (except 0) with this macro. Default if undefined is 3.
+ */
+/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */
+/* The above macro defines the startup condition for data toggling on the
+ * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1.
+ * Since the token is toggled BEFORE sending any data, the first packet is
+ * sent with the oposite value of this configuration!
+ */
+#define USB_CFG_IMPLEMENT_HALT 0
+/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature
+ * for endpoint 1 (interrupt endpoint). Although you may not need this feature,
+ * it is required by the standard. We have made it a config option because it
+ * bloats the code considerably.
+ */
+#define USB_CFG_SUPPRESS_INTR_CODE 0
+/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
+ * want to send any data over them. If this macro is defined to 1, functions
+ * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if
+ * you need the interrupt-in endpoints in order to comply to an interface
+ * (e.g. HID), but never want to send any data. This option saves a couple
+ * of bytes in flash memory and the transmit buffers in RAM.
+ */
+#define USB_CFG_INTR_POLL_INTERVAL 10
+/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
+ * interval. The value is in milliseconds and must not be less than 10 ms for
+ * low speed devices.
+ */
+#define USB_CFG_IS_SELF_POWERED 0
+/* Define this to 1 if the device has its own power supply. Set it to 0 if the
+ * device is powered from the USB bus.
+ */
+#define USB_CFG_MAX_BUS_POWER 100
+/* Set this variable to the maximum USB bus power consumption of your device.
+ * The value is in milliamperes. [It will be divided by two since USB
+ * communicates power requirements in units of 2 mA.]
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITE 1
+/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
+ * transfers. Set it to 0 if you don't need it and want to save a couple of
+ * bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_READ 0
+/* Set this to 1 if you need to send control replies which are generated
+ * "on the fly" when usbFunctionRead() is called. If you only want to send
+ * data from a static buffer, set it to 0 and return the data from
+ * usbFunctionSetup(). This saves a couple of bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0
+/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints.
+ * You must implement the function usbFunctionWriteOut() which receives all
+ * interrupt/bulk data sent to any endpoint other than 0. The endpoint number
+ * can be found in 'usbRxToken'.
+ */
+#define USB_CFG_HAVE_FLOWCONTROL 0
+/* Define this to 1 if you want flowcontrol over USB data. See the definition
+ * of the macros usbDisableAllRequests() and usbEnableAllRequests() in
+ * usbdrv.h.
+ */
+#define USB_CFG_DRIVER_FLASH_PAGE 0
+/* If the device has more than 64 kBytes of flash, define this to the 64 k page
+ * where the driver's constants (descriptors) are located. Or in other words:
+ * Define this to 1 for boot loaders on the ATMega128.
+ */
+#define USB_CFG_LONG_TRANSFERS 0
+/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
+ * in a single control-in or control-out transfer. Note that the capability
+ * for long transfers increases the driver size.
+ */
+/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
+/* This macro is a hook if you want to do unconventional things. If it is
+ * defined, it's inserted at the beginning of received message processing.
+ * If you eat the received message and don't want default processing to
+ * proceed, do a return after doing your things. One possible application
+ * (besides debugging) is to flash a status LED on each packet.
+ */
+/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */
+/* This macro is a hook if you need to know when an USB RESET occurs. It has
+ * one parameter which distinguishes between the start of RESET state and its
+ * end.
+ */
+/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */
+/* This macro (if defined) is executed when a USB SET_ADDRESS request was
+ * received.
+ */
+#define USB_COUNT_SOF 0
+/* define this macro to 1 if you need the global variable "usbSofCount" which
+ * counts SOF packets. This feature requires that the hardware interrupt is
+ * connected to D- instead of D+.
+ */
+/* #ifdef __ASSEMBLER__
+ * macro myAssemblerMacro
+ * in YL, TCNT0
+ * sts timer0Snapshot, YL
+ * endm
+ * #endif
+ * #define USB_SOF_HOOK myAssemblerMacro
+ * This macro (if defined) is executed in the assembler module when a
+ * Start Of Frame condition is detected. It is recommended to define it to
+ * the name of an assembler macro which is defined here as well so that more
+ * than one assembler instruction can be used. The macro may use the register
+ * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
+ * immediately after an SOF pulse may be lost and must be retried by the host.
+ * What can you do with this hook? Since the SOF signal occurs exactly every
+ * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
+ * designs running on the internal RC oscillator.
+ * Please note that Start Of Frame detection works only if D- is wired to the
+ * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
+ */
+#define USB_CFG_CHECK_DATA_TOGGLING 0
+/* define this macro to 1 if you want to filter out duplicate data packets
+ * sent by the host. Duplicates occur only as a consequence of communication
+ * errors, when the host does not receive an ACK. Please note that you need to
+ * implement the filtering yourself in usbFunctionWriteOut() and
+ * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
+ * for each control- and out-endpoint to check for duplicate packets.
+ */
+#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
+/* define this macro to 1 if you want the function usbMeasureFrameLength()
+ * compiled in. This function can be used to calibrate the AVR's RC oscillator.
+ */
+#define USB_USE_FAST_CRC 0
+/* The assembler module has two implementations for the CRC algorithm. One is
+ * faster, the other is smaller. This CRC routine is only used for transmitted
+ * messages where timing is not critical. The faster routine needs 31 cycles
+ * per byte while the smaller one needs 61 to 69 cycles. The faster routine
+ * may be worth the 32 bytes bigger code size if you transmit lots of data and
+ * run the AVR close to its limit.
+ */
+
+/* -------------------------- Device Description --------------------------- */
+
+#define USB_CFG_VENDOR_ID (VENDOR_ID & 0xFF), ((VENDOR_ID >> 8) & 0xFF)
+/* USB vendor ID for the device, low byte first. If you have registered your
+ * own Vendor ID, define it here. Otherwise you may use one of obdev's free
+ * shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules!
+ * *** IMPORTANT NOTE ***
+ * This template uses obdev's shared VID/PID pair for Vendor Class devices
+ * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
+ * the implications!
+ */
+#define USB_CFG_DEVICE_ID (PRODUCT_ID & 0xFF), ((PRODUCT_ID >> 8) & 0xFF)
+/* This is the ID of the product, low byte first. It is interpreted in the
+ * scope of the vendor ID. If you have registered your own VID with usb.org
+ * or if you have licensed a PID from somebody else, define it here. Otherwise
+ * you may use one of obdev's free shared VID/PID pairs. See the file
+ * USB-IDs-for-free.txt for details!
+ * *** IMPORTANT NOTE ***
+ * This template uses obdev's shared VID/PID pair for Vendor Class devices
+ * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
+ * the implications!
+ */
+#define USB_CFG_DEVICE_VERSION 0x00, 0x01
+/* Version number of the device: Minor number first, then major number.
+ */
+#define USB_CFG_VENDOR_NAME 't', '.', 'm', '.', 'k', '.'
+#define USB_CFG_VENDOR_NAME_LEN 6
+/* These two values define the vendor name returned by the USB device. The name
+ * must be given as a list of characters under single quotes. The characters
+ * are interpreted as Unicode (UTF-16) entities.
+ * If you don't want a vendor name string, undefine these macros.
+ * ALWAYS define a vendor name containing your Internet domain name if you use
+ * obdev's free shared VID/PID pair. See the file USB-IDs-for-free.txt for
+ * details.
+ */
+#define USB_CFG_DEVICE_NAME 'P', 'S', '/', '2', ' ', 'k', 'e', 'y', 'b', 'o', 'a', 'r', 'd', ' ', 'c', 'o', 'n', 'v', 'e', 'r', 't', 'e', 'r'
+#define USB_CFG_DEVICE_NAME_LEN 23
+/* Same as above for the device name. If you don't want a device name, undefine
+ * the macros. See the file USB-IDs-for-free.txt before you assign a name if
+ * you use a shared VID/PID.
+ */
+/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */
+/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */
+/* Same as above for the serial number. If you don't want a serial number,
+ * undefine the macros.
+ * It may be useful to provide the serial number through other means than at
+ * compile time. See the section about descriptor properties below for how
+ * to fine tune control over USB descriptors such as the string descriptor
+ * for the serial number.
+ */
+#define USB_CFG_DEVICE_CLASS 0
+#define USB_CFG_DEVICE_SUBCLASS 0
+/* See USB specification if you want to conform to an existing device class.
+ * Class 0xff is "vendor specific".
+ */
+#define USB_CFG_INTERFACE_CLASS 3 /* HID */
+#define USB_CFG_INTERFACE_SUBCLASS 1 /* Boot */
+#define USB_CFG_INTERFACE_PROTOCOL 1 /* Keyboard */
+/* See USB specification if you want to conform to an existing device class or
+ * protocol. The following classes must be set at interface level:
+ * HID class is 3, no subclass and protocol required (but may be useful!)
+ * CDC class is 2, use subclass 2 and protocol 1 for ACM
+ */
+#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 0
+/* Define this to the length of the HID report descriptor, if you implement
+ * an HID device. Otherwise don't define it or define it to 0.
+ * If you use this define, you must add a PROGMEM character array named
+ * "usbHidReportDescriptor" to your code which contains the report descriptor.
+ * Don't forget to keep the array and this define in sync!
+ */
+
+/* #define USB_PUBLIC static */
+/* Use the define above if you #include usbdrv.c instead of linking against it.
+ * This technique saves a couple of bytes in flash memory.
+ */
+
+/* ------------------- Fine Control over USB Descriptors ------------------- */
+/* If you don't want to use the driver's default USB descriptors, you can
+ * provide our own. These can be provided as (1) fixed length static data in
+ * flash memory, (2) fixed length static data in RAM or (3) dynamically at
+ * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more
+ * information about this function.
+ * Descriptor handling is configured through the descriptor's properties. If
+ * no properties are defined or if they are 0, the default descriptor is used.
+ * Possible properties are:
+ * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
+ * at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is
+ * used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if
+ * you want RAM pointers.
+ * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
+ * in static memory is in RAM, not in flash memory.
+ * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
+ * the driver must know the descriptor's length. The descriptor itself is
+ * found at the address of a well known identifier (see below).
+ * List of static descriptor names (must be declared PROGMEM if in flash):
+ * char usbDescriptorDevice[];
+ * char usbDescriptorConfiguration[];
+ * char usbDescriptorHidReport[];
+ * char usbDescriptorString0[];
+ * int usbDescriptorStringVendor[];
+ * int usbDescriptorStringDevice[];
+ * int usbDescriptorStringSerialNumber[];
+ * Other descriptors can't be provided statically, they must be provided
+ * dynamically at runtime.
+ *
+ * Descriptor properties are or-ed or added together, e.g.:
+ * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18))
+ *
+ * The following descriptors are defined:
+ * USB_CFG_DESCR_PROPS_DEVICE
+ * USB_CFG_DESCR_PROPS_CONFIGURATION
+ * USB_CFG_DESCR_PROPS_STRINGS
+ * USB_CFG_DESCR_PROPS_STRING_0
+ * USB_CFG_DESCR_PROPS_STRING_VENDOR
+ * USB_CFG_DESCR_PROPS_STRING_PRODUCT
+ * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
+ * USB_CFG_DESCR_PROPS_HID
+ * USB_CFG_DESCR_PROPS_HID_REPORT
+ * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
+ *
+ * Note about string descriptors: String descriptors are not just strings, they
+ * are Unicode strings prefixed with a 2 byte header. Example:
+ * int serialNumberDescriptor[] = {
+ * USB_STRING_DESCRIPTOR_HEADER(6),
+ * 'S', 'e', 'r', 'i', 'a', 'l'
+ * };
+ */
+
+#define USB_CFG_DESCR_PROPS_DEVICE 0
+#define USB_CFG_DESCR_PROPS_CONFIGURATION USB_PROP_IS_DYNAMIC
+//#define USB_CFG_DESCR_PROPS_CONFIGURATION 0
+#define USB_CFG_DESCR_PROPS_STRINGS 0
+#define USB_CFG_DESCR_PROPS_STRING_0 0
+#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0
+#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0
+#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0
+//#define USB_CFG_DESCR_PROPS_HID USB_PROP_IS_DYNAMIC
+#define USB_CFG_DESCR_PROPS_HID 0
+#define USB_CFG_DESCR_PROPS_HID_REPORT USB_PROP_IS_DYNAMIC
+//#define USB_CFG_DESCR_PROPS_HID_REPORT 0
+#define USB_CFG_DESCR_PROPS_UNKNOWN 0
+
+/* ----------------------- Optional MCU Description ------------------------ */
+
+/* The following configurations have working defaults in usbdrv.h. You
+ * usually don't need to set them explicitly. Only if you want to run
+ * the driver on a device which is not yet supported or with a compiler
+ * which is not fully supported (such as IAR C) or if you use a differnt
+ * interrupt than INT0, you may have to define some of these.
+ */
+/* #define USB_INTR_CFG MCUCR */
+/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */
+/* #define USB_INTR_CFG_CLR 0 */
+/* #define USB_INTR_ENABLE GIMSK */
+/* #define USB_INTR_ENABLE_BIT INT0 */
+/* #define USB_INTR_PENDING GIFR */
+/* #define USB_INTR_PENDING_BIT INTF0 */
+/* #define USB_INTR_VECTOR INT0_vect */
+
+#endif /* __usbconfig_h_included__ */
+++ /dev/null
-# Target file name (without extension).
-TARGET = ps2_vusb
-
-# Directory common source filess exist
-COMMON_DIR = ..
-
-# Directory keyboard dependent files exist
-TARGET_DIR = .
-
-# keyboard dependent files
-TARGET_SRC = main.c \
- keymap.c \
- matrix.c \
- led.c \
- ps2_usart.c \
- sendchar_dummy.c
-# sendchar_usart.c
-
-OPT_DEFS = -DDEBUG_LEVEL=0
-
-
-# MCU name, you MUST set this to match the board you are using
-# type "make clean" after changing this, so all files will be rebuilt
-#MCU = at90usb162 # Teensy 1.0
-#MCU = atmega32u4 # Teensy 2.0
-#MCU = at90usb646 # Teensy++ 1.0
-#MCU = at90usb1286 # Teensy++ 2.0
-MCU = atmega168
-
-
-# Processor frequency.
-# Normally the first thing your program should do is set the clock prescaler,
-# so your program will run at the correct speed. You should also set this
-# variable to same clock speed. The _delay_ms() macro uses this, and many
-# examples use this variable to calculate timings. Do not add a "UL" here.
-F_CPU = 20000000
-
-
-# Build Options
-# comment out to disable the options.
-#
-MOUSEKEY_ENABLE = yes # Mouse keys
-#USB_EXTRA_ENABLE = yes # Enhanced feature for Windows(Audio control and System control)
-#USB_NKRO_ENABLE = yes # USB Nkey Rollover
-
-
-
-#---------------- Programming Options (avrdude) ----------------
-# Type: avrdude -c ? to get a full listing.
-AVRDUDE_PROGRAMMER = usbasp
-AVRDUDE_PORT =
-AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
-#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
-
-# Uncomment the following if you want avrdude's erase cycle counter.
-# Note that this counter needs to be initialized first using -Yn,
-# see avrdude manual.
-#AVRDUDE_ERASE_COUNTER = -y
-
-# Uncomment the following if you do /not/ wish a verification to be
-# performed after programming the device.
-#AVRDUDE_NO_VERIFY = -V
-
-# Increase verbosity level. Please use this when submitting bug
-# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
-# to submit bug reports.
-#AVRDUDE_VERBOSE = -v -v
-
-#AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
-AVRDUDE_FLAGS = -p $(MCU) -c $(AVRDUDE_PROGRAMMER)
-AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
-AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
-AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
-
-
-
-include $(COMMON_DIR)/Makefile.vusb
-include $(COMMON_DIR)/Makefile.common
+++ /dev/null
-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.
+++ /dev/null
-#ifndef CONFIG_H
-#define CONFIG_H
-
-
-#define VENDOR_ID 0xFEED
-#define PRODUCT_ID 0x2233
-// TODO: share these strings with usbconfig.h
-// Edit usbconfig.h to change these.
-#define MANUFACTURER t.m.k.
-#define PRODUCT PS/2 keyboard converter
-#define DESCRIPTION convert PS/2 keyboard to USB
-
-/* matrix size */
-#define MATRIX_ROWS 32 // keycode bit: 3-0
-#define MATRIX_COLS 8 // keycode bit: 6-4
-
-/* 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
-#endif
-
-/* mouse keys */
-#ifdef MOUSEKEY_ENABLE
-# define MOUSEKEY_DELAY_TIME 255
-#endif
-
-
-/* PS/2 lines */
-#define PS2_CLOCK_PORT PORTD
-#define PS2_CLOCK_PIN PIND
-#define PS2_CLOCK_DDR DDRD
-#define PS2_CLOCK_BIT 4
-#define PS2_DATA_PORT PORTD
-#define PS2_DATA_PIN PIND
-#define PS2_DATA_DDR DDRD
-#define PS2_DATA_BIT 0
-
-
-// Synchronous USART is used to receive data from keyboard.
-// Use RXD pin for PS/2 DATA line and XCK for PS/2 CLOCK.
-// NOTE: This is recomended strongly if you use V-USB library.
-#define PS2_USE_USART
-
-// External or Pin Change Interrupt is used to receive data from keyboard.
-// Use INT1 or PCINTxx for PS/2 CLOCK line. see below.
-//#define PS2_USE_INT
-
-
-#ifdef PS2_USE_USART
-// synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge
-// set DDR of CLOCK as input to be slave
-#define PS2_USART_INIT() do { \
- PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT); \
- PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); \
- UCSR0C = ((1 << UMSEL00) | \
- (3 << UPM00) | \
- (0 << USBS0) | \
- (3 << UCSZ00) | \
- (0 << UCPOL0)); \
- UCSR0A = 0; \
- UBRR0H = 0; \
- UBRR0L = 0; \
-} while (0)
-#define PS2_USART_RX_INT_ON() do { \
- UCSR0B = ((1 << RXCIE0) | \
- (1 << RXEN0)); \
-} while (0)
-#define PS2_USART_RX_POLL_ON() do { \
- UCSR0B = (1 << RXEN0); \
-} while (0)
-#define PS2_USART_OFF() do { \
- UCSR0C = 0; \
- UCSR0B &= ~((1 << RXEN0) | \
- (1 << TXEN0)); \
-} while (0)
-#define PS2_USART_RX_READY (UCSR0A & (1<<RXC0))
-#define PS2_USART_RX_DATA UDR0
-#define PS2_USART_ERROR (UCSR0A & ((1<<FE0) | (1<<DOR0) | (1<<UPE0)))
-#define PS2_USART_RX_VECT USART_RX_vect
-#endif
-
-
-#ifdef PS2_USE_INT
-/* INT1
-#define PS2_INT_INIT() do { \
- EICRA |= ((1<<ISC11) | \
- (0<<ISC10)); \
-} while (0)
-#define PS2_INT_ON() do { \
- EIMSK |= (1<<INT1); \
-} while (0)
-#define PS2_INT_OFF() do { \
- EIMSK &= ~(1<<INT1); \
-} while (0)
-#define PS2_INT_VECT INT1_vect
-*/
-
-/* PCINT20 */
-#define PS2_INT_INIT() do { \
- PCICR |= (1<<PCIE2); \
-} while (0)
-#define PS2_INT_ON() do { \
- PCMSK2 |= (1<<PCINT20); \
-} while (0)
-#define PS2_INT_OFF() do { \
- PCMSK2 &= ~(1<<PCINT20); \
- PCICR &= ~(1<<PCIE2); \
-} while (0)
-#define PS2_INT_VECT PCINT2_vect
-#endif
-
-#endif
+++ /dev/null
-/*
- * Keymap for PS/2 keyboard
- */
-#include <stdint.h>
-#include <stdbool.h>
-#include <avr/pgmspace.h>
-#include "usb_keycodes.h"
-#include "host.h"
-#include "print.h"
-#include "debug.h"
-#include "util.h"
-#include "keymap_skel.h"
-
-
-#define KEYCODE(layer, row, col) (pgm_read_byte(&keymaps[(layer)][(row)][(col)]))
-
-// Convert physical keyboard layout to matrix array.
-// This is a macro to define keymap easily in keyboard layout form.
-#define KEYMAP( \
- K76, K05,K06,K04,K0C, K03,K0B,K83,K0A, K01,K09,K78,K07, KFC,K7E,KFE, KB7,KBF,KDE, \
- K0E,K16,K1E,K26,K25,K2E,K36,K3D,K3E,K46,K45,K4E,K55,K66, KF0,KEC,KFD, K77,KCA,K7C,K7B, \
- K0D,K15,K1D,K24,K2D,K2C,K35,K3C,K43,K44,K4D,K54,K5B,K5D, KF1,KE9,KFA, K6C,K75,K7D, \
- K58,K1C,K1B,K23,K2B,K34,K33,K3B,K42,K4B,K4C,K52, K5A, K6B,K73,K74,K79, \
- K12,K1A,K22,K21,K2A,K32,K31,K3A,K41,K49,K4A, K59, KF5, K69,K72,K7A, \
- K14,K9F,K11, K29, K91,KA7,KAF,K94, KEB,KF2,KF4, K70, K71,KDA \
-) { \
- { KB_NO, KB_##K01, KB_NO, KB_##K03, KB_##K04, KB_##K05, KB_##K06, KB_##K07 }, \
- { KB_NO, KB_##K09, KB_##K0A, KB_##K0B, KB_##K0C, KB_##K0D, KB_##K0E, KB_NO }, \
- { KB_NO, KB_##K11, KB_##K12, KB_NO, KB_##K14, KB_##K15, KB_##K16, KB_NO }, \
- { KB_NO, KB_NO, KB_##K1A, KB_##K1B, KB_##K1C, KB_##K1D, KB_##K1E, KB_NO }, \
- { KB_NO, KB_##K21, KB_##K22, KB_##K23, KB_##K24, KB_##K25, KB_##K26, KB_NO }, \
- { KB_NO, KB_##K29, KB_##K2A, KB_##K2B, KB_##K2C, KB_##K2D, KB_##K2E, KB_NO }, \
- { KB_NO, KB_##K31, KB_##K32, KB_##K33, KB_##K34, KB_##K35, KB_##K36, KB_NO }, \
- { KB_NO, KB_NO, KB_##K3A, KB_##K3B, KB_##K3C, KB_##K3D, KB_##K3E, KB_NO }, \
- { KB_NO, KB_##K41, KB_##K42, KB_##K43, KB_##K44, KB_##K45, KB_##K46, KB_NO }, \
- { KB_NO, KB_##K49, KB_##K4A, KB_##K4B, KB_##K4C, KB_##K4D, KB_##K4E, KB_NO }, \
- { KB_NO, KB_NO, KB_##K52, KB_NO, KB_##K54, KB_##K55, KB_NO, KB_NO }, \
- { KB_##K58, KB_##K59, KB_##K5A, KB_##K5B, KB_NO, KB_##K5D, KB_NO, KB_NO }, \
- { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_##K66, KB_NO }, \
- { KB_NO, KB_##K69, KB_NO, KB_##K6B, KB_##K6C, KB_NO, KB_NO, KB_NO }, \
- { KB_##K70, KB_##K71, KB_##K72, KB_##K73, KB_##K74, KB_##K75, KB_##K76, KB_##K77 }, \
- { KB_##K78, KB_##K79, KB_##K7A, KB_##K7B, KB_##K7C, KB_##K7D, KB_##K7E, KB_NO }, \
- { KB_NO, KB_NO, KB_NO, KB_##K83, KB_NO, KB_NO, KB_NO, KB_NO }, \
- { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \
- { KB_NO, KB_##K91, KB_NO, KB_NO, KB_##K94, KB_NO, KB_NO, KB_NO }, \
- { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_##K9F }, \
- { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_##KA7 }, \
- { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_##KAF }, \
- { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_##KB7 }, \
- { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_##KBF }, \
- { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \
- { KB_NO, KB_NO, KB_##KCA, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \
- { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \
- { KB_NO, KB_NO, KB_##KDA, KB_NO, KB_NO, KB_NO, KB_##KDE, KB_NO }, \
- { KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO }, \
- { KB_NO, KB_##KE9, KB_NO, KB_##KEB, KB_##KEC, KB_NO, KB_NO, KB_NO }, \
- { KB_##KF0, KB_##KF1, KB_##KF2, KB_NO, KB_##KF4, KB_##KF5, KB_NO, KB_NO }, \
- { KB_NO, KB_NO, KB_##KFA, KB_NO, KB_##KFC, KB_##KFD, KB_##KFE, KB_NO }, \
-}
-
-
-// Assign Fn key(0-7) to a layer to which switch with the Fn key pressed.
-static const uint8_t PROGMEM fn_layer[] = {
- 5, // Fn0
- 6, // Fn1
- 5, // Fn2
- 0, // Fn3
- 0, // Fn4
- 0, // Fn5
- 0, // Fn6
- 0 // Fn7
-};
-
-// Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer.
-// See layer.c for details.
-static const uint8_t PROGMEM fn_keycode[] = {
- KB_SCLN, // Fn0
- KB_SLSH, // Fn1
- KB_A, // Fn2
- KB_NO, // Fn3
- KB_NO, // Fn4
- KB_NO, // Fn5
- KB_NO, // Fn6
- KB_NO // Fn7
-};
-
-static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
- /* keymap
- * ,---. ,---------------. ,---------------. ,---------------. ,-----------. ,-----------.
- * |Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau| |Pwr|Slp|Wak|
- * `---' `---------------' `---------------' `---------------' `-----------' `-----------'
- * ,-----------------------------------------------------------. ,-----------. ,---------------.
- * | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backspa| |Ins|Hom|PgU| |NmL| /| *| -|
- * |-----------------------------------------------------------| |-----------| |---------------|
- * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD| | 7| 8| 9| |
- * |-----------------------------------------------------------| `-----------' |-----------| +|
- * |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Return | | 4| 5| 6| |
- * |-----------------------------------------------------------| ,---. |---------------|
- * |Shift | Z| X| C| V| B| N| M| ,| ,| /|Shift | |Up | | 1| 2| 3| |
- * |-----------------------------------------------------------| ,-----------. |-----------|Ent|
- * |Ctrl |Gui |Alt | Space |Alt |Gui |Menu|Ctrl| |Lef|Dow|Rig| | 0| .| |
- * `-----------------------------------------------------------' `-----------' `---------------'
- */
- /* 0: default */
- KEYMAP(
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, PWR, F13, F14,
- GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
- TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9,
- CAPS,FN2, S, D, F, G, H, J, K, L, FN0, QUOT, ENT, P4, P5, P6, PPLS,
- LSFT,Z, X, C, V, B, N, M, COMM,DOT, FN1, RSFT, UP, P1, P2, P3,
- LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
- ),
- /* 1: plain Qwerty without layer switching */
- KEYMAP(
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, PWR, F13, F14,
- GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
- TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9,
- CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, ENT, P4, P5, P6, PPLS,
- LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3,
- LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
- ),
- /* 2: Colemak http://colemak.com */
- KEYMAP(
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, PWR, F13, F14,
- GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
- TAB, Q, W, F, P, G, J, L, U, Y, SCLN,LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9,
- BSPC,A, R, S, T, D, H, N, E, I, O, QUOT, ENT, P4, P5, P6, PPLS,
- LSFT,Z, X, C, V, B, K, M, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3,
- LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
- ),
- /* 3: Dvorak http://en.wikipedia.org/wiki/Dvorak_Simplified_Keyboard */
- KEYMAP(
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, PWR, F13, F14,
- GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, LBRC,RBRC,BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
- TAB, QUOT,COMM,DOT, P, Y, F, G, C, R, L, SLSH,EQL, BSLS, DEL, END, PGDN, P7, P8, P9,
- CAPS,A, O, E, U, I, D, H, T, N, S, MINS, ENT, P4, P5, P6, PPLS,
- LSFT,SCLN,Q, J, K, X, B, M, W, V, Z, RSFT, UP, P1, P2, P3,
- LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
- ),
- /* 4: Workman http://viralintrospection.wordpress.com/2010/09/06/a-different-philosophy-in-designing-keyboard-layouts/ */
- KEYMAP(
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, PWR, F13, F14,
- GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
- TAB, Q, D, R, W, B, J, F, U, P, SCLN,LBRC,RBRC,BSLS, DEL, END, PGDN, P7, P8, P9,
- BSPC,A, S, H, T, G, Y, N, E, O, I, QUOT, ENT, P4, P5, P6, PPLS,
- LSFT,Z, X, M, C, V, K, L, COMM,DOT, SLSH, RSFT, UP, P1, P2, P3,
- LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
- ),
- /* 5: Mouse keys */
- KEYMAP(
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, PWR, F13, F14,
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F8, F10, F11, F12, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
- TAB, WH_L,WH_D,MS_U,WH_U,WH_R,WH_L,WH_D,WH_U,WH_R,NO, NO, NO, BSLS, DEL, END, PGDN, P7, P8, P9,
- CAPS,FN2, MS_L,MS_D,MS_R,NO, MS_L,MS_D,MS_U,MS_R,FN0, NO, ENT, P4, P5, P6, PPLS,
- LSFT,VOLD,VOLU,MUTE,BTN2,BTN3,BTN2,BTN1,VOLD,VOLU,MUTE, RSFT, UP, P1, P2, P3,
- LCTL,LGUI,LALT, BTN1, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
- ),
- /* 6: Cursor keys */
- KEYMAP(
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK, PWR, F13, F14,
- ESC, F1, F2, F3, F4, F5, F6, F7, F8, F8, F10, F11, F12, BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
- TAB, NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, NO, NO, NO, BSLS, DEL, END, PGDN, P7, P8, P9,
- CAPS,NO, NO, NO, NO, NO, LEFT,DOWN,UP, RGHT,NO, NO, ENT, P4, P5, P6, PPLS,
- LSFT,VOLD,VOLU,MUTE,NO, NO, HOME,PGDN,PGUP,END, FN1, RSFT, UP, P1, P2, P3,
- LCTL,LGUI,LALT, SPC, RALT,RGUI,APP, RCTL, LEFT,DOWN,RGHT, P0, PDOT,PENT
- ),
-};
-
-
-uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col)
-{
- return KEYCODE(layer, row, col);
-}
-
-uint8_t keymap_fn_layer(uint8_t fn_bits)
-{
- return pgm_read_byte(&fn_layer[biton(fn_bits)]);
-}
-
-uint8_t keymap_fn_keycode(uint8_t fn_bits)
-{
- return pgm_read_byte(&fn_keycode[(biton(fn_bits))]);
-}
-
-// define a condition to enter special function mode
-bool keymap_is_special_mode(uint8_t fn_bits)
-{
- return host_get_mods() == (BIT_LSHIFT | BIT_RSHIFT) || host_get_mods() == (BIT_LCTRL | BIT_RSHIFT);
-}
+++ /dev/null
-#include "stdint.h"
-#include "ps2.h"
-#include "led.h"
-
-
-void led_set(uint8_t usb_led)
-{
- uint8_t ps2_led = 0;
- if (usb_led & (1<<USB_LED_SCROLL_LOCK))
- ps2_led |= (1<<PS2_LED_SCROLL_LOCK);
- if (usb_led & (1<<USB_LED_NUM_LOCK))
- ps2_led |= (1<<PS2_LED_NUM_LOCK);
- if (usb_led & (1<<USB_LED_CAPS_LOCK))
- ps2_led |= (1<<PS2_LED_CAPS_LOCK);
- ps2_host_set_led(ps2_led);
-}
+++ /dev/null
-/* PS/2 to USB keyboard converter
- * 2011/02/20
- * Copyright (c) 2011 tmk
- */
-/* Name: main.c
- * Project: hid-mouse, a very simple HID example
- * Author: Christian Starkjohann
- * Creation Date: 2008-04-07
- * Tabsize: 4
- * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
- * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
- * This Revision: $Id: main.c 790 2010-05-30 21:00:26Z cs $
- */
-#include <stdint.h>
-#include <avr/wdt.h>
-#include <avr/interrupt.h>
-#include <util/delay.h>
-#include "usbdrv.h"
-#include "oddebug.h"
-#include "host_vusb.h"
-#include "keyboard.h"
-
-
-#if 0
-#define DEBUGP_INIT() do { DDRC = 0xFF; } while (0)
-#define DEBUGP(x) do { PORTC = x; } while (0)
-#else
-#define DEBUGP_INIT()
-#define DEBUGP(x)
-#endif
-
-
-int main(void)
-{
- DEBUGP_INIT();
- wdt_enable(WDTO_1S);
- odDebugInit();
- usbInit();
-
- /* enforce re-enumeration, do this while interrupts are disabled! */
- usbDeviceDisconnect();
- uint8_t i = 0;
- /* fake USB disconnect for > 250 ms */
- while(--i){
- wdt_reset();
- _delay_ms(1);
- }
- usbDeviceConnect();
- sei();
-
- keyboard_init();
-
- while (1) {
- DEBUGP(0x1);
- wdt_reset();
- usbPoll();
- DEBUGP(0x2);
- keyboard_proc();
- DEBUGP(0x3);
- host_vusb_keyboard_send();
- }
-}
+++ /dev/null
-/*
- * scan matrix
- */
-#include <stdint.h>
-#include <stdbool.h>
-#include <avr/io.h>
-#include <util/delay.h>
-#include "print.h"
-#include "util.h"
-#include "debug.h"
-#include "ps2.h"
-#include "matrix_skel.h"
-
-
-#if (MATRIX_COLS > 16)
-# error "MATRIX_COLS must not exceed 16"
-#endif
-#if (MATRIX_ROWS > 255)
-# error "MATRIX_ROWS must not exceed 255"
-#endif
-
-
-/*
- * Matrix usage:
- * "PS/2 Scan Codes Set 2" is assigned to 256(32x8)cells matrix.
- * Hmm, It is very sparse and not efficient :(
- *
- * 8bit
- * ---------
- * 0| |
- * :| XX | 00-7F for normal codes(without E0-prefix)
- * f|_________|
- * 10| |
- * :| E0 XX | 80-FF for E0-prefix codes(use (XX|0x80) as code)
- * 1f| |
- * ---------
- * exceptions:
- * 83: F8[0x83](normal codes but > 0x7F)
- * FC: PrintScreen[E0 7C or 84]
- * FE: Puause
- */
-#define F8 (0x83)
-#define PRINT_SCREEN (0xFC)
-#define PAUSE (0xFE)
-#define ROW(code) (code>>3)
-#define COL(code) (code&0x07)
-
-static bool is_modified = false;
-
-// matrix state buffer(1:on, 0:off)
-#if (MATRIX_COLS <= 8)
-static uint8_t matrix[MATRIX_ROWS];
-#else
-static uint16_t matrix[MATRIX_ROWS];
-#endif
-
-#ifdef MATRIX_HAS_GHOST
-static bool matrix_has_ghost_in_row(uint8_t row);
-#endif
-static void matrix_make(uint8_t code);
-static void matrix_break(uint8_t code);
-
-
-inline
-uint8_t matrix_rows(void)
-{
- return MATRIX_ROWS;
-}
-
-inline
-uint8_t matrix_cols(void)
-{
- return MATRIX_COLS;
-}
-
-void matrix_init(void)
-{
- ps2_host_init();
-
- // initialize matrix state: all keys off
- for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
-
- return;
-}
-
-/*
- * PS/2 Scan Code Set 2: Exceptional Handling
- *
- * There are several keys to be handled exceptionally.
- * The scan code for these keys are varied or prefix/postfix'd
- * depending on modifier key state.
- *
- * References:
- * http://www.microsoft.com/whdc/archive/scancode.mspx
- * http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
- *
- *
- * Insert, Delete, Home, End, PageUp, PageDown, Up, Down, Right, Left:
- * Num Lock: off
- * modifiers | make | break
- * ----------+---------------------------+----------------------
- * Ohter | <make> | <break>
- * LShift | E0 F0 12 <make> | <break> E0 12
- * RShift | E0 F0 59 <make> | <break> E0 59
- * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12
- *
- * Num Lock: on
- * modifiers | make | break
- * ----------+---------------------------+----------------------
- * Other | E0 12 <make> | <break> E0 F0 12
- * Shift'd | <make> | <break>
- *
- * Handling: ignore these prefix/postfix codes
- *
- *
- * Keypad-/:
- * modifiers | make | break
- * ----------+---------------------------+----------------------
- * Ohter | <make> | <break>
- * LShift | E0 F0 12 <make> | <break> E0 12
- * RShift | E0 F0 59 <make> | <break> E0 59
- * L+RShift | E0 F0 12 E0 F0 59 <make> | <break> E0 59 E0 12
- *
- * Handling: ignore these prefix/postfix codes
- *
- *
- * PrintScreen:
- * With hoding down modifiers, the scan code is sent as following:
- *
- * modifiers | make | break
- * ----------+--------------+-----------------------------------
- * Other | E0 12 E0 7C | E0 F0 7C E0 F0 12
- * Shift'd | E0 7C | E0 F0 7C
- * Control'd | E0 7C | E0 F0 7C
- * Alt'd | 84 | F0 84
- *
- * Handling: ignore prefix/postfix codes and treat both scan code
- * E0 7C and 84 as PrintScreen.
- *
- * Pause:
- * With hoding down modifiers, the scan code is sent as following:
- *
- * modifiers | make(no break code)
- * ----------+--------------------------------------------------
- * no mods | E1 14 77 E1 F0 14 F0 77
- * Control'd | E0 7E E0 F0 7E
- *
- * Handling: treat these two code sequence as Pause
- *
- */
-uint8_t matrix_scan(void)
-{
-
- static enum {
- INIT,
- F0,
- E0,
- E0_F0,
- // states for Pause/Break
- E1,
- E1_14,
- E1_14_77,
- E1_14_77_E1,
- E1_14_77_E1_F0,
- E1_14_77_E1_F0_14,
- E1_14_77_E1_F0_14_F0,
- } state = INIT;
-
-
- is_modified = false;
-
- // Pause/Break off(PS/2 has no break for this key)
- if (matrix_is_on(ROW(PAUSE), COL(PAUSE))) {
- matrix_break(PAUSE);
- }
-
- uint8_t code;
- while ((code = ps2_host_recv())) {
- switch (state) {
- case INIT:
- switch (code) {
- case 0xE0: // 2byte make
- state = E0;
- break;
- case 0xF0: // break code
- state = F0;
- break;
- case 0xE1: // Pause/Break
- state = E1;
- break;
- case 0x83: // F8
- matrix_make(F8);
- state = INIT;
- break;
- case 0x84: // PrintScreen
- matrix_make(PRINT_SCREEN);
- state = INIT;
- break;
- default: // normal key make
- if (code < 0x80) {
- matrix_make(code);
- } else {
- debug("unexpected scan code at INIT: "); debug_hex(code); debug("\n");
- }
- state = INIT;
- }
- break;
- case E0:
- switch (code) {
- case 0x12: // postfix/postfix code for exceptional keys
- case 0x59: // postfix/postfix code for exceptional keys
- // ignore
- state = INIT;
- break;
- case 0x7E: // former part of Control-Pause[E0 7E E0 F0 7E]
- matrix_make(PAUSE);
- state = INIT;
- break;
- case 0xF0: // E0 break
- state = E0_F0;
- break;
- default: // E0 make
- if (code < 0x80) {
- matrix_make(code|0x80);
- } else {
- debug("unexpected scan code at E0: "); debug_hex(code); debug("\n");
- }
- state = INIT;
- }
- break;
- case F0:
- switch (code) {
- case 0x83:
- matrix_break(F8);
- state = INIT;
- break;
- case 0x84:
- matrix_break(PRINT_SCREEN);
- state = INIT;
- break;
- default:
- if (code < 0x80) {
- matrix_break(code);
- } else {
- debug("unexpected scan code at F0: "); debug_hex(code); debug("\n");
- }
- state = INIT;
- }
- break;
- case E0_F0: // E0 break
- switch (code) {
- case 0x12: // postfix/postfix code for exceptional keys
- case 0x59: // postfix/postfix code for exceptional keys
- case 0x7E: // latter part of Control-Pause[E0 7E E0 F0 7E]
- // ignore
- state = INIT;
- break;
- default:
- if (code < 0x80) {
- matrix_break(code|0x80);
- } else {
- debug("unexpected scan code at E0_F0: "); debug_hex(code); debug("\n");
- }
- state = INIT;
- }
- break;
- /* Pause */
- case E1:
- switch (code) {
- case 0x14:
- state = E1_14;
- break;
- default:
- state = INIT;
- }
- break;
- case E1_14:
- switch (code) {
- case 0x77:
- state = E1_14_77;
- break;
- default:
- state = INIT;
- }
- break;
- case E1_14_77:
- switch (code) {
- case 0xE1:
- state = E1_14_77_E1;
- break;
- default:
- state = INIT;
- }
- break;
- case E1_14_77_E1:
- switch (code) {
- case 0xF0:
- state = E1_14_77_E1_F0;
- break;
- default:
- state = INIT;
- }
- break;
- case E1_14_77_E1_F0:
- switch (code) {
- case 0x14:
- state = E1_14_77_E1_F0_14;
- break;
- default:
- state = INIT;
- }
- break;
- case E1_14_77_E1_F0_14:
- switch (code) {
- case 0xF0:
- state = E1_14_77_E1_F0_14_F0;
- break;
- default:
- state = INIT;
- }
- break;
- case E1_14_77_E1_F0_14_F0:
- switch (code) {
- case 0x77:
- matrix_make(PAUSE);
- state = INIT;
- break;
- default:
- state = INIT;
- }
- break;
- default:
- state = INIT;
- }
- }
- return 1;
-}
-
-bool matrix_is_modified(void)
-{
- return is_modified;
-}
-
-inline
-bool matrix_has_ghost(void)
-{
-#ifdef MATRIX_HAS_GHOST
- for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
- if (matrix_has_ghost_in_row(i))
- return true;
- }
-#endif
- return false;
-}
-
-inline
-bool matrix_is_on(uint8_t row, uint8_t col)
-{
- return (matrix[row] & (1<<col));
-}
-
-inline
-#if (MATRIX_COLS <= 8)
-uint8_t matrix_get_row(uint8_t row)
-#else
-uint16_t matrix_get_row(uint8_t row)
-#endif
-{
- return matrix[row];
-}
-
-void matrix_print(void)
-{
-#if (MATRIX_COLS <= 8)
- print("\nr/c 01234567\n");
-#else
- print("\nr/c 0123456789ABCDEF\n");
-#endif
- for (uint8_t row = 0; row < matrix_rows(); row++) {
- phex(row); print(": ");
-#if (MATRIX_COLS <= 8)
- pbin_reverse(matrix_get_row(row));
-#else
- pbin_reverse16(matrix_get_row(row));
-#endif
-#ifdef MATRIX_HAS_GHOST
- if (matrix_has_ghost_in_row(row)) {
- print(" <ghost");
- }
-#endif
- print("\n");
- }
-}
-
-uint8_t matrix_key_count(void)
-{
- uint8_t count = 0;
- for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
-#if (MATRIX_COLS <= 8)
- count += bitpop(matrix[i]);
-#else
- count += bitpop16(matrix[i]);
-#endif
- }
- return count;
-}
-
-#ifdef MATRIX_HAS_GHOST
-inline
-static bool matrix_has_ghost_in_row(uint8_t row)
-{
- // no ghost exists in case less than 2 keys on
- if (((matrix[row] - 1) & matrix[row]) == 0)
- return false;
-
- // ghost exists in case same state as other row
- for (uint8_t i=0; i < MATRIX_ROWS; i++) {
- if (i != row && (matrix[i] & matrix[row]) == matrix[row])
- return true;
- }
- return false;
-}
-#endif
-
-
-inline
-static void matrix_make(uint8_t code)
-{
- if (!matrix_is_on(ROW(code), COL(code))) {
- matrix[ROW(code)] |= 1<<COL(code);
- is_modified = true;
- //print("matrix_make: "); phex(code); print("\n");
- }
-}
-
-inline
-static void matrix_break(uint8_t code)
-{
- if (matrix_is_on(ROW(code), COL(code))) {
- matrix[ROW(code)] &= ~(1<<COL(code));
- is_modified = true;
- //print("matrix_break: "); phex(code); print("\n");
- }
-}
+++ /dev/null
-/*
-Copyright (c) 2010,2011 Jun WAKO <wakojun@gmail.com>
-
-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.
-*/
-/*
-Primitive PS/2 Library for AVR
-==============================
-Host side is only supported now.
-Synchronous USART is used to receive data by hardware process
-rather than interrupt. During V-USB interrupt runs, CLOCK interrupt
-cannot interpose. In the result it is prone to lost CLOCK edge.
-
-
-I/O control
------------
-High state is asserted by internal pull-up.
-If you have a signaling problem, you may need to have
-external pull-up resisters on CLOCK and DATA line.
-
-
-PS/2 References
----------------
-http://www.computer-engineering.org/ps2protocol/
-http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
-*/
-#include <stdbool.h>
-#include <avr/io.h>
-#include <avr/interrupt.h>
-#include <util/delay.h>
-#include "ps2.h"
-#include "debug.h"
-
-
-#if 0
-#define DEBUGP_INIT() do { DDRC = 0xFF; } while (0)
-#define DEBUGP(x) do { PORTC = x; } while (0)
-#else
-#define DEBUGP_INIT()
-#define DEBUGP(x)
-#endif
-
-#define WAIT(stat, us, err) do { \
- if (!wait_##stat(us)) { \
- ps2_error = err; \
- goto ERROR; \
- } \
-} while (0)
-
-
-uint8_t ps2_error = PS2_ERR_NONE;
-
-
-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);
-static inline void idle(void);
-static inline void inhibit(void);
-#if defined PS2_USE_INT || defined PS2_USE_USART
-static inline uint8_t pbuf_dequeue(void);
-static inline void pbuf_enqueue(uint8_t data);
-#endif
-
-
-void ps2_host_init(void)
-{
- DEBUGP_INIT();
- DEBUGP(0x1);
- idle();
- PS2_USART_INIT();
- PS2_USART_RX_INT_ON();
-}
-
-uint8_t ps2_host_send(uint8_t data)
-{
- uint8_t res = 0;
- bool parity = true;
- ps2_error = PS2_ERR_NONE;
-
- DEBUGP(0x6);
- PS2_USART_OFF();
-
- /* terminate a transmission if we have */
- inhibit();
- _delay_us(100);
-
- /* start bit [1] */
- data_lo();
- clock_hi();
- WAIT(clock_lo, 15000, 1);
- /* data [2-9] */
- for (uint8_t i = 0; i < 8; i++) {
- _delay_us(15);
- if (data&(1<<i)) {
- parity = !parity;
- data_hi();
- } else {
- data_lo();
- }
- WAIT(clock_hi, 50, 2);
- WAIT(clock_lo, 50, 3);
- }
- /* parity [10] */
- _delay_us(15);
- if (parity) { data_hi(); } else { data_lo(); }
- WAIT(clock_hi, 50, 4);
- WAIT(clock_lo, 50, 5);
- /* stop bit [11] */
- _delay_us(15);
- data_hi();
- /* ack [12] */
- WAIT(data_lo, 50, 6);
- WAIT(clock_lo, 50, 7);
-
- /* wait for idle state */
- WAIT(clock_hi, 50, 8);
- WAIT(data_hi, 50, 9);
-
- res = ps2_host_recv_response();
-ERROR:
- idle();
- PS2_USART_INIT();
- PS2_USART_RX_INT_ON();
- return res;
-}
-
-// Do polling data from keyboard to get response to last command.
-uint8_t ps2_host_recv_response(void)
-{
- uint8_t data = 0;
- PS2_USART_INIT();
- PS2_USART_RX_POLL_ON();
- while (!PS2_USART_RX_READY)
- ;
- data = PS2_USART_RX_DATA;
- PS2_USART_OFF();
- DEBUGP(0x9);
- return data;
-}
-
-uint8_t ps2_host_recv(void)
-{
- return pbuf_dequeue();
-}
-
-ISR(PS2_USART_RX_VECT)
-{
- DEBUGP(0x7);
- uint8_t error = PS2_USART_ERROR;
- uint8_t data = PS2_USART_RX_DATA;
- if (error) {
- DEBUGP(error>>2);
- } else {
- pbuf_enqueue(data);
- }
- DEBUGP(0x8);
-}
-
-/* send LED state to keyboard */
-void ps2_host_set_led(uint8_t led)
-{
- // send 0xED then keyboard keeps waiting for next LED data
- // and keyboard does not send any scan codes during waiting.
- // If fail to send LED data keyboard looks like being freezed.
- uint8_t retry = 3;
- while (retry-- && ps2_host_send(PS2_SET_LED) != PS2_ACK)
- ;
- retry = 3;
- while (retry-- && ps2_host_send(led) != PS2_ACK)
- ;
-}
-
-
-/*--------------------------------------------------------------------
- * static functions
- *------------------------------------------------------------------*/
-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);
- _delay_us(1);
- 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);
- _delay_us(1);
- 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;
-}
-
-/* idle state that device can send */
-static inline void idle(void)
-{
- clock_hi();
- data_hi();
-}
-
-/* inhibit device to send */
-static inline void inhibit(void)
-{
- clock_lo();
- data_hi();
-}
-
-
-/*--------------------------------------------------------------------
- * Ring buffer to store scan codes from keyboard
- *------------------------------------------------------------------*/
-#define PBUF_SIZE 8
-static uint8_t pbuf[PBUF_SIZE];
-static uint8_t pbuf_head = 0;
-static uint8_t pbuf_tail = 0;
-static inline void pbuf_enqueue(uint8_t data)
-{
- if (!data)
- return;
-
- uint8_t sreg = SREG;
- cli();
- uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
- if (next != pbuf_tail) {
- pbuf[pbuf_head] = data;
- pbuf_head = next;
- } else {
- debug("pbuf: full\n");
- }
- SREG = sreg;
-}
-
-static inline uint8_t pbuf_dequeue(void)
-{
- uint8_t val = 0;
-
- uint8_t sreg = SREG;
- cli();
- if (pbuf_head != pbuf_tail) {
- val = pbuf[pbuf_tail];
- pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
- }
- SREG = sreg;
-
- return val;
-}
+++ /dev/null
-#include <stdint.h>
-#include "sendchar.h"
-
-
-int8_t sendchar(uint8_t c)
-{
- return 1;
-}
+++ /dev/null
-#include <stdint.h>
-#include "oddebug.h"
-#include "sendchar.h"
-
-
-/* from oddebug.h */
-#if defined UBRR
-# define ODDBG_UBRR UBRR
-#elif defined UBRRL
-# define ODDBG_UBRR UBRRL
-#elif defined UBRR0
-# define ODDBG_UBRR UBRR0
-#elif defined UBRR0L
-# define ODDBG_UBRR UBRR0L
-#endif
-
-#if defined UCR
-# define ODDBG_UCR UCR
-#elif defined UCSRB
-# define ODDBG_UCR UCSRB
-#elif defined UCSR0B
-# define ODDBG_UCR UCSR0B
-#endif
-
-#if defined TXEN
-# define ODDBG_TXEN TXEN
-#else
-# define ODDBG_TXEN TXEN0
-#endif
-
-#if defined USR
-# define ODDBG_USR USR
-#elif defined UCSRA
-# define ODDBG_USR UCSRA
-#elif defined UCSR0A
-# define ODDBG_USR UCSR0A
-#endif
-
-#if defined UDRE
-# define ODDBG_UDRE UDRE
-#else
-# define ODDBG_UDRE UDRE0
-#endif
-
-#if defined UDR
-# define ODDBG_UDR UDR
-#elif defined UDR0
-# define ODDBG_UDR UDR0
-#endif
-
-
-/* from oddebug.c */
-int8_t sendchar(uint8_t c)
-{
- while(!(ODDBG_USR & (1 << ODDBG_UDRE))); /* wait for data register empty */
- ODDBG_UDR = c;
- return 1;
-}
+++ /dev/null
-/* Name: usbconfig.h
- * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
- * Author: Christian Starkjohann
- * Creation Date: 2005-04-01
- * Tabsize: 4
- * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
- * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
- * This Revision: $Id: usbconfig-prototype.h 785 2010-05-30 17:57:07Z cs $
- */
-
-#ifndef __usbconfig_h_included__
-#define __usbconfig_h_included__
-
-#include "config.h"
-
-/*
-General Description:
-This file is an example configuration (with inline documentation) for the USB
-driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
-also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
-wire the lines to any other port, as long as D+ is also wired to INT0 (or any
-other hardware interrupt, as long as it is the highest level interrupt, see
-section at the end of this file).
-*/
-
-/* ---------------------------- Hardware Config ---------------------------- */
-
-#define USB_CFG_IOPORTNAME D
-/* This is the port where the USB bus is connected. When you configure it to
- * "B", the registers PORTB, PINB and DDRB will be used.
- */
-#define USB_CFG_DMINUS_BIT 3
-/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
- * This may be any bit in the port.
- */
-#define USB_CFG_DPLUS_BIT 2
-/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
- * This may be any bit in the port. Please note that D+ must also be connected
- * to interrupt pin INT0! [You can also use other interrupts, see section
- * "Optional MCU Description" below, or you can connect D- to the interrupt, as
- * it is required if you use the USB_COUNT_SOF feature. If you use D- for the
- * interrupt, the USB interrupt will also be triggered at Start-Of-Frame
- * markers every millisecond.]
- */
-#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
-/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000,
- * 16500, 18000 and 20000. The 12.8 MHz and 16.5 MHz versions of the code
- * require no crystal, they tolerate +/- 1% deviation from the nominal
- * frequency. All other rates require a precision of 2000 ppm and thus a
- * crystal!
- * Since F_CPU should be defined to your actual clock rate anyway, you should
- * not need to modify this setting.
- */
-#define USB_CFG_CHECK_CRC 0
-/* Define this to 1 if you want that the driver checks integrity of incoming
- * data packets (CRC checks). CRC checks cost quite a bit of code size and are
- * currently only available for 18 MHz crystal clock. You must choose
- * USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
- */
-
-/* ----------------------- Optional Hardware Config ------------------------ */
-
-/* #define USB_CFG_PULLUP_IOPORTNAME D */
-/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
- * V+, you can connect and disconnect the device from firmware by calling
- * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
- * This constant defines the port on which the pullup resistor is connected.
- */
-/* #define USB_CFG_PULLUP_BIT 4 */
-/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
- * above) where the 1.5k pullup resistor is connected. See description
- * above for details.
- */
-
-/* --------------------------- Functional Range ---------------------------- */
-
-#define USB_CFG_HAVE_INTRIN_ENDPOINT 1
-/* Define this to 1 if you want to compile a version with two endpoints: The
- * default control endpoint 0 and an interrupt-in endpoint (any other endpoint
- * number).
- */
-#define USB_CFG_HAVE_INTRIN_ENDPOINT3 1
-/* Define this to 1 if you want to compile a version with three endpoints: The
- * default control endpoint 0, an interrupt-in endpoint 3 (or the number
- * configured below) and a catch-all default interrupt-in endpoint as above.
- * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
- */
-#define USB_CFG_EP3_NUMBER 3
-/* If the so-called endpoint 3 is used, it can now be configured to any other
- * endpoint number (except 0) with this macro. Default if undefined is 3.
- */
-/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */
-/* The above macro defines the startup condition for data toggling on the
- * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1.
- * Since the token is toggled BEFORE sending any data, the first packet is
- * sent with the oposite value of this configuration!
- */
-#define USB_CFG_IMPLEMENT_HALT 0
-/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature
- * for endpoint 1 (interrupt endpoint). Although you may not need this feature,
- * it is required by the standard. We have made it a config option because it
- * bloats the code considerably.
- */
-#define USB_CFG_SUPPRESS_INTR_CODE 0
-/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
- * want to send any data over them. If this macro is defined to 1, functions
- * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if
- * you need the interrupt-in endpoints in order to comply to an interface
- * (e.g. HID), but never want to send any data. This option saves a couple
- * of bytes in flash memory and the transmit buffers in RAM.
- */
-#define USB_CFG_INTR_POLL_INTERVAL 10
-/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
- * interval. The value is in milliseconds and must not be less than 10 ms for
- * low speed devices.
- */
-#define USB_CFG_IS_SELF_POWERED 0
-/* Define this to 1 if the device has its own power supply. Set it to 0 if the
- * device is powered from the USB bus.
- */
-#define USB_CFG_MAX_BUS_POWER 100
-/* Set this variable to the maximum USB bus power consumption of your device.
- * The value is in milliamperes. [It will be divided by two since USB
- * communicates power requirements in units of 2 mA.]
- */
-#define USB_CFG_IMPLEMENT_FN_WRITE 1
-/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
- * transfers. Set it to 0 if you don't need it and want to save a couple of
- * bytes.
- */
-#define USB_CFG_IMPLEMENT_FN_READ 0
-/* Set this to 1 if you need to send control replies which are generated
- * "on the fly" when usbFunctionRead() is called. If you only want to send
- * data from a static buffer, set it to 0 and return the data from
- * usbFunctionSetup(). This saves a couple of bytes.
- */
-#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0
-/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints.
- * You must implement the function usbFunctionWriteOut() which receives all
- * interrupt/bulk data sent to any endpoint other than 0. The endpoint number
- * can be found in 'usbRxToken'.
- */
-#define USB_CFG_HAVE_FLOWCONTROL 0
-/* Define this to 1 if you want flowcontrol over USB data. See the definition
- * of the macros usbDisableAllRequests() and usbEnableAllRequests() in
- * usbdrv.h.
- */
-#define USB_CFG_DRIVER_FLASH_PAGE 0
-/* If the device has more than 64 kBytes of flash, define this to the 64 k page
- * where the driver's constants (descriptors) are located. Or in other words:
- * Define this to 1 for boot loaders on the ATMega128.
- */
-#define USB_CFG_LONG_TRANSFERS 0
-/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
- * in a single control-in or control-out transfer. Note that the capability
- * for long transfers increases the driver size.
- */
-/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
-/* This macro is a hook if you want to do unconventional things. If it is
- * defined, it's inserted at the beginning of received message processing.
- * If you eat the received message and don't want default processing to
- * proceed, do a return after doing your things. One possible application
- * (besides debugging) is to flash a status LED on each packet.
- */
-/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */
-/* This macro is a hook if you need to know when an USB RESET occurs. It has
- * one parameter which distinguishes between the start of RESET state and its
- * end.
- */
-/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */
-/* This macro (if defined) is executed when a USB SET_ADDRESS request was
- * received.
- */
-#define USB_COUNT_SOF 0
-/* define this macro to 1 if you need the global variable "usbSofCount" which
- * counts SOF packets. This feature requires that the hardware interrupt is
- * connected to D- instead of D+.
- */
-/* #ifdef __ASSEMBLER__
- * macro myAssemblerMacro
- * in YL, TCNT0
- * sts timer0Snapshot, YL
- * endm
- * #endif
- * #define USB_SOF_HOOK myAssemblerMacro
- * This macro (if defined) is executed in the assembler module when a
- * Start Of Frame condition is detected. It is recommended to define it to
- * the name of an assembler macro which is defined here as well so that more
- * than one assembler instruction can be used. The macro may use the register
- * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
- * immediately after an SOF pulse may be lost and must be retried by the host.
- * What can you do with this hook? Since the SOF signal occurs exactly every
- * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
- * designs running on the internal RC oscillator.
- * Please note that Start Of Frame detection works only if D- is wired to the
- * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
- */
-#define USB_CFG_CHECK_DATA_TOGGLING 0
-/* define this macro to 1 if you want to filter out duplicate data packets
- * sent by the host. Duplicates occur only as a consequence of communication
- * errors, when the host does not receive an ACK. Please note that you need to
- * implement the filtering yourself in usbFunctionWriteOut() and
- * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
- * for each control- and out-endpoint to check for duplicate packets.
- */
-#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
-/* define this macro to 1 if you want the function usbMeasureFrameLength()
- * compiled in. This function can be used to calibrate the AVR's RC oscillator.
- */
-#define USB_USE_FAST_CRC 0
-/* The assembler module has two implementations for the CRC algorithm. One is
- * faster, the other is smaller. This CRC routine is only used for transmitted
- * messages where timing is not critical. The faster routine needs 31 cycles
- * per byte while the smaller one needs 61 to 69 cycles. The faster routine
- * may be worth the 32 bytes bigger code size if you transmit lots of data and
- * run the AVR close to its limit.
- */
-
-/* -------------------------- Device Description --------------------------- */
-
-#define USB_CFG_VENDOR_ID (VENDOR_ID & 0xFF), ((VENDOR_ID >> 8) & 0xFF)
-/* USB vendor ID for the device, low byte first. If you have registered your
- * own Vendor ID, define it here. Otherwise you may use one of obdev's free
- * shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules!
- * *** IMPORTANT NOTE ***
- * This template uses obdev's shared VID/PID pair for Vendor Class devices
- * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
- * the implications!
- */
-#define USB_CFG_DEVICE_ID (PRODUCT_ID & 0xFF), ((PRODUCT_ID >> 8) & 0xFF)
-/* This is the ID of the product, low byte first. It is interpreted in the
- * scope of the vendor ID. If you have registered your own VID with usb.org
- * or if you have licensed a PID from somebody else, define it here. Otherwise
- * you may use one of obdev's free shared VID/PID pairs. See the file
- * USB-IDs-for-free.txt for details!
- * *** IMPORTANT NOTE ***
- * This template uses obdev's shared VID/PID pair for Vendor Class devices
- * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
- * the implications!
- */
-#define USB_CFG_DEVICE_VERSION 0x00, 0x01
-/* Version number of the device: Minor number first, then major number.
- */
-#define USB_CFG_VENDOR_NAME 't', '.', 'm', '.', 'k', '.'
-#define USB_CFG_VENDOR_NAME_LEN 6
-/* These two values define the vendor name returned by the USB device. The name
- * must be given as a list of characters under single quotes. The characters
- * are interpreted as Unicode (UTF-16) entities.
- * If you don't want a vendor name string, undefine these macros.
- * ALWAYS define a vendor name containing your Internet domain name if you use
- * obdev's free shared VID/PID pair. See the file USB-IDs-for-free.txt for
- * details.
- */
-#define USB_CFG_DEVICE_NAME 'P', 'S', '/', '2', ' ', 'k', 'e', 'y', 'b', 'o', 'a', 'r', 'd', ' ', 'c', 'o', 'n', 'v', 'e', 'r', 't', 'e', 'r'
-#define USB_CFG_DEVICE_NAME_LEN 23
-/* Same as above for the device name. If you don't want a device name, undefine
- * the macros. See the file USB-IDs-for-free.txt before you assign a name if
- * you use a shared VID/PID.
- */
-/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */
-/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */
-/* Same as above for the serial number. If you don't want a serial number,
- * undefine the macros.
- * It may be useful to provide the serial number through other means than at
- * compile time. See the section about descriptor properties below for how
- * to fine tune control over USB descriptors such as the string descriptor
- * for the serial number.
- */
-#define USB_CFG_DEVICE_CLASS 0
-#define USB_CFG_DEVICE_SUBCLASS 0
-/* See USB specification if you want to conform to an existing device class.
- * Class 0xff is "vendor specific".
- */
-#define USB_CFG_INTERFACE_CLASS 3 /* HID */
-#define USB_CFG_INTERFACE_SUBCLASS 1 /* Boot */
-#define USB_CFG_INTERFACE_PROTOCOL 1 /* Keyboard */
-/* See USB specification if you want to conform to an existing device class or
- * protocol. The following classes must be set at interface level:
- * HID class is 3, no subclass and protocol required (but may be useful!)
- * CDC class is 2, use subclass 2 and protocol 1 for ACM
- */
-#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 0
-/* Define this to the length of the HID report descriptor, if you implement
- * an HID device. Otherwise don't define it or define it to 0.
- * If you use this define, you must add a PROGMEM character array named
- * "usbHidReportDescriptor" to your code which contains the report descriptor.
- * Don't forget to keep the array and this define in sync!
- */
-
-/* #define USB_PUBLIC static */
-/* Use the define above if you #include usbdrv.c instead of linking against it.
- * This technique saves a couple of bytes in flash memory.
- */
-
-/* ------------------- Fine Control over USB Descriptors ------------------- */
-/* If you don't want to use the driver's default USB descriptors, you can
- * provide our own. These can be provided as (1) fixed length static data in
- * flash memory, (2) fixed length static data in RAM or (3) dynamically at
- * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more
- * information about this function.
- * Descriptor handling is configured through the descriptor's properties. If
- * no properties are defined or if they are 0, the default descriptor is used.
- * Possible properties are:
- * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
- * at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is
- * used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if
- * you want RAM pointers.
- * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
- * in static memory is in RAM, not in flash memory.
- * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
- * the driver must know the descriptor's length. The descriptor itself is
- * found at the address of a well known identifier (see below).
- * List of static descriptor names (must be declared PROGMEM if in flash):
- * char usbDescriptorDevice[];
- * char usbDescriptorConfiguration[];
- * char usbDescriptorHidReport[];
- * char usbDescriptorString0[];
- * int usbDescriptorStringVendor[];
- * int usbDescriptorStringDevice[];
- * int usbDescriptorStringSerialNumber[];
- * Other descriptors can't be provided statically, they must be provided
- * dynamically at runtime.
- *
- * Descriptor properties are or-ed or added together, e.g.:
- * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18))
- *
- * The following descriptors are defined:
- * USB_CFG_DESCR_PROPS_DEVICE
- * USB_CFG_DESCR_PROPS_CONFIGURATION
- * USB_CFG_DESCR_PROPS_STRINGS
- * USB_CFG_DESCR_PROPS_STRING_0
- * USB_CFG_DESCR_PROPS_STRING_VENDOR
- * USB_CFG_DESCR_PROPS_STRING_PRODUCT
- * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
- * USB_CFG_DESCR_PROPS_HID
- * USB_CFG_DESCR_PROPS_HID_REPORT
- * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
- *
- * Note about string descriptors: String descriptors are not just strings, they
- * are Unicode strings prefixed with a 2 byte header. Example:
- * int serialNumberDescriptor[] = {
- * USB_STRING_DESCRIPTOR_HEADER(6),
- * 'S', 'e', 'r', 'i', 'a', 'l'
- * };
- */
-
-#define USB_CFG_DESCR_PROPS_DEVICE 0
-#define USB_CFG_DESCR_PROPS_CONFIGURATION USB_PROP_IS_DYNAMIC
-//#define USB_CFG_DESCR_PROPS_CONFIGURATION 0
-#define USB_CFG_DESCR_PROPS_STRINGS 0
-#define USB_CFG_DESCR_PROPS_STRING_0 0
-#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0
-#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0
-#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0
-//#define USB_CFG_DESCR_PROPS_HID USB_PROP_IS_DYNAMIC
-#define USB_CFG_DESCR_PROPS_HID 0
-#define USB_CFG_DESCR_PROPS_HID_REPORT USB_PROP_IS_DYNAMIC
-//#define USB_CFG_DESCR_PROPS_HID_REPORT 0
-#define USB_CFG_DESCR_PROPS_UNKNOWN 0
-
-/* ----------------------- Optional MCU Description ------------------------ */
-
-/* The following configurations have working defaults in usbdrv.h. You
- * usually don't need to set them explicitly. Only if you want to run
- * the driver on a device which is not yet supported or with a compiler
- * which is not fully supported (such as IAR C) or if you use a differnt
- * interrupt than INT0, you may have to define some of these.
- */
-/* #define USB_INTR_CFG MCUCR */
-/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */
-/* #define USB_INTR_CFG_CLR 0 */
-/* #define USB_INTR_ENABLE GIMSK */
-/* #define USB_INTR_ENABLE_BIT INT0 */
-/* #define USB_INTR_PENDING GIFR */
-/* #define USB_INTR_PENDING_BIT INTF0 */
-/* #define USB_INTR_VECTOR INT0_vect */
-
-#endif /* __usbconfig_h_included__ */
#include <util/delay.h>
#include "keyboard.h"
#include "usb.h"
-#include "matrix_skel.h"
+#include "matrix.h"
#include "print.h"
#include "debug.h"
#include "util.h"