diff --git a/common.mk b/common.mk index d0e04df8..9bf34f2b 100644 --- a/common.mk +++ b/common.mk @@ -1,22 +1,23 @@ -SRC += host.c \ - keyboard.c \ - command.c \ - layer.c \ - timer.c \ - print.c \ - bootloader.c \ - util.c +COMMON_DIR = common +SRC += $(COMMON_DIR)/host.c \ + $(COMMON_DIR)/keyboard.c \ + $(COMMON_DIR)/command.c \ + $(COMMON_DIR)/layer.c \ + $(COMMON_DIR)/timer.c \ + $(COMMON_DIR)/print.c \ + $(COMMON_DIR)/bootloader.c \ + $(COMMON_DIR)/util.c # Option modules ifdef MOUSEKEY_ENABLE - SRC += mousekey.c + SRC += $(COMMON_DIR)/mousekey.c OPT_DEFS += -DMOUSEKEY_ENABLE endif ifdef PS2_MOUSE_ENABLE - SRC += ps2.c \ - ps2_mouse.c + SRC += $(COMMON_DIR)/ps2.c \ + $(COMMON_DIR)/ps2_mouse.c OPT_DEFS += -DPS2_MOUSE_ENABLE endif diff --git a/common/bootloader.c b/common/bootloader.c index 5cbfc72e..612b9496 100644 --- a/common/bootloader.c +++ b/common/bootloader.c @@ -1,22 +1,87 @@ -/* -Copyright 2011 Jun Wako +#include +#include +#include +#include "bootloader.h" -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. +/* Start Bootloader from Application + * See + * http://www.pjrc.com/teensy/jump_to_bootloader.html + * http://www.fourwalledcubicle.com/files/LUFA/Doc/120219/html/_page__software_bootloader_start.html + */ -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. +// TODO: support usbasp +/* Boot Section Size in bytes + * Teensy halfKay 512 + * Atmel DFU loader 4096 + * LUFA bootloader 4096 + */ +#ifndef BOOT_SIZE +#define BOOT_SIZE 512 +#endif -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ +#define FLASH_SIZE (FLASHEND + 1) +#define BOOTLOADER_START (FLASHEND - BOOT_SIZE) -#include "bootloader.h" +void bootloader_jump(void) { + cli(); + + // + //Teensy + // +#if defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) + // disable watchdog, if enabled + // disable all peripherals + UDCON = 1; + USBCON = (1<send_system)(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; diff --git a/common/keyboard.c b/common/keyboard.c index 5c2643c9..25f32eb0 100644 --- a/common/keyboard.c +++ b/common/keyboard.c @@ -49,6 +49,7 @@ void keyboard_proc(void) uint8_t fn_bits = 0; #ifdef EXTRAKEY_ENABLE uint16_t consumer_code = 0; + uint16_t system_code = 0; #endif matrix_scan(); @@ -89,22 +90,13 @@ void keyboard_proc(void) #ifdef HOST_PJRC if (suspend && remote_wakeup) { usb_remote_wakeup(); - } else { - host_system_send(SYSTEM_POWER_DOWN); } -#else - host_system_send(SYSTEM_POWER_DOWN); #endif - host_system_send(0); - _delay_ms(500); + system_code = SYSTEM_POWER_DOWN; } else if (code == KB_SYSTEM_SLEEP) { - host_system_send(SYSTEM_SLEEP); - host_system_send(0); - _delay_ms(500); + system_code = SYSTEM_SLEEP; } else if (code == KB_SYSTEM_WAKE) { - host_system_send(SYSTEM_WAKE_UP); - host_system_send(0); - _delay_ms(500); + system_code = SYSTEM_WAKE_UP; } // Consumer Page else if (code == KB_AUDIO_MUTE) { @@ -173,6 +165,7 @@ void keyboard_proc(void) host_send_keyboard_report(); #ifdef EXTRAKEY_ENABLE host_consumer_send(consumer_code); + host_system_send(system_code); #endif #ifdef DEBUG_LED // LED flash for debug diff --git a/common/mousekey.c b/common/mousekey.c index 76bd0fd3..1d35355b 100644 --- a/common/mousekey.c +++ b/common/mousekey.c @@ -121,12 +121,12 @@ void mousekey_clear_report(void) static void mousekey_debug(void) { if (!debug_mouse) return; - print("mousekey[btn|x y v h]: "); + print("mousekey [btn|x y v h]rep: ["); phex(report.buttons); print("|"); phex(report.x); print(" "); phex(report.y); print(" "); phex(report.v); print(" "); - phex(report.h); + phex(report.h); print("]"); phex(mousekey_repeat); print("\n"); } diff --git a/common/report.h b/common/report.h index b85b86c5..45f5c0b8 100644 --- a/common/report.h +++ b/common/report.h @@ -82,15 +82,14 @@ typedef struct { uint8_t mods; uint8_t rserved; uint8_t keys[REPORT_KEYS]; -} report_keyboard_t; +} __attribute__ ((packed)) 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; +} __attribute__ ((packed)) report_mouse_t; #endif diff --git a/converter/adb_usb/Makefile b/converter/adb_usb/Makefile index 248261df..e9a90695 100644 --- a/converter/adb_usb/Makefile +++ b/converter/adb_usb/Makefile @@ -8,8 +8,7 @@ TOP_DIR = ../.. TARGET_DIR = . # keyboard dependent files -SRC = main.c \ - keymap.c \ +SRC = keymap.c \ matrix.c \ led.c \ adb.c @@ -42,16 +41,11 @@ EXTRAKEY_ENABLE = yes # Audio control and System control #NKRO_ENABLE = yes # USB Nkey Rollover - -#---------------- Programming Options -------------------------- -PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex - - +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) include $(TOP_DIR)/protocol/pjrc.mk include $(TOP_DIR)/protocol.mk include $(TOP_DIR)/common.mk include $(TOP_DIR)/rules.mk - -dfu: PROGRAM_CMD = dfu-programmer atmega32u4 flash $(TARGET).hex -dfu: program diff --git a/converter/m0110_usb/Makefile b/converter/m0110_usb/Makefile index 4a687b93..1fee258a 100644 --- a/converter/m0110_usb/Makefile +++ b/converter/m0110_usb/Makefile @@ -8,8 +8,7 @@ TOP_DIR = ../.. TARGET_DIR = . # keyboard dependent files -SRC = main.c \ - keymap.c \ +SRC = keymap.c \ matrix.c \ led.c \ m0110.c @@ -47,6 +46,10 @@ EXTRAKEY_ENABLE = yes # Audio control and System control PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) + include $(TOP_DIR)/protocol/pjrc.mk include $(TOP_DIR)/protocol.mk diff --git a/converter/news_usb/Makefile.pjrc b/converter/news_usb/Makefile.pjrc index 376133ad..3233463d 100644 --- a/converter/news_usb/Makefile.pjrc +++ b/converter/news_usb/Makefile.pjrc @@ -13,8 +13,7 @@ TOP_DIR = ../.. TARGET_DIR = . # keyboard dependent files -SRC = main.c \ - keymap.c \ +SRC = keymap.c \ matrix.c \ led.c \ news.c @@ -51,6 +50,10 @@ NKRO_ENABLE = yes # USB Nkey Rollover PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) + include $(TOP_DIR)/protocol/pjrc.mk include $(TOP_DIR)/protocol.mk diff --git a/converter/ps2_usb/Makefile b/converter/ps2_usb/Makefile index 0bba191a..1278a74b 100644 --- a/converter/ps2_usb/Makefile +++ b/converter/ps2_usb/Makefile @@ -13,8 +13,7 @@ TOP_DIR = ../.. TARGET_DIR = . # keyboard dependent files -SRC = main.c \ - keymap.c \ +SRC = keymap.c \ matrix.c \ led.c \ ps2.c @@ -51,6 +50,10 @@ NKRO_ENABLE = yes # USB Nkey Rollover PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) + include $(TOP_DIR)/protocol/pjrc.mk include $(TOP_DIR)/protocol.mk diff --git a/converter/ps2_usb/Makefile.pjrc_usart b/converter/ps2_usb/Makefile.pjrc_usart index 3dad7e2f..dd74712e 100644 --- a/converter/ps2_usb/Makefile.pjrc_usart +++ b/converter/ps2_usb/Makefile.pjrc_usart @@ -13,8 +13,7 @@ TOP_DIR = ../.. TARGET_DIR = . # keyboard dependent files -SRC = main.c \ - keymap.c \ +SRC = keymap.c \ matrix.c \ led.c \ ps2_usart.c @@ -51,6 +50,10 @@ NKRO_ENABLE = yes # USB Nkey Rollover PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) + include $(TOP_DIR)/protocol/pjrc.mk include $(TOP_DIR)/protocol.mk diff --git a/converter/ps2_usb/Makefile.vusb b/converter/ps2_usb/Makefile.vusb index 4d5240c3..b08d30d5 100644 --- a/converter/ps2_usb/Makefile.vusb +++ b/converter/ps2_usb/Makefile.vusb @@ -13,8 +13,7 @@ TOP_DIR = ../.. TARGET_DIR = . # keyboard dependent files -SRC = main.c \ - keymap.c \ +SRC = keymap.c \ matrix.c \ led.c \ ps2_usart.c @@ -85,6 +84,18 @@ AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) PROGRAM_CMD = $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) +# Boot Section Size in bytes +# Teensy halfKay 512 +# Atmel DFU loader 4096 +# LUFA bootloader 4096 +# USBasp 2048 +OPT_DEFS += -DBOOT_SIZE=2048 + + +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) + include $(TOP_DIR)/protocol/vusb.mk include $(TOP_DIR)/protocol.mk diff --git a/converter/terminal_usb/Makefile.102_pjrc b/converter/terminal_usb/Makefile.102_pjrc index e9d14e7a..e2d1a00a 100644 --- a/converter/terminal_usb/Makefile.102_pjrc +++ b/converter/terminal_usb/Makefile.102_pjrc @@ -13,8 +13,7 @@ TOP_DIR = ../.. TARGET_DIR = . # keyboard dependent files -SRC = main.c \ - keymap_102.c \ +SRC = keymap_102.c \ matrix.c \ led.c \ ps2.c @@ -51,6 +50,10 @@ NKRO_ENABLE = yes # USB Nkey Rollover PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) + include $(TOP_DIR)/protocol/pjrc.mk include $(TOP_DIR)/protocol.mk diff --git a/converter/terminal_usb/Makefile.122_pjrc b/converter/terminal_usb/Makefile.122_pjrc index bec00510..ee42dd74 100644 --- a/converter/terminal_usb/Makefile.122_pjrc +++ b/converter/terminal_usb/Makefile.122_pjrc @@ -13,8 +13,7 @@ TOP_DIR = ../.. TARGET_DIR = . # keyboard dependent files -SRC = main.c \ - keymap_122.c \ +SRC = keymap_122.c \ matrix.c \ led.c \ ps2.c @@ -51,6 +50,10 @@ F_CPU = 16000000 PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) + include $(TOP_DIR)/protocol/pjrc.mk include $(TOP_DIR)/protocol.mk diff --git a/converter/x68k_usb/Makefile b/converter/x68k_usb/Makefile index c3b5fa29..62b976c5 100644 --- a/converter/x68k_usb/Makefile +++ b/converter/x68k_usb/Makefile @@ -13,8 +13,7 @@ TOP_DIR = ../.. TARGET_DIR = . # keyboard dependent files -SRC = main.c \ - keymap.c \ +SRC = keymap.c \ matrix.c \ led.c \ x68k.c @@ -80,6 +79,10 @@ AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) PROGRAM_CMD = dfu-programmer atmega32u4 flash $(TARGET).hex +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) + include $(TOP_DIR)/protocol/pjrc.mk include $(TOP_DIR)/protocol.mk diff --git a/keyboard/hbkb/Makefile b/keyboard/hbkb/Makefile deleted file mode 100644 index 26be322e..00000000 --- a/keyboard/hbkb/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -# Target file name (without extension). -TARGET = hbk - -# Directory common source filess exist -TOP_DIR = ../.. - -# Directory keyboard dependent files exist -TARGET_DIR = . - -# keyboard dependent files -SRC = main.c \ - keymap.c \ - matrix.c \ - led.c - -CONFIG_H = config.h - - -# MCU name, you MUST set this to match the board you are using -# type "make clean" after changing this, so all files will be rebuilt -#MCU = at90usb162 # Teensy 1.0 -MCU = atmega32u4 # Teensy 2.0 -#MCU = at90usb646 # Teensy++ 1.0 -#MCU = at90usb1286 # Teensy++ 2.0 - - -# 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 = 16000000 - - -# Build Options -# comment out to disable the options. -# -MOUSEKEY_ENABLE = yes # Mouse keys -#PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support -EXTRAKEY_ENABLE = yes # Audio control and System control -#NKRO_ENABLE = yes # USB Nkey Rollover - - - -#---------------- Programming Options -------------------------- -#PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex -PROGRAM_CMD = /opt/dfu-programmer-0.5.2/bin/dfu-programmer $(MCU) erase && \ - /opt/dfu-programmer-0.5.2/bin/dfu-programmer $(MCU) flash $(TARGET).hex && \ - /opt/dfu-programmer-0.5.2/bin/dfu-programmer $(MCU) start - - - -include $(TOP_DIR)/protocol/pjrc.mk -include $(TOP_DIR)/protocol.mk -include $(TOP_DIR)/common.mk -include $(TOP_DIR)/rules.mk diff --git a/keyboard/hbkb/Makefile b/keyboard/hbkb/Makefile new file mode 120000 index 00000000..f00d036d --- /dev/null +++ b/keyboard/hbkb/Makefile @@ -0,0 +1 @@ +Makefile.lufa \ No newline at end of file diff --git a/keyboard/hbkb/Makefile.lufa b/keyboard/hbkb/Makefile.lufa new file mode 100644 index 00000000..c73a0ca7 --- /dev/null +++ b/keyboard/hbkb/Makefile.lufa @@ -0,0 +1,119 @@ +#---------------------------------------------------------------------------- +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF. +# +# make extcoff = Convert ELF to AVR Extended COFF. +# +# make program = Download the hex file to the device. +# Please customize your programmer settings(PROGRAM_CMD) +# +# make teensy = Download the hex file to the device, using teensy_loader_cli. +# (must have teensy_loader_cli installed). +# +# make dfu = Download the hex file to the device, using dfu-programmer (must +# have dfu-programmer installed). +# +# make flip = Download the hex file to the device, using Atmel FLIP (must +# have Atmel FLIP installed). +# +# make dfu-ee = Download the eeprom file to the device, using dfu-programmer +# (must have dfu-programmer installed). +# +# make flip-ee = Download the eeprom file to the device, using Atmel FLIP +# (must have Atmel FLIP installed). +# +# make debug = Start either simulavr or avarice as specified for debugging, +# with avr-gdb or avr-insight as the front end for debugging. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# make filename.i = Create a preprocessed source file for use in submitting +# bug reports to the GCC project. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + +# Target file name (without extension). +TARGET = hbkb_lufa + +# Directory common source filess exist +TOP_DIR = ../.. + +# Directory keyboard dependent files exist +TARGET_DIR = . + + +# List C source files here. (C dependencies are automatically generated.) +SRC += keymap.c \ + matrix.c \ + led.c + +CONFIG_H = config.h + + +# MCU name +#MCU = at90usb1287 +MCU = atmega32u4 + +# Processor frequency. +# This will define a symbol, F_CPU, in all source code files equal to the +# processor frequency in Hz. You can then use this symbol in your source code to +# calculate timings. Do NOT tack on a 'UL' at the end, this will be done +# automatically to create a 32-bit value in your source code. +# +# This will be an integer division of F_USB below, as it is sourced by +# F_USB after it has run through any CPU prescalers. Note that this value +# does not *change* the processor frequency - it should merely be updated to +# reflect the processor speed set externally so that the code can use accurate +# software delays. +F_CPU = 16000000 + + +# +# LUFA specific +# +# Target architecture (see library "Board Types" documentation). +ARCH = AVR8 + +# Input clock frequency. +# This will define a symbol, F_USB, in all source code files equal to the +# input clock frequency (before any prescaling is performed) in Hz. This value may +# differ from F_CPU if prescaling is used on the latter, and is required as the +# raw input clock is fed directly to the PLL sections of the AVR for high speed +# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' +# at the end, this will be done automatically to create a 32-bit value in your +# source code. +# +# If no clock division is performed on the input clock inside the AVR (via the +# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. +F_USB = $(F_CPU) + + +# 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 +#PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support + + +# Boot Section Size in bytes +# Teensy halfKay 512 +# Atmel DFU loader 4096 +# LUFA bootloader 4096 +OPT_DEFS += -DBOOT_SIZE=4096 + + +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) + +include $(TOP_DIR)/protocol/lufa.mk +include $(TOP_DIR)/common.mk +include $(TOP_DIR)/rules.mk diff --git a/keyboard/macway/Makefile b/keyboard/hbkb/Makefile.pjrc similarity index 81% rename from keyboard/macway/Makefile rename to keyboard/hbkb/Makefile.pjrc index afee38b1..159f56b4 100644 --- a/keyboard/macway/Makefile +++ b/keyboard/hbkb/Makefile.pjrc @@ -1,5 +1,5 @@ # Target file name (without extension). -TARGET = macway +TARGET = hbkb # Directory common source filess exist TOP_DIR = ../.. @@ -43,7 +43,10 @@ EXTRAKEY_ENABLE = yes # Audio control and System control #---------------- Programming Options -------------------------- -PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex +#PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex +PROGRAM_CMD = /opt/dfu-programmer-0.5.2/bin/dfu-programmer $(MCU) erase && \ + /opt/dfu-programmer-0.5.2/bin/dfu-programmer $(MCU) flash $(TARGET).hex && \ + /opt/dfu-programmer-0.5.2/bin/dfu-programmer $(MCU) start diff --git a/keyboard/hbkb/config.h b/keyboard/hbkb/config.h index 5262399d..deaabb24 100644 --- a/keyboard/hbkb/config.h +++ b/keyboard/hbkb/config.h @@ -24,7 +24,10 @@ along with this program. If not, see . #define VENDOR_ID 0xFEED #define PRODUCT_ID 0xBB00 #define MANUFACTURER t.m.k. +#define DEVICE_VER 0x0100 #define PRODUCT Happy Buckling Keyboard + + #define DESCRIPTION mod version of IBM Model M keyboard diff --git a/keyboard/hhkb/Makefile.lufa b/keyboard/hhkb/Makefile.lufa new file mode 100644 index 00000000..cdd68f40 --- /dev/null +++ b/keyboard/hhkb/Makefile.lufa @@ -0,0 +1,119 @@ +#---------------------------------------------------------------------------- +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF. +# +# make extcoff = Convert ELF to AVR Extended COFF. +# +# make program = Download the hex file to the device. +# Please customize your programmer settings(PROGRAM_CMD) +# +# make teensy = Download the hex file to the device, using teensy_loader_cli. +# (must have teensy_loader_cli installed). +# +# make dfu = Download the hex file to the device, using dfu-programmer (must +# have dfu-programmer installed). +# +# make flip = Download the hex file to the device, using Atmel FLIP (must +# have Atmel FLIP installed). +# +# make dfu-ee = Download the eeprom file to the device, using dfu-programmer +# (must have dfu-programmer installed). +# +# make flip-ee = Download the eeprom file to the device, using Atmel FLIP +# (must have Atmel FLIP installed). +# +# make debug = Start either simulavr or avarice as specified for debugging, +# with avr-gdb or avr-insight as the front end for debugging. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# make filename.i = Create a preprocessed source file for use in submitting +# bug reports to the GCC project. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + +# Target file name (without extension). +TARGET = hhkb_lufa + +# Directory common source filess exist +TOP_DIR = ../.. + +# Directory keyboard dependent files exist +TARGET_DIR = . + + +# List C source files here. (C dependencies are automatically generated.) +SRC += keymap.c \ + matrix.c \ + led.c + +CONFIG_H = config.h + + +# MCU name +MCU = at90usb1286 +#MCU = atmega32u4 + +# Processor frequency. +# This will define a symbol, F_CPU, in all source code files equal to the +# processor frequency in Hz. You can then use this symbol in your source code to +# calculate timings. Do NOT tack on a 'UL' at the end, this will be done +# automatically to create a 32-bit value in your source code. +# +# This will be an integer division of F_USB below, as it is sourced by +# F_USB after it has run through any CPU prescalers. Note that this value +# does not *change* the processor frequency - it should merely be updated to +# reflect the processor speed set externally so that the code can use accurate +# software delays. +F_CPU = 16000000 + + +# +# LUFA specific +# +# Target architecture (see library "Board Types" documentation). +ARCH = AVR8 + +# Input clock frequency. +# This will define a symbol, F_USB, in all source code files equal to the +# input clock frequency (before any prescaling is performed) in Hz. This value may +# differ from F_CPU if prescaling is used on the latter, and is required as the +# raw input clock is fed directly to the PLL sections of the AVR for high speed +# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' +# at the end, this will be done automatically to create a 32-bit value in your +# source code. +# +# If no clock division is performed on the input clock inside the AVR (via the +# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. +F_USB = $(F_CPU) + + +# 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 +#PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support + + +# Boot Section Size in bytes +# Teensy halfKay 512 +# Atmel DFU loader 4096 +# LUFA bootloader 4096 +#OPT_DEFS += -DBOOT_SIZE=4096 + + +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) + +include $(TOP_DIR)/protocol/lufa.mk +include $(TOP_DIR)/common.mk +include $(TOP_DIR)/rules.mk diff --git a/keyboard/hhkb/Makefile.pjrc b/keyboard/hhkb/Makefile.pjrc index f6d133ea..f8836a2c 100644 --- a/keyboard/hhkb/Makefile.pjrc +++ b/keyboard/hhkb/Makefile.pjrc @@ -13,12 +13,11 @@ TOP_DIR = ../.. TARGET_DIR = . # keyboard dependent files -SRC = main.c \ - keymap.c \ +SRC = keymap.c \ matrix.c \ led.c -CONFIG_H = config_pjrc.h +CONFIG_H = config.h # MCU name, you MUST set this to match the board you are using @@ -53,8 +52,8 @@ PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex # Search Path VPATH = $(TARGET_DIR) +VPATH = $(TOP_DIR) include $(TOP_DIR)/protocol/pjrc.mk -include $(TOP_DIR)/protocol.mk include $(TOP_DIR)/common.mk include $(TOP_DIR)/rules.mk diff --git a/keyboard/hhkb/config_pjrc.h b/keyboard/hhkb/config.h similarity index 97% rename from keyboard/hhkb/config_pjrc.h rename to keyboard/hhkb/config.h index fffe3522..91446466 100644 --- a/keyboard/hhkb/config_pjrc.h +++ b/keyboard/hhkb/config.h @@ -21,11 +21,14 @@ along with this program. If not, see . /* controller configuration */ #include "controller_teensy.h" + #define VENDOR_ID 0xFEED -#define PRODUCT_ID 0xCAFE +#define PRODUCT_ID 0xCAFF #define DEVICE_VER 0x0101 #define MANUFACTURER t.m.k. #define PRODUCT HHKB mod + + #define DESCRIPTION t.m.k. keyboard firmware for HHKB mod diff --git a/keyboard/hhkb/keymap.c b/keyboard/hhkb/keymap.c index 85a7c31b..88a6737b 100644 --- a/keyboard/hhkb/keymap.c +++ b/keyboard/hhkb/keymap.c @@ -110,7 +110,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * |Gui |Alt |Space |Alt |xxx| * `--------------------------------------------' */ - KEYMAP(ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ + KEYMAP(PWR, 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, \ diff --git a/keyboard/hhkb/matrix.c b/keyboard/hhkb/matrix.c index 350066b9..79d2d987 100644 --- a/keyboard/hhkb/matrix.c +++ b/keyboard/hhkb/matrix.c @@ -68,8 +68,8 @@ static bool matrix_has_ghost_in_row(uint8_t row); // key: on: 0/off: 1 // prev: unknown: output previous key state(negated)? -#ifdef HOST_PJRC -// Ports for Teensy +#if defined(__AVR_AT90USB1286__) +// Ports for Teensy++ // row: PB0-2 // col: PB3-5,6 // key: PE6(pull-uped) @@ -90,7 +90,8 @@ static bool matrix_has_ghost_in_row(uint8_t row); #define KEY_PREV_OFF() (PORTE &= ~(1<<7)) #define KEY_POWER_ON() #define KEY_POWER_OFF() -#else + +#elif defined(__AVR_ATmega328P__) // Ports for V-USB // key: PB0(pull-uped) // prev: PB1 @@ -126,6 +127,9 @@ static bool matrix_has_ghost_in_row(uint8_t row); DDRC &= ~0x0F; \ PORTC &= ~0x0F; \ } while (0) + +#else +# error "define code for matrix scan" #endif diff --git a/keyboard/macway/Makefile.lufa b/keyboard/macway/Makefile.lufa new file mode 100644 index 00000000..9c9388ee --- /dev/null +++ b/keyboard/macway/Makefile.lufa @@ -0,0 +1,119 @@ +#---------------------------------------------------------------------------- +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF. +# +# make extcoff = Convert ELF to AVR Extended COFF. +# +# make program = Download the hex file to the device. +# Please customize your programmer settings(PROGRAM_CMD) +# +# make teensy = Download the hex file to the device, using teensy_loader_cli. +# (must have teensy_loader_cli installed). +# +# make dfu = Download the hex file to the device, using dfu-programmer (must +# have dfu-programmer installed). +# +# make flip = Download the hex file to the device, using Atmel FLIP (must +# have Atmel FLIP installed). +# +# make dfu-ee = Download the eeprom file to the device, using dfu-programmer +# (must have dfu-programmer installed). +# +# make flip-ee = Download the eeprom file to the device, using Atmel FLIP +# (must have Atmel FLIP installed). +# +# make debug = Start either simulavr or avarice as specified for debugging, +# with avr-gdb or avr-insight as the front end for debugging. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# make filename.i = Create a preprocessed source file for use in submitting +# bug reports to the GCC project. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + +# Target file name (without extension). +TARGET = macway_lufa + +# Directory common source filess exist +TOP_DIR = ../.. + +# Directory keyboard dependent files exist +TARGET_DIR = . + + +# List C source files here. (C dependencies are automatically generated.) +SRC += keymap.c \ + matrix.c \ + led.c + +CONFIG_H = config.h + + +# MCU name +#MCU = at90usb1287 +MCU = atmega32u4 + +# Processor frequency. +# This will define a symbol, F_CPU, in all source code files equal to the +# processor frequency in Hz. You can then use this symbol in your source code to +# calculate timings. Do NOT tack on a 'UL' at the end, this will be done +# automatically to create a 32-bit value in your source code. +# +# This will be an integer division of F_USB below, as it is sourced by +# F_USB after it has run through any CPU prescalers. Note that this value +# does not *change* the processor frequency - it should merely be updated to +# reflect the processor speed set externally so that the code can use accurate +# software delays. +F_CPU = 16000000 + + +# +# LUFA specific +# +# Target architecture (see library "Board Types" documentation). +ARCH = AVR8 + +# Input clock frequency. +# This will define a symbol, F_USB, in all source code files equal to the +# input clock frequency (before any prescaling is performed) in Hz. This value may +# differ from F_CPU if prescaling is used on the latter, and is required as the +# raw input clock is fed directly to the PLL sections of the AVR for high speed +# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' +# at the end, this will be done automatically to create a 32-bit value in your +# source code. +# +# If no clock division is performed on the input clock inside the AVR (via the +# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. +F_USB = $(F_CPU) + + +# 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 +#PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support + + +# Boot Section Size in bytes +# Teensy halfKay 512 +# Atmel DFU loader 4096 +# LUFA bootloader 4096 +#OPT_DEFS += -DBOOT_SIZE=4096 + + +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) + +include $(TOP_DIR)/protocol/lufa.mk +include $(TOP_DIR)/common.mk +include $(TOP_DIR)/rules.mk diff --git a/keyboard/macway/Makefile.pjrc b/keyboard/macway/Makefile.pjrc new file mode 100644 index 00000000..ecc236e3 --- /dev/null +++ b/keyboard/macway/Makefile.pjrc @@ -0,0 +1,95 @@ +#---------------------------------------------------------------------------- +# On command line: +# +# make all = Make software. +# +# make clean = Clean out built project files. +# +# make coff = Convert ELF to AVR COFF. +# +# make extcoff = Convert ELF to AVR Extended COFF. +# +# make program = Download the hex file to the device. +# Please customize your programmer settings(PROGRAM_CMD) +# +# make teensy = Download the hex file to the device, using teensy_loader_cli. +# (must have teensy_loader_cli installed). +# +# make dfu = Download the hex file to the device, using dfu-programmer (must +# have dfu-programmer installed). +# +# make flip = Download the hex file to the device, using Atmel FLIP (must +# have Atmel FLIP installed). +# +# make dfu-ee = Download the eeprom file to the device, using dfu-programmer +# (must have dfu-programmer installed). +# +# make flip-ee = Download the eeprom file to the device, using Atmel FLIP +# (must have Atmel FLIP installed). +# +# make debug = Start either simulavr or avarice as specified for debugging, +# with avr-gdb or avr-insight as the front end for debugging. +# +# make filename.s = Just compile filename.c into the assembler code only. +# +# make filename.i = Create a preprocessed source file for use in submitting +# bug reports to the GCC project. +# +# To rebuild project do "make clean" then "make all". +#---------------------------------------------------------------------------- + +# Target file name (without extension). +TARGET = macway_pjrc + +# Directory common source filess exist +TOP_DIR = ../.. + +# Directory keyboard dependent files exist +TARGET_DIR = . + +# keyboard dependent files +SRC = keymap.c \ + matrix.c \ + led.c + +CONFIG_H = config.h + + +# MCU name, you MUST set this to match the board you are using +# type "make clean" after changing this, so all files will be rebuilt +#MCU = at90usb162 # Teensy 1.0 +MCU = atmega32u4 # Teensy 2.0 +#MCU = at90usb646 # Teensy++ 1.0 +#MCU = at90usb1286 # Teensy++ 2.0 + + +# 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 = 16000000 + + +# Build Options +# comment out to disable the options. +# +MOUSEKEY_ENABLE = yes # Mouse keys +#PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support +EXTRAKEY_ENABLE = yes # Audio control and System control +#NKRO_ENABLE = yes # USB Nkey Rollover + + + +#---------------- Programming Options -------------------------- +PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex + + + +# Search Path +VPATH += $(TARGET_DIR) +VPATH += $(TOP_DIR) + +include $(TOP_DIR)/protocol/pjrc.mk +include $(TOP_DIR)/common.mk +include $(TOP_DIR)/rules.mk diff --git a/keyboard/macway/config.h b/keyboard/macway/config.h index b68ea20d..5503c77e 100644 --- a/keyboard/macway/config.h +++ b/keyboard/macway/config.h @@ -21,10 +21,16 @@ along with this program. If not, see . /* controller configuration */ #include "controller_teensy.h" + +/* USB Device descriptor parameter */ #define VENDOR_ID 0xFEED #define PRODUCT_ID 0xBEE0 +#define DEVICE_VER 0x0202 #define MANUFACTURER t.m.k. #define PRODUCT Macway mod + + +/* message strings */ #define DESCRIPTION t.m.k. keyboard firmware for Macway mod diff --git a/keyboard/macway/keymap.c b/keyboard/macway/keymap.c index 89634e2f..76c0d8b7 100644 --- a/keyboard/macway/keymap.c +++ b/keyboard/macway/keymap.c @@ -59,7 +59,7 @@ static const uint8_t PROGMEM fn_layer[] = { 3, // Fn3 4, // Fn4 0, // Fn5 - 2, // Fn6 + 3, // Fn6 3 // Fn7 }; @@ -94,7 +94,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSLS, \ 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, \ - FN7, LGUI,LALT,FN4, RALT,BSLS,GRV, FN6, RCTL), + FN7, LGUI,LALT,FN4, RALT,GRV, FN6, FN6, RCTL), /* Layer 1: HHKB mode (HHKB Fn) @@ -110,8 +110,8 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * | |Gui |Alt | |Alt |Gui| | |Ctr| * `-----------------------------------------------------------' */ - KEYMAP(ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, \ - CAPS,NO, NO, NO, NO, NO, NO, NO, PSCR,SLCK,BRK, UP, NO, NO, \ + KEYMAP(PWR, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, DEL, \ + CAPS,NO, NO, NO, NO, NO, NO, NO, PSCR,SLCK,BRK, UP, NO, NLCK,\ 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, \ NO, LGUI,LALT,SPC, RALT,NO, NO, NO, RCTL), @@ -155,7 +155,7 @@ static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { BSLS,WH_L,WH_D,MS_U,WH_U,WH_R,WH_L,WH_D,WH_U,WH_R,NO, NO, NO, NO, \ LCTL,NO, MS_L,MS_D,MS_R,NO, MS_L,MS_D,MS_U,MS_R,FN3, NO, BSLS, \ LSFT,NO, NO, BTN1,BTN2,BTN3,BTN2,BTN1,NO, NO, NO, RSFT,NO, \ - FN7, LGUI,LALT,BTN1,RALT,NO, NO, NO, NO), + FN7, LGUI,LALT,BTN1,RALT,NO, FN6, FN6, NO), /* Layer 4: Matias half keyboard style (Space) diff --git a/protocol/lufa.mk b/protocol/lufa.mk new file mode 100644 index 00000000..ad6cab6d --- /dev/null +++ b/protocol/lufa.mk @@ -0,0 +1,34 @@ +LUFA_DIR = protocol/lufa + +# Path to the LUFA library +LUFA_PATH = $(TOP_DIR)/protocol/lufa/LUFA-120219 + +# Create the LUFA source path variables by including the LUFA root makefile +include $(LUFA_PATH)/LUFA/makefile + +LUFA_SRC = $(LUFA_DIR)/lufa.c \ + $(LUFA_DIR)/descriptor.c \ + $(LUFA_SRC_USB) +SRC += $(subst $(LUFA_PATH)/,,$(LUFA_SRC)) + +# Search Path +VPATH += $(LUFA_PATH) + +# Option modules +#ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE) +#endif + +#ifdef EXTRAKEY_ENABLE +#endif + +# LUFA library compile-time options and predefined tokens +LUFA_OPTS = -D USB_DEVICE_ONLY +LUFA_OPTS += -D FIXED_CONTROL_ENDPOINT_SIZE=8 +LUFA_OPTS += -D FIXED_NUM_CONFIGURATIONS=1 +LUFA_OPTS += -D USE_FLASH_DESCRIPTORS +LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)" + +OPT_DEFS += -DF_USB=$(F_USB)UL +OPT_DEFS += -DARCH=ARCH_$(ARCH) +OPT_DEFS += $(LUFA_OPTS) +OPT_DEFS += -DHOST_LUFA diff --git a/protocol/lufa/descriptor.c b/protocol/lufa/descriptor.c new file mode 100644 index 00000000..d3f740bf --- /dev/null +++ b/protocol/lufa/descriptor.c @@ -0,0 +1,558 @@ +/* + * Copyright 2012 Jun Wako + * This file is based on: + * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse + * LUFA-120219/Demos/Device/Lowlevel/GenericHID + */ + +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim 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, 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 "util.h" +#include "report.h" +#include "descriptor.h" + + +/******************************************************************************* + * HID Report Descriptors + ******************************************************************************/ +const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = +{ + HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ + HID_RI_USAGE(8, 0x06), /* Keyboard */ + HID_RI_COLLECTION(8, 0x01), /* Application */ + HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */ + HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */ + HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */ + HID_RI_LOGICAL_MINIMUM(8, 0x00), + HID_RI_LOGICAL_MAXIMUM(8, 0x01), + HID_RI_REPORT_COUNT(8, 0x08), + HID_RI_REPORT_SIZE(8, 0x01), + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), + HID_RI_REPORT_COUNT(8, 0x01), + HID_RI_REPORT_SIZE(8, 0x08), + HID_RI_INPUT(8, HID_IOF_CONSTANT), + HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */ + HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */ + HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */ + HID_RI_REPORT_COUNT(8, 0x05), + HID_RI_REPORT_SIZE(8, 0x01), + HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), + HID_RI_REPORT_COUNT(8, 0x01), + HID_RI_REPORT_SIZE(8, 0x03), + HID_RI_OUTPUT(8, HID_IOF_CONSTANT), + HID_RI_USAGE_PAGE(8, 0x07), /* Keyboard */ + HID_RI_USAGE_MINIMUM(8, 0x00), /* Reserved (no event indicated) */ + HID_RI_USAGE_MAXIMUM(8, 0xFF), /* Keyboard Application */ + HID_RI_LOGICAL_MINIMUM(8, 0x00), + HID_RI_LOGICAL_MAXIMUM(8, 0xFF), + HID_RI_REPORT_COUNT(8, 0x06), + HID_RI_REPORT_SIZE(8, 0x08), + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), + HID_RI_END_COLLECTION(0), +}; + +const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] = +{ + HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ + HID_RI_USAGE(8, 0x02), /* Mouse */ + HID_RI_COLLECTION(8, 0x01), /* Application */ + HID_RI_USAGE(8, 0x01), /* Pointer */ + HID_RI_COLLECTION(8, 0x00), /* Physical */ + + HID_RI_USAGE_PAGE(8, 0x09), /* Button */ + HID_RI_USAGE_MINIMUM(8, 0x01), /* Button 1 */ + HID_RI_USAGE_MAXIMUM(8, 0x05), /* Button 5 */ + HID_RI_LOGICAL_MINIMUM(8, 0x00), + HID_RI_LOGICAL_MAXIMUM(8, 0x01), + HID_RI_REPORT_COUNT(8, 0x05), + HID_RI_REPORT_SIZE(8, 0x01), + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), + HID_RI_REPORT_COUNT(8, 0x01), + HID_RI_REPORT_SIZE(8, 0x03), + HID_RI_INPUT(8, HID_IOF_CONSTANT), + + HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ + HID_RI_USAGE(8, 0x30), /* Usage X */ + HID_RI_USAGE(8, 0x31), /* Usage Y */ + HID_RI_LOGICAL_MINIMUM(8, -127), + HID_RI_LOGICAL_MAXIMUM(8, 127), + HID_RI_REPORT_COUNT(8, 0x02), + HID_RI_REPORT_SIZE(8, 0x08), + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE), + + HID_RI_USAGE(8, 0x38), /* Wheel */ + HID_RI_LOGICAL_MINIMUM(8, -127), + HID_RI_LOGICAL_MAXIMUM(8, 127), + HID_RI_REPORT_COUNT(8, 0x01), + HID_RI_REPORT_SIZE(8, 0x08), + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE), + + HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */ + HID_RI_USAGE(16, 0x0238), /* AC Pan (Horizontal wheel) */ + HID_RI_LOGICAL_MINIMUM(8, -127), + HID_RI_LOGICAL_MAXIMUM(8, 127), + HID_RI_REPORT_COUNT(8, 0x01), + HID_RI_REPORT_SIZE(8, 0x08), + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE), + + HID_RI_END_COLLECTION(0), + HID_RI_END_COLLECTION(0), +}; + +const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] = +{ + HID_RI_USAGE_PAGE(16, 0xFF31), /* Vendor Page(PJRC Teensy compatible) */ + HID_RI_USAGE(8, 0x74), /* Vendor Usage(PJRC Teensy compatible) */ + HID_RI_COLLECTION(8, 0x01), /* Application */ + HID_RI_USAGE(8, 0x75), /* Vendor Usage 0x75 */ + HID_RI_LOGICAL_MINIMUM(8, 0x00), + HID_RI_LOGICAL_MAXIMUM(8, 0xFF), + HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE), + HID_RI_REPORT_SIZE(8, 0x08), + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), + HID_RI_USAGE(8, 0x76), /* Vendor Usage 0x76 */ + HID_RI_LOGICAL_MINIMUM(8, 0x00), + HID_RI_LOGICAL_MAXIMUM(8, 0xFF), + HID_RI_REPORT_COUNT(8, CONSOLE_EPSIZE), + HID_RI_REPORT_SIZE(8, 0x08), + HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), + HID_RI_END_COLLECTION(0), +}; + +#ifdef EXTRAKEY_ENABLE +const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtraReport[] = +{ + HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ + HID_RI_USAGE(8, 0x80), /* System Control */ + HID_RI_COLLECTION(8, 0x01), /* Application */ + HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM), + HID_RI_LOGICAL_MINIMUM(16, 0x0081), + HID_RI_LOGICAL_MAXIMUM(16, 0x00B7), + HID_RI_USAGE_MINIMUM(16, 0x0081), /* System Power Down */ + HID_RI_USAGE_MAXIMUM(16, 0x00B7), /* System Display LCD Autoscale */ + HID_RI_REPORT_SIZE(8, 16), + HID_RI_REPORT_COUNT(8, 1), + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), + HID_RI_END_COLLECTION(0), + + HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer */ + HID_RI_USAGE(8, 0x01), /* Consumer Control */ + HID_RI_COLLECTION(8, 0x01), /* Application */ + HID_RI_REPORT_ID(8, REPORT_ID_CONSUMER), + HID_RI_LOGICAL_MINIMUM(16, 0x0010), + HID_RI_LOGICAL_MAXIMUM(16, 0x029C), + HID_RI_USAGE_MINIMUM(16, 0x0010), /* +10 */ + HID_RI_USAGE_MAXIMUM(16, 0x029C), /* AC Distribute Vertically */ + HID_RI_REPORT_SIZE(8, 16), + HID_RI_REPORT_COUNT(8, 1), + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), + HID_RI_END_COLLECTION(0), +}; +#endif + +#ifdef NKRO_ENABLE +const USB_Descriptor_HIDReport_Datatype_t PROGMEM NKROReport[] = +{ + HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */ + HID_RI_USAGE(8, 0x06), /* Keyboard */ + HID_RI_COLLECTION(8, 0x01), /* Application */ + HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */ + HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */ + HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */ + HID_RI_LOGICAL_MINIMUM(8, 0x00), + HID_RI_LOGICAL_MAXIMUM(8, 0x01), + HID_RI_REPORT_COUNT(8, 0x08), + HID_RI_REPORT_SIZE(8, 0x01), + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), + + HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */ + HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */ + HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */ + HID_RI_REPORT_COUNT(8, 0x05), + HID_RI_REPORT_SIZE(8, 0x01), + HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), + HID_RI_REPORT_COUNT(8, 0x01), + HID_RI_REPORT_SIZE(8, 0x03), + HID_RI_OUTPUT(8, HID_IOF_CONSTANT), + + HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */ + HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */ + HID_RI_USAGE_MAXIMUM(8, NKRO_SIZE*8-1), /* Keyboard Right GUI */ + HID_RI_LOGICAL_MINIMUM(8, 0x00), + HID_RI_LOGICAL_MAXIMUM(8, 0x01), + HID_RI_REPORT_COUNT(8, NKRO_SIZE*8), + HID_RI_REPORT_SIZE(8, 0x01), +}; +#endif + +/******************************************************************************* + * Device Descriptors + ******************************************************************************/ +const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = +{ + .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device}, + + .USBSpecification = VERSION_BCD(01.10), + .Class = USB_CSCP_NoDeviceClass, + .SubClass = USB_CSCP_NoDeviceSubclass, + .Protocol = USB_CSCP_NoDeviceProtocol, + + .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE, + + .VendorID = VENDOR_ID, + .ProductID = PRODUCT_ID, + .ReleaseNumber = DEVICE_VER, + + .ManufacturerStrIndex = 0x01, + .ProductStrIndex = 0x02, + .SerialNumStrIndex = NO_DESCRIPTOR, + + .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS +}; + +/******************************************************************************* + * Configuration Descriptors + ******************************************************************************/ +const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor = +{ + .Config = + { + .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration}, + + .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t), + .TotalInterfaces = TOTAL_INTERFACES, + + .ConfigurationNumber = 1, + .ConfigurationStrIndex = NO_DESCRIPTOR, + + .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP), + + .MaxPowerConsumption = USB_CONFIG_POWER_MA(100) + }, + + /* + * Keyboard + */ + .Keyboard_Interface = + { + .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, + + .InterfaceNumber = KEYBOARD_INTERFACE, + .AlternateSetting = 0x00, + + .TotalEndpoints = 1, + + .Class = HID_CSCP_HIDClass, + .SubClass = HID_CSCP_BootSubclass, + .Protocol = HID_CSCP_KeyboardBootProtocol, + + .InterfaceStrIndex = NO_DESCRIPTOR + }, + + .Keyboard_HID = + { + .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, + + .HIDSpec = VERSION_BCD(01.11), + .CountryCode = 0x00, + .TotalReportDescriptors = 1, + .HIDReportType = HID_DTYPE_Report, + .HIDReportLength = sizeof(KeyboardReport) + }, + + .Keyboard_INEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = (ENDPOINT_DIR_IN | KEYBOARD_IN_EPNUM), + .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = KEYBOARD_EPSIZE, + .PollingIntervalMS = 0x01 + }, + + /* + * Mouse + */ +#ifdef MOUSE_ENABLE + .Mouse_Interface = + { + .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, + + .InterfaceNumber = MOUSE_INTERFACE, + .AlternateSetting = 0x00, + + .TotalEndpoints = 1, + + .Class = HID_CSCP_HIDClass, + .SubClass = HID_CSCP_BootSubclass, + .Protocol = HID_CSCP_MouseBootProtocol, + + .InterfaceStrIndex = NO_DESCRIPTOR + }, + + .Mouse_HID = + { + .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, + + .HIDSpec = VERSION_BCD(01.11), + .CountryCode = 0x00, + .TotalReportDescriptors = 1, + .HIDReportType = HID_DTYPE_Report, + .HIDReportLength = sizeof(MouseReport) + }, + + .Mouse_INEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = (ENDPOINT_DIR_IN | MOUSE_IN_EPNUM), + .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = MOUSE_EPSIZE, + .PollingIntervalMS = 0x01 + }, +#endif + + /* + * Console + */ + .Console_Interface = + { + .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, + + .InterfaceNumber = CONSOLE_INTERFACE, + .AlternateSetting = 0x00, + + .TotalEndpoints = 2, + + .Class = HID_CSCP_HIDClass, + .SubClass = HID_CSCP_NonBootSubclass, + .Protocol = HID_CSCP_NonBootProtocol, + + .InterfaceStrIndex = NO_DESCRIPTOR + }, + + .Console_HID = + { + .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, + + .HIDSpec = VERSION_BCD(01.11), + .CountryCode = 0x00, + .TotalReportDescriptors = 1, + .HIDReportType = HID_DTYPE_Report, + .HIDReportLength = sizeof(ConsoleReport) + }, + + .Console_INEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = (ENDPOINT_DIR_IN | CONSOLE_IN_EPNUM), + .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = CONSOLE_EPSIZE, + .PollingIntervalMS = 0x01 + }, + + .Console_OUTEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = (ENDPOINT_DIR_OUT | CONSOLE_OUT_EPNUM), + .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = CONSOLE_EPSIZE, + .PollingIntervalMS = 0x01 + }, + + /* + * Extra + */ +#ifdef EXTRAKEY_ENABLE + .Extra_Interface = + { + .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface}, + + .InterfaceNumber = EXTRA_INTERFACE, + .AlternateSetting = 0x00, + + .TotalEndpoints = 1, + + .Class = HID_CSCP_HIDClass, + .SubClass = HID_CSCP_NonBootSubclass, + .Protocol = HID_CSCP_NonBootProtocol, + + .InterfaceStrIndex = NO_DESCRIPTOR + }, + + .Extra_HID = + { + .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID}, + + .HIDSpec = VERSION_BCD(01.11), + .CountryCode = 0x00, + .TotalReportDescriptors = 1, + .HIDReportType = HID_DTYPE_Report, + .HIDReportLength = sizeof(ExtraReport) + }, + + .Extra_INEndpoint = + { + .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint}, + + .EndpointAddress = (ENDPOINT_DIR_IN | EXTRA_IN_EPNUM), + .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA), + .EndpointSize = EXTRA_EPSIZE, + .PollingIntervalMS = 0x01 + }, +#endif +}; + + +/******************************************************************************* + * String Descriptors + ******************************************************************************/ +const USB_Descriptor_String_t PROGMEM LanguageString = +{ + .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String}, + + .UnicodeString = {LANGUAGE_ID_ENG} +}; + +const USB_Descriptor_String_t PROGMEM ManufacturerString = +{ + .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String}, + + .UnicodeString = LSTR(MANUFACTURER) +}; + +const USB_Descriptor_String_t PROGMEM ProductString = +{ + .Header = {.Size = USB_STRING_LEN(28), .Type = DTYPE_String}, + + .UnicodeString = LSTR(PRODUCT) +}; + + +/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors" + * documentation) by the application code so that the address and size of a requested descriptor can be given + * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function + * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the + * USB host. + */ +uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, + const uint8_t wIndex, + const void** const DescriptorAddress) +{ + const uint8_t DescriptorType = (wValue >> 8); + const uint8_t DescriptorIndex = (wValue & 0xFF); + + const void* Address = NULL; + uint16_t Size = NO_DESCRIPTOR; + + switch (DescriptorType) + { + case DTYPE_Device: + Address = &DeviceDescriptor; + Size = sizeof(USB_Descriptor_Device_t); + break; + case DTYPE_Configuration: + Address = &ConfigurationDescriptor; + Size = sizeof(USB_Descriptor_Configuration_t); + break; + case DTYPE_String: + switch (DescriptorIndex ) + { + case 0x00: + Address = &LanguageString; + Size = pgm_read_byte(&LanguageString.Header.Size); + break; + case 0x01: + Address = &ManufacturerString; + Size = pgm_read_byte(&ManufacturerString.Header.Size); + break; + case 0x02: + Address = &ProductString; + Size = pgm_read_byte(&ProductString.Header.Size); + break; + } + break; + case HID_DTYPE_HID: + switch (wIndex) { + case KEYBOARD_INTERFACE: + Address = &ConfigurationDescriptor.Keyboard_HID; + Size = sizeof(USB_HID_Descriptor_HID_t); + break; +#ifdef MOUSE_ENABLE + case MOUSE_INTERFACE: + Address = &ConfigurationDescriptor.Mouse_HID; + Size = sizeof(USB_HID_Descriptor_HID_t); + break; +#endif + case CONSOLE_INTERFACE: + Address = &ConfigurationDescriptor.Console_HID; + Size = sizeof(USB_HID_Descriptor_HID_t); + break; +#ifdef EXTRAKEY_ENABLE + case EXTRA_INTERFACE: + Address = &ConfigurationDescriptor.Extra_HID; + Size = sizeof(USB_HID_Descriptor_HID_t); + break; +#endif + } + break; + case HID_DTYPE_Report: + switch (wIndex) { + case KEYBOARD_INTERFACE: + Address = &KeyboardReport; + Size = sizeof(KeyboardReport); + break; +#ifdef MOUSE_ENABLE + case MOUSE_INTERFACE: + Address = &MouseReport; + Size = sizeof(MouseReport); + break; +#endif + case CONSOLE_INTERFACE: + Address = &ConsoleReport; + Size = sizeof(ConsoleReport); + break; +#ifdef EXTRAKEY_ENABLE + case EXTRA_INTERFACE: + Address = &ExtraReport; + Size = sizeof(ExtraReport); + break; +#endif + } + break; + } + + *DescriptorAddress = Address; + return Size; +} diff --git a/protocol/lufa/descriptor.h b/protocol/lufa/descriptor.h new file mode 100644 index 00000000..001e072e --- /dev/null +++ b/protocol/lufa/descriptor.h @@ -0,0 +1,122 @@ +/* + * Copyright 2012 Jun Wako + * This file is based on: + * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse + * LUFA-120219/Demos/Device/Lowlevel/GenericHID + */ + +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim 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, 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. +*/ + +/** \file + * + * Header file for Descriptors.c. + */ + +#ifndef _DESCRIPTORS_H_ +#define _DESCRIPTORS_H_ + +#include +#include + + +typedef struct +{ + USB_Descriptor_Configuration_Header_t Config; + + // Keyboard HID Interface + USB_Descriptor_Interface_t Keyboard_Interface; + USB_HID_Descriptor_HID_t Keyboard_HID; + USB_Descriptor_Endpoint_t Keyboard_INEndpoint; + + // Mouse HID Interface +#ifdef MOUSE_ENABLE + USB_Descriptor_Interface_t Mouse_Interface; + USB_HID_Descriptor_HID_t Mouse_HID; + USB_Descriptor_Endpoint_t Mouse_INEndpoint; +#endif + + // Console HID Interface + USB_Descriptor_Interface_t Console_Interface; + USB_HID_Descriptor_HID_t Console_HID; + USB_Descriptor_Endpoint_t Console_INEndpoint; + USB_Descriptor_Endpoint_t Console_OUTEndpoint; + + // Extra HID Interface +#ifdef EXTRAKEY_ENABLE + USB_Descriptor_Interface_t Extra_Interface; + USB_HID_Descriptor_HID_t Extra_HID; + USB_Descriptor_Endpoint_t Extra_INEndpoint; +#endif +} USB_Descriptor_Configuration_t; + + +/* index of interface */ +#define KEYBOARD_INTERFACE 0 + +#ifdef MOUSE_ENABLE +# define MOUSE_INTERFACE (KEYBOARD_INTERFACE + 1) +#else +# define MOUSE_INTERFACE KEYBOARD_INTERFACE +#endif + +#ifdef EXTRAKEY_ENABLE +# define EXTRA_INTERFACE (MOUSE_INTERFACE + 1) +#else +# define EXTRA_INTERFACE MOUSE_INTERFACE +#endif + +#define CONSOLE_INTERFACE (EXTRA_INTERFACE + 1) + + +/* nubmer of interfaces */ +#define TOTAL_INTERFACES (CONSOLE_INTERFACE + 1) + + +// Endopoint number and size +#define KEYBOARD_IN_EPNUM 1 +#define MOUSE_IN_EPNUM 2 +#define CONSOLE_IN_EPNUM 3 +#define CONSOLE_OUT_EPNUM 4 +#define EXTRA_IN_EPNUM 5 + +#define KEYBOARD_EPSIZE 8 +#define MOUSE_EPSIZE 8 +#define CONSOLE_EPSIZE 8 +#define EXTRA_EPSIZE 8 + + +uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, + const uint8_t wIndex, + const void** const DescriptorAddress) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); + +#endif diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c new file mode 100644 index 00000000..8fa719bc --- /dev/null +++ b/protocol/lufa/lufa.c @@ -0,0 +1,408 @@ +/* + * Copyright 2012 Jun Wako + * This file is based on: + * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse + * LUFA-120219/Demos/Device/Lowlevel/GenericHID + */ + +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim 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, 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 "report.h" +#include "host.h" +#include "host_driver.h" +#include "keyboard.h" +#include "sendchar.h" +#include "debug.h" + +#include "descriptor.h" +#include "lufa.h" + +static uint8_t idle_duration = 0; +static uint8_t protocol_report = 1; +static uint8_t keyboard_led_stats = 0; + +static report_keyboard_t keyboard_report_sent; + + +/* 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 lufa_driver = { + keyboard_leds, + send_keyboard, + send_mouse, + send_system, + send_consumer +}; + + +static void SetupHardware(void); +static void Console_HID_Task(void); + +int main(void) +{ + SetupHardware(); + sei(); + + print_enable = true; + debug_enable = true; + debug_matrix = true; + debug_keyboard = true; + debug_mouse = true; + + // TODO: can't print here + debug("LUFA init\n"); + + keyboard_init(); + host_set_driver(&lufa_driver); + while (1) { + keyboard_proc(); + + Console_HID_Task(); + USB_USBTask(); + } +} + +void SetupHardware(void) +{ + /* Disable watchdog if enabled by bootloader/fuses */ + MCUSR &= ~(1 << WDRF); + wdt_disable(); + + /* Disable clock division */ + clock_prescale_set(clock_div_1); + + USB_Init(); +} + +static void Console_HID_Task(void) +{ + /* Device must be connected and configured for the task to run */ + if (USB_DeviceState != DEVICE_STATE_Configured) + return; + + // TODO: impl receivechar()/recvchar() + Endpoint_SelectEndpoint(CONSOLE_OUT_EPNUM); + + /* Check to see if a packet has been sent from the host */ + if (Endpoint_IsOUTReceived()) + { + /* Check to see if the packet contains data */ + if (Endpoint_IsReadWriteAllowed()) + { + /* Create a temporary buffer to hold the read in report from the host */ + uint8_t ConsoleData[CONSOLE_EPSIZE]; + + /* Read Console Report Data */ + Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL); + + /* Process Console Report Data */ + //ProcessConsoleHIDReport(ConsoleData); + } + + /* Finalize the stream transfer to send the last packet */ + Endpoint_ClearOUT(); + } + + /* IN packet */ + Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM); + // send IN packet + if (Endpoint_IsINReady()) + Endpoint_ClearIN(); +} + + +/******************************************************************************* + * USB Events + ******************************************************************************/ +/** Event handler for the USB_Connect event. */ +void EVENT_USB_Device_Connect(void) +{ +} + +/** Event handler for the USB_Disconnect event. */ +void EVENT_USB_Device_Disconnect(void) +{ +} + +/** Event handler for the USB_ConfigurationChanged event. + * This is fired when the host sets the current configuration of the USB device after enumeration. + */ +void EVENT_USB_Device_ConfigurationChanged(void) +{ + bool ConfigSuccess = true; + + /* Setup Keyboard HID Report Endpoints */ + ConfigSuccess &= Endpoint_ConfigureEndpoint(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, + KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE); + +#ifdef MOUSE_ENABLE + /* Setup Mouse HID Report Endpoint */ + ConfigSuccess &= Endpoint_ConfigureEndpoint(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, + MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE); +#endif + +#ifdef EXTRAKEY_ENABLE + /* Setup Extra HID Report Endpoint */ + ConfigSuccess &= Endpoint_ConfigureEndpoint(EXTRA_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, + EXTRA_EPSIZE, ENDPOINT_BANK_SINGLE); +#endif + + /* Setup Console HID Report Endpoints */ + ConfigSuccess &= Endpoint_ConfigureEndpoint(CONSOLE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, + CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE); + ConfigSuccess &= Endpoint_ConfigureEndpoint(CONSOLE_OUT_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_OUT, + CONSOLE_EPSIZE, ENDPOINT_BANK_SINGLE); +} + +/* +Appendix G: HID Request Support Requirements + +The following table enumerates the requests that need to be supported by various types of HID class devices. + +Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol +------------------------------------------------------------------------------------------ +Boot Mouse Required Optional Optional Optional Required Required +Non-Boot Mouse Required Optional Optional Optional Optional Optional +Boot Keyboard Required Optional Required Required Required Required +Non-Boot Keybrd Required Optional Required Required Optional Optional +Other Device Required Optional Optional Optional Optional Optional +*/ +/** Event handler for the USB_ControlRequest event. + * This is fired before passing along unhandled control requests to the library for processing internally. + */ +void EVENT_USB_Device_ControlRequest(void) +{ + uint8_t* ReportData = NULL; + uint8_t ReportSize = 0; + + /* Handle HID Class specific requests */ + switch (USB_ControlRequest.bRequest) + { + case HID_REQ_GetReport: + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + + // Interface + switch (USB_ControlRequest.wIndex) { + case KEYBOARD_INTERFACE: + // TODO: test/check + ReportData = (uint8_t*)&keyboard_report_sent; + ReportSize = sizeof(keyboard_report_sent); + break; + } + + /* Write the report data to the control endpoint */ + Endpoint_Write_Control_Stream_LE(ReportData, ReportSize); + Endpoint_ClearOUT(); + } + + break; + case HID_REQ_SetReport: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + { + + // Interface + switch (USB_ControlRequest.wIndex) { + case KEYBOARD_INTERFACE: + Endpoint_ClearSETUP(); + + while (!(Endpoint_IsOUTReceived())) { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + keyboard_led_stats = Endpoint_Read_8(); + + Endpoint_ClearOUT(); + Endpoint_ClearStatusStage(); + break; + } + + } + + break; + + case HID_REQ_GetProtocol: + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + while (!(Endpoint_IsINReady())); + Endpoint_Write_8(protocol_report); + Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); + } + + break; + case HID_REQ_SetProtocol: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + Endpoint_ClearStatusStage(); + + protocol_report = ((USB_ControlRequest.wValue & 0xFF) != 0x00); + } + + break; + case HID_REQ_SetIdle: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + Endpoint_ClearStatusStage(); + + idle_duration = ((USB_ControlRequest.wValue & 0xFF00) >> 8); + } + + break; + case HID_REQ_GetIdle: + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + while (!(Endpoint_IsINReady())); + Endpoint_Write_8(idle_duration); + Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); + } + + break; + } +} + +/******************************************************************************* + * Host driver + ******************************************************************************/ +static uint8_t keyboard_leds(void) +{ + return keyboard_led_stats; +} + +static void send_keyboard(report_keyboard_t *report) +{ + // TODO: handle NKRO report + /* Select the Keyboard Report Endpoint */ + Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM); + + /* Check if Keyboard Endpoint Ready for Read/Write */ + if (Endpoint_IsReadWriteAllowed()) + { + /* Write Keyboard Report Data */ + Endpoint_Write_Stream_LE(report, sizeof(report_keyboard_t), NULL); + + /* Finalize the stream transfer to send the last packet */ + Endpoint_ClearIN(); + } + keyboard_report_sent = *report; +} + +static void send_mouse(report_mouse_t *report) +{ +#ifdef MOUSE_ENABLE + /* Select the Mouse Report Endpoint */ + Endpoint_SelectEndpoint(MOUSE_IN_EPNUM); + + /* Check if Mouse Endpoint Ready for Read/Write */ + if (Endpoint_IsReadWriteAllowed()) + { + /* Write Mouse Report Data */ + Endpoint_Write_Stream_LE(report, sizeof(report_mouse_t), NULL); + + /* Finalize the stream transfer to send the last packet */ + Endpoint_ClearIN(); + } +#endif +} + +static void send_system(uint16_t data) +{ + report_extra_t r = { + .report_id = REPORT_ID_SYSTEM, + .usage = data + }; + Endpoint_SelectEndpoint(EXTRA_IN_EPNUM); + if (Endpoint_IsReadWriteAllowed()) { + Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL); + Endpoint_ClearIN(); + } +} + +static void send_consumer(uint16_t data) +{ + report_extra_t r = { + .report_id = REPORT_ID_CONSUMER, + .usage = data + }; + Endpoint_SelectEndpoint(EXTRA_IN_EPNUM); + if (Endpoint_IsReadWriteAllowed()) { + Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL); + Endpoint_ClearIN(); + } +} + + +/******************************************************************************* + * sendchar + ******************************************************************************/ +int8_t sendchar(uint8_t c) +{ + if (USB_DeviceState != DEVICE_STATE_Configured) + return -1; + + Endpoint_SelectEndpoint(CONSOLE_IN_EPNUM); + + uint8_t timeout = 10; + uint16_t prevFN = USB_Device_GetFrameNumber(); + while (!Endpoint_IsINReady()) { + switch (USB_DeviceState) { + case DEVICE_STATE_Unattached: + case DEVICE_STATE_Suspended: + return -1; + } + if (Endpoint_IsStalled()) + return -1; + if (prevFN != USB_Device_GetFrameNumber()) { + if (!(timeout--)) + return -1; + prevFN = USB_Device_GetFrameNumber(); + } + } + + Endpoint_Write_8(c); + + // send when packet is full + if (!Endpoint_IsReadWriteAllowed()) + Endpoint_ClearIN(); + + return 0; +} diff --git a/protocol/lufa/lufa.h b/protocol/lufa/lufa.h new file mode 100644 index 00000000..71c279b0 --- /dev/null +++ b/protocol/lufa/lufa.h @@ -0,0 +1,58 @@ +/* + * Copyright 2012 Jun Wako + * This file is based on: + * LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse + * LUFA-120219/Demos/Device/Lowlevel/GenericHID + */ + +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2010 Denver Gingerich (denver [at] ossguy [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim 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, 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. +*/ + +#ifndef _LUFA_H_ +#define _LUFA_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + + +/* extra report structure */ +typedef struct { + uint8_t report_id; + uint16_t usage; +} __attribute__ ((packed)) report_extra_t; + +#endif diff --git a/protocol/pjrc.mk b/protocol/pjrc.mk index 1ee45e9e..cccdf620 100644 --- a/protocol/pjrc.mk +++ b/protocol/pjrc.mk @@ -1,21 +1,21 @@ -OPT_DEFS += -DHOST_PJRC - -SRC += pjrc.c \ - usb_keyboard.c \ - usb_debug.c \ - usb.c \ - bootloader_teensy.c +PJRC_DIR = protocol/pjrc +OPT_DEFS += -DHOST_PJRC -# Search Path -VPATH += $(TOP_DIR)/protocol/pjrc - +SRC += $(PJRC_DIR)/main.c \ + $(PJRC_DIR)/pjrc.c \ + $(PJRC_DIR)/usb_keyboard.c \ + $(PJRC_DIR)/usb_debug.c \ + $(PJRC_DIR)/usb.c # Option modules ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE) - SRC += usb_mouse.c + SRC += $(PJRC_DIR)/usb_mouse.c endif ifdef EXTRAKEY_ENABLE - SRC += usb_extra.c + SRC += $(PJRC_DIR)/usb_extra.c endif + +# Search Path +VPATH += $(TOP_DIR)/$(PJRC_DIR) diff --git a/protocol/pjrc/bootloader_teensy.c b/protocol/pjrc/bootloader_teensy.c deleted file mode 100644 index 9d34852f..00000000 --- a/protocol/pjrc/bootloader_teensy.c +++ /dev/null @@ -1,40 +0,0 @@ -/* See http://www.pjrc.com/teensy/jump_to_bootloader.html */ -#include -#include -#include -#include "bootloader.h" - -void bootloader_jump(void) { - cli(); - // disable watchdog, if enabled - // disable all peripherals - UDCON = 1; - USBCON = (1< - -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 . -*/ - -#include -#include -#include "bootloader.h" - - -void bootloader_jump(void) { - cli(); - // This makes custom USBasploader come up. - MCUSR = 0; - - // ATmega168PA - // initialize ports - PORTB = 0; PORTC= 0; PORTD = 0; - DDRB = 0; DDRC= 0; DDRD = 0; - - // disable interrupts - EIMSK = 0; EECR = 0; SPCR = 0; - ACSR = 0; SPMCSR = 0; WDTCSR = 0; PCICR = 0; - TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; - ADCSRA = 0; TWCR = 0; UCSR0B = 0; - - // Boot Loader Section Start Address: - // BOOTSZ Size Address - // (lock bit) (word) (word) (byte) - // '11' 128 0x1F80 0x3F00 - // '10' 256 0x1F00 0x3E00 - // '01' 512 0x1E00 0x3C00 - // '00' 1024 0x1C00 0x3800 - asm volatile("jmp 0x3800"); -} diff --git a/protocol/vusb/main.c b/protocol/vusb/main.c index 1bf9035b..3deb8223 100644 --- a/protocol/vusb/main.c +++ b/protocol/vusb/main.c @@ -90,10 +90,15 @@ int main(void) } } #endif - if (!suspended) + if (!suspended) { usbPoll(); - keyboard_proc(); - if (!suspended) + + // TODO: configuration process is incosistent. it sometime fails. + // To prevent failing to configure NOT scan keyboard during configuration + if (usbConfiguration && usbInterruptIsReady()) { + keyboard_proc(); + } vusb_transfer_keyboard(); + } } } diff --git a/protocol/vusb/vusb.c b/protocol/vusb/vusb.c index 0bfe21e9..4e11836e 100644 --- a/protocol/vusb/vusb.c +++ b/protocol/vusb/vusb.c @@ -91,20 +91,38 @@ static void send_keyboard(report_keyboard_t *report) } +typedef struct { + uint8_t report_id; + report_mouse_t report; +} __attribute__ ((packed)) vusb_mouse_report_t; + static void send_mouse(report_mouse_t *report) { - report->report_id = REPORT_ID_MOUSE; + vusb_mouse_report_t r = { + .report_id = REPORT_ID_MOUSE, + .report = *report + }; if (usbInterruptIsReady3()) { - usbSetInterrupt3((void *)report, sizeof(*report)); + usbSetInterrupt3((void *)&r, sizeof(vusb_mouse_report_t)); } } + +typedef struct { + uint8_t report_id; + uint16_t usage; +} __attribute__ ((packed)) report_extra_t; + static void send_system(uint16_t data) { - // Not need static? - static uint8_t report[] = { REPORT_ID_SYSTEM, 0, 0 }; - report[1] = data&0xFF; - report[2] = (data>>8)&0xFF; + static uint16_t last_data = 0; + if (data == last_data) return; + last_data = data; + + report_extra_t report = { + .report_id = REPORT_ID_SYSTEM, + .usage = data + }; if (usbInterruptIsReady3()) { usbSetInterrupt3((void *)&report, sizeof(report)); } @@ -116,10 +134,10 @@ static void send_consumer(uint16_t data) if (data == last_data) return; last_data = data; - // Not need static? - static uint8_t report[] = { REPORT_ID_CONSUMER, 0, 0 }; - report[1] = data&0xFF; - report[2] = (data>>8)&0xFF; + report_extra_t report = { + .report_id = REPORT_ID_CONSUMER, + .usage = data + }; if (usbInterruptIsReady3()) { usbSetInterrupt3((void *)&report, sizeof(report)); } diff --git a/rules.mk b/rules.mk index 104031fb..e561eae6 100644 --- a/rules.mk +++ b/rules.mk @@ -25,8 +25,23 @@ # # make extcoff = Convert ELF to AVR Extended COFF. # -# make program = Download the hex file to the device, using avrdude. -# Please customize the avrdude settings below first! +# make program = Download the hex file to the device. +# Please customize your programmer settings(PROGRAM_CMD) +# +# make teensy = Download the hex file to the device, using teensy_loader_cli. +# (must have teensy_loader_cli installed). +# +# make dfu = Download the hex file to the device, using dfu-programmer (must +# have dfu-programmer installed). +# +# make flip = Download the hex file to the device, using Atmel FLIP (must +# have Atmel FLIP installed). +# +# make dfu-ee = Download the eeprom file to the device, using dfu-programmer +# (must have dfu-programmer installed). +# +# make flip-ee = Download the eeprom file to the device, using Atmel FLIP +# (must have Atmel FLIP installed). # # make debug = Start either simulavr or avarice as specified for debugging, # with avr-gdb or avr-insight as the front end for debugging. @@ -109,8 +124,10 @@ CFLAGS += -O$(OPT) CFLAGS += -funsigned-char CFLAGS += -funsigned-bitfields CFLAGS += -ffunction-sections +CFLAGS += -fno-inline-small-functions CFLAGS += -fpack-struct CFLAGS += -fshort-enums +CFLAGS += -fno-strict-aliasing CFLAGS += -Wall CFLAGS += -Wstrict-prototypes #CFLAGS += -mshort-calls @@ -230,7 +247,7 @@ EXTMEMOPTS = # (.vectors+0x30): relocation truncated to fit: R_AVR_13_PCREL against symbol `__vector_12' # LDFLAGS = -Wl,-Map=$(TARGET).map,--cref -#LDFLAGS += -Wl,--relax +LDFLAGS += -Wl,--relax LDFLAGS += -Wl,--gc-sections LDFLAGS += $(EXTMEMOPTS) LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) @@ -387,6 +404,34 @@ gccversion : program: $(TARGET).hex $(TARGET).eep $(PROGRAM_CMD) +teensy: $(TARGET).hex + teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex + +flip: $(TARGET).hex + batchisp -hardware usb -device $(MCU) -operation erase f + batchisp -hardware usb -device $(MCU) -operation loadbuffer $(TARGET).hex program + batchisp -hardware usb -device $(MCU) -operation start reset 0 + +dfu: $(TARGET).hex + dfu-programmer $(MCU) erase + dfu-programmer $(MCU) flash $(TARGET).hex + dfu-programmer $(MCU) reset + +dfu-start: + dfu-programmer $(MCU) reset + dfu-programmer $(MCU) start + +flip-ee: $(TARGET).hex $(TARGET).eep + $(COPY) $(TARGET).eep $(TARGET)eep.hex + batchisp -hardware usb -device $(MCU) -operation memory EEPROM erase + batchisp -hardware usb -device $(MCU) -operation memory EEPROM loadbuffer $(TARGET)eep.hex program + batchisp -hardware usb -device $(MCU) -operation start reset 0 + $(REMOVE) $(TARGET)eep.hex + +dfu-ee: $(TARGET).hex $(TARGET).eep + dfu-programmer $(MCU) eeprom-flash $(TARGET).eep + dfu-programmer $(MCU) reset + # Generate avr-gdb config/init file which does the following: # define the reset signal, load the target file, connect to target, and set @@ -488,6 +533,7 @@ extcoff: $(TARGET).elf # Compile: create object files from C source files. $(OBJDIR)/%.o : %.c @echo + mkdir -p $(@D) @echo $(MSG_COMPILING) $< $(CC) -c $(ALL_CFLAGS) $< -o $@ @@ -538,7 +584,11 @@ clean_list : $(REMOVE) $(OBJ:.o=.s) $(REMOVE) $(OBJ:.o=.i) $(REMOVE) -r .dep - $(REMOVEDIR) $(OBJDIR) + $(REMOVE) -r $(OBJDIR) + +show_path: + @echo VPATH=$(VPATH) + @echo SRC=$(SRC) # Create object files directory @@ -552,5 +602,5 @@ $(shell mkdir $(OBJDIR) 2>/dev/null) # Listing of phony targets. .PHONY : all begin finish end sizebefore sizeafter gccversion \ build elf hex eep lss sym coff extcoff \ -clean clean_list program debug gdb-config - +clean clean_list debug gdb-config show_path \ +program teensy dfu flip dfu-ee flip-ee dfu-start