summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.vusb11
-rw-r--r--POWER.txt62
-rw-r--r--README4
-rw-r--r--adb_usb/Makefile20
-rw-r--r--adb_usb/README8
-rw-r--r--adb_usb/config.h4
-rw-r--r--command.c56
-rw-r--r--command.h2
-rw-r--r--common.mk (renamed from Makefile.common)15
-rw-r--r--hhkb/FUSE.txt40
-rw-r--r--hhkb/Makefile.iwrap91
-rw-r--r--hhkb/Makefile.pjrc (renamed from hhkb/Makefile)19
-rw-r--r--hhkb/Makefile.vusb29
-rw-r--r--hhkb/README113
-rw-r--r--hhkb/config_iwrap.h55
-rw-r--r--hhkb/config_pjrc.h6
-rw-r--r--hhkb/config_vusb.h12
-rw-r--r--hhkb/doc/Bluetooth.txt4
-rwxr-xr-xhhkb/doc/Bluetooth_img/.picasa.ini2
-rwxr-xr-xhhkb/doc/Bluetooth_img/BT_circuit.jpgbin0 -> 502118 bytes
-rw-r--r--hhkb/doc/HHKB_img/HHKB_TP1684.jpg (renamed from hhkb/doc/HHKB_TP1684.jpg)bin149082 -> 149082 bytes
-rw-r--r--hhkb/doc/HHKB_img/HHKB_chart1.jpg (renamed from hhkb/doc/HHKB_chart1.jpg)bin155342 -> 155342 bytes
-rw-r--r--hhkb/doc/HHKB_img/HHKB_chart2.jpg (renamed from hhkb/doc/HHKB_chart2.jpg)bin148225 -> 148225 bytes
-rw-r--r--hhkb/doc/HHKB_img/HHKB_connector.jpg (renamed from hhkb/doc/HHKB_connector.jpg)bin193900 -> 193900 bytes
-rw-r--r--hhkb/doc/HHKB_img/HHKB_controller.jpg (renamed from hhkb/doc/HHKB_controller.jpg)bin135100 -> 135100 bytes
-rw-r--r--hhkb/doc/HHKB_img/HHKB_keyswitch.jpg (renamed from hhkb/doc/HHKB_keyswitch.jpg)bin171469 -> 171469 bytes
-rw-r--r--hhkb/doc/HHKB_img/connector_contact.jpg (renamed from hhkb/doc/connector_contact.jpg)bin192830 -> 192830 bytes
-rw-r--r--hhkb/doc/HHKB_img/logic_analyzer.jpg (renamed from hhkb/doc/logic_analyzer.jpg)bin169564 -> 169564 bytes
-rw-r--r--hhkb/doc/HHKB_img/probe_contact.jpg (renamed from hhkb/doc/probe_contact.jpg)bin208477 -> 208477 bytes
-rw-r--r--hhkb/doc/HHKB_img/teensy_install.jpg (renamed from hhkb/doc/teensy_install.jpg)bin135851 -> 135851 bytes
-rw-r--r--hhkb/doc/HHKB_img/teensy_wiring.jpg (renamed from hhkb/doc/teensy_wiring.jpg)bin154695 -> 154695 bytes
-rw-r--r--hhkb/keymap.c115
-rw-r--r--hhkb/matrix.c66
-rw-r--r--hhkb/usbconfig.h16
-rw-r--r--host.c190
-rw-r--r--host.h89
-rw-r--r--host_driver.h33
-rw-r--r--iwrap.mk10
-rw-r--r--iwrap/iWRAP.txt376
-rw-r--r--iwrap/iwrap.c467
-rw-r--r--iwrap/iwrap.h49
-rw-r--r--iwrap/main.c378
-rw-r--r--iwrap/suart.S156
-rw-r--r--iwrap/suart.h8
-rw-r--r--iwrap/wd.h159
-rw-r--r--keyboard.c9
-rwxr-xr-xlayer.c4
-rw-r--r--macway/Makefile16
-rw-r--r--macway/config.h4
-rw-r--r--[-rwxr-xr-x]macway/doc/back.jpgbin122135 -> 122135 bytes
-rw-r--r--[-rwxr-xr-x]macway/doc/case.jpgbin146003 -> 146003 bytes
-rw-r--r--[-rwxr-xr-x]macway/doc/keys.jpgbin116365 -> 116365 bytes
-rw-r--r--[-rwxr-xr-x]macway/doc/side.jpgbin109755 -> 109755 bytes
-rw-r--r--[-rwxr-xr-x]macway/doc/switch.jpgbin115526 -> 115526 bytes
-rw-r--r--[-rwxr-xr-x]macway/doc/teensy.jpgbin165814 -> 165814 bytes
-rw-r--r--[-rwxr-xr-x]macway/doc/wiring.jpgbin165569 -> 165569 bytes
-rw-r--r--[-rwxr-xr-x]macway/doc/withHHKB.jpgbin152832 -> 152832 bytes
-rw-r--r--[-rwxr-xr-x]macway/doc/withThinkPad.jpgbin118993 -> 118993 bytes
-rw-r--r--main_vusb.c58
-rwxr-xr-x[-rw-r--r--]mousekey.c10
-rw-r--r--pjrc.mk (renamed from Makefile.pjrc)10
-rw-r--r--pjrc/host.c10
-rw-r--r--pjrc/main.c (renamed from main_pjrc.c)3
-rw-r--r--pjrc/pjrc.c76
-rw-r--r--pjrc/pjrc.h26
-rw-r--r--pjrc/usb.c34
-rw-r--r--pjrc/usb.h2
-rw-r--r--pjrc/usb_keyboard.c4
-rw-r--r--print.c13
-rw-r--r--print.h2
-rw-r--r--ps2_usb/Makefile18
-rw-r--r--ps2_usb/Makefile.vusb19
-rw-r--r--ps2_usb/config_pjrc.h4
-rw-r--r--ps2_usb/config_vusb.h4
-rw-r--r--ps2_usb/keymap.c6
-rw-r--r--ps2_usb/matrix.c1
-rw-r--r--report.h96
-rw-r--r--rules.mk (renamed from Makefile.rules)0
-rw-r--r--sendchar.h4
-rw-r--r--sendchar_null.c (renamed from vusb/host_vusb.h)10
-rw-r--r--sendchar_uart.c25
-rw-r--r--timer.c35
-rw-r--r--timer.h21
-rw-r--r--uart.c129
-rw-r--r--uart.h11
-rw-r--r--usb_keycodes.h8
-rw-r--r--vusb.mk17
-rw-r--r--vusb/main.c99
-rw-r--r--vusb/vusb.c (renamed from vusb/host.c)207
-rw-r--r--vusb/vusb.h27
90 files changed, 3150 insertions, 537 deletions
diff --git a/Makefile.vusb b/Makefile.vusb
deleted file mode 100644
index b8e71a8e3..000000000
--- a/Makefile.vusb
+++ /dev/null
@@ -1,11 +0,0 @@
-OPT_DEFS += -DHOST_VUSB
-
-SRC = usbdrv.c \
- usbdrvasm.S \
- oddebug.c \
- sendchar_usart.c
-SRC += $(TARGET_SRC)
-
-
-# C source file search path
-VPATH = $(TARGET_DIR):$(COMMON_DIR):$(COMMON_DIR)/vusb:$(COMMON_DIR)/vusb/usbdrv
diff --git a/POWER.txt b/POWER.txt
new file mode 100644
index 000000000..0abbbe48e
--- /dev/null
+++ b/POWER.txt
@@ -0,0 +1,62 @@
+Time to Sleep
+=============
+USB suspend no activity on USB line for 3ms
+No Interaction no user interaction
+ matrix has no change
+ matrix has no switch on
+
+
+AVR Power Management
+====================
+
+V-USB suspend
+ USB suspend
+ http://vusb.wikidot.com/examples
+
+MCUSR MCU Status Register
+ WDRF Watchdog Reset Flag
+ BORF
+ EXTRF
+ PORF Power-on Reset Flag
+
+SMCR Sleep Mode Control Register
+ SE Sleep Enable
+ SM2:0
+ #define set_sleep_mode(mode) \
+ #define SLEEP_MODE_IDLE (0)
+ #define SLEEP_MODE_ADC _BV(SM0)
+ #define SLEEP_MODE_PWR_DOWN _BV(SM1)
+ #define SLEEP_MODE_PWR_SAVE (_BV(SM0) | _BV(SM1))
+ #define SLEEP_MODE_STANDBY (_BV(SM1) | _BV(SM2))
+ #define SLEEP_MODE_EXT_STANDBY (_BV(SM0) | _BV(SM1) | _BV(SM2))
+
+
+ACSR Analog Comparator Control and Status Register
+ To disable Analog Comparator
+ ACSR = 0x80;
+ or
+ ACSR &= ~_BV(ACIE);
+ ACSR |= _BV(ACD);
+
+ ACD: Analog Comparator Disable
+ When this bit is written logic one, the power to the Analog Comparator is
+ switched off. This bit can be set at any time to turn off the Analog
+ Comparator. This will reduce power consumption in Active and Idle mode.
+ When changing the ACD bit, the Analog Comparator Interrupt must be disabled
+ by clearing the ACIE bit in ACSR. Otherwise an interrupt can occur when
+ the bit is changed.
+
+DIDR1 Digital Input Disable Register 1
+ AIN1D
+ AIN0D
+ When this bit is written logic one, the digital input buffer on the AIN1/0 pin is disabled. The corresponding PIN Register bit will always read as zero when this bit is set. When an analog signal is applied to the AIN1/0 pin and the digital input from this pin is not needed, this bit should be written logic one to reduce power consumption in the digital input buffer.
+
+
+PRR Power Reduction Register
+ PRTWI
+ PRTIM2
+ PRTIM0
+ PRTIM1
+ PRSPI
+ PRUSART0
+ PRADC
diff --git a/README b/README
index 2aa0106b0..d85f512c7 100644
--- a/README
+++ b/README
@@ -96,8 +96,8 @@ Build Options
3. Choose optional modules as needed. Comment out to disable optional modules.
MOUSEKEY_ENABLE = yes # Mouse keys
PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support
- USB_EXTRA_ENABLE = yes # Enhanced feature for Windows(Audio control and System control)
- USB_NKRO_ENABLE = yes # USB Nkey Rollover
+ EXTRAKEY_ENABLE = yes # Enhanced feature for Windows(Audio control and System control)
+ NKRO_ENABLE = yes # USB Nkey Rollover
<target>/config.h:
1. USB vendor/product ID and device description
diff --git a/adb_usb/Makefile b/adb_usb/Makefile
index 802b4248c..56b342df9 100644
--- a/adb_usb/Makefile
+++ b/adb_usb/Makefile
@@ -8,11 +8,11 @@ COMMON_DIR = ..
TARGET_DIR = .
# keyboard dependent files
-TARGET_SRC = main_pjrc.c \
- keymap.c \
- matrix.c \
- led.c \
- adb.c
+SRC = main.c \
+ keymap.c \
+ matrix.c \
+ led.c \
+ adb.c
CONFIG_H = config.h
@@ -36,10 +36,10 @@ F_CPU = 16000000
# Build Options
# comment out to disable the options.
#
-MOUSEKEY_ENABLE = yes # Mouse keys
+#MOUSEKEY_ENABLE = yes # Mouse keys
#PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support
-USB_EXTRA_ENABLE = yes # Audio control and System control
-#USB_NKRO_ENABLE = yes # USB Nkey Rollover
+#EXTRAKEY_ENABLE = yes # Audio control and System control
+#NKRO_ENABLE = yes # USB Nkey Rollover
@@ -48,5 +48,5 @@ PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex
-include $(COMMON_DIR)/Makefile.pjrc
-include $(COMMON_DIR)/Makefile.common
+include $(COMMON_DIR)/pjrc.mk
+include $(COMMON_DIR)/common.mk
diff --git a/adb_usb/README b/adb_usb/README
index b4bd35bb3..5d0e1bc86 100644
--- a/adb_usb/README
+++ b/adb_usb/README
@@ -59,4 +59,12 @@ effort at this time.
),
+Notes
+-----
+Many ADB keyboards has no discrimination between right modifier and left one,
+you will always see left control even if you press right control key.
+Apple Extended Keyboard and Apple Extended Keyboard II are the examples.
+Though ADB protocol itsef has the ability of distinction between right and left.
+And most ADB keyboard has no NKRO functionality, though ADB protocol itsef has that.
+
EOF
diff --git a/adb_usb/config.h b/adb_usb/config.h
index 27f31ca9e..6431ede4c 100644
--- a/adb_usb/config.h
+++ b/adb_usb/config.h
@@ -37,8 +37,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* key combination for command */
#define IS_COMMAND() ( \
- keyboard_report->mods == (BIT_LSHIFT | BIT_LCTRL | BIT_LALT | BIT_LGUI) || \
- keyboard_report->mods == (BIT_LSHIFT | BIT_RSHIFT) \
+ keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_LCTRL) | MOD_BIT(KB_LALT) | MOD_BIT(KB_LGUI)) || \
+ keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)) \
)
diff --git a/command.c b/command.c
index 0a07aebfc..22f25e99c 100644
--- a/command.c
+++ b/command.c
@@ -30,24 +30,49 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef HOST_PJRC
# include "jump_bootloader.h"
# include "usb_keyboard.h"
-# ifdef USB_EXTRA_ENABLE
+# ifdef EXTRAKEY_ENABLE
# include "usb_extra.h"
# endif
#endif
+#ifdef HOST_VUSB
+# include "usbdrv.h"
+#endif
+
+static uint8_t command_common(void);
static void help(void);
static void switch_layer(uint8_t layer);
+static bool last_print_enable;
uint8_t command_proc(void)
{
+ uint8_t processed = 0;
+ last_print_enable = print_enable;
+
if (!IS_COMMAND())
return 0;
- uint8_t processed = 1;
- bool last_print_enable = print_enable;
print_enable = true;
+ if (command_extra() || command_common()) {
+ processed = 1;
+ _delay_ms(500);
+ }
+ print_enable = last_print_enable;
+ return processed;
+}
+
+/* This allows to define extra commands. return 0 when not processed. */
+uint8_t command_extra(void) __attribute__ ((weak));
+uint8_t command_extra(void)
+{
+ return 0;
+}
+
+
+static uint8_t command_common(void)
+{
switch (host_get_first_key()) {
case KB_H:
help();
@@ -123,20 +148,26 @@ uint8_t command_proc(void)
print("usb_keyboard_idle_config:"); phex(usb_keyboard_idle_config); print("\n");
print("usb_keyboard_idle_count:"); phex(usb_keyboard_idle_count); print("\n");
#endif
+
+#ifdef HOST_VUSB
+# if USB_COUNT_SOF
+ print("usbSofCount: "); phex(usbSofCount); print("\n");
+# endif
+#endif
break;
-#ifdef USB_NKRO_ENABLE
+#ifdef NKRO_ENABLE
case KB_N:
// send empty report before change
host_clear_keyboard_report();
host_send_keyboard_report();
keyboard_nkro = !keyboard_nkro;
if (keyboard_nkro)
- print("USB_NKRO: enabled\n");
+ print("NKRO: enabled\n");
else
- print("USB_NKRO: disabled\n");
+ print("NKRO: disabled\n");
break;
#endif
-#ifdef USB_EXTRA_ENABLE
+#ifdef EXTRAKEY_ENABLE
case KB_ESC:
host_clear_keyboard_report();
host_send_keyboard_report();
@@ -175,12 +206,9 @@ uint8_t command_proc(void)
switch_layer(4);
break;
default:
- processed = 0;
+ return 0;
}
- if (processed)
- _delay_ms(500);
- print_enable = last_print_enable;
- return processed;
+ return 1;
}
static void help(void)
@@ -194,8 +222,8 @@ static void help(void)
print("v: print version\n");
print("t: print timer count\n");
print("s: print status\n");
-#ifdef USB_NKRO_ENABLE
- print("n: toggle USB_NKRO\n");
+#ifdef NKRO_ENABLE
+ print("n: toggle NKRO\n");
#endif
print("Backspace: clear matrix\n");
print("ESC: power down/wake up\n");
diff --git a/command.h b/command.h
index dca6da456..4888f5ee0 100644
--- a/command.h
+++ b/command.h
@@ -19,5 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define COMMAND
uint8_t command_proc(void);
+/* This allows to extend commands. Return 0 when command is not processed. */
+uint8_t command_extra(void);
#endif
diff --git a/Makefile.common b/common.mk
index 1922def00..17c6816f6 100644
--- a/Makefile.common
+++ b/common.mk
@@ -19,17 +19,20 @@ ifdef PS2_MOUSE_ENABLE
OPT_DEFS += -DPS2_MOUSE_ENABLE
endif
-ifdef USB_EXTRA_ENABLE
- OPT_DEFS += -DUSB_EXTRA_ENABLE
+ifdef EXTRAKEY_ENABLE
+ OPT_DEFS += -DEXTRAKEY_ENABLE
endif
-ifdef USB_NKRO_ENABLE
- OPT_DEFS += -DUSB_NKRO_ENABLE
+ifdef NKRO_ENABLE
+ OPT_DEFS += -DNKRO_ENABLE
endif
ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE)
- OPT_DEFS += -DUSB_MOUSE_ENABLE
+ OPT_DEFS += -DMOUSE_ENABLE
endif
+# Search Path
+VPATH += $(COMMON_DIR)
-include $(COMMON_DIR)/Makefile.rules
+
+include $(COMMON_DIR)/rules.mk
diff --git a/hhkb/FUSE.txt b/hhkb/FUSE.txt
new file mode 100644
index 000000000..40055e5ab
--- /dev/null
+++ b/hhkb/FUSE.txt
@@ -0,0 +1,40 @@
+ATMega168P Fuse/Lock Bits
+=========================
+This configuration is from usbasploader's Makefile.
+
+ HFUSE 0xD6
+ LFUSE 0xDF
+ EFUSE 0x00
+ LOCK 0x3F(intact)
+
+#---------------------------------------------------------------------
+# ATMega168P
+#---------------------------------------------------------------------
+# Fuse extended byte:
+# 0x00 = 0 0 0 0 0 0 0 0 <-- BOOTRST (boot reset vector at 0x1800)
+# \+/
+# +------- BOOTSZ (00 = 2k bytes)
+# Fuse high byte:
+# 0xd6 = 1 1 0 1 0 1 1 0
+# ^ ^ ^ ^ ^ \-+-/
+# | | | | | +------ BODLEVEL 0..2 (110 = 1.8 V)
+# | | | | + --------- EESAVE (preserve EEPROM over chip erase)
+# | | | +-------------- WDTON (if 0: watchdog always on)
+# | | +---------------- SPIEN (allow serial programming)
+# | +------------------ DWEN (debug wire enable)
+# +-------------------- RSTDISBL (reset pin is enabled)
+# Fuse low byte:
+# 0xdf = 1 1 0 1 1 1 1 1
+# ^ ^ \ / \--+--/
+# | | | +------- CKSEL 3..0 (external >8M crystal)
+# | | +--------------- SUT 1..0 (crystal osc, BOD enabled)
+# | +------------------ CKOUT (if 0: Clock output enabled)
+# +-------------------- CKDIV8 (if 0: divide by 8)
+
+
+# Lock Bits
+# 0x3f = - - 1 1 1 1 1 1
+# \ / \-/ \-/
+# | | +----- LB 2..1 (No memory lock features enabled)
+# | +--------- BLB0 2..1 (No restrictions for SPM or LPM accessing the Application section)
+# +--------------- BLB1 2..1 (No restrictions for SPM or LPM accessing the Boot Loader section)
diff --git a/hhkb/Makefile.iwrap b/hhkb/Makefile.iwrap
new file mode 100644
index 000000000..cf020b94a
--- /dev/null
+++ b/hhkb/Makefile.iwrap
@@ -0,0 +1,91 @@
+#
+# Makefile for iWRAP
+#
+
+
+# Target file name (without extension).
+TARGET = hhkb_iwrap
+
+# Directory common source filess exist
+COMMON_DIR = ..
+
+# Directory keyboard dependent files exist
+TARGET_DIR = .
+
+# keyboard dependent files
+SRC = main.c \
+ keymap.c \
+ matrix.c \
+ led.c
+
+CONFIG_H = config_iwrap.h
+
+
+# V-USB debug level: To use ps2_usart.c level must be 0
+# ps2_usart.c requires USART to receive PS/2 signal.
+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 = atmega168p
+# avrdude doesn't know atmega168p
+AVRDUDE_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 = 12000000
+
+
+# Build Options
+# comment out to disable the options.
+#
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+#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 $(AVRDUDE_MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
+AVRDUDE_FLAGS = -p $(AVRDUDE_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)
+
+
+
+# Search Path
+VPATH = $(TARGET_DIR)
+
+include $(COMMON_DIR)/iwrap.mk
+# To be swatchable btween Bluetooth and USB. Comment out if you don't need USB.
+include $(COMMON_DIR)/vusb.mk
+include $(COMMON_DIR)/common.mk
diff --git a/hhkb/Makefile b/hhkb/Makefile.pjrc
index e1cc2f210..17aa865dd 100644
--- a/hhkb/Makefile
+++ b/hhkb/Makefile.pjrc
@@ -13,10 +13,10 @@ COMMON_DIR = ..
TARGET_DIR = .
# keyboard dependent files
-TARGET_SRC = main_pjrc.c \
- keymap.c \
- matrix.c \
- led.c
+SRC = main.c \
+ keymap.c \
+ matrix.c \
+ led.c
CONFIG_H = config_pjrc.h
@@ -41,8 +41,8 @@ F_CPU = 16000000
# comment out to disable the options.
MOUSEKEY_ENABLE = yes # Mouse keys
#PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support
-USB_EXTRA_ENABLE = yes # Audio control and System control
-USB_NKRO_ENABLE = yes # USB Nkey Rollover
+EXTRAKEY_ENABLE = yes # Audio control and System control
+NKRO_ENABLE = yes # USB Nkey Rollover
@@ -51,5 +51,8 @@ PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex
-include $(COMMON_DIR)/Makefile.pjrc
-include $(COMMON_DIR)/Makefile.common
+# Search Path
+VPATH = $(TARGET_DIR)
+
+include $(COMMON_DIR)/pjrc.mk
+include $(COMMON_DIR)/common.mk
diff --git a/hhkb/Makefile.vusb b/hhkb/Makefile.vusb
index 77841b824..5bfc233df 100644
--- a/hhkb/Makefile.vusb
+++ b/hhkb/Makefile.vusb
@@ -13,10 +13,10 @@ COMMON_DIR = ..
TARGET_DIR = .
# keyboard dependent files
-TARGET_SRC = main_vusb.c \
- keymap.c \
- matrix.c \
- led.c
+SRC = main.c \
+ keymap.c \
+ matrix.c \
+ led.c
CONFIG_H = config_vusb.h
@@ -28,7 +28,9 @@ 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 = atmega168
+MCU = atmega168p
+# avrdude doesn't know atmega168p
+AVRDUDE_MCU = atmega168
# Processor frequency.
@@ -36,15 +38,15 @@ MCU = atmega168
# 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
+F_CPU = 12000000
# Build Options
# comment out to disable the options.
#
MOUSEKEY_ENABLE = yes # Mouse keys
-USB_EXTRA_ENABLE = yes # Audio control and System control
-#USB_NKRO_ENABLE = yes # USB Nkey Rollover
+EXTRAKEY_ENABLE = yes # Audio control and System control
+#NKRO_ENABLE = yes # USB Nkey Rollover
@@ -70,8 +72,8 @@ AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
# 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 = -p $(AVRDUDE_MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
+AVRDUDE_FLAGS = -p $(AVRDUDE_MCU) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
@@ -80,5 +82,8 @@ PROGRAM_CMD = $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE
-include $(COMMON_DIR)/Makefile.vusb
-include $(COMMON_DIR)/Makefile.common
+# Search Path
+VPATH = $(TARGET_DIR)
+
+include $(COMMON_DIR)/vusb.mk
+include $(COMMON_DIR)/common.mk
diff --git a/hhkb/README b/hhkb/README
index 2a4418101..65f7dcab5 100644
--- a/hhkb/README
+++ b/hhkb/README
@@ -4,7 +4,7 @@ Alternative Controller for HHKB
Feature
-------
- Mouse Keys
-- NKRO on USB
+- NKRO on USB(PJRC Tennsy only)
- Keymap Layers
@@ -13,8 +13,11 @@ Customize Keymap
see keymap.c.
-Build for Teensy
-----------------
+
+Build
+=====
+PJRC Teensy
+-----------
0. Edit matrix.c.
adjust scan code to your pin configuration.(see doc/HHKB.txt for pinouts)
1. Define macros in config_pjrc.h.(Optional)
@@ -22,15 +25,15 @@ Build for Teensy
IS_COMMAND
2. Edit Makefile for MCU setting and build options.
MCU, F_CPU
- MOUSEKEY_ENABLE, USB_EXTRA_ENABLE, USB_NKRO_ENABLE
+ MOUSEKEY_ENABLE, EXTRAKEY_ENABLE, NKRO_ENABLE
3. Build hex file.
- $ make
+ $ make -f Makefile.pjrc
4. Program MCU.
- $ make program
+ $ make -f Makefile.pjrc program
-Build for V-USB
----------------
+V-USB
+-----
0. Edit matrix.c and usbconfig.h.
adjust scan code to your pin configuration.(see doc/HHKB.txt for pinouts)
define macros for V-USB in usbconfig.h.
@@ -38,7 +41,7 @@ Build for V-USB
IS_COMMAND
2. Edit Makefile.vusb for MCU setting and build options.
MCU, F_CPU
- MOUSEKEY_ENABLE, USB_EXTRA_ENABLE, USB_NKRO_ENABLE
+ MOUSEKEY_ENABLE, EXTRAKEY_ENABLE
3. Build hex file.
$ make -f Makefile.vusb
4. Program MCU.
@@ -52,21 +55,59 @@ Build for V-USB
http://www.obdev.at/products/vusb/usbasploader.html
-V-USB Circuit
--------------
+iWRAP
+-----
+0. Edit matrix.c and usbconfig.h.
+ adjust scan code to your pin configuration.(see doc/HHKB.txt for pinouts)
+ define macros for V-USB in usbconfig.h.
+1. Define macros in config_iwrap.h.(Optional)
+ IS_COMMAND
+2. Edit Makefile.iwrap for MCU setting and build options.
+ MCU, F_CPU
+ MOUSEKEY_ENABLE, EXTRAKEY_ENABLE
+3. Build hex file.
+ $ make -f Makefile.iwrap
+4. Program MCU.
+ $ make -f Makefile.iwrap program
+
+
+
+Hardware
+========
+PJRC Teensy
+-----------
+ +---------------+
+ | Teensy++ |
+ | |
+ | | HHKB
+ | | ~~~~
+ | PB0-2|------->ROW(6-8)
+ | PB3-5|------->COL(9-11)
+ | PB6|------->ENABLE(12)
+ | PE6|<-------KEY(4)
+ | PE7|------->PREV(5)
+ | |
+ | |
+ | |
+ +---------------+
+
+
+V-USB
+-----
+---+ +---------------+
USB GND | | ATmega168 |
-=== C3 | |
+~~~ C3 | |
5V <-------+--------+---|Vcc,AVCC | HHKB
- R1 | | ====
-D- <----+--+-----R2-----|INT1 PB0-2|------->ROW
-D+ <----|---+----R3-----|INT0 PB3-5|------->COL
- Z1 Z2 | PB6|------->ENABLE
-GND<----+---+--+--+-----|GND PE6|------->KEY
- | | | PE7|------->PREV
- | C2-+--|XTAL1 | (see doc/HHKB.txt for pinouts)
- | X1 | |
- +--C3-+--|XTAL2 RST|---SW--+GND
+ R1 | | ~~~~
+D- <----+--+-----R2-----|INT1 PB2-4|------->ROW(6-8)
+D+ <----|---+----R3-----|INT0 PC0-2|------->COL(9-11)
+ Z1 Z2 | PC3|------->ENABLE(12)
+GND<----+---+-----------|GND PB0|<-------KEY(4)
+ | PB1|------->PREV(5)
+ | |
+ GND+-C2--+--|XTAL1 RXD|------->Debug Console
+ X1 | TXD|<-------Debug Console
+ GND+-C3--+--|XTAL2 RST|---SW--+GND
+---------------+
R1: 1.5K Ohm
R2,R3: 68 Ohm
@@ -77,4 +118,34 @@ X1: Crystal 20MHz(16MHz/12MHz)
SW: Push Switch(Optional for bootloader)
+iWRAP
+-----
+ +---------------+ WT12
+ 5V | ATmega168 | 5V/3.3V~~~~
+ +-----+---|Vcc,AVCC PC4|---/--->iWRAP(RxD)
+USB | C3 | PC5|<--/----iWRAP(TxD)
+~~~ | + | |
+5V <--BATT + GND | | HHKB
+ R1 | | ~~~~
+D- <----+-----+--R2-----|INT1 PB2-4|------->ROW(6-8)
+D+ <----|---+----R3-----|INT0 PC0-2|------->COL(9-11)
+ Z1 Z2 | PC3|------->ENABLE(12)
+GND<----+---+-----------|GND PB0|<-------KEY(4)
+ | PB1|------->PREV(5)
+ | |
+ GND+-C2--+--|XTAL1 RXD|------->Debug Console
+ X1 | TXD|<-------Debug Console
+ GND+-C3--+--|XTAL2 RST|---SW--+GND
+ +---------------+
+
+R1: 1.5K Ohm
+R2,R3: 68 Ohm
+Z1,Z2: Zener 3.6V
+C1,C2: 22pF
+C3: 0.1uF
+X1: Crystal 12MHz
+SW: Push Switch(Optional)
+BATT: Li-Po Battery, Battery Charger and Voltage Regulator(5V and 3.3V).
+
+
EOF
diff --git a/hhkb/config_iwrap.h b/hhkb/config_iwrap.h
new file mode 100644
index 000000000..80ab64398
--- /dev/null
+++ b/hhkb/config_iwrap.h
@@ -0,0 +1,55 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#define VENDOR_ID 0xFEED
+#define PRODUCT_ID 0xBEEA
+// TODO: share these strings with usbconfig.h
+// Edit usbconfig.h to change these.
+#define MANUFACTURER t.m.k.
+#define PRODUCT HHKB mod
+#define DESCRIPTION t.m.k. keyboard firmware for HHKB mod
+
+
+/* matrix size */
+#define MATRIX_ROWS 8
+#define MATRIX_COLS 8
+
+
+/* key combination for command */
+#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)))
+
+/* mouse keys */
+#ifdef MOUSEKEY_ENABLE
+# define MOUSEKEY_DELAY_TIME 255
+#endif
+
+/* pins for Software UART */
+#define SUART_IN_PIN PINC
+#define SUART_IN_BIT 5
+#define SUART_OUT_PORT PORTC
+#define SUART_OUT_BIT 4
+
+
+#define DEBUG_LED 1
+#define DEBUG_LED_CONFIG (DDRD |= (1<<4))
+#define DEBUG_LED_OFF (PORTD |= (1<<4))
+#define DEBUG_LED_ON (PORTD &= ~(1<<4))
+
+#endif
diff --git a/hhkb/config_pjrc.h b/hhkb/config_pjrc.h
index ef2efe2d9..8379202ca 100644
--- a/hhkb/config_pjrc.h
+++ b/hhkb/config_pjrc.h
@@ -36,11 +36,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* key combination for command */
-#define IS_COMMAND() ( \
- keyboard_report->mods == (BIT_LSHIFT | BIT_RSHIFT) || \
- keyboard_report->mods == (BIT_LCTRL | BIT_RSHIFT) \
-)
-
+#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)))
/* mouse keys */
#ifdef MOUSEKEY_ENABLE
diff --git a/hhkb/config_vusb.h b/hhkb/config_vusb.h
index 115b73de3..268644849 100644
--- a/hhkb/config_vusb.h
+++ b/hhkb/config_vusb.h
@@ -18,7 +18,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef CONFIG_H
#define CONFIG_H
-
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0xC0FE
// TODO: share these strings with usbconfig.h
@@ -34,11 +33,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* key combination for command */
-#define IS_COMMAND() ( \
- keyboard_report->mods == (BIT_LSHIFT | BIT_RSHIFT) || \
- keyboard_report->mods == (BIT_LCTRL | BIT_RSHIFT) \
-)
-
+#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)))
/* mouse keys */
#ifdef MOUSEKEY_ENABLE
@@ -46,4 +41,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#endif
+#define DEBUG_LED 1
+#define DEBUG_LED_CONFIG (DDRD |= (1<<4))
+#define DEBUG_LED_OFF (PORTD |= (1<<4))
+#define DEBUG_LED_ON (PORTD &= ~(1<<4))
+
#endif
diff --git a/hhkb/doc/Bluetooth.txt b/hhkb/doc/Bluetooth.txt
new file mode 100644
index 000000000..b27f19700
--- /dev/null
+++ b/hhkb/doc/Bluetooth.txt
@@ -0,0 +1,4 @@
+HHKB Bluetooth mod
+==================
+See this article:
+http://geekhack.org/showwiki.php?title=Island:20851
diff --git a/hhkb/doc/Bluetooth_img/.picasa.ini b/hhkb/doc/Bluetooth_img/.picasa.ini
new file mode 100755
index 000000000..f6a4f6067
--- /dev/null
+++ b/hhkb/doc/Bluetooth_img/.picasa.ini
@@ -0,0 +1,2 @@
+[Picasa]
+name=Bluetooth_img
diff --git a/hhkb/doc/Bluetooth_img/BT_circuit.jpg b/hhkb/doc/Bluetooth_img/BT_circuit.jpg
new file mode 100755
index 000000000..2e5a25e81
--- /dev/null
+++ b/hhkb/doc/Bluetooth_img/BT_circuit.jpg
Binary files differ
diff --git a/hhkb/doc/HHKB_TP1684.jpg b/hhkb/doc/HHKB_img/HHKB_TP1684.jpg
index 0a0316409..0a0316409 100644
--- a/hhkb/doc/HHKB_TP1684.jpg
+++ b/hhkb/doc/HHKB_img/HHKB_TP1684.jpg
Binary files differ
diff --git a/hhkb/doc/HHKB_chart1.jpg b/hhkb/doc/HHKB_img/HHKB_chart1.jpg
index 1f09bd185..1f09bd185 100644
--- a/hhkb/doc/HHKB_chart1.jpg
+++ b/hhkb/doc/HHKB_img/HHKB_chart1.jpg
Binary files differ
diff --git a/hhkb/doc/HHKB_chart2.jpg b/hhkb/doc/HHKB_img/HHKB_chart2.jpg
index 45f5ada90..45f5ada90 100644
--- a/hhkb/doc/HHKB_chart2.jpg
+++ b/hhkb/doc/HHKB_img/HHKB_chart2.jpg
Binary files differ
diff --git a/hhkb/doc/HHKB_connector.jpg b/hhkb/doc/HHKB_img/HHKB_connector.jpg
index e8a09e9b2..e8a09e9b2 100644
--- a/hhkb/doc/HHKB_connector.jpg
+++ b/hhkb/doc/HHKB_img/HHKB_connector.jpg
Binary files differ
diff --git a/hhkb/doc/HHKB_controller.jpg b/hhkb/doc/HHKB_img/HHKB_controller.jpg
index e3dae8e86..e3dae8e86 100644
--- a/hhkb/doc/HHKB_controller.jpg
+++ b/hhkb/doc/HHKB_img/HHKB_controller.jpg
Binary files differ
diff --git a/hhkb/doc/HHKB_keyswitch.jpg b/hhkb/doc/HHKB_img/HHKB_keyswitch.jpg
index 3afc269e7..3afc269e7 100644
--- a/hhkb/doc/HHKB_keyswitch.jpg
+++ b/hhkb/doc/HHKB_img/HHKB_keyswitch.jpg
Binary files differ
diff --git a/hhkb/doc/connector_contact.jpg b/hhkb/doc/HHKB_img/connector_contact.jpg
index 5304bc8d7..5304bc8d7 100644
--- a/hhkb/doc/connector_contact.jpg
+++ b/hhkb/doc/HHKB_img/connector_contact.jpg
Binary files differ
diff --git a/hhkb/doc/logic_analyzer.jpg b/hhkb/doc/HHKB_img/logic_analyzer.jpg
index f1b438ae7..f1b438ae7 100644
--- a/hhkb/doc/logic_analyzer.jpg
+++ b/hhkb/doc/HHKB_img/logic_analyzer.jpg
Binary files differ
diff --git a/hhkb/doc/probe_contact.jpg b/hhkb/doc/HHKB_img/probe_contact.jpg
index dc79afa0c..dc79afa0c 100644
--- a/hhkb/doc/probe_contact.jpg
+++ b/hhkb/doc/HHKB_img/probe_contact.jpg
Binary files differ
diff --git a/hhkb/doc/teensy_install.jpg b/hhkb/doc/HHKB_img/teensy_install.jpg
index 873d988ed..873d988ed 100644
--- a/hhkb/doc/teensy_install.jpg
+++ b/hhkb/doc/HHKB_img/teensy_install.jpg
Binary files differ
diff --git a/hhkb/doc/teensy_wiring.jpg b/hhkb/doc/HHKB_img/teensy_wiring.jpg
index 1c4eb6743..1c4eb6743 100644
--- a/hhkb/doc/teensy_wiring.jpg
+++ b/hhkb/doc/HHKB_img/teensy_wiring.jpg
Binary files differ
diff --git a/hhkb/keymap.c b/hhkb/keymap.c
index f539a06cc..85a7c31b7 100644
--- a/hhkb/keymap.c
+++ b/hhkb/keymap.c
@@ -32,21 +32,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// Convert physical keyboard layout to matrix array.
// This is a macro to define keymap easily in keyboard layout form.
#define KEYMAP( \
- R3C1, R3C0, R0C0, R1C0, R1C1, R2C0, R2C1, R4C0, R4C1, R6C0, R6C1, R7C0, R7C1, R5C0, R5C1, \
- R3C2, R0C1, R0C2, R1C3, R1C2, R2C3, R2C2, R4C2, R4C3, R6C2, R6C3, R7C3, R7C2, R5C2, \
- R3C3, R0C4, R0C3, R1C4, R1C5, R2C4, R2C5, R4C5, R4C4, R6C5, R6C4, R7C4, R5C3, \
- R3C4, R0C5, R0C6, R0C7, R1C6, R1C7, R2C6, R4C6, R6C6, R7C6, R7C5, R5C5, R5C4, \
- R3C5, R3C6, R3C7, R5C7, R5C6 \
+ K31, K30, K00, K10, K11, K20, K21, K40, K41, K60, K61, K70, K71, K50, K51, \
+ K32, K01, K02, K13, K12, K23, K22, K42, K43, K62, K63, K73, K72, K52, \
+ K33, K04, K03, K14, K15, K24, K25, K45, K44, K65, K64, K74, K53, \
+ K34, K05, K06, K07, K16, K17, K26, K46, K66, K76, K75, K55, K54, \
+ K35, K36, K37, K57, K56 \
) \
{ \
- { R0C0, R0C1, R0C2, R0C3, R0C4, R0C5, R0C6, R0C7 }, \
- { R1C0, R1C1, R1C2, R1C3, R1C4, R1C5, R1C6, R1C7 }, \
- { R2C0, R2C1, R2C2, R2C3, R2C4, R2C5, R2C6, KB_NO }, \
- { R3C0, R3C1, R3C2, R3C3, R3C4, R3C5, R3C6, R3C7 }, \
- { R4C0, R4C1, R4C2, R4C3, R4C4, R4C5, R4C6, KB_NO }, \
- { R5C0, R5C1, R5C2, R5C3, R5C4, R5C5, R5C6, R5C7 }, \
- { R6C0, R6C1, R6C2, R6C3, R6C4, R6C5, R6C6, KB_NO }, \
- { R7C0, R7C1, R7C2, R7C3, R7C4, R7C5, R7C6, KB_NO } \
+ { KB_##K00, KB_##K01, KB_##K02, KB_##K03, KB_##K04, KB_##K05, KB_##K06, KB_##K07 }, \
+ { KB_##K10, KB_##K11, KB_##K12, KB_##K13, KB_##K14, KB_##K15, KB_##K16, KB_##K17 }, \
+ { KB_##K20, KB_##K21, KB_##K22, KB_##K23, KB_##K24, KB_##K25, KB_##K26, KB_NO }, \
+ { KB_##K30, KB_##K31, KB_##K32, KB_##K33, KB_##K34, KB_##K35, KB_##K36, KB_##K37 }, \
+ { KB_##K40, KB_##K41, KB_##K42, KB_##K43, KB_##K44, KB_##K45, KB_##K46, KB_NO }, \
+ { KB_##K50, KB_##K51, KB_##K52, KB_##K53, KB_##K54, KB_##K55, KB_##K56, KB_##K57 }, \
+ { KB_##K60, KB_##K61, KB_##K62, KB_##K63, KB_##K64, KB_##K65, KB_##K66, KB_NO }, \
+ { KB_##K70, KB_##K71, KB_##K72, KB_##K73, KB_##K74, KB_##K75, KB_##K76, KB_NO } \
}
#define KEYCODE(layer, row, col) (pgm_read_byte(&keymaps[(layer)][(row)][(col)]))
@@ -58,8 +58,8 @@ static const uint8_t PROGMEM fn_layer[] = {
1, // Fn1
2, // Fn2
3, // Fn3
- 4, // Fn4
- 0, // Fn5
+ 3, // Fn4
+ 4, // Fn5
0, // Fn6
0 // Fn7
};
@@ -71,8 +71,8 @@ static const uint8_t PROGMEM fn_keycode[] = {
KB_NO, // Fn1
KB_SLSH, // Fn2
KB_SCLN, // Fn3
- KB_SPC, // Fn4
- KB_NO, // Fn5
+ KB_NO, // Fn4
+ KB_SPC, // Fn5
KB_NO, // Fn6
KB_NO // Fn7
};
@@ -91,11 +91,11 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |Gui|Alt |Fn5 |Alt |Fn4|
* `-------------------------------------------'
*/
- KEYMAP(KB_ESC, KB_1, KB_2, KB_3, KB_4, KB_5, KB_6, KB_7, KB_8, KB_9, KB_0, KB_MINS,KB_EQL, KB_BSLS,KB_GRV, \
- KB_TAB, KB_Q, KB_W, KB_E, KB_R, KB_T, KB_Y, KB_U, KB_I, KB_O, KB_P, KB_LBRC,KB_RBRC,KB_BSPC, \
- KB_LCTL,KB_A, KB_S, KB_D, KB_F, KB_G, KB_H, KB_J, KB_K, KB_L, KB_FN3, KB_QUOT,KB_ENT, \
- KB_LSFT,KB_Z, KB_X, KB_C, KB_V, KB_B, KB_N, KB_M, KB_COMM,KB_DOT, KB_FN2, KB_RSFT,KB_FN1, \
- KB_LGUI,KB_LALT,KB_FN4, KB_RALT,KB_RGUI),
+ KEYMAP(ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSLS,GRV, \
+ TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSPC, \
+ LCTL,A, S, D, F, G, H, J, K, L, FN3, QUOT,ENT, \
+ LSFT,Z, X, C, V, B, N, M, COMM,DOT, FN2, RSFT,FN1, \
+ LGUI,LALT, FN5, RALT,FN4),
/* Layer 1: HHKB mode (HHKB Fn)
* ,-----------------------------------------------------------.
@@ -110,11 +110,11 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |Gui |Alt |Space |Alt |xxx|
* `--------------------------------------------'
*/
- KEYMAP(KB_ESC, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_INS, KB_DEL, \
- KB_CAPS,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_PSCR,KB_SLCK,KB_BRK, KB_UP, KB_NO, KB_BSPC, \
- KB_LCTL,KB_VOLD,KB_VOLU,KB_MUTE,KB_NO, KB_NO, KB_PAST,KB_PSLS,KB_HOME,KB_PGUP,KB_LEFT,KB_RGHT,KB_ENT, \
- KB_LSFT,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_PPLS,KB_PMNS,KB_END, KB_PGDN,KB_DOWN,KB_RSFT,KB_FN1, \
- KB_LGUI,KB_LALT,KB_SPC, KB_RALT,KB_FN7),
+ KEYMAP(ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \
+ CAPS,NO, NO, NO, NO, NO, NO, NO, PSCR,SLCK,BRK, UP, NO, BSPC, \
+ LCTL,VOLD,VOLU,MUTE,NO, NO, PAST,PSLS,HOME,PGUP,LEFT,RGHT,ENT, \
+ LSFT,NO, NO, NO, NO, NO, PPLS,PMNS,END, PGDN,DOWN,RSFT,FN1, \
+ LGUI,LALT, SPC, RALT,FN7),
/* Layer 2: Vi mode (Slash)
* ,-----------------------------------------------------------.
@@ -129,11 +129,11 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* |Gui|Alt |Space |Alt |Gui|
* `-------------------------------------------'
*/
- KEYMAP(KB_ESC, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_INS, KB_DEL, \
- KB_TAB, KB_HOME,KB_PGDN,KB_UP, KB_PGUP,KB_END, KB_HOME,KB_PGDN,KB_PGUP,KB_END, KB_NO, KB_NO, KB_NO, KB_BSPC, \
- KB_LCTL,KB_NO, KB_LEFT,KB_DOWN,KB_RGHT,KB_NO, KB_LEFT,KB_DOWN,KB_UP, KB_RGHT,KB_NO, KB_NO, KB_ENT, \
- KB_LSFT,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_HOME,KB_PGDN,KB_PGUP,KB_END, KB_FN2, KB_RSFT,KB_NO, \
- KB_LGUI,KB_LALT,KB_SPC, KB_RALT,KB_RGUI),
+ KEYMAP(ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \
+ TAB, HOME,PGDN,UP, PGUP,END, HOME,PGDN,PGUP,END, NO, NO, NO, BSPC, \
+ LCTL,NO, LEFT,DOWN,RGHT,NO, LEFT,DOWN,UP, RGHT,NO, NO, ENT, \
+ LSFT,NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, FN2, RSFT,NO, \
+ LGUI,LALT, SPC, RALT,RGUI),
/* Layer 3: Mouse mode (Semicolon)
* ,-----------------------------------------------------------.
@@ -149,11 +149,24 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `--------------------------------------------'
* Mc: Mouse Cursor / Mb: Mouse Button / Mw: Mouse Wheel
*/
- KEYMAP(KB_ESC, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_INS, KB_DEL, \
- KB_TAB, KB_WH_L,KB_WH_U,KB_MS_U,KB_WH_D,KB_WH_R,KB_WH_L,KB_WH_D,KB_WH_U,KB_WH_R,KB_NO, KB_NO, KB_NO, KB_BSPC, \
- KB_LCTL,KB_NO, KB_MS_L,KB_MS_D,KB_MS_R,KB_NO, KB_MS_L,KB_MS_D,KB_MS_U,KB_MS_R,KB_FN3, KB_NO, KB_ENT, \
- KB_LSFT,KB_BTN4,KB_BTN5,KB_BTN1,KB_BTN2,KB_BTN3,KB_BTN2,KB_BTN1,KB_BTN4,KB_BTN5,KB_NO, KB_RSFT,KB_NO, \
- KB_LGUI,KB_LALT,KB_BTN1,KB_RALT,KB_RGUI),
+#ifdef HOST_IWRAP
+// iWRAP does not support mouse wheel, use these keycodes to remap as wheel
+#define KB_KPPL KB_KP_PLUS
+#define KB_KPMI KB_KP_MINUS
+#define KB_KPAS KB_KP_ASTERISK
+#define KB_KPSL KB_KP_SLASH
+ KEYMAP(ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \
+ TAB, KPAS,KPPL,MS_U,KPMI,KPSL,KPAS,KPPL,KPMI,KPSL,NO, NO, NO, BSPC, \
+ LCTL,NO, MS_L,MS_D,MS_R,NO, MS_L,MS_D,MS_U,MS_R,FN3, NO, ENT, \
+ LSFT,BTN4,BTN5,BTN1,BTN2,BTN3,BTN2,BTN1,NO, NO, NO, RSFT,NO, \
+ LGUI,LALT, BTN1, RALT,FN4),
+#else
+ KEYMAP(ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \
+ TAB, WH_L,WH_U,MS_U,WH_D,WH_R,WH_L,WH_D,WH_U,WH_R,NO, NO, NO, BSPC, \
+ LCTL,NO, MS_L,MS_D,MS_R,NO, MS_L,MS_D,MS_U,MS_R,FN3, NO, ENT, \
+ LSFT,BTN4,BTN5,BTN1,BTN2,BTN3,BTN2,BTN1,BTN4,BTN5,NO, RSFT,NO, \
+ LGUI,LALT, BTN1, RALT,FN4),
+#endif
/* Layer 4: Matias half keyboard style (Space)
* ,-----------------------------------------------------------.
@@ -169,18 +182,26 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* `--------------------------------------------'
*/
/*
- KEYMAP(KB_MINS,KB_0, KB_9, KB_8, KB_7, KB_6, KB_5, KB_4, KB_3, KB_2, KB_1, KB_NO, KB_NO, KB_NO, KB_ESC, \
- KB_BSPC,KB_P, KB_O, KB_I, KB_U, KB_Y, KB_T, KB_R, KB_E, KB_W, KB_Q, KB_NO, KB_NO, KB_TAB, \
- KB_LCTL,KB_SCLN,KB_L, KB_K, KB_J, KB_H, KB_G, KB_F, KB_D, KB_S, KB_A, KB_RCTL,KB_RCTL, \
- KB_LSFT,KB_SLSH,KB_DOT, KB_COMM,KB_M, KB_N, KB_B, KB_V, KB_C, KB_X, KB_Z, KB_RSFT,KB_NO, \
- KB_LGUI,KB_LALT,KB_FN4, KB_RALT,KB_RGUI)
+ KEYMAP(MINS,0, 9, 8, 7, 6, 5, 4, 3, 2, 1, NO, NO, NO, ESC, \
+ BSPC,P, O, I, U, Y, T, R, E, W, Q, NO, NO, TAB, \
+ LCTL,SCLN,L, K, J, H, G, F, D, S, A, RCTL,RCTL, \
+ LSFT,SLSH,DOT, COMM,M, N, B, V, C, X, Z, RSFT,NO, \
+ LGUI,LALT, FN5, RALT,RGUI)
*/
/* Mouse mode (Space) */
- KEYMAP(KB_ESC, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_INS, KB_DEL, \
- KB_TAB, KB_WH_L,KB_WH_U,KB_MS_U,KB_WH_D,KB_WH_R,KB_WH_L,KB_WH_D,KB_WH_U,KB_WH_R,KB_NO, KB_NO, KB_NO, KB_BSPC, \
- KB_LCTL,KB_NO, KB_MS_L,KB_MS_D,KB_MS_R,KB_NO, KB_MS_L,KB_MS_D,KB_MS_U,KB_MS_R,KB_FN3, KB_NO, KB_ENT, \
- KB_LSFT,KB_BTN4,KB_BTN5,KB_BTN1,KB_BTN2,KB_BTN3,KB_BTN2,KB_BTN1,KB_BTN4,KB_BTN5,KB_NO, KB_RSFT,KB_NO, \
- KB_LGUI,KB_LALT,KB_FN4, KB_RALT,KB_RGUI),
+#ifdef HOST_IWRAP
+ KEYMAP(ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \
+ TAB, KPAS,KPPL,MS_U,KPMI,KPSL,KPAS,KPPL,KPMI,KPSL,NO, NO, NO, BSPC, \
+ LCTL,NO, MS_L,MS_D,MS_R,NO, MS_L,MS_D,MS_U,MS_R,FN3, NO, ENT, \
+ LSFT,BTN4,BTN5,BTN1,BTN2,BTN3,BTN2,BTN1,BTN4,BTN5,NO, RSFT,NO, \
+ LGUI,LALT, FN5, RALT,RGUI),
+#else
+ KEYMAP(ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \
+ TAB, WH_L,WH_U,MS_U,WH_D,WH_R,WH_L,WH_D,WH_U,WH_R,NO, NO, NO, BSPC, \
+ LCTL,NO, MS_L,MS_D,MS_R,NO, MS_L,MS_D,MS_U,MS_R,FN3, NO, ENT, \
+ LSFT,BTN4,BTN5,BTN1,BTN2,BTN3,BTN2,BTN1,BTN4,BTN5,NO, RSFT,NO, \
+ LGUI,LALT, FN5, RALT,RGUI),
+#endif
};
diff --git a/hhkb/matrix.c b/hhkb/matrix.c
index a77febb29..350066b90 100644
--- a/hhkb/matrix.c
+++ b/hhkb/matrix.c
@@ -25,9 +25,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <util/delay.h>
#include "print.h"
#include "util.h"
+#include "timer.h"
#include "matrix.h"
+// Timer resolution check
+#if (1000000/TIMER_RAW_FREQ > 20)
+# error "Timer resolution(>20us) is not enough for HHKB matrix scan tweak on V-USB."
+#endif
+
#if (MATRIX_COLS > 16)
# error "MATRIX_COLS must not exceed 16"
#endif
@@ -82,18 +88,22 @@ static bool matrix_has_ghost_in_row(uint8_t row);
#define KEY_STATE() (PINE & (1<<6))
#define KEY_PREV_ON() (PORTE |= (1<<7))
#define KEY_PREV_OFF() (PORTE &= ~(1<<7))
-
+#define KEY_POWER_ON()
+#define KEY_POWER_OFF()
#else
// Ports for V-USB
// key: PB0(pull-uped)
// prev: PB1
// row: PB2-4
// col: PC0-2,3
+// power: PB5(Low:on/Hi-z:off)
#define KEY_INIT() do { \
- DDRB |= 0x1E; \
- DDRB &= ~(1<<0); \
- PORTB |= (1<<0); \
- DDRC |= 0x0F; \
+ DDRB |= 0x3E; \
+ DDRB &= ~(1<<0); \
+ PORTB |= 1<<0; \
+ DDRC |= 0x0F; \
+ KEY_UNABLE(); \
+ KEY_PREV_OFF(); \
} while (0)
#define KEY_SELECT(ROW, COL) do { \
PORTB = (PORTB & 0xE3) | ((ROW) & 0x07)<<2; \
@@ -104,6 +114,18 @@ static bool matrix_has_ghost_in_row(uint8_t row);
#define KEY_STATE() (PINB & (1<<0))
#define KEY_PREV_ON() (PORTB |= (1<<1))
#define KEY_PREV_OFF() (PORTB &= ~(1<<1))
+// Power supply switching
+#define KEY_POWER_ON() do { \
+ KEY_INIT(); \
+ PORTB &= ~(1<<5); \
+ _delay_us(200); \
+} while (0)
+#define KEY_POWER_OFF() do { \
+ DDRB &= ~0x3F; \
+ PORTB &= ~0x3F; \
+ DDRC &= ~0x0F; \
+ PORTC &= ~0x0F; \
+} while (0)
#endif
@@ -138,36 +160,46 @@ uint8_t matrix_scan(void)
matrix_prev = matrix;
matrix = tmp;
+ KEY_POWER_ON();
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
KEY_SELECT(row, col);
- _delay_us(40); // from logic analyzer chart
+ _delay_us(40);
+
+ // Not sure this is needed. This just emulates HHKB controller's behaviour.
if (matrix_prev[row] & (1<<col)) {
KEY_PREV_ON();
}
- _delay_us(7); // from logic analyzer chart
+ _delay_us(7);
+
+ // NOTE: KEY_STATE is valid only in 20us after KEY_ENABLE.
+ // If V-USB interrupts in this section we could lose 40us or so
+ // and would read invalid value from KEY_STATE.
+ uint8_t last = TIMER_RAW;
-#if HOST_VUSB
- // to avoid V-USB interrupt during read key state
- uint8_t sreg = SREG;
- cli();
-#endif
KEY_ENABLE();
- _delay_us(10); // from logic analyzer chart
+ // Wait for KEY_STATE outputs its value.
+ // 1us was ok on one HHKB, but not worked on another.
+ _delay_us(10);
if (KEY_STATE()) {
matrix[row] &= ~(1<<col);
} else {
matrix[row] |= (1<<col);
}
-#if HOST_VUSB
- SREG = sreg;
-#endif
+
+ // Ignore if this code region execution time elapses more than 20us.
+ if (TIMER_DIFF_RAW(TIMER_RAW, last) > 20/(1000000/TIMER_RAW_FREQ)) {
+ matrix[row] = matrix_prev[row];
+ }
KEY_PREV_OFF();
KEY_UNABLE();
- _delay_us(150); // from logic analyzer chart
+ // NOTE: KEY_STATE keep its state in 20us after KEY_ENABLE.
+ // This takes 25us or more to make sure KEY_STATE returns to idle state.
+ _delay_us(150);
}
}
+ KEY_POWER_OFF();
return 1;
}
diff --git a/hhkb/usbconfig.h b/hhkb/usbconfig.h
index e8283505e..c3aad34be 100644
--- a/hhkb/usbconfig.h
+++ b/hhkb/usbconfig.h
@@ -171,7 +171,7 @@ section at the end of this file).
/* This macro (if defined) is executed when a USB SET_ADDRESS request was
* received.
*/
-#define USB_COUNT_SOF 0
+#define USB_COUNT_SOF 1
/* 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+.
@@ -352,8 +352,8 @@ section at the end of this file).
#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 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
@@ -375,4 +375,14 @@ section at the end of this file).
/* #define USB_INTR_PENDING_BIT INTF0 */
/* #define USB_INTR_VECTOR INT0_vect */
+/* Set INT1 for D- falling edge to count SOF */
+/* #define USB_INTR_CFG EICRA */
+#define USB_INTR_CFG_SET ((1 << ISC11) | (0 << ISC10))
+/* #define USB_INTR_CFG_CLR 0 */
+/* #define USB_INTR_ENABLE EIMSK */
+#define USB_INTR_ENABLE_BIT INT1
+/* #define USB_INTR_PENDING EIFR */
+#define USB_INTR_PENDING_BIT INTF1
+#define USB_INTR_VECTOR INT1_vect
+
#endif /* __usbconfig_h_included__ */
diff --git a/host.c b/host.c
new file mode 100644
index 000000000..65b5ddcbb
--- /dev/null
+++ b/host.c
@@ -0,0 +1,190 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdint.h>
+#include <avr/interrupt.h>
+#include "usb_keycodes.h"
+#include "host.h"
+#include "util.h"
+#include "debug.h"
+
+
+#ifdef NKRO_ENABLE
+bool keyboard_nkro = false;
+#endif
+
+static host_driver_t *driver;
+static report_keyboard_t report0;
+static report_keyboard_t report1;
+report_keyboard_t *keyboard_report = &report0;
+report_keyboard_t *keyboard_report_prev = &report1;
+
+
+static inline void add_key_byte(uint8_t code);
+static inline void add_key_bit(uint8_t code);
+
+
+void host_set_driver(host_driver_t *d)
+{
+ driver = d;
+}
+
+host_driver_t *host_get_driver(void)
+{
+ return driver;
+}
+
+uint8_t host_keyboard_leds(void)
+{
+ if (!driver) return 0;
+ return (*driver->keyboard_leds)();
+}
+
+/* keyboard report operations */
+void host_add_key(uint8_t key)
+{
+#ifdef NKRO_ENABLE
+ if (keyboard_nkro) {
+ add_key_bit(key);
+ return;
+ }
+#endif
+ add_key_byte(key);
+}
+
+void host_add_mod_bit(uint8_t mod)
+{
+ keyboard_report->mods |= mod;
+}
+
+void host_set_mods(uint8_t mods)
+{
+ keyboard_report->mods = mods;
+}
+
+void host_add_code(uint8_t code)
+{
+ if (IS_MOD(code)) {
+ host_add_mod_bit(MOD_BIT(code));
+ } else {
+ host_add_key(code);
+ }
+}
+
+void host_swap_keyboard_report(void)
+{
+ uint8_t sreg = SREG;
+ cli();
+ report_keyboard_t *tmp = keyboard_report_prev;
+ keyboard_report_prev = keyboard_report;
+ keyboard_report = tmp;
+ SREG = sreg;
+}
+
+void host_clear_keyboard_report(void)
+{
+ keyboard_report->mods = 0;
+ for (int8_t i = 0; i < REPORT_KEYS; i++) {
+ keyboard_report->keys[i] = 0;
+ }
+}
+
+uint8_t host_has_anykey(void)
+{
+ uint8_t cnt = 0;
+ for (int i = 0; i < REPORT_KEYS; i++) {
+ if (keyboard_report->keys[i])
+ cnt++;
+ }
+ return cnt;
+}
+
+uint8_t host_get_first_key(void)
+{
+#ifdef NKRO_ENABLE
+ if (keyboard_nkro) {
+ uint8_t i = 0;
+ for (; i < REPORT_KEYS && !keyboard_report->keys[i]; i++)
+ ;
+ return i<<3 | biton(keyboard_report->keys[i]);
+ }
+#endif
+ return keyboard_report->keys[0];
+}
+
+
+void host_send_keyboard_report(void)
+{
+ if (!driver) return;
+ (*driver->send_keyboard)(keyboard_report);
+}
+
+void host_mouse_send(report_mouse_t *report)
+{
+ if (!driver) return;
+ (*driver->send_mouse)(report);
+}
+
+void host_system_send(uint16_t data)
+{
+ if (!driver) return;
+ (*driver->send_consumer)(data);
+}
+
+void host_consumer_send(uint16_t data)
+{
+ // TODO: this is needed?
+ static uint16_t last_data = 0;
+ if (data == last_data) return;
+ last_data = data;
+
+ if (!driver) return;
+ (*driver->send_consumer)(data);
+}
+
+
+static inline void add_key_byte(uint8_t code)
+{
+ // TODO: fix ugly code
+ int8_t i = 0;
+ int8_t empty = -1;
+ for (; i < REPORT_KEYS; i++) {
+ if (keyboard_report_prev->keys[i] == code) {
+ keyboard_report->keys[i] = code;
+ break;
+ }
+ if (empty == -1 &&
+ keyboard_report_prev->keys[i] == 0 &&
+ keyboard_report->keys[i] == 0) {
+ empty = i;
+ }
+ }
+ if (i == REPORT_KEYS) {
+ if (empty != -1) {
+ keyboard_report->keys[empty] = code;
+ }
+ }
+}
+
+static inline void add_key_bit(uint8_t code)
+{
+ if ((code>>3) < REPORT_KEYS) {
+ keyboard_report->keys[code>>3] |= 1<<(code&7);
+ } else {
+ debug("add_key_bit: can't add: "); phex(code); debug("\n");
+ }
+}
diff --git a/host.h b/host.h
index bdbd7db05..06f1311ab 100644
--- a/host.h
+++ b/host.h
@@ -19,88 +19,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define HOST_H
#include <stdint.h>
+#include "report.h"
+#include "host_driver.h"
-/* report id */
-#define REPORT_ID_MOUSE 1
-#define REPORT_ID_SYSTEM 2
-#define REPORT_ID_CONSUMER 3
-
-/* keyboard Modifiers in boot protocol report */
-#define BIT_LCTRL (1<<0)
-#define BIT_LSHIFT (1<<1)
-#define BIT_LALT (1<<2)
-#define BIT_LGUI (1<<3)
-#define BIT_RCTRL (1<<4)
-#define BIT_RSHIFT (1<<5)
-#define BIT_RALT (1<<6)
-#define BIT_RGUI (1<<7)
-#define BIT_LCTL BIT_LCTRL
-#define BIT_RCTL BIT_RCTRL
-#define BIT_LSFT BIT_LSHIFT
-#define BIT_RSFT BIT_RSHIFT
-
-/* mouse buttons */
-#define MOUSE_BTN1 (1<<0)
-#define MOUSE_BTN2 (1<<1)
-#define MOUSE_BTN3 (1<<2)
-#define MOUSE_BTN4 (1<<3)
-#define MOUSE_BTN5 (1<<4)
-
-// Consumer Page(0x0C)
-#define AUDIO_MUTE 0x00E2
-#define AUDIO_VOL_UP 0x00E9
-#define AUDIO_VOL_DOWN 0x00EA
-#define TRANSPORT_NEXT_TRACK 0x00B5
-#define TRANSPORT_PREV_TRACK 0x00B6
-#define TRANSPORT_STOP 0x00B7
-#define TRANSPORT_PLAY_PAUSE 0x00CD
-#define AL_CC_CONFIG 0x0183
-#define AL_EMAIL 0x018A
-#define AL_CALCULATOR 0x0192
-#define AL_LOCAL_BROWSER 0x0194
-#define AC_SEARCH 0x0221
-#define AC_HOME 0x0223
-#define AC_BACK 0x0224
-#define AC_FORWARD 0x0225
-#define AC_STOP 0x0226
-#define AC_REFRESH 0x0227
-#define AC_BOOKMARKS 0x022A
-
-// Generic Desktop Page(0x01)
-#define SYSTEM_POWER_DOWN 0x0081
-#define SYSTEM_SLEEP 0x0082
-#define SYSTEM_WAKE_UP 0x0083
-
-
-#if defined(HOST_PJRC)
-# include "usb.h"
-# if defined(KBD2_REPORT_KEYS) && KBD2_REPORT_KEYS > KBD_REPORT_KEYS
-# define REPORT_KEYS KBD2_REPORT_KEYS
-# else
-# define REPORT_KEYS KBD_REPORT_KEYS
-# endif
-#elif defined(HOST_VUSB)
-# define REPORT_KEYS 6
-#endif
-
-typedef struct {
- uint8_t mods;
- uint8_t rserved;
- uint8_t keys[REPORT_KEYS];
-} report_keyboard_t;
-
-typedef struct {
- uint8_t report_id;
- uint8_t buttons;
- int8_t x;
- int8_t y;
- int8_t v;
- int8_t h;
-} report_mouse_t;
-
-
-#ifdef USB_NKRO_ENABLE
+#ifdef NKRO_ENABLE
extern bool keyboard_nkro;
#endif
@@ -108,6 +31,8 @@ extern report_keyboard_t *keyboard_report;
extern report_keyboard_t *keyboard_report_prev;
+void host_set_driver(host_driver_t *driver);
+host_driver_t *host_get_driver(void);
uint8_t host_keyboard_leds(void);
/* keyboard report operations */
@@ -122,12 +47,8 @@ uint8_t host_get_first_key(void);
void host_send_keyboard_report(void);
-#if defined(MOUSEKEY_ENABLE) || defined(PS2_MOUSE_ENABLE)
void host_mouse_send(report_mouse_t *report);
-#endif
-#ifdef USB_EXTRA_ENABLE
void host_system_send(uint16_t data);
void host_consumer_send(uint16_t data);
-#endif
#endif
diff --git a/host_driver.h b/host_driver.h
new file mode 100644
index 000000000..edb9e5dd9
--- /dev/null
+++ b/host_driver.h
@@ -0,0 +1,33 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef HOST_DRIVER_H
+#define HOST_DRIVER_H
+
+#include <stdint.h>
+#include "report.h"
+
+
+typedef struct {
+ uint8_t (*keyboard_leds)(void);
+ void (*send_keyboard)(report_keyboard_t *);
+ void (*send_mouse)(report_mouse_t *);
+ void (*send_system)(uint16_t);
+ void (*send_consumer)(uint16_t);
+} host_driver_t;
+
+#endif
diff --git a/iwrap.mk b/iwrap.mk
new file mode 100644
index 000000000..ea4a6e972
--- /dev/null
+++ b/iwrap.mk
@@ -0,0 +1,10 @@
+OPT_DEFS += -DHOST_IWRAP
+
+SRC += iwrap.c \
+ suart.S \
+ sendchar_uart.c \
+ uart.c
+
+
+# Search Path
+VPATH += $(COMMON_DIR)/iwrap
diff --git a/iwrap/iWRAP.txt b/iwrap/iWRAP.txt
new file mode 100644
index 000000000..2a062d9d9
--- /dev/null
+++ b/iwrap/iWRAP.txt
@@ -0,0 +1,376 @@
+Bulegiga WT12
+=============
+WT12 is a bluetooth module from Bluegiga. http://www.bluegiga.com/
+
+iWRAP
+ higher layer interface for bluetooth firmware
+ communicate with UART
+
+iWRAP HID
+default setting
+ 115200 8bit/n/1/n
+
+
+TODO
+----
+KiCAD circuit/PCB design
+power saving
+ AVR sleep(15ms by watch dog timer)
+ WT12 sleep
+ measuring current consumption
+ measuring battery life of normal usage/idle/intensive usage
+software reset/bootloarder
+LED indicator(chaging/paring/connecting)
+license confirmation of suart.c
+consumer page is not working
+authenticate method/SSP
+SPP keyboard support
+SPP debug console support
+mouse wheel feature request to Bluegiga
+
+
+Problems
+--------
+power consumption
+no consumer page support(bug?)
+no mouse wheel support
+no paring management
+no interactive auth method
+
+
+UART hardware flow control
+--------------------------
+(iWRAP4 User Guide 9.5)
+Hardware flow control is enabled by default and it should not be disabled unless mandatory, because without the hardware flow control the data transmission may not be reliable.
+If the hardware flow control is enabled from PS-keys, but no flow control is used, the following steps should be implemented in the hardware design:
+- CTS pin must be grounded
+- RTS pin must be left floating
+
+
+Power Saving
+------------
+power consume
+ without opimization: 4hr to shutdown(310mAh)
+ 2011/08/25: 9hr(310mAh) SNIFF MASTER sleep/WDTO_120MS
+
+measure current consumption
+ HHKB keyswitch matrix board
+ idle
+ scanning
+ Bluegiga WT12 module
+ SLEEP command
+ deep sleep on/off in config bits
+
+HHKB keyswich
+ how to power off
+ I/O pin configuration when sleeping
+ FET switch for 5V regulator
+
+Bluetooth module
+ power off when in USB mode
+ power off by FET switch
+
+AVR configuration
+ unused pins
+ ADC
+
+
+
+SET CONTROL CONFIG
+------------------
+ SET CONTROL CONFIG 4810
+ SET CONTROL CONFIG LIST
+ SET CONTROL CONFIG 0000 0000 4910 DEEP_SLEEP KLUDGE INTERACTIVE_PIN UART_LATENCY
+
+ Bit14 UART low latency
+ Bit11 Interactive pairing mode
+ Bit04 Deep sleep
+
+
+Reconnection
+------------
+SET CONTROL AUTOCALL 1124 5000 HID
+ 1124 HID service class
+ 5000 interval ms
+
+HID profile
+-----------
+This is needed to configure only once.
+ SET PROFILE HID ON
+ RESET
+
+HID class
+---------
+ SET BT CLASS 005C0 // keyboard/mouse combined devie
+
+Pairing Security
+----------------
+Secure Simple Pairing(SSP)
+ SET BT SSP 2 0 // Enables SSP for keyboard and Man-in-the-middle protection
+ SET BT SSP 3 0 // Enables SSP just works mode
+
+for keyboard with SSP
+ SET BT AUTH * 0000
+ SET BT SSP 2 0
+ SET CONTROL CONFIG 800
+ RESET
+
+for keyboard without SSP
+ SET BT AUTH * 0000
+ SET CONTROL CONFIG 800
+ RESET
+
+AUTH
+ AUTH xx:xx:xx:xx:xx:xx? // Pairing request event
+ AUTH xx:xx:xx:xx:xx:xx 0000
+
+ SSP PASSKEY 78:dd:08:b7:e4:a2 ?
+ SSP PASSKEY 78:dd:08:b7:e4:a2 xxxxx
+ (SSP COMPLETE 78:dd:08:b7:e4:a2 HCI_ERROR_AUTH_FAIL // failed)
+ RING 0 78:dd:08:b7:e4:a2 11 HID
+
+Connecton
+ RING xx:xx:xx:xx:xx:xx xx HID // connection event
+
+ KILL xx:xx:xx:xx:xx:xx
+
+Mode
+----
+Command mode
+Data mode
+ Raw mode
+ (Simple mode not for a real keyboard)
+
+Raw mode
+ Keyboard:
+ 0x9f, length(10), 0xa1, 0x01, mods, 0x00, key1, key2, key3, key4, key5, key6
+
+ Mouse:
+ 0x9f, length(5), 0xa1, 0x02, buttons, X, Y
+
+ Consumer page:
+ 0x9f, length(5), 0xa1, 0x03, bitfield1, bitfield2, bitfield3
+
+ consumer page suage
+ Bitfield 1:
+ 0x01 Volume Increment
+ 0x02 Volume Decrement
+ 0x04 Mute
+ 0x08 Play/Pause
+ 0x10 Scan Next Track
+ 0x20 Scan Previous Track
+ 0x40 Stop
+ 0x80 Eject
+ Bitfield 2:
+ 0x01 Email Reader
+ 0x02 Application Control Search
+ 0x04 AC Bookmarks
+ 0x08 AC Home
+ 0x10 AC Back
+ 0x20 AC Forward
+ 0x40 AC Stop
+ 0x80 AC Refresh
+ Bitfield 3:
+ 0x01 Application Launch Generic Consumer Control
+ 0x02 AL Internet Browser
+ 0x04 AL Calculator
+ 0x08 AL Terminal Lock / Screensaver
+ 0x10 AL Local Machine Browser
+ 0x20 AC Minimize
+ 0x40 Record
+ 0x80 Rewind
+
+
+
+
+
+2011/07/13
+set
+SET BT BDADDR 00:07:80:47:22:14
+SET BT NAME HHKB pro BT
+SET BT CLASS 0005c0
+SET BT AUTH * 0000
+SET BT IDENT BT:47 f000 4.1.0 Bluegiga iWRAP
+SET BT LAP 9e8b33
+SET BT PAGEMODE 4 2000 1
+SET BT PAIR 78:dd:08:b7:e4:a2 a191189cd7e51030ad6a07848ce879bb
+SET BT POWER 3 3 3
+SET BT ROLE 0 f 7d00
+SET BT SNIFF 0 20 1 8
+SET BT SSP 2 1
+SET BT MTU 667
+SET CONTROL AUTOCALL 1124 3000 HID
+SET CONTROL BAUD 38400,8n1
+SET CONTROL CD 00 0
+SET CONTROL ECHO 7
+SET CONTROL ESCAPE 43 00 1
+SET CONTROL GAIN 0 5
+SET CONTROL INIT SET CONTROL MUX 0
+SET CONTROL MSC DTE 00 00 00 00 00 00
+SET CONTROL MUX 1
+SET CONTROL PIO 00 00
+SET CONTROL READY 00
+SET PROFILE HID f HID
+SET
+
+info config
+
+!!! THIS IS BETA RELEASE AND MAY BE USED FOR EVALUATION PURPOSES ONLY !!!
+
+WRAP THOR AI (4.1.0 build 435)
+Copyright (c) 2003-2011 Bluegiga Technologies Inc.
+Compiled on Jun 28 2011 17:19:51, running on WT12-A module, psr v31
+ AVRCP BGIO FTP HFP HFP_AG HID HID_CONSUMER_PAGE HSP LEDS MAP OTA PBAP PIO=0x00fc SSP SUBRATE TEST VOLUME
+ - BOCK3 version 435 (Jun 28 2011 17:19:37) (max acl/sco 7/1)
+ - Bluetooth version 2.1, Power class 2
+ - Loader 4279, firmware 6297 (56-bit encryption), native execution mode
+ - up 0 days, 06:23, 2 connections (pool 2)
+ - User configuration:
+&028a = 0001 0000 0000 0011 0024 0000 0000 0010 0000 0080 0000 0000 0080 005f 009b 0034 00fb 0006
+&028b = 0000 0bb8
+&028d = 0001
+&0295 = 0000 0005 000b 0000 0003 0000 0000 0000 0000 0000 0000
+&0298 = a006
+&0299 = 0000 0000
+&02a3 = 0030 0030 0030 0030
+&02a4 = 009d 0000
+&02a5 = 0053 0045 0054 0020 0043 004f 004e 0054 0052 004f 004c 0020 004d 0055 0058 0020 0030
+&02a7 = 0000 05c0
+&02a8 = 4910 0000 0000
+&02aa = 0004 2000 0001 0033 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
+&02ac = 0000 0000 002b 0000 0000 0000 0000 0000 0000 0000 0002 0000 0000 0000 0010 0000 0000 0000 0000 029b 0000 0000 0000 0000
+&02ad = 4848 424b 7020 6f72 4220 0054
+&02b3 = 0005 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003
+&02b7 = 000f 4948 0044
+&02bb = 8000
+READY.
+
+
+
+
+2011/07/07 settings:
+set
+SET BT BDADDR 00:07:80:47:22:14
+SET BT NAME HHKB Pro BT
+SET BT CLASS 0005c0
+SET BT AUTH * 000
+SET BT IDENT BT:47 f000 4.0.0 Bluegiga iWRAP
+SET BT LAP 9e8b33
+SET BT PAGEMODE 4 2000 1
+SET BT PAIR 78:dd:08:b7:e4:a2 9e54d0aabb1b4d73cfccddb1ea4ef2d6
+SET BT POWER 3 3 3
+SET BT ROLE 0 f 7d00
+SET BT SNIFF 0 20 1 8
+SET BT SSP 3 0
+SET BT MTU 667
+SET CONTROL BAUD 38400,8n1
+SET CONTROL CD 00 0
+SET CONTROL ECHO 7
+SET CONTROL ESCAPE 255 00 1
+SET CONTROL GAIN 0 5
+SET CONTROL INIT set control mux 0
+SET CONTROL MSC DTE 00 00 00 00 00 00
+SET CONTROL PREAMP 1 1
+SET CONTROL READY 00
+SET PROFILE HID HID
+SET PROFILE SPP Bluetooth Serial Port
+SET
+
+info config
+WRAP THOR AI (4.0.0 build 317)
+Copyright (c) 2003-2010 Bluegiga Technologies Inc.
+Compiled on Apr 20 2010 16:44:28, running on WT12-A module, psr v31
+ AVRCP FTP PBAP PIO=0x00fc SSP SUBRATE VOLUME
+ - BOCK3 version 317 (Apr 20 2010 16:44:21) (max acl/sco 7/1)
+ - Bluetooth version 2.1, Power class 2
+ - Loader 4279, firmware 6297 (56-bit encryption), native execution mode
+ - up 0 days, 00:00, 0 connections (pool 1)
+ - User configuration:
+&028c = 0001 0020 0000 0001 0008 0000
+&028d = 0000
+&0296 = 0047 0001 f000 0400 6c42 6575 6967 6167 6920 5257 5041
+&0298 = c006
+&02a3 = 0030 0030 0030
+&02a4 = 009d 0000
+&02a5 = 0073 0065 0074 0020 0063 006f 006e 0074 0072 006f 006c 0020 006d 0075 0078 0020 0030
+&02a7 = 0000 05c0
+&02a8 = 0800 0000 0000
+&02ac = 0000 0000 00ff 0000 0000 0000 0000 0000 0000 0000 0002 0000 0000 0000 0010 0000 0000 0000 0000 029b 0000 0000 0000 0000
+&02ad = 4848 424b 5020 6f72 4220 0054
+&02b3 = 0004 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003
+&02b7 = 0000
+&02bb = 6c42 6575 6f74 746f 2068 6553 6972 6c61 5020 726f 0074
+READY.
+
+
+
+2011/08/23:
+SET BT BDADDR 00:07:80:47:22:14
+SET BT NAME HHKB pro BT
+SET BT CLASS 0005c0
+SET BT AUTH * 0000
+SET BT IDENT BT:47 f000 4.1.0 Bluegiga iWRAP
+SET BT LAP 9e8b33
+SET BT PAGEMODE 4 2000 1
+SET BT PAIRCOUNT 4
+SET BT POWER 3 3 3
+SET BT ROLE 1 f 12c0
+SET BT SNIFF 10 2 1 8
+SET BT SSP 3 0
+SET BT MTU 667
+SET CONTROL BAUD 38400,8n1
+SET CONTROL CD 00 0
+SET CONTROL ECHO 7
+SET CONTROL ESCAPE 43 00 1
+SET CONTROL GAIN 0 5
+SET CONTROL INIT SET CONTROL MUX 0
+SET CONTROL MSC DTE 00 00 00 00 00 00
+SET CONTROL MUX 1
+SET CONTROL PIO 00 00
+SET CONTROL READY 00
+SET PROFILE HID 7 HIDKeyboardMouse
+SET
+
+SET CONTROL CONFIG 0000 0004 481e CLOCK_CACHE INTERLACED_INQ INTERLACED_PAGE DEEP_SLEEP INTERACTIVE_PIN UART_LATENCY 23D_NOKLUDGE
+
+
+
+2011/08/25:
+SET BT BDADDR 00:07:80:47:22:14
+SET BT NAME HHKB pro BT
+SET BT CLASS 0005c0
+
+SET BT IDENT BT:47 f000 4.1.0 Bluegiga iWRAP
+SET BT LAP 9e8b33
+SET BT PAGEMODE 4 2000 1
+SET BT PAIRCOUNT 4
+SET BT PAIR 78:dd:08:b7:e4:a2 0be83335a03fed8ededae42e99554e28
+SET BT POWER 3 3 3
+SET BT ROLE 1 f 12c0
+SET BT SNIFF 100 20 1 8
+SET BT SSP 3 0
+SET BT MTU 667
+SET CONTROL BAUD 38400,8n1
+SET CONTROL CD 00 0
+SET CONTROL ECHO 7
+SET CONTROL ESCAPE - 20 1
+SET CONTROL GAIN 0 5
+SET CONTROL INIT SET CONTROL MUX 0
+SET CONTROL MSC DTE 00 00 00 00 00 00
+SET CONTROL MUX 1
+SET CONTROL PIO 00 00
+SET CONTROL READY 00
+SET PROFILE HID f HIDKeyboardMouse
+SET
+
+
+SET CONTROL CONFIG 0000 0000 490e CLOCK_CACHE INTERLACED_INQ INTERLACED_PAGE KLUDGE INTERACTIVE_PIN UART_LATENCY
+
+
+2011/09/08:
+SET CONTROL CONFIG 0000 0000 410e CLOCK_CACHE INTERLACED_INQ INTERLACED_PAGE KLUDGE UART_LATENCY
+
+ Removed INTERACTIVE_PIN to avoid interactive auth and use SET BT AUTH pin(0000).
+
+
+EOF
diff --git a/iwrap/iwrap.c b/iwrap/iwrap.c
new file mode 100644
index 000000000..9c68761bf
--- /dev/null
+++ b/iwrap/iwrap.c
@@ -0,0 +1,467 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* host driver for Bulegiga iWRAP */
+/* Bluegiga BT12
+ * Connections
+ * Hardware UART Software UART BlueTooth
+ * PC=====UART=======AVR=====SUART====iWRAP(BT12)-----------PC
+ *
+ * - Hardware UART for Debug Console to communicate iWRAP
+ * - Software UART for iWRAP control to send keyboard/mouse data
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <avr/interrupt.h>
+#include <util/delay.h>
+#include "usb_keycodes.h"
+#include "suart.h"
+#include "uart.h"
+#include "report.h"
+#include "host_driver.h"
+#include "iwrap.h"
+#include "print.h"
+
+
+/* iWRAP MUX mode utils. 3.10 HID raw mode(iWRAP_HID_Application_Note.pdf) */
+#define MUX_HEADER(LINK, LENGTH) do { \
+ xmit(0xbf); /* SOF */ \
+ xmit(LINK); /* Link */ \
+ xmit(0x00); /* Flags */ \
+ xmit(LENGTH); /* Length */ \
+} while (0)
+#define MUX_FOOTER(LINK) xmit(LINK^0xff)
+
+
+static uint8_t connected = 0;
+//static uint8_t channel = 1;
+
+/* iWRAP buffer */
+#define MUX_BUF_SIZE 64
+static char buf[MUX_BUF_SIZE];
+static uint8_t snd_pos = 0;
+
+#define MUX_RCV_BUF_SIZE 256
+static char rcv_buf[MUX_RCV_BUF_SIZE];
+static uint8_t rcv_head = 0;
+static uint8_t rcv_tail = 0;
+
+
+/* receive buffer */
+static void rcv_enq(char c)
+{
+ uint8_t next = (rcv_head + 1) % MUX_RCV_BUF_SIZE;
+ if (next != rcv_tail) {
+ rcv_buf[rcv_head] = c;
+ rcv_head = next;
+ }
+}
+
+static char rcv_deq(void)
+{
+ char c = 0;
+ if (rcv_head != rcv_tail) {
+ c = rcv_buf[rcv_tail++];
+ rcv_tail %= MUX_RCV_BUF_SIZE;
+ }
+ return c;
+}
+
+/*
+static char rcv_peek(void)
+{
+ if (rcv_head == rcv_tail)
+ return 0;
+ return rcv_buf[rcv_tail];
+}
+*/
+
+static void rcv_clear(void)
+{
+ rcv_tail = rcv_head = 0;
+}
+
+/* iWRAP response */
+ISR(PCINT1_vect, ISR_BLOCK) // recv() runs away in case of ISR_NOBLOCK
+{
+ if ((SUART_IN_PIN & (1<<SUART_IN_BIT)))
+ return;
+
+ static volatile uint8_t mux_state = 0xff;
+ static volatile uint8_t mux_link = 0xff;
+ uint8_t c = recv();
+ switch (mux_state) {
+ case 0xff: // SOF
+ if (c == 0xbf)
+ mux_state--;
+ break;
+ case 0xfe: // Link
+ mux_state--;
+ mux_link = c;
+ break;
+ case 0xfd: // Flags
+ mux_state--;
+ break;
+ case 0xfc: // Length
+ mux_state = c;
+ break;
+ case 0x00:
+ mux_state = 0xff;
+ mux_link = 0xff;
+ break;
+ default:
+ if (mux_state--) {
+ uart_putchar(c);
+ rcv_enq(c);
+ }
+ }
+}
+
+
+/*------------------------------------------------------------------*
+ * iWRAP communication
+ *------------------------------------------------------------------*/
+void iwrap_init(void)
+{
+ // reset iWRAP if in already MUX mode after AVR software-reset
+ iwrap_send("RESET");
+ iwrap_mux_send("RESET");
+ _delay_ms(3000);
+ iwrap_send("\r\nSET CONTROL MUX 1\r\n");
+ _delay_ms(500);
+ iwrap_check_connection();
+}
+
+void iwrap_mux_send(const char *s)
+{
+ rcv_clear();
+ MUX_HEADER(0xff, strlen((char *)s));
+ iwrap_send(s);
+ MUX_FOOTER(0xff);
+}
+
+void iwrap_send(const char *s)
+{
+ while (*s)
+ xmit(*s++);
+}
+
+/* send buffer */
+void iwrap_buf_add(uint8_t c)
+{
+ // need space for '\0'
+ if (snd_pos < MUX_BUF_SIZE-1)
+ buf[snd_pos++] = c;
+}
+
+void iwrap_buf_del(void)
+{
+ if (snd_pos)
+ snd_pos--;
+}
+
+void iwrap_buf_send(void)
+{
+ buf[snd_pos] = '\0';
+ snd_pos = 0;
+ iwrap_mux_send(buf);
+}
+
+void iwrap_call(void)
+{
+ char *p;
+
+ iwrap_mux_send("SET BT PAIR");
+ _delay_ms(500);
+
+ p = rcv_buf + rcv_tail;
+ while (!strncmp(p, "SET BT PAIR", 11)) {
+ p += 7;
+ strncpy(p, "CALL", 4);
+ strncpy(p+22, " 11 HID\n\0", 9);
+ print_S(p);
+ iwrap_mux_send(p);
+ // TODO: skip to next line
+ p += 57;
+
+ DEBUG_LED_CONFIG;
+ DEBUG_LED_ON;
+ _delay_ms(500);
+ DEBUG_LED_OFF;
+ _delay_ms(500);
+ DEBUG_LED_ON;
+ _delay_ms(500);
+ DEBUG_LED_OFF;
+ _delay_ms(500);
+ DEBUG_LED_ON;
+ _delay_ms(500);
+ DEBUG_LED_OFF;
+ _delay_ms(500);
+ DEBUG_LED_ON;
+ _delay_ms(500);
+ DEBUG_LED_OFF;
+ _delay_ms(500);
+ DEBUG_LED_ON;
+ _delay_ms(500);
+ DEBUG_LED_OFF;
+ _delay_ms(500);
+ }
+ iwrap_check_connection();
+}
+
+void iwrap_kill(void)
+{
+ char c;
+ iwrap_mux_send("LIST");
+ _delay_ms(500);
+
+ while ((c = rcv_deq()) && c != '\n') ;
+ if (strncmp(rcv_buf + rcv_tail, "LIST ", 5)) {
+ print("no connection to kill.\n");
+ return;
+ }
+ // skip 10 'space' chars
+ for (uint8_t i = 10; i; i--)
+ while ((c = rcv_deq()) && c != ' ') ;
+
+ char *p = rcv_buf + rcv_tail - 5;
+ strncpy(p, "KILL ", 5);
+ strncpy(p + 22, "\n\0", 2);
+ print_S(p);
+ iwrap_mux_send(p);
+ _delay_ms(500);
+
+ iwrap_check_connection();
+}
+
+void iwrap_unpair(void)
+{
+ iwrap_mux_send("SET BT PAIR");
+ _delay_ms(500);
+
+ char *p = rcv_buf + rcv_tail;
+ if (!strncmp(p, "SET BT PAIR", 11)) {
+ strncpy(p+29, "\n\0", 2);
+ print_S(p);
+ iwrap_mux_send(p);
+ }
+}
+
+void iwrap_sleep(void)
+{
+ iwrap_mux_send("SLEEP");
+}
+
+void iwrap_sniff(void)
+{
+}
+
+void iwrap_subrate(void)
+{
+}
+
+bool iwrap_failed(void)
+{
+ if (strncmp(rcv_buf, "SYNTAX ERROR", 12))
+ return true;
+ else
+ return false;
+}
+
+uint8_t iwrap_connected(void)
+{
+ return connected;
+}
+
+uint8_t iwrap_check_connection(void)
+{
+ iwrap_mux_send("LIST");
+ _delay_ms(100);
+
+ if (strncmp(rcv_buf, "LIST ", 5) || !strncmp(rcv_buf, "LIST 0", 6))
+ connected = 0;
+ else
+ connected = 1;
+ return connected;
+}
+
+
+/*------------------------------------------------------------------*
+ * Host driver
+ *------------------------------------------------------------------*/
+static uint8_t keyboard_leds(void);
+static void send_keyboard(report_keyboard_t *report);
+static void send_mouse(report_mouse_t *report);
+static void send_system(uint16_t data);
+static void send_consumer(uint16_t data);
+
+static host_driver_t driver = {
+ keyboard_leds,
+ send_keyboard,
+ send_mouse,
+ send_system,
+ send_consumer
+};
+
+host_driver_t *iwrap_driver(void)
+{
+ return &driver;
+}
+
+static uint8_t keyboard_leds(void) {
+ return 0;
+}
+
+static void send_keyboard(report_keyboard_t *report)
+{
+ if (!iwrap_connected() && !iwrap_check_connection()) return;
+ MUX_HEADER(0x01, 0x0c);
+ // HID raw mode header
+ xmit(0x9f);
+ xmit(0x0a); // Length
+ xmit(0xa1); // keyboard report
+ xmit(0x01);
+ xmit(report->mods);
+ xmit(0x00); // reserved byte(always 0)
+ xmit(report->keys[0]);
+ xmit(report->keys[1]);
+ xmit(report->keys[2]);
+ xmit(report->keys[3]);
+ xmit(report->keys[4]);
+ xmit(report->keys[5]);
+ MUX_FOOTER(0x01);
+}
+
+static void send_mouse(report_mouse_t *report)
+{
+#if defined(MOUSEKEY_ENABLE) || defined(PS2_MOUSE_ENABLE)
+ if (!iwrap_connected() && !iwrap_check_connection()) return;
+ MUX_HEADER(0x01, 0x07);
+ // HID raw mode header
+ xmit(0x9f);
+ xmit(0x05); // Length
+ xmit(0xa1); // mouse report
+ xmit(0x02);
+ xmit(report->buttons);
+ xmit(report->x);
+ xmit(report->y);
+ MUX_FOOTER(0x01);
+#endif
+}
+
+static void send_system(uint16_t data)
+{
+ /* not supported */
+}
+
+static void send_consumer(uint16_t data)
+{
+#ifdef EXTRAKEY_ENABLE
+ static uint16_t last_data = 0;
+ uint8_t bits1 = 0;
+ uint8_t bits2 = 0;
+ uint8_t bits3 = 0;
+
+ if (!iwrap_connected() && !iwrap_check_connection()) return;
+ if (data == last_data) return;
+ last_data = data;
+
+ // 3.10 HID raw mode(iWRAP_HID_Application_Note.pdf)
+ switch (data) {
+ case AUDIO_VOL_UP:
+ bits1 = 0x01;
+ break;
+ case AUDIO_VOL_DOWN:
+ bits1 = 0x02;
+ break;
+ case AUDIO_MUTE:
+ bits1 = 0x04;
+ break;
+ case TRANSPORT_PLAY_PAUSE:
+ bits1 = 0x08;
+ break;
+ case TRANSPORT_NEXT_TRACK:
+ bits1 = 0x10;
+ break;
+ case TRANSPORT_PREV_TRACK:
+ bits1 = 0x20;
+ break;
+ case TRANSPORT_STOP:
+ bits1 = 0x40;
+ break;
+ case TRANSPORT_EJECT:
+ bits1 = 0x80;
+ break;
+ case AL_EMAIL:
+ bits2 = 0x01;
+ break;
+ case AC_SEARCH:
+ bits2 = 0x02;
+ break;
+ case AC_BOOKMARKS:
+ bits2 = 0x04;
+ break;
+ case AC_HOME:
+ bits2 = 0x08;
+ break;
+ case AC_BACK:
+ bits2 = 0x10;
+ break;
+ case AC_FORWARD:
+ bits2 = 0x20;
+ break;
+ case AC_STOP:
+ bits2 = 0x40;
+ break;
+ case AC_REFRESH:
+ bits2 = 0x80;
+ break;
+ case AL_CC_CONFIG:
+ bits3 = 0x01;
+ break;
+ case AL_CALCULATOR:
+ bits3 = 0x04;
+ break;
+ case AL_LOCK:
+ bits3 = 0x08;
+ break;
+ case AL_LOCAL_BROWSER:
+ bits3 = 0x10;
+ break;
+ case AC_MINIMIZE:
+ bits3 = 0x20;
+ break;
+ case TRANSPORT_RECORD:
+ bits3 = 0x40;
+ break;
+ case TRANSPORT_REWIND:
+ bits3 = 0x80;
+ break;
+ }
+
+ MUX_HEADER(0x01, 0x07);
+ xmit(0x9f);
+ xmit(0x05); // Length
+ xmit(0xa1); // consumer report
+ xmit(0x03);
+ xmit(bits1);
+ xmit(bits2);
+ xmit(bits3);
+ MUX_FOOTER(0x01);
+#endif
+}
diff --git a/iwrap/iwrap.h b/iwrap/iwrap.h
new file mode 100644
index 000000000..ffaad9395
--- /dev/null
+++ b/iwrap/iwrap.h
@@ -0,0 +1,49 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef IWRAP_H
+#define IWRAP_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "host_driver.h"
+
+
+/* enable iWRAP MUX mode */
+#define MUX_MODE
+
+
+host_driver_t *iwrap_driver(void);
+
+void iwrap_init(void);
+void iwrap_send(const char *s);
+void iwrap_mux_send(const char *s);
+void iwrap_buf_send(void);
+void iwrap_buf_add(uint8_t c);
+void iwrap_buf_del(void);
+
+void iwrap_call(void);
+void iwrap_kill(void);
+void iwrap_unpair(void);
+void iwrap_sleep(void);
+void iwrap_sniff(void);
+void iwrap_subrate(void);
+bool iwrap_failed(void);
+uint8_t iwrap_connected(void);
+uint8_t iwrap_check_connection(void);
+
+#endif
diff --git a/iwrap/main.c b/iwrap/main.c
new file mode 100644
index 000000000..a552afb67
--- /dev/null
+++ b/iwrap/main.c
@@ -0,0 +1,378 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <stdint.h>
+#include <avr/interrupt.h>
+#include <avr/io.h>
+//#include <avr/wdt.h>
+#include "wd.h" // in order to use watchdog in interrupt mode
+#include <avr/sleep.h>
+#include <util/delay.h>
+#include <avr/power.h>
+#include "keyboard.h"
+#include "matrix.h"
+#include "host.h"
+#include "iwrap.h"
+#ifdef HOST_VUSB
+# include "vusb.h"
+# include "usbdrv.h"
+#endif
+#include "uart.h"
+#include "suart.h"
+#include "timer.h"
+#include "debug.h"
+#include "usb_keycodes.h"
+#include "command.h"
+
+
+static void sleep(uint8_t term);
+static bool console(void);
+static uint8_t console_command(uint8_t c);
+static uint8_t key2asc(uint8_t key);
+
+
+/*
+static void set_prr(void)
+{
+ power_adc_disable();
+ power_spi_disable();
+ power_twi_disable();
+#ifndef TIMER_H
+ //power_timer0_disable(); // used in timer.c
+#endif
+ power_timer1_disable();
+ power_timer2_disable();
+}
+*/
+
+/*
+static void pullup_pins(void)
+{
+ // DDRs are set to 0(input) by default.
+#ifdef PORTA
+ PORTA = 0xFF;
+#endif
+ PORTB = 0xFF;
+ PORTC = 0xFF;
+ PORTD = 0xFF;
+#ifdef PORTE
+ PORTE = 0xFF;
+#endif
+#ifdef PORTE
+ PORTF = 0xFF;
+#endif
+}
+*/
+
+
+#ifdef HOST_VUSB
+static void disable_vusb(void)
+{
+ // disable interrupt & disconnect to prevent host from enumerating
+ USB_INTR_ENABLE &= ~(1 << USB_INTR_ENABLE_BIT);
+ usbDeviceDisconnect();
+}
+
+static void enable_vusb(void)
+{
+ USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
+ usbDeviceConnect();
+}
+
+static void init_vusb(void)
+{
+ uint8_t i = 0;
+
+ usbInit();
+ disable_vusb();
+ /* fake USB disconnect for > 250 ms */
+ while(--i){
+ _delay_ms(1);
+ }
+ enable_vusb();
+}
+#endif
+
+void change_driver(host_driver_t *driver)
+{
+ host_clear_keyboard_report();
+ host_swap_keyboard_report();
+ host_clear_keyboard_report();
+ host_send_keyboard_report();
+ _delay_ms(1000);
+ host_set_driver(driver);
+}
+
+
+static bool sleeping = false;
+static bool insomniac = false; // TODO: should be false for power saving
+static uint16_t last_timer = 0;
+
+int main(void)
+{
+ MCUSR = 0;
+ clock_prescale_set(clock_div_1);
+ WD_SET(WD_OFF);
+
+ // power saving: the result is worse than nothing... why?
+ //pullup_pins();
+ //set_prr();
+
+ print_enable = true;
+ debug_enable = false;
+
+#ifdef HOST_VUSB
+ disable_vusb();
+#endif
+ uart_init(115200);
+ keyboard_init();
+ print("\nSend BREAK for UART Console Commands.\n");
+
+ // TODO: move to iWRAP/suart file
+ print("suart init\n");
+ // suart init
+ // PC4: Tx Output IDLE(Hi)
+ PORTC |= (1<<4);
+ DDRC |= (1<<4);
+ // PC5: Rx Input(pull-up)
+ PORTC |= (1<<5);
+ DDRC &= ~(1<<5);
+ // suart receive interrut(PC5/PCINT13)
+ PCMSK1 = 0b00100000;
+ PCICR = 0b00000010;
+
+ host_set_driver(iwrap_driver());
+
+ print("iwrap_init()\n");
+ iwrap_init();
+ iwrap_call();
+
+ last_timer = timer_read();
+ while (true) {
+#ifdef HOST_VUSB
+ if (host_get_driver() == vusb_driver())
+ usbPoll();
+#endif
+ keyboard_proc();
+#ifdef HOST_VUSB
+ if (host_get_driver() == vusb_driver())
+ vusb_transfer_keyboard();
+#endif
+ if (matrix_is_modified() || console()) {
+ last_timer = timer_read();
+ sleeping = false;
+ } else if (!sleeping && timer_elapsed(last_timer) > 4000) {
+ sleeping = true;
+ iwrap_check_connection();
+ }
+
+ if (host_get_driver() == iwrap_driver()) {
+ if (sleeping && !insomniac) {
+ _delay_ms(1); // wait for UART to send
+ iwrap_sleep();
+ sleep(WDTO_60MS);
+ }
+ }
+ }
+}
+
+static void sleep(uint8_t term)
+{
+ WD_SET(WD_IRQ, term);
+
+ cli();
+ set_sleep_mode(SLEEP_MODE_PWR_DOWN);
+ sleep_enable();
+ sleep_bod_disable();
+ sei();
+ sleep_cpu();
+ sleep_disable();
+
+ WD_SET(WD_OFF);
+}
+
+ISR(WDT_vect)
+{
+ // wake up
+}
+
+static bool console(void)
+{
+ // Send to Bluetoot module WT12
+ static bool breaked = false;
+ if (!uart_available())
+ return false;
+ else {
+ uint8_t c;
+ c = uart_getchar();
+ uart_putchar(c);
+ switch (c) {
+ case 0x00: // BREAK signal
+ if (!breaked) {
+ print("break(? for help): ");
+ breaked = true;
+ }
+ break;
+ case '\r':
+ uart_putchar('\n');
+ iwrap_buf_send();
+ break;
+ case '\b':
+ iwrap_buf_del();
+ break;
+ default:
+ if (breaked) {
+ print("\n");
+ console_command(c);
+ breaked = false;
+ } else {
+ iwrap_buf_add(c);
+ }
+ break;
+ }
+ return true;
+ }
+}
+
+uint8_t command_extra()
+{
+ return console_command(key2asc(host_get_first_key()));
+}
+
+static uint8_t console_command(uint8_t c)
+{
+ switch (c) {
+ case 'h':
+ case '?':
+ print("\nCommands for Bluetooth(WT12/iWRAP):\n");
+ print("r: reset. software reset by watchdog\n");
+ print("i: insomniac. prevent KB from sleeping\n");
+ print("c: iwrap_call. CALL for BT connection.\n");
+#ifdef HOST_VUSB
+ print("u: USB mode. switch to USB.\n");
+ print("w: BT mode. switch to Bluetooth.\n");
+#endif
+ print("k: kill first connection.\n");
+ print("Del: unpair first pairing.\n");
+ print("\n");
+ return 0;
+ case 'r':
+ print("reset\n");
+ WD_AVR_RESET();
+ return 1;
+ case 'i':
+ insomniac = !insomniac;
+ if (insomniac)
+ print("insomniac\n");
+ else
+ print("not insomniac\n");
+ return 1;
+ case 'c':
+ print("iwrap_call()\n");
+ iwrap_call();
+ return 1;
+#ifdef HOST_VUSB
+ case 'u':
+ print("USB mode\n");
+ init_vusb();
+ change_driver(vusb_driver());
+ //iwrap_kill();
+ //iwrap_sleep();
+ // disable suart receive interrut(PC5/PCINT13)
+ PCMSK1 &= ~(0b00100000);
+ PCICR &= ~(0b00000010);
+ return 1;
+ case 'w':
+ print("iWRAP mode\n");
+ change_driver(iwrap_driver());
+ disable_vusb();
+ // enable suart receive interrut(PC5/PCINT13)
+ PCMSK1 |= 0b00100000;
+ PCICR |= 0b00000010;
+ return 1;
+#endif
+ case 'k':
+ print("kill\n");
+ iwrap_kill();
+ return 1;
+ case 0x7F: // DELETE
+ print("unpair\n");
+ iwrap_unpair();
+ return 1;
+ }
+ return 0;
+}
+
+// convert keycode into ascii charactor
+static uint8_t key2asc(uint8_t key)
+{
+ switch (key) {
+ case KB_A: return 'a';
+ case KB_B: return 'b';
+ case KB_C: return 'c';
+ case KB_D: return 'd';
+ case KB_E: return 'e';
+ case KB_F: return 'f';
+ case KB_G: return 'g';
+ case KB_H: return 'h';
+ case KB_I: return 'i';
+ case KB_J: return 'j';
+ case KB_K: return 'k';
+ case KB_L: return 'l';
+ case KB_M: return 'm';
+ case KB_N: return 'n';
+ case KB_O: return 'o';
+ case KB_P: return 'p';
+ case KB_Q: return 'q';
+ case KB_R: return 'r';
+ case KB_S: return 's';
+ case KB_T: return 't';
+ case KB_U: return 'u';
+ case KB_V: return 'v';
+ case KB_W: return 'w';
+ case KB_X: return 'x';
+ case KB_Y: return 'y';
+ case KB_Z: return 'z';
+ case KB_1: return '1';
+ case KB_2: return '2';
+ case KB_3: return '3';
+ case KB_4: return '4';
+ case KB_5: return '5';
+ case KB_6: return '6';
+ case KB_7: return '7';
+ case KB_8: return '8';
+ case KB_9: return '9';
+ case KB_0: return '0';
+ case KB_ENTER: return '\n';
+ case KB_ESCAPE: return 0x1B;
+ case KB_BSPACE: return '\b';
+ case KB_TAB: return '\t';
+ case KB_SPACE: return ' ';
+ case KB_MINUS: return '-';
+ case KB_EQUAL: return '=';
+ case KB_LBRACKET: return '[';
+ case KB_RBRACKET: return ']';
+ case KB_BSLASH: return '\\';
+ case KB_NONUS_HASH: return '\\';
+ case KB_SCOLON: return ';';
+ case KB_QUOTE: return '\'';
+ case KB_GRAVE: return '`';
+ case KB_COMMA: return ',';
+ case KB_DOT: return '.';
+ case KB_SLASH: return '/';
+ default: return 0x00;
+ }
+}
diff --git a/iwrap/suart.S b/iwrap/suart.S
new file mode 100644
index 000000000..1b0290963
--- /dev/null
+++ b/iwrap/suart.S
@@ -0,0 +1,156 @@
+;---------------------------------------------------------------------------;
+; Software implemented UART module ;
+; (C)ChaN, 2005 (http://elm-chan.org/) ;
+;---------------------------------------------------------------------------;
+; Bit rate settings:
+;
+; 1MHz 2MHz 4MHz 6MHz 8MHz 10MHz 12MHz 16MHz 20MHz
+; 2.4kbps 138 - - - - - - - -
+; 4.8kbps 68 138 - - - - - - -
+; 9.6kbps 33 68 138 208 - - - - -
+; 19.2kbps - 33 68 102 138 173 208 - -
+; 38.4kbps - - 33 50 68 85 102 138 172
+; 57.6kbps - - 21 33 44 56 68 91 114
+; 115.2kbps - - - - 21 27 33 44 56
+
+.nolist
+#include <avr/io.h>
+.list
+
+#define BPS 102 /* Bit delay. (see above table) */
+#define BIDIR 0 /* 0:Separated Tx/Rx, 1:Shared Tx/Rx */
+
+#define OUT_1 sbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 1 */
+#define OUT_0 cbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 0 */
+#define SKIP_IN_1 sbis _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT /* Skip if 1 */
+#define SKIP_IN_0 sbic _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT /* Skip if 0 */
+
+
+
+#ifdef SPM_PAGESIZE
+.macro _LPMI reg
+ lpm \reg, Z+
+.endm
+.macro _MOVW dh,dl, sh,sl
+ movw \dl, \sl
+.endm
+#else
+.macro _LPMI reg
+ lpm
+ mov \reg, r0
+ adiw ZL, 1
+.endm
+.macro _MOVW dh,dl, sh,sl
+ mov \dl, \sl
+ mov \dh, \sh
+.endm
+#endif
+
+
+
+;---------------------------------------------------------------------------;
+; Transmit a byte in serial format of N81
+;
+;Prototype: void xmit (uint8_t data);
+;Size: 16 words
+
+.global xmit
+.func xmit
+xmit:
+#if BIDIR
+ ldi r23, BPS-1 ;Pre-idle time for bidirectional data line
+5: dec r23 ;
+ brne 5b ;/
+#endif
+ in r0, _SFR_IO_ADDR(SREG) ;Save flags
+
+ com r24 ;C = start bit
+ ldi r25, 10 ;Bit counter
+ cli ;Start critical section
+
+1: ldi r23, BPS-1 ;----- Bit transferring loop
+2: dec r23 ;Wait for a bit time
+ brne 2b ;/
+ brcs 3f ;MISO = bit to be sent
+ OUT_1 ;
+3: brcc 4f ;
+ OUT_0 ;/
+4: lsr r24 ;Get next bit into C
+ dec r25 ;All bits sent?
+ brne 1b ; no, coutinue
+
+ out _SFR_IO_ADDR(SREG), r0 ;End of critical section
+ ret
+.endfunc
+
+
+
+;---------------------------------------------------------------------------;
+; Receive a byte
+;
+;Prototype: uint8_t rcvr (void);
+;Size: 19 words
+
+.global rcvr
+.func rcvr
+rcvr:
+ in r0, _SFR_IO_ADDR(SREG) ;Save flags
+
+ ldi r24, 0x80 ;Receiving shift reg
+ cli ;Start critical section
+
+1: SKIP_IN_1 ;Wait for idle
+ rjmp 1b
+2: SKIP_IN_0 ;Wait for start bit
+ rjmp 2b
+ ldi r25, BPS/2 ;Wait for half bit time
+3: dec r25
+ brne 3b
+
+4: ldi r25, BPS ;----- Bit receiving loop
+5: dec r25 ;Wait for a bit time
+ brne 5b ;/
+ lsr r24 ;Next bit
+ SKIP_IN_0 ;Get a data bit into r24.7
+ ori r24, 0x80
+ brcc 4b ;All bits received? no, continue
+
+ out _SFR_IO_ADDR(SREG), r0 ;End of critical section
+ ret
+.endfunc
+
+
+; Not wait for start bit. This should be called after detecting start bit.
+.global recv
+.func recv
+recv:
+ in r0, _SFR_IO_ADDR(SREG) ;Save flags
+
+ ldi r24, 0x80 ;Receiving shift reg
+ cli ;Start critical section
+
+;1: SKIP_IN_1 ;Wait for idle
+; rjmp 1b
+;2: SKIP_IN_0 ;Wait for start bit
+; rjmp 2b
+ ldi r25, BPS/2 ;Wait for half bit time
+3: dec r25
+ brne 3b
+
+4: ldi r25, BPS ;----- Bit receiving loop
+5: dec r25 ;Wait for a bit time
+ brne 5b ;/
+ lsr r24 ;Next bit
+ SKIP_IN_0 ;Get a data bit into r24.7
+ ori r24, 0x80
+ brcc 4b ;All bits received? no, continue
+
+ ldi r25, BPS/2 ;Wait for half bit time
+6: dec r25
+ brne 6b
+7: SKIP_IN_1 ;Wait for stop bit
+ rjmp 7b
+
+ out _SFR_IO_ADDR(SREG), r0 ;End of critical section
+ ret
+.endfunc
diff --git a/iwrap/suart.h b/iwrap/suart.h
new file mode 100644
index 000000000..72725b998
--- /dev/null
+++ b/iwrap/suart.h
@@ -0,0 +1,8 @@
+#ifndef SUART
+#define SUART
+
+void xmit(uint8_t);
+uint8_t rcvr(void);
+uint8_t recv(void);
+
+#endif /* SUART */
diff --git a/iwrap/wd.h b/iwrap/wd.h
new file mode 100644
index 000000000..99058f033
--- /dev/null
+++ b/iwrap/wd.h
@@ -0,0 +1,159 @@
+/* This is from http://www.mtcnet.net/~henryvm/wdt/ */
+#ifndef _AVR_WD_H_
+#define _AVR_WD_H_
+
+#include <avr/io.h>
+
+/*
+Copyright (c) 2009, Curt Van Maanen
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+include usage-
+ #include "wd.h" //if in same directory as project
+ #include <avr/wd.h> //if wd.h is in avr directory
+
+set watchdog modes and prescale
+
+usage-
+ WD_SET(mode,[timeout]); //prescale always set
+
+modes-
+ WD_OFF disabled
+ WD_RST normal reset mode
+ WD_IRQ interrupt only mode (if supported)
+ WD_RST_IRQ interrupt+reset mode (if supported)
+
+timeout-
+ WDTO_15MS default if no timeout provided
+ WDTO_30MS
+ WDTO_60MS
+ WDTO_120MS
+ WDTO_250MS
+ WDTO_500MS
+ WDTO_1S
+ WDTO_2S
+ WDTO_4S (if supported)
+ WDTO_8S (if supported)
+
+examples-
+ WD_SET(WD_RST,WDTO_1S); //reset mode, 1s timeout
+ WD_SET(WD_OFF); //watchdog disabled (if not fused on)
+ WD_SET(WD_RST); //reset mode, 15ms (default timeout)
+ WD_SET(WD_IRQ,WDTO_120MS); //interrupt only mode, 120ms timeout
+ WD_SET(WD_RST_IRQ,WDTO_2S); //interrupt+reset mode, 2S timeout
+
+
+for enhanced watchdogs, if the watchdog is not being used WDRF should be
+cleared on every power up or reset, along with disabling the watchdog-
+ WD_DISABLE(); //clear WDRF, then turn off watchdog
+
+*/
+
+//reset registers to the same name (MCUCSR)
+#if !defined(MCUCSR)
+#define MCUCSR MCUSR
+#endif
+
+//watchdog registers to the same name (WDTCSR)
+#if !defined(WDTCSR)
+#define WDTCSR WDTCR
+#endif
+
+//if enhanced watchdog, define irq values, create disable macro
+#if defined(WDIF)
+#define WD_IRQ 0xC0
+#define WD_RST_IRQ 0xC8
+#define WD_DISABLE() do{ \
+ MCUCSR &= ~(1<<WDRF); \
+ WD_SET(WD_OFF); \
+ }while(0)
+#endif
+
+//all watchdogs
+#define WD_RST 8
+#define WD_OFF 0
+
+//prescale values
+#define WDTO_15MS 0
+#define WDTO_30MS 1
+#define WDTO_60MS 2
+#define WDTO_120MS 3
+#define WDTO_250MS 4
+#define WDTO_500MS 5
+#define WDTO_1S 6
+#define WDTO_2S 7
+
+//prescale values for avrs with WDP3
+#if defined(WDP3)
+#define WDTO_4S 0x20
+#define WDTO_8S 0x21
+#endif
+
+//watchdog reset
+#define WDR() __asm__ __volatile__("wdr")
+
+//avr reset using watchdog
+#define WD_AVR_RESET() do{ \
+ __asm__ __volatile__("cli"); \
+ WD_SET_UNSAFE(WD_RST); \
+ while(1); \
+ }while(0)
+
+/*set the watchdog-
+1. save SREG
+2. turn off irq's
+3. reset watchdog timer
+4. enable watchdog change
+5. write watchdog value
+6. restore SREG (restoring irq status)
+*/
+#define WD_SET(val,...) \
+ __asm__ __volatile__( \
+ "in __tmp_reg__,__SREG__" "\n\t" \
+ "cli" "\n\t" \
+ "wdr" "\n\t" \
+ "sts %[wdreg],%[wden]" "\n\t" \
+ "sts %[wdreg],%[wdval]" "\n\t" \
+ "out __SREG__,__tmp_reg__" "\n\t" \
+ : \
+ : [wdreg] "M" (&WDTCSR), \
+ [wden] "r" ((uint8_t)(0x18)), \
+ [wdval] "r" ((uint8_t)(val|(__VA_ARGS__+0))) \
+ : "r0" \
+)
+
+/*set the watchdog when I bit in SREG known to be clear-
+1. reset watchdog timer
+2. enable watchdog change
+5. write watchdog value
+*/
+#define WD_SET_UNSAFE(val,...) \
+ __asm__ __volatile__( \
+ "wdr" "\n\t" \
+ "sts %[wdreg],%[wden]" "\n\t" \
+ "sts %[wdreg],%[wdval]" "\n\t" \
+ : \
+ : [wdreg] "M" (&WDTCSR), \
+ [wden] "r" ((uint8_t)(0x18)), \
+ [wdval] "r" ((uint8_t)(val|(__VA_ARGS__+0))) \
+)
+
+
+//for compatibility with avr/wdt.h
+#define wdt_enable(val) WD_SET(WD_RST,val)
+#define wdt_disable() WD_SET(WD_OFF)
+
+
+#endif /* _AVR_WD_H_ */
diff --git a/keyboard.c b/keyboard.c
index 9bba409f1..5c2643c95 100644
--- a/keyboard.c
+++ b/keyboard.c
@@ -27,7 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef MOUSEKEY_ENABLE
#include "mousekey.h"
#endif
-#ifdef USB_EXTRA_ENABLE
+#ifdef EXTRAKEY_ENABLE
#include <util/delay.h>
#endif
@@ -47,7 +47,7 @@ void keyboard_init(void)
void keyboard_proc(void)
{
uint8_t fn_bits = 0;
-#ifdef USB_EXTRA_ENABLE
+#ifdef EXTRAKEY_ENABLE
uint16_t consumer_code = 0;
#endif
@@ -82,7 +82,8 @@ void keyboard_proc(void)
} else if (IS_FN(code)) {
fn_bits |= FN_BIT(code);
}
-#ifdef USB_EXTRA_ENABLE
+// TODO: use table or something
+#ifdef EXTRAKEY_ENABLE
// System Control
else if (code == KB_SYSTEM_POWER) {
#ifdef HOST_PJRC
@@ -170,7 +171,7 @@ void keyboard_proc(void)
// TODO: should send only when changed from last report
if (matrix_is_modified()) {
host_send_keyboard_report();
-#ifdef USB_EXTRA_ENABLE
+#ifdef EXTRAKEY_ENABLE
host_consumer_send(consumer_code);
#endif
#ifdef DEBUG_LED
diff --git a/layer.c b/layer.c
index 8c1648572..3f9e55a15 100755
--- a/layer.c
+++ b/layer.c
@@ -69,10 +69,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// LAYER_ENTER_DELAY: prevent from moving new layer
-#define LAYER_ENTER_DELAY 10
+#define LAYER_ENTER_DELAY 150
// LAYER_SEND_FN_TERM: send keycode if release key in this term
-#define LAYER_SEND_FN_TERM 40
+#define LAYER_SEND_FN_TERM 500
uint8_t default_layer = 0;
diff --git a/macway/Makefile b/macway/Makefile
index 6e7fa7fd9..b8b0a85e1 100644
--- a/macway/Makefile
+++ b/macway/Makefile
@@ -8,10 +8,10 @@ COMMON_DIR = ..
TARGET_DIR = .
# keyboard dependent files
-TARGET_SRC = main_pjrc.c \
- keymap.c \
- matrix.c \
- led.c
+SRC = main.c \
+ keymap.c \
+ matrix.c \
+ led.c
CONFIG_H = config.h
@@ -37,8 +37,8 @@ F_CPU = 16000000
#
MOUSEKEY_ENABLE = yes # Mouse keys
#PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support
-USB_EXTRA_ENABLE = yes # Audio control and System control
-#USB_NKRO_ENABLE = yes # USB Nkey Rollover
+EXTRAKEY_ENABLE = yes # Audio control and System control
+#NKRO_ENABLE = yes # USB Nkey Rollover
@@ -47,5 +47,5 @@ PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex
-include $(COMMON_DIR)/Makefile.pjrc
-include $(COMMON_DIR)/Makefile.common
+include $(COMMON_DIR)/pjrc.mk
+include $(COMMON_DIR)/common.mk
diff --git a/macway/config.h b/macway/config.h
index ff62bfdb0..546067beb 100644
--- a/macway/config.h
+++ b/macway/config.h
@@ -37,8 +37,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* key combination for command */
#define IS_COMMAND() ( \
- keyboard_report->mods == (BIT_LSHIFT | BIT_RSHIFT) || \
- keyboard_report->mods == (BIT_LCTRL | BIT_RSHIFT) \
+ keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_LCTRL) | MOD_BIT(KB_LALT) | MOD_BIT(KB_LGUI)) || \
+ keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)) \
)
diff --git a/macway/doc/back.jpg b/macway/doc/back.jpg
index 0774401f6..0774401f6 100755..100644
--- a/macway/doc/back.jpg
+++ b/macway/doc/back.jpg
Binary files differ
diff --git a/macway/doc/case.jpg b/macway/doc/case.jpg
index c776d5e05..c776d5e05 100755..100644
--- a/macway/doc/case.jpg
+++ b/macway/doc/case.jpg
Binary files differ
diff --git a/macway/doc/keys.jpg b/macway/doc/keys.jpg
index f340ebe8e..f340ebe8e 100755..100644
--- a/macway/doc/keys.jpg
+++ b/macway/doc/keys.jpg
Binary files differ
diff --git a/macway/doc/side.jpg b/macway/doc/side.jpg
index bdf8268f2..bdf8268f2 100755..100644
--- a/macway/doc/side.jpg
+++ b/macway/doc/side.jpg
Binary files differ
diff --git a/macway/doc/switch.jpg b/macway/doc/switch.jpg
index a1500d707..a1500d707 100755..100644
--- a/macway/doc/switch.jpg
+++ b/macway/doc/switch.jpg
Binary files differ
diff --git a/macway/doc/teensy.jpg b/macway/doc/teensy.jpg
index 07207475d..07207475d 100755..100644
--- a/macway/doc/teensy.jpg
+++ b/macway/doc/teensy.jpg
Binary files differ
diff --git a/macway/doc/wiring.jpg b/macway/doc/wiring.jpg
index 0f3490f10..0f3490f10 100755..100644
--- a/macway/doc/wiring.jpg
+++ b/macway/doc/wiring.jpg
Binary files differ
diff --git a/macway/doc/withHHKB.jpg b/macway/doc/withHHKB.jpg
index 9921856e7..9921856e7 100755..100644
--- a/macway/doc/withHHKB.jpg
+++ b/macway/doc/withHHKB.jpg
Binary files differ
diff --git a/macway/doc/withThinkPad.jpg b/macway/doc/withThinkPad.jpg
index 231c61d03..231c61d03 100755..100644
--- a/macway/doc/withThinkPad.jpg
+++ b/macway/doc/withThinkPad.jpg
Binary files differ
diff --git a/main_vusb.c b/main_vusb.c
deleted file mode 100644
index 017888e97..000000000
--- a/main_vusb.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* 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();
- }
-}
diff --git a/mousekey.c b/mousekey.c
index 69b75240f..76bd0fd36 100644..100755
--- a/mousekey.c
+++ b/mousekey.c
@@ -63,10 +63,10 @@ void mousekey_decode(uint8_t code)
else if (code == KB_MS_BTN3) report.buttons |= MOUSE_BTN3;
else if (code == KB_MS_BTN4) report.buttons |= MOUSE_BTN4;
else if (code == KB_MS_BTN5) report.buttons |= MOUSE_BTN5;
- else if (code == KB_MS_WH_UP) report.v += 1;
- else if (code == KB_MS_WH_DOWN) report.v -= 1;
- else if (code == KB_MS_WH_LEFT) report.h -= 1;
- else if (code == KB_MS_WH_RIGHT)report.h += 1;
+ else if (code == KB_MS_WH_UP) report.v += move_unit()/4;
+ else if (code == KB_MS_WH_DOWN) report.v -= move_unit()/4;
+ else if (code == KB_MS_WH_LEFT) report.h -= move_unit()/4;
+ else if (code == KB_MS_WH_RIGHT)report.h += move_unit()/4;
}
bool mousekey_changed(void)
@@ -87,7 +87,7 @@ void mousekey_send(void)
// send immediately when buttun state is changed
if (report.buttons == report_prev.buttons) {
- if (timer_elapsed(last_timer) < 5) {
+ if (timer_elapsed(last_timer) < 100) {
mousekey_clear_report();
return;
}
diff --git a/Makefile.pjrc b/pjrc.mk
index 894d4dcee..0bc47ac93 100644
--- a/Makefile.pjrc
+++ b/pjrc.mk
@@ -1,14 +1,14 @@
OPT_DEFS += -DHOST_PJRC
-SRC = usb_keyboard.c \
+SRC += pjrc.c \
+ usb_keyboard.c \
usb_debug.c \
usb.c \
jump_bootloader.c
-SRC += $(TARGET_SRC)
-# C source file search path
-VPATH = $(TARGET_DIR):$(COMMON_DIR):$(COMMON_DIR)/pjrc
+# Search Path
+VPATH += $(COMMON_DIR):$(COMMON_DIR)/pjrc
# Option modules
@@ -16,6 +16,6 @@ ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE)
SRC += usb_mouse.c
endif
-ifdef USB_EXTRA_ENABLE
+ifdef EXTRAKEY_ENABLE
SRC += usb_extra.c
endif
diff --git a/pjrc/host.c b/pjrc/host.c
index 35d59de80..fcf71d579 100644
--- a/pjrc/host.c
+++ b/pjrc/host.c
@@ -22,7 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#if defined(MOUSEKEY_ENABLE) || defined(PS2_MOUSE_ENABLE)
#include "usb_mouse.h"
#endif
-#ifdef USB_EXTRA_ENABLE
+#ifdef EXTRAKEY_ENABLE
#include "usb_extra.h"
#endif
#include "debug.h"
@@ -30,7 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "util.h"
-#ifdef USB_NKRO_ENABLE
+#ifdef NKRO_ENABLE
bool keyboard_nkro = false;
#endif
@@ -51,7 +51,7 @@ uint8_t host_keyboard_leds(void)
/* keyboard report operations */
void host_add_key(uint8_t key)
{
-#ifdef USB_NKRO_ENABLE
+#ifdef NKRO_ENABLE
if (keyboard_nkro) {
add_key_bit(key);
return;
@@ -109,7 +109,7 @@ uint8_t host_has_anykey(void)
uint8_t host_get_first_key(void)
{
-#ifdef USB_NKRO_ENABLE
+#ifdef NKRO_ENABLE
if (keyboard_nkro) {
uint8_t i = 0;
for (; i < REPORT_KEYS && !keyboard_report->keys[i]; i++)
@@ -133,7 +133,7 @@ void host_mouse_send(report_mouse_t *report)
}
#endif
-#ifdef USB_EXTRA_ENABLE
+#ifdef EXTRAKEY_ENABLE
void host_system_send(uint16_t data)
{
usb_extra_system_send(data);
diff --git a/main_pjrc.c b/pjrc/main.c
index 6ba62040d..f84925d7f 100644
--- a/main_pjrc.c
+++ b/pjrc/main.c
@@ -35,6 +35,8 @@
#ifdef PS2_MOUSE_ENABLE
# include "ps2_mouse.h"
#endif
+#include "host.h"
+#include "pjrc.h"
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
@@ -88,6 +90,7 @@ int main(void)
}
+ host_set_driver(pjrc_driver());
while (1) {
keyboard_proc();
}
diff --git a/pjrc/pjrc.c b/pjrc/pjrc.c
new file mode 100644
index 000000000..0562a12ff
--- /dev/null
+++ b/pjrc/pjrc.c
@@ -0,0 +1,76 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdint.h>
+#include "usb_keyboard.h"
+#include "usb_mouse.h"
+#include "usb_extra.h"
+#include "host_driver.h"
+#include "pjrc.h"
+
+
+/*------------------------------------------------------------------*
+ * Host driver
+ *------------------------------------------------------------------*/
+static uint8_t keyboard_leds(void);
+static void send_keyboard(report_keyboard_t *report);
+static void send_mouse(report_mouse_t *report);
+static void send_system(uint16_t data);
+static void send_consumer(uint16_t data);
+
+static host_driver_t driver = {
+ keyboard_leds,
+ send_keyboard,
+ send_mouse,
+ send_system,
+ send_consumer
+};
+
+host_driver_t *pjrc_driver(void)
+{
+ return &driver;
+}
+
+static uint8_t keyboard_leds(void) {
+ return usb_keyboard_leds;
+}
+
+static void send_keyboard(report_keyboard_t *report)
+{
+ usb_keyboard_send_report(report);
+}
+
+static void send_mouse(report_mouse_t *report)
+{
+#ifdef MOUSE_ENABLE
+ usb_mouse_send(report->x, report->y, report->v, report->h, report->buttons);
+#endif
+}
+
+static void send_system(uint16_t data)
+{
+#ifdef EXTRAKEY_ENABLE
+ usb_extra_system_send(data);
+#endif
+}
+
+static void send_consumer(uint16_t data)
+{
+#ifdef EXTRAKEY_ENABLE
+ usb_extra_consumer_send(data);
+#endif
+}
diff --git a/pjrc/pjrc.h b/pjrc/pjrc.h
new file mode 100644
index 000000000..06e79626f
--- /dev/null
+++ b/pjrc/pjrc.h
@@ -0,0 +1,26 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef PJRC_H
+#define PJRC_H
+
+#include "host_driver.h"
+
+
+host_driver_t *pjrc_driver(void);
+
+#endif
diff --git a/pjrc/usb.c b/pjrc/usb.c
index ea2e71b3d..9989a4b2d 100644
--- a/pjrc/usb.c
+++ b/pjrc/usb.c
@@ -91,18 +91,18 @@ bool suspend = false;
static const uint8_t PROGMEM endpoint_config_table[] = {
// enable, UECFG0X(type, direction), UECFG1X(size, bank, allocation)
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KBD_SIZE) | KBD_BUFFER, // 1
-#ifdef USB_MOUSE_ENABLE
+#ifdef MOUSE_ENABLE
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(MOUSE_SIZE) | MOUSE_BUFFER, // 2
#else
0, // 2
#endif
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER, // 3
-#ifdef USB_EXTRA_ENABLE
+#ifdef EXTRAKEY_ENABLE
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(EXTRA_SIZE) | EXTRA_BUFFER, // 4
#else
0, // 4
#endif
-#ifdef USB_NKRO_ENABLE
+#ifdef NKRO_ENABLE
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KBD2_SIZE) | KBD2_BUFFER, // 5
#else
0, // 5
@@ -176,7 +176,7 @@ static uint8_t PROGMEM keyboard_hid_report_desc[] = {
0x81, 0x00, // Input (Data, Array),
0xc0 // End Collection
};
-#ifdef USB_NKRO_ENABLE
+#ifdef NKRO_ENABLE
static uint8_t PROGMEM keyboard2_hid_report_desc[] = {
0x05, 0x01, // Usage Page (Generic Desktop),
0x09, 0x06, // Usage (Keyboard),
@@ -213,7 +213,7 @@ static uint8_t PROGMEM keyboard2_hid_report_desc[] = {
};
#endif
-#ifdef USB_MOUSE_ENABLE
+#ifdef MOUSE_ENABLE
// Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
// http://www.microchip.com/forums/tm.aspx?high=&m=391435&mpage=1#391521
// http://www.keil.com/forum/15671/
@@ -282,7 +282,7 @@ static uint8_t PROGMEM debug_hid_report_desc[] = {
0xC0 // end collection
};
-#ifdef USB_EXTRA_ENABLE
+#ifdef EXTRAKEY_ENABLE
// audio controls & system controls
// http://www.microsoft.com/whdc/archive/w2kbd.mspx
static uint8_t PROGMEM extra_hid_report_desc[] = {
@@ -318,7 +318,7 @@ static uint8_t PROGMEM extra_hid_report_desc[] = {
#define KBD_HID_DESC_NUM 0
#define KBD_HID_DESC_OFFSET (9+(9+9+7)*KBD_HID_DESC_NUM+9)
-#ifdef USB_MOUSE_ENABLE
+#ifdef MOUSE_ENABLE
# define MOUSE_HID_DESC_NUM (KBD_HID_DESC_NUM + 1)
# define MOUSE_HID_DESC_OFFSET (9+(9+9+7)*MOUSE_HID_DESC_NUM+9)
#else
@@ -328,14 +328,14 @@ static uint8_t PROGMEM extra_hid_report_desc[] = {
#define DEBUG_HID_DESC_NUM (MOUSE_HID_DESC_NUM + 1)
#define DEBUG_HID_DESC_OFFSET (9+(9+9+7)*DEBUG_HID_DESC_NUM+9)
-#ifdef USB_EXTRA_ENABLE
+#ifdef EXTRAKEY_ENABLE
# define EXTRA_HID_DESC_NUM (DEBUG_HID_DESC_NUM + 1)
# define EXTRA_HID_DESC_OFFSET (9+(9+9+7)*EXTRA_HID_DESC_NUM+9)
#else
# define EXTRA_HID_DESC_NUM (DEBUG_HID_DESC_NUM + 0)
#endif
-#ifdef USB_NKRO_ENABLE
+#ifdef NKRO_ENABLE
# define KBD2_HID_DESC_NUM (EXTRA_HID_DESC_NUM + 1)
# define KBD2_HID_DESC_OFFSET (9+(9+9+7)*EXTRA_HID_DESC_NUM+9)
#else
@@ -383,7 +383,7 @@ static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
KBD_SIZE, 0, // wMaxPacketSize
10, // bInterval
-#ifdef USB_MOUSE_ENABLE
+#ifdef MOUSE_ENABLE
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
9, // bLength
4, // bDescriptorType
@@ -444,7 +444,7 @@ static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
DEBUG_TX_SIZE, 0, // wMaxPacketSize
1, // bInterval
-#ifdef USB_EXTRA_ENABLE
+#ifdef EXTRAKEY_ENABLE
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
9, // bLength
4, // bDescriptorType
@@ -473,7 +473,7 @@ static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
10, // bInterval
#endif
-#ifdef USB_NKRO_ENABLE
+#ifdef NKRO_ENABLE
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
9, // bLength
4, // bDescriptorType
@@ -542,17 +542,17 @@ static struct descriptor_list_struct {
// HID/REPORT descriptors
{0x2100, KBD_INTERFACE, config1_descriptor+KBD_HID_DESC_OFFSET, 9},
{0x2200, KBD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
-#ifdef USB_MOUSE_ENABLE
+#ifdef MOUSE_ENABLE
{0x2100, MOUSE_INTERFACE, config1_descriptor+MOUSE_HID_DESC_OFFSET, 9},
{0x2200, MOUSE_INTERFACE, mouse_hid_report_desc, sizeof(mouse_hid_report_desc)},
#endif
{0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9},
{0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)},
-#ifdef USB_EXTRA_ENABLE
+#ifdef EXTRAKEY_ENABLE
{0x2100, EXTRA_INTERFACE, config1_descriptor+EXTRA_HID_DESC_OFFSET, 9},
{0x2200, EXTRA_INTERFACE, extra_hid_report_desc, sizeof(extra_hid_report_desc)},
#endif
-#ifdef USB_NKRO_ENABLE
+#ifdef NKRO_ENABLE
{0x2100, KBD2_INTERFACE, config1_descriptor+KBD2_HID_DESC_OFFSET, 9},
{0x2200, KBD2_INTERFACE, keyboard2_hid_report_desc, sizeof(keyboard2_hid_report_desc)},
#endif
@@ -653,7 +653,7 @@ ISR(USB_GEN_vect)
}
}
/* TODO: should keep IDLE rate on each keyboard interface */
-#ifdef USB_NKRO_ENABLE
+#ifdef NKRO_ENABLE
if (!keyboard_nkro && usb_keyboard_idle_config && (++div4 & 3) == 0) {
#else
if (usb_keyboard_idle_config && (++div4 & 3) == 0) {
@@ -894,7 +894,7 @@ ISR(USB_COM_vect)
}
}
}
-#ifdef USB_MOUSE_ENABLE
+#ifdef MOUSE_ENABLE
if (wIndex == MOUSE_INTERFACE) {
if (bmRequestType == 0xA1) {
if (bRequest == HID_GET_REPORT) {
diff --git a/pjrc/usb.h b/pjrc/usb.h
index a4e40bdd1..82e18f176 100644
--- a/pjrc/usb.h
+++ b/pjrc/usb.h
@@ -120,7 +120,7 @@ void usb_remote_wakeup(void);
#define KBD_REPORT_KEYS (KBD_SIZE - 2)
// secondary keyboard
-#ifdef USB_NKRO_ENABLE
+#ifdef NKRO_ENABLE
#define KBD2_INTERFACE 4
#define KBD2_ENDPOINT 5
#define KBD2_SIZE 16
diff --git a/pjrc/usb_keyboard.c b/pjrc/usb_keyboard.c
index 34e9d495b..e057c77fa 100644
--- a/pjrc/usb_keyboard.c
+++ b/pjrc/usb_keyboard.c
@@ -55,7 +55,7 @@ int8_t usb_keyboard_send_report(report_keyboard_t *report)
{
int8_t result = 0;
-#ifdef USB_NKRO_ENABLE
+#ifdef NKRO_ENABLE
if (keyboard_nkro)
result = send_report(report, KBD2_ENDPOINT, 0, KBD2_REPORT_KEYS);
else
@@ -105,7 +105,7 @@ static inline int8_t send_report(report_keyboard_t *report, uint8_t endpoint, ui
UENUM = endpoint;
}
UEDATX = report->mods;
-#ifdef USB_NKRO_ENABLE
+#ifdef NKRO_ENABLE
if (!keyboard_nkro)
UEDATX = 0;
#else
diff --git a/print.c b/print.c
index d9152971b..558181ea7 100644
--- a/print.c
+++ b/print.c
@@ -29,6 +29,19 @@
bool print_enable = false;
+void print_S(const char *s)
+{
+ if (!print_enable) return;
+ char c;
+
+ while (1) {
+ c = *s++;
+ if (!c) break;
+ if (c == '\n') sendchar('\r');
+ sendchar(c);
+ }
+}
+
void print_P(const char *s)
{
if (!print_enable) return;
diff --git a/print.h b/print.h
index edc540fab..686fa89ac 100644
--- a/print.h
+++ b/print.h
@@ -24,6 +24,7 @@
#ifndef PRINT_H__
#define PRINT_H__ 1
+#include <stdint.h>
#include <stdbool.h>
#include <avr/pgmspace.h>
@@ -34,6 +35,7 @@ extern bool print_enable;
// the string is automatically placed into flash memory :)
#define print(s) print_P(PSTR(s))
+void print_S(const char *s);
void print_P(const char *s);
void phex(unsigned char c);
void phex16(unsigned int i);
diff --git a/ps2_usb/Makefile b/ps2_usb/Makefile
index a548b56d4..7352f6b13 100644
--- a/ps2_usb/Makefile
+++ b/ps2_usb/Makefile
@@ -13,11 +13,11 @@ COMMON_DIR = ..
TARGET_DIR = .
# keyboard dependent files
-TARGET_SRC = main_pjrc.c \
- keymap.c \
- matrix.c \
- led.c \
- ps2.c
+SRC = main.c \
+ keymap.c \
+ matrix.c \
+ led.c \
+ ps2.c
CONFIG_H = config_pjrc.h
@@ -42,8 +42,8 @@ F_CPU = 16000000
# comment out to disable the options.
#
MOUSEKEY_ENABLE = yes # Mouse keys
-USB_EXTRA_ENABLE = yes # Audio control and System control
-USB_NKRO_ENABLE = yes # USB Nkey Rollover
+EXTRAKEY_ENABLE = yes # Audio control and System control
+NKRO_ENABLE = yes # USB Nkey Rollover
@@ -52,5 +52,5 @@ PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex
-include $(COMMON_DIR)/Makefile.pjrc
-include $(COMMON_DIR)/Makefile.common
+include $(COMMON_DIR)/pjrc.mk
+include $(COMMON_DIR)/common.mk
diff --git a/ps2_usb/Makefile.vusb b/ps2_usb/Makefile.vusb
index ff86d7998..5b6978f01 100644
--- a/ps2_usb/Makefile.vusb
+++ b/ps2_usb/Makefile.vusb
@@ -13,11 +13,11 @@ COMMON_DIR = ..
TARGET_DIR = .
# keyboard dependent files
-TARGET_SRC = main_vusb.c \
- keymap.c \
- matrix.c \
- led.c \
- ps2_usart.c
+SRC = main.c \
+ keymap.c \
+ matrix.c \
+ led.c \
+ ps2_usart.c
CONFIG_H = config_vusb.h
@@ -48,8 +48,9 @@ F_CPU = 20000000
# comment out to disable the options.
#
MOUSEKEY_ENABLE = yes # Mouse keys
-USB_EXTRA_ENABLE = yes # Audio control and System control
-#USB_NKRO_ENABLE = yes # USB Nkey Rollover
+EXTRAKEY_ENABLE = yes # Audio control and System control
+#NKRO_ENABLE = yes # USB Nkey Rollover
+NO_UART = yes # UART is unavailable
@@ -85,5 +86,5 @@ PROGRAM_CMD = $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE
-include $(COMMON_DIR)/Makefile.vusb
-include $(COMMON_DIR)/Makefile.common
+include $(COMMON_DIR)/vusb.mk
+include $(COMMON_DIR)/common.mk
diff --git a/ps2_usb/config_pjrc.h b/ps2_usb/config_pjrc.h
index 56917beec..883ffab27 100644
--- a/ps2_usb/config_pjrc.h
+++ b/ps2_usb/config_pjrc.h
@@ -35,8 +35,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* key combination for command */
#define IS_COMMAND() ( \
- keyboard_report->mods == (BIT_LSHIFT | BIT_RSHIFT) || \
- keyboard_report->mods == (BIT_LCTRL | BIT_RSHIFT) \
+ keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)) || \
+ keyboard_report->mods == (MOD_BIT(KB_LCTRL) | MOD_BIT(KB_RSHIFT)) \
)
diff --git a/ps2_usb/config_vusb.h b/ps2_usb/config_vusb.h
index 426bb61e2..afd2f7911 100644
--- a/ps2_usb/config_vusb.h
+++ b/ps2_usb/config_vusb.h
@@ -35,8 +35,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* key combination for command */
#define IS_COMMAND() ( \
- keyboard_report->mods == (BIT_LSHIFT | BIT_RSHIFT) || \
- keyboard_report->mods == (BIT_LCTRL | BIT_RSHIFT) \
+ keyboard_report->mods == (MOD_BIT(KB_LSHIFT) | MOD_BIT(KB_RSHIFT)) || \
+ keyboard_report->mods == (MOD_BIT(KB_LCTRL) | MOD_BIT(KB_RSHIFT)) \
)
diff --git a/ps2_usb/keymap.c b/ps2_usb/keymap.c
index ef11daa28..e84e8c29b 100644
--- a/ps2_usb/keymap.c
+++ b/ps2_usb/keymap.c
@@ -124,7 +124,7 @@ static const uint8_t PROGMEM fn_layer[] = {
static const uint8_t PROGMEM fn_keycode[] = {
KB_SCLN, // Fn0
KB_SLSH, // Fn1
- KB_A, // Fn2
+ KB_NO, // Fn2
KB_NO, // Fn3
KB_NO, // Fn4
KB_NO, // Fn5
@@ -154,7 +154,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
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,
+ CAPS,A, 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
),
@@ -204,7 +204,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,BRK,
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,
+ CAPS,NO, 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
),
diff --git a/ps2_usb/matrix.c b/ps2_usb/matrix.c
index 5d73cc2a3..1aac3f866 100644
--- a/ps2_usb/matrix.c
+++ b/ps2_usb/matrix.c
@@ -349,6 +349,7 @@ uint8_t matrix_scan(void)
default:
state = INIT;
}
+ phex(code);
}
return 1;
}
diff --git a/report.h b/report.h
new file mode 100644
index 000000000..b85b86c5f
--- /dev/null
+++ b/report.h
@@ -0,0 +1,96 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef REPORT_H
+#define REPORT_H
+
+#include <stdint.h>
+
+
+/* report id */
+#define REPORT_ID_MOUSE 1
+#define REPORT_ID_SYSTEM 2
+#define REPORT_ID_CONSUMER 3
+
+/* mouse buttons */
+#define MOUSE_BTN1 (1<<0)
+#define MOUSE_BTN2 (1<<1)
+#define MOUSE_BTN3 (1<<2)
+#define MOUSE_BTN4 (1<<3)
+#define MOUSE_BTN5 (1<<4)
+
+// Consumer Page(0x0C)
+// following are supported by Windows: http://msdn.microsoft.com/en-us/windows/hardware/gg463372.aspx
+#define AUDIO_MUTE 0x00E2
+#define AUDIO_VOL_UP 0x00E9
+#define AUDIO_VOL_DOWN 0x00EA
+#define TRANSPORT_NEXT_TRACK 0x00B5
+#define TRANSPORT_PREV_TRACK 0x00B6
+#define TRANSPORT_STOP 0x00B7
+#define TRANSPORT_PLAY_PAUSE 0x00CD
+#define AL_CC_CONFIG 0x0183
+#define AL_EMAIL 0x018A
+#define AL_CALCULATOR 0x0192
+#define AL_LOCAL_BROWSER 0x0194
+#define AC_SEARCH 0x0221
+#define AC_HOME 0x0223
+#define AC_BACK 0x0224
+#define AC_FORWARD 0x0225
+#define AC_STOP 0x0226
+#define AC_REFRESH 0x0227
+#define AC_BOOKMARKS 0x022A
+// supplement for Bluegiga iWRAP HID(not supported by Windows?)
+#define AL_LOCK 0x019E
+#define TRANSPORT_RECORD 0x00B2
+#define TRANSPORT_REWIND 0x00B4
+#define TRANSPORT_EJECT 0x00B8
+#define AC_MINIMIZE 0x0206
+
+// Generic Desktop Page(0x01)
+#define SYSTEM_POWER_DOWN 0x0081
+#define SYSTEM_SLEEP 0x0082
+#define SYSTEM_WAKE_UP 0x0083
+
+
+// key report size(NKRO or boot mode)
+#if defined(HOST_PJRC)
+# include "usb.h"
+# if defined(KBD2_REPORT_KEYS) && KBD2_REPORT_KEYS > KBD_REPORT_KEYS
+# define REPORT_KEYS KBD2_REPORT_KEYS
+# else
+# define REPORT_KEYS KBD_REPORT_KEYS
+# endif
+#else
+# define REPORT_KEYS 6
+#endif
+
+typedef struct {
+ uint8_t mods;
+ uint8_t rserved;
+ uint8_t keys[REPORT_KEYS];
+} report_keyboard_t;
+
+typedef struct {
+ uint8_t report_id;
+ uint8_t buttons;
+ int8_t x;
+ int8_t y;
+ int8_t v;
+ int8_t h;
+} report_mouse_t;
+
+#endif
diff --git a/Makefile.rules b/rules.mk
index f1d0a301c..f1d0a301c 100644
--- a/Makefile.rules
+++ b/rules.mk
diff --git a/sendchar.h b/sendchar.h
index b31665441..7c81303c7 100644
--- a/sendchar.h
+++ b/sendchar.h
@@ -18,8 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef SENDCHAR_H
#define SENDCHAR_H
+#include <stdint.h>
+
+
/* transmit a character. return 0 on success, -1 on error. */
int8_t sendchar(uint8_t c);
#endif
-
diff --git a/vusb/host_vusb.h b/sendchar_null.c
index be9886e88..293330622 100644
--- a/vusb/host_vusb.h
+++ b/sendchar_null.c
@@ -14,10 +14,10 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "sendchar.h"
-#ifndef HOST_VUSB_H
-#define HOST_VUSB_H
-void host_vusb_keyboard_send(void);
-
-#endif
+int8_t sendchar(uint8_t c)
+{
+ return 0;
+}
diff --git a/sendchar_uart.c b/sendchar_uart.c
new file mode 100644
index 000000000..0241859eb
--- /dev/null
+++ b/sendchar_uart.c
@@ -0,0 +1,25 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "uart.h"
+#include "sendchar.h"
+
+
+int8_t sendchar(uint8_t c)
+{
+ uart_putchar(c);
+ return 0;
+}
diff --git a/timer.c b/timer.c
index edbb4409d..48a38c9b6 100644
--- a/timer.c
+++ b/timer.c
@@ -20,17 +20,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h>
#include "timer.h"
+
+// counter resolution 1ms
volatile uint16_t timer_count = 0;
-// Configure timer 0 to generate a timer overflow interrupt every
-// 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock
-// This demonstrates how to use interrupts to implement a simple
-// inactivity timeout.
void timer_init(void)
{
- TCCR0A = 0x00;
+ // Timer0 CTC mode
+ TCCR0A = 0x02;
+
+#if TIMER_PRESCALER == 1
+ TCCR0B = 0x01;
+#elif TIMER_PRESCALER == 8
+ TCCR0B = 0x02;
+#elif TIMER_PRESCALER == 64
+ TCCR0B = 0x03;
+#elif TIMER_PRESCALER == 256
+ TCCR0B = 0x04;
+#elif TIMER_PRESCALER == 1024
TCCR0B = 0x05;
- TIMSK0 = (1<<TOIE0);
+#else
+# error "Timer prescaler value is NOT vaild."
+#endif
+
+ OCR0A = TIMER_RAW_TOP;
+ TIMSK0 = (1<<OCIE0A);
}
inline
@@ -65,14 +79,11 @@ uint16_t timer_elapsed(uint16_t last)
t = timer_count;
SREG = sreg;
- return TIMER_DIFF(t, last);
+ return TIMER_DIFF_MS(t, last);
}
-// This interrupt routine is run approx 61 times per second.
-// A very simple inactivity timeout is implemented, where we
-// will send a space character and print a message to the
-// hid_listen debug message window.
-ISR(TIMER0_OVF_vect)
+// excecuted once per 1ms.(excess for just timer count?)
+ISR(TIMER0_COMPA_vect)
{
timer_count++;
}
diff --git a/timer.h b/timer.h
index 402d4acc1..f9e8181e6 100644
--- a/timer.h
+++ b/timer.h
@@ -20,7 +20,26 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h>
-#define TIMER_DIFF(a, b) ((a) >= (b) ? (a) - (b) : UINT16_MAX - (b) + (a))
+#ifndef TIMER_PRESCALER
+# if F_CPU > 16000000
+# define TIMER_PRESCALER 256
+# elif F_CPU >= 4000000
+# define TIMER_PRESCALER 64
+# else
+# define TIMER_PRESCALER 8
+# endif
+#endif
+#define TIMER_RAW_FREQ (F_CPU/TIMER_PRESCALER)
+#define TIMER_RAW TCNT0
+#define TIMER_RAW_TOP (TIMER_RAW_FREQ/1000)
+
+#if (TIMER_RAW_TOP > 255)
+# error "Timer0 can't count 1ms at this clock freq. Use larger prescaler."
+#endif
+
+#define TIMER_DIFF(a, b, max) ((a) >= (b) ? (a) - (b) : (max) - (b) + (a))
+#define TIMER_DIFF_RAW(a, b) TIMER_DIFF(a, b, UINT8_MAX)
+#define TIMER_DIFF_MS(a, b) TIMER_DIFF(a, b, UINT16_MAX)
extern volatile uint16_t timer_count;
diff --git a/uart.c b/uart.c
new file mode 100644
index 000000000..c17649b08
--- /dev/null
+++ b/uart.c
@@ -0,0 +1,129 @@
+// TODO: Teensy support(ATMega32u4/AT90USB128)
+// Fixed for Arduino Duemilanove ATmega168p by Jun Wako
+/* UART Example for Teensy USB Development Board
+ * http://www.pjrc.com/teensy/
+ * Copyright (c) 2009 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.
+ */
+
+// Version 1.0: Initial Release
+// Version 1.1: Add support for Teensy 2.0, minor optimizations
+
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+#include "uart.h"
+
+// These buffers may be any size from 2 to 256 bytes.
+#define RX_BUFFER_SIZE 64
+#define TX_BUFFER_SIZE 40
+
+static volatile uint8_t tx_buffer[TX_BUFFER_SIZE];
+static volatile uint8_t tx_buffer_head;
+static volatile uint8_t tx_buffer_tail;
+static volatile uint8_t rx_buffer[RX_BUFFER_SIZE];
+static volatile uint8_t rx_buffer_head;
+static volatile uint8_t rx_buffer_tail;
+
+// Initialize the UART
+void uart_init(uint32_t baud)
+{
+ cli();
+ UBRR0 = (F_CPU / 4 / baud - 1) / 2;
+ UCSR0A = (1<<U2X0);
+ UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0);
+ UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
+ tx_buffer_head = tx_buffer_tail = 0;
+ rx_buffer_head = rx_buffer_tail = 0;
+ sei();
+}
+
+// Transmit a byte
+void uart_putchar(uint8_t c)
+{
+ uint8_t i;
+
+ i = tx_buffer_head + 1;
+ if (i >= TX_BUFFER_SIZE) i = 0;
+ while (tx_buffer_tail == i) ; // wait until space in buffer
+ //cli();
+ tx_buffer[i] = c;
+ tx_buffer_head = i;
+ UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0) | (1<<UDRIE0);
+ //sei();
+}
+
+// Receive a byte
+uint8_t uart_getchar(void)
+{
+ uint8_t c, i;
+
+ while (rx_buffer_head == rx_buffer_tail) ; // wait for character
+ i = rx_buffer_tail + 1;
+ if (i >= RX_BUFFER_SIZE) i = 0;
+ c = rx_buffer[i];
+ rx_buffer_tail = i;
+ return c;
+}
+
+// Return the number of bytes waiting in the receive buffer.
+// Call this before uart_getchar() to check if it will need
+// to wait for a byte to arrive.
+uint8_t uart_available(void)
+{
+ uint8_t head, tail;
+
+ head = rx_buffer_head;
+ tail = rx_buffer_tail;
+ if (head >= tail) return head - tail;
+ return RX_BUFFER_SIZE + head - tail;
+}
+
+// Transmit Interrupt
+ISR(USART_UDRE_vect)
+{
+ uint8_t i;
+
+ if (tx_buffer_head == tx_buffer_tail) {
+ // buffer is empty, disable transmit interrupt
+ UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0);
+ } else {
+ i = tx_buffer_tail + 1;
+ if (i >= TX_BUFFER_SIZE) i = 0;
+ UDR0 = tx_buffer[i];
+ tx_buffer_tail = i;
+ }
+}
+
+// Receive Interrupt
+ISR(USART_RX_vect)
+{
+ uint8_t c, i;
+
+ c = UDR0;
+ i = rx_buffer_head + 1;
+ if (i >= RX_BUFFER_SIZE) i = 0;
+ if (i != rx_buffer_tail) {
+ rx_buffer[i] = c;
+ rx_buffer_head = i;
+ }
+}
+
diff --git a/uart.h b/uart.h
new file mode 100644
index 000000000..41136a396
--- /dev/null
+++ b/uart.h
@@ -0,0 +1,11 @@
+#ifndef _uart_included_h_
+#define _uart_included_h_
+
+#include <stdint.h>
+
+void uart_init(uint32_t baud);
+void uart_putchar(uint8_t c);
+uint8_t uart_getchar(void);
+uint8_t uart_available(void);
+
+#endif
diff --git a/usb_keycodes.h b/usb_keycodes.h
index 8b8d4d350..391d21f20 100644
--- a/usb_keycodes.h
+++ b/usb_keycodes.h
@@ -16,7 +16,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
- * Key codes from HID Keyboard/Keypad Page
+ * Key codes: HID Keyboard/Keypad Page(0x07)
* http://www.usb.org/developers/devclass_docs/Hut1_12.pdf
*/
#ifndef USB_KEYCODES_H
@@ -353,7 +353,8 @@ enum keycodes {
KB_CRSEL,
KB_EXSEL,
- /* NOTE: uses 0xB0-DF for special keycodes */
+ /* NOTE: 0xB0-DF are used as special_keycodes */
+#if 0
KB_KP_00 = 0xB0,
KB_KP_000,
KB_THOUSANDS_SEPARATOR,
@@ -400,6 +401,7 @@ enum keycodes {
KB_KP_OCTAL,
KB_KP_DECIMAL,
KB_KP_HEXADECIMAL,
+#endif
/* Modifiers */
KB_LCTRL = 0xE0,
@@ -411,7 +413,7 @@ enum keycodes {
KB_RALT,
KB_RGUI,
- /* NOTE: uses 0xE8-FF for special keycodes */
+ /* NOTE: 0xE8-FF are used as special_keycodes */
};
#endif /* USB_KEYCODES_H */
diff --git a/vusb.mk b/vusb.mk
new file mode 100644
index 000000000..7fd5dc054
--- /dev/null
+++ b/vusb.mk
@@ -0,0 +1,17 @@
+OPT_DEFS += -DHOST_VUSB
+
+SRC += vusb.c \
+ usbdrv.c \
+ usbdrvasm.S \
+ oddebug.c
+
+ifdef NO_UART
+SRC += sendchar_null.c
+else
+SRC += sendchar_uart.c \
+ uart.c
+endif
+
+
+# Search Path
+VPATH += $(COMMON_DIR)/vusb:$(COMMON_DIR)/vusb/usbdrv
diff --git a/vusb/main.c b/vusb/main.c
new file mode 100644
index 000000000..1bf9035b3
--- /dev/null
+++ b/vusb/main.c
@@ -0,0 +1,99 @@
+/* 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/interrupt.h>
+#include <avr/wdt.h>
+#include <avr/sleep.h>
+#include <util/delay.h>
+#include "usbdrv.h"
+#include "oddebug.h"
+#include "vusb.h"
+#include "keyboard.h"
+#include "host.h"
+#include "timer.h"
+#include "uart.h"
+#include "debug.h"
+
+
+#define UART_BAUD_RATE 115200
+
+
+/* This is from main.c of USBaspLoader */
+static void initForUsbConnectivity(void)
+{
+ uint8_t i = 0;
+
+ usbInit();
+ /* enforce USB re-enumerate: */
+ usbDeviceDisconnect(); /* do this while interrupts are disabled */
+ while(--i){ /* fake USB disconnect for > 250 ms */
+ wdt_reset();
+ _delay_ms(1);
+ }
+ usbDeviceConnect();
+ sei();
+}
+
+int main(void)
+{
+ bool suspended = false;
+#if USB_COUNT_SOF
+ uint16_t last_timer = timer_read();
+#endif
+
+ CLKPR = 0x80, CLKPR = 0;
+#ifndef PS2_USE_USART
+ uart_init(UART_BAUD_RATE);
+#endif
+
+ debug_enable = true;
+ print_enable = true;
+
+ debug("keyboard_init()\n");
+ keyboard_init();
+ host_set_driver(vusb_driver());
+
+ debug("initForUsbConnectivity()\n");
+ initForUsbConnectivity();
+
+ debug("main loop\n");
+ while (1) {
+#if USB_COUNT_SOF
+ if (usbSofCount != 0) {
+ suspended = false;
+ usbSofCount = 0;
+ last_timer = timer_read();
+ } else {
+ // Suspend when no SOF in 3ms-10ms(7.1.7.4 Suspending of USB1.1)
+ if (timer_elapsed(last_timer) > 5) {
+ suspended = true;
+/*
+ uart_putchar('S');
+ _delay_ms(1);
+ cli();
+ set_sleep_mode(SLEEP_MODE_PWR_DOWN);
+ sleep_enable();
+ sleep_bod_disable();
+ sei();
+ sleep_cpu();
+ sleep_disable();
+ _delay_ms(10);
+ uart_putchar('W');
+*/
+ }
+ }
+#endif
+ if (!suspended)
+ usbPoll();
+ keyboard_proc();
+ if (!suspended)
+ vusb_transfer_keyboard();
+ }
+}
diff --git a/vusb/host.c b/vusb/vusb.c
index 8cd38d0b3..638611f32 100644
--- a/vusb/host.c
+++ b/vusb/vusb.c
@@ -16,133 +16,69 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
-#include <avr/interrupt.h>
#include "usbdrv.h"
#include "usbconfig.h"
-#include "print.h"
-#include "usb_keycodes.h"
#include "host.h"
-#include "host_vusb.h"
+#include "report.h"
+#include "print.h"
#include "debug.h"
+#include "host_driver.h"
+#include "vusb.h"
-static report_keyboard_t report0;
-static report_keyboard_t report1;
-report_keyboard_t *keyboard_report = &report0;
-report_keyboard_t *keyboard_report_prev = &report1;
-
-static uint8_t keyboard_leds = 0;
-static uchar idleRate = 0;
-
-uint8_t host_keyboard_leds(void)
-{
- return keyboard_leds;
-}
-
-
-/*------------------------------------------------------------------*
- * Keyboard report operations
- *------------------------------------------------------------------*/
-void host_add_key(uint8_t code)
-{
- int8_t i = 0;
- int8_t empty = -1;
- for (; i < REPORT_KEYS; i++) {
- if (keyboard_report_prev->keys[i] == code) {
- keyboard_report->keys[i] = code;
- break;
- }
- if (empty == -1 && keyboard_report_prev->keys[i] == KB_NO && keyboard_report->keys[i] == KB_NO) {
- empty = i;
- }
- }
- if (i == REPORT_KEYS && empty != -1) {
- keyboard_report->keys[empty] = code;
- }
-}
-
-void host_add_mod_bit(uint8_t mod)
-{
- keyboard_report->mods |= mod;
-}
-
-void host_set_mods(uint8_t mods)
-{
- keyboard_report->mods = mods;
-}
-
-void host_add_code(uint8_t code)
-{
- if (IS_MOD(code)) {
- host_add_mod_bit(MOD_BIT(code));
- } else {
- host_add_key(code);
- }
-}
-
-void host_swap_keyboard_report(void)
-{
- uint8_t sreg = SREG;
- cli();
- report_keyboard_t *tmp = keyboard_report_prev;
- keyboard_report_prev = keyboard_report;
- keyboard_report = tmp;
- SREG = sreg;
-}
+static uint8_t vusb_keyboard_leds = 0;
+static uint8_t vusb_idle_rate = 0;
-void host_clear_keyboard_report(void)
-{
- keyboard_report->mods = 0;
- for (int8_t i = 0; i < REPORT_KEYS; i++) {
- keyboard_report->keys[i] = 0;
- }
-}
+/* Keyboard report send buffer */
+#define KBUF_SIZE 16
+static report_keyboard_t kbuf[KBUF_SIZE];
+static uint8_t kbuf_head = 0;
+static uint8_t kbuf_tail = 0;
-uint8_t host_has_anykey(void)
-{
- uint8_t cnt = 0;
- for (int i = 0; i < REPORT_KEYS; i++) {
- if (keyboard_report->keys[i])
- cnt++;
- }
- return cnt;
-}
-uint8_t host_get_first_key(void)
+/* transfer keyboard report from buffer */
+void vusb_transfer_keyboard(void)
{
-#ifdef USB_NKRO_ENABLE
- if (keyboard_nkro) {
- uint8_t i = 0;
- for (; i < REPORT_KEYS && !keyboard_report->keys[i]; i++)
- ;
- return i<<3 | biton(keyboard_report->keys[i]);
+ if (usbInterruptIsReady()) {
+ if (kbuf_head != kbuf_tail) {
+ usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t));
+ kbuf_tail = (kbuf_tail + 1) % KBUF_SIZE;
+ }
}
-#endif
- return keyboard_report->keys[0];
}
/*------------------------------------------------------------------*
- * Keyboard report send buffer
+ * Host driver
*------------------------------------------------------------------*/
-#define KBUF_SIZE 16
-static report_keyboard_t kbuf[KBUF_SIZE];
-static uint8_t kbuf_head = 0;
-static uint8_t kbuf_tail = 0;
+static uint8_t keyboard_leds(void);
+static void send_keyboard(report_keyboard_t *report);
+static void send_mouse(report_mouse_t *report);
+static void send_system(uint16_t data);
+static void send_consumer(uint16_t data);
+
+static host_driver_t driver = {
+ keyboard_leds,
+ send_keyboard,
+ send_mouse,
+ send_system,
+ send_consumer
+};
-void host_vusb_keyboard_send(void)
+host_driver_t *vusb_driver(void)
{
- if (usbInterruptIsReady() && kbuf_head != kbuf_tail) {
- usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t));
- kbuf_tail = (kbuf_tail + 1) % KBUF_SIZE;
- }
+ return &driver;
}
-void host_send_keyboard_report(void)
+static uint8_t keyboard_leds(void) {
+ return vusb_keyboard_leds;
+}
+
+static void send_keyboard(report_keyboard_t *report)
{
uint8_t next = (kbuf_head + 1) % KBUF_SIZE;
if (next != kbuf_tail) {
- kbuf[kbuf_head] = *keyboard_report;
+ kbuf[kbuf_head] = *report;
kbuf_head = next;
} else {
debug("kbuf: full\n");
@@ -150,20 +86,15 @@ void host_send_keyboard_report(void)
}
-#if defined(MOUSEKEY_ENABLE) || defined(PS2_MOUSE_ENABLE)
-void host_mouse_send(report_mouse_t *report)
+static void send_mouse(report_mouse_t *report)
{
report->report_id = REPORT_ID_MOUSE;
if (usbInterruptIsReady3()) {
usbSetInterrupt3((void *)report, sizeof(*report));
- } else {
- debug("Int3 not ready\n");
}
}
-#endif
-#ifdef USB_EXTRA_ENABLE
-void host_system_send(uint16_t data)
+static void send_system(uint16_t data)
{
// Not need static?
static uint8_t report[] = { REPORT_ID_SYSTEM, 0, 0 };
@@ -171,12 +102,10 @@ void host_system_send(uint16_t data)
report[2] = (data>>8)&0xFF;
if (usbInterruptIsReady3()) {
usbSetInterrupt3((void *)&report, sizeof(report));
- } else {
- debug("Int3 not ready\n");
}
}
-void host_consumer_send(uint16_t data)
+static void send_consumer(uint16_t data)
{
static uint16_t last_data = 0;
if (data == last_data) return;
@@ -188,11 +117,8 @@ void host_consumer_send(uint16_t data)
report[2] = (data>>8)&0xFF;
if (usbInterruptIsReady3()) {
usbSetInterrupt3((void *)&report, sizeof(report));
- } else {
- debug("Int3 not ready\n");
}
}
-#endif
@@ -213,32 +139,36 @@ usbRequest_t *rq = (void *)data;
if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */
if(rq->bRequest == USBRQ_HID_GET_REPORT){
- debug(" GET_REPORT");
+ debug("GET_REPORT:");
/* we only have one report type, so don't look at wValue */
usbMsgPtr = (void *)keyboard_report_prev;
return sizeof(*keyboard_report_prev);
}else if(rq->bRequest == USBRQ_HID_GET_IDLE){
- debug(" GET_IDLE: ");
- debug_hex(idleRate);
- usbMsgPtr = &idleRate;
+ debug("GET_IDLE: ");
+ //debug_hex(vusb_idle_rate);
+ usbMsgPtr = &vusb_idle_rate;
return 1;
}else if(rq->bRequest == USBRQ_HID_SET_IDLE){
- idleRate = rq->wValue.bytes[1];
- debug(" SET_IDLE: ");
- debug_hex(idleRate);
+ vusb_idle_rate = rq->wValue.bytes[1];
+ debug("SET_IDLE: ");
+ debug_hex(vusb_idle_rate);
}else if(rq->bRequest == USBRQ_HID_SET_REPORT){
- //debug(" SET_REPORT: ");
+ debug("SET_REPORT: ");
+ // Report Type: 0x02(Out)/ReportID: 0x00(none) && Interface: 0(keyboard)
if (rq->wValue.word == 0x0200 && rq->wIndex.word == 0) {
+ debug("SET_LED: ");
last_req.kind = SET_LED;
last_req.len = rq->wLength.word;
}
return USB_NO_MSG; // to get data in usbFunctionWrite
+ } else {
+ debug("UNKNOWN:");
}
- debug("\n");
}else{
- debug("VENDOR\n");
+ debug("VENDOR:");
/* no vendor specific requests implemented */
}
+ debug("\n");
return 0; /* default for not implemented requests: return no data back to host */
}
@@ -249,8 +179,10 @@ uchar usbFunctionWrite(uchar *data, uchar len)
}
switch (last_req.kind) {
case SET_LED:
- //debug("SET_LED\n");
- keyboard_leds = data[0];
+ debug("SET_LED: ");
+ debug_hex(data[0]);
+ debug("\n");
+ vusb_keyboard_leds = data[0];
last_req.len = 0;
return 1;
break;
@@ -484,13 +416,14 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq)
{
usbMsgLen_t len = 0;
+/*
debug("usbFunctionDescriptor: ");
debug_hex(rq->bmRequestType); debug(" ");
debug_hex(rq->bRequest); debug(" ");
debug_hex16(rq->wValue.word); debug(" ");
debug_hex16(rq->wIndex.word); debug(" ");
debug_hex16(rq->wLength.word); debug("\n");
-
+*/
switch (rq->wValue.bytes[1]) {
#if USB_CFG_DESCR_PROPS_CONFIGURATION
case USBDESCR_CONFIG:
@@ -499,8 +432,16 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq)
break;
#endif
case USBDESCR_HID:
- usbMsgPtr = (unsigned char *)(usbDescriptorConfiguration + 18);
- len = 9;
+ switch (rq->wValue.bytes[0]) {
+ case 0:
+ usbMsgPtr = (unsigned char *)(usbDescriptorConfiguration + 9 + 9);
+ len = 9;
+ break;
+ case 1:
+ usbMsgPtr = (unsigned char *)(usbDescriptorConfiguration + 9 + (9 + 9 + 7) + 9);
+ len = 9;
+ break;
+ }
break;
case USBDESCR_HID_REPORT:
/* interface index */
@@ -516,6 +457,6 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq)
}
break;
}
- debug("desc len: "); debug_hex(len); debug("\n");
+ //debug("desc len: "); debug_hex(len); debug("\n");
return len;
}
diff --git a/vusb/vusb.h b/vusb/vusb.h
new file mode 100644
index 000000000..5accf233b
--- /dev/null
+++ b/vusb/vusb.h
@@ -0,0 +1,27 @@
+/*
+Copyright 2011 Jun Wako <wakojun@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef VUSB_H
+#define VUSB_H
+
+#include "host_driver.h"
+
+
+host_driver_t *vusb_driver(void);
+void vusb_transfer_keyboard(void);
+
+#endif