Merge branch 'hhkb_tmk'

daktil_manuform
tmk 2013-07-11 16:26:00 +09:00
commit f4c69652c1
7 changed files with 357 additions and 94 deletions

View File

@ -0,0 +1,129 @@
#----------------------------------------------------------------------------
# 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_tmk
# 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)
# Interrupt driven control endpoint task
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# comment out to disable the options.
#
#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration
MOUSEKEY_ENABLE = yes # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = yes # Console for debug
COMMAND_ENABLE = yes # Commands for debug and configuration
#NKRO_ENABLE = yes # USB Nkey Rollover
# Search Path
VPATH += $(TARGET_DIR)
VPATH += $(TOP_DIR)
include $(TOP_DIR)/protocol/lufa.mk
include $(TOP_DIR)/common.mk
include $(TOP_DIR)/rules.mk
debug-on: EXTRAFLAGS += -DDEBUG
debug-on: all

View File

@ -2,128 +2,144 @@ Alternative Controller for HHKB Pro
=================================== ===================================
I wanted to add some features like vi cursor and mouse keys to my [HHKB][HHKB] but its controller is not programmable and I wanted to add some features like vi cursor and mouse keys to my [HHKB][HHKB] but its controller is not programmable and
firmware source code is not open, of course. This means customizing this keyboard needs to replace original firmware source code is not open, of course. This means customizing this keyboard needs to replace original
controller with programmable one. For this purpose I used PJRC [Teensy++][Teensy] as alternative controller. controller with programmable one. This controller can work with HHKB Professional and Professional 2 model.
See [this thread][AltController] in geekhack.org.
[HHKB]: http://www.pfu.fujitsu.com/hhkeyboard/ [HHKB]: http://www.pfu.fujitsu.com/hhkeyboard/
[AltController]: http://geekhack.org/index.php?topic=12047.0
[Teensy]: http://www.pjrc.com/teensy/ [Teensy]: http://www.pjrc.com/teensy/
My keyboard firmware source tree is here: http://github.com/tmk/tmk_keyboard
See directory keyboard/hhkb to build firmware for HHKB.
##Features ##Features
* Customizable keymap * Customizable keymap
* More keymap layers(more Fn keys) * More keymap layers(more Fn keys)
* Mouse keys * Mouse keys
* USB NKRO * USB NKRO
See README of [tmk_keyboard] for more.
[tmk_keyboard]: http://github.com/tmk/tmk_keyboard
###Pros ###Pros
* No risk: Everything is all reversible
* Without PCB trace cutting, case mod or any destructives * Without PCB trace cutting, case mod or any destructives
* Can keep original controller intact * Can keep original controller intact
* Can change all HHKB behaviour as you like * Can change all HHKB behaviour as you like
###Cons ###Cons
* Void your warranty * Void your warranty
* Lose USB hub function in case of Pro2 * Lose USB hub function of Pro2
##DISCLAIMER ##DISCLAIMER
I'm not a professional of electronics or MCU programming. This may damage your HHKB. I'm not a professional of electronics nor MCU programming. This may damage your HHKB.
And my English writing is poor, I'm not sure I can convey my notions accurately. And my English writing is poor, I'm not sure I can convey my notions accurately.
##Documents
See [doc/HHKB.txt](doc/HHKB.txt) and files under [doc/](doc/) for internal of HHKB and this controller.
##Build Firmware & Program
You can choose some combination of hardware and USB protocol stack([LUFA], [PJRC]).
### Install Tools
See [this document](../../doc/build.md).
### TMK Alt Controller Board
$ make -f Makefile.tmk
This programs the controller with [dfu-programmer] if the tool is intalled and configured properly.
$ make -f Makefile.tmk dfu
Push reset button and program with [FLIP]. The tool should be intalled and configured properly.
$ make -f Makefile.tmk flip
Or you can also program with FLIP GUI.
[dfu-programmer]: http://dfu-programmer.sourceforge.net/
[FLIP]: http://www.atmel.com/tools/FLIP.aspx
##Build Firmware ### PJRC Teensy++
You can choose some combination of MCU and USB protocol stack. Build with [LUFA] USB stack:
### Teensy++(AVR USB family) with [LUFA] $ make -f Makefile.lufa
0. Edit **matrix.c** to use your pin configuration. See doc/HHKB.txt for detail.
1. Edit **keymap.c** to use your favoirte keymap. or with [PJRC] USB stack:
2. Edit **Makefile** if you want to use other `MCU` than Teensy++ 2.0. $ make -f Makefile.pjrc
3. Build firmware binary file: Push reset button and program with [Teensy Loader(command line)]. The tool should be intalled and configured properly.
`$ make -f Makefile.lufa`
4. Program MCU with PJRC [Teensy Loader] tool. If you install command line version of the loader just run: $ make -f Makefile.lufa teensy
`$ make -f Makefile.lufa teensy` $ make -f Makefile.pjrc teensy
Or you can also program with [Teensy Loader(GUI)].
[LUFA]: http://www.fourwalledcubicle.com/LUFA.php [LUFA]: http://www.fourwalledcubicle.com/LUFA.php
[Teensy Loader]: http://www.pjrc.com/teensy/loader.html [PJRC]: http://www.pjrc.com/teensy/usb_keyboard.html
[Teensy Loader(command line)]: http://www.pjrc.com/teensy/loader_cli.html
[Teensy Loader(GUI)]: http://www.pjrc.com/teensy/loader.html
###AVR Mega with [V-USB] ###AVR Mega with [V-USB]
Follow below if you want to use AVR with V-USB as . Build:
$ make -f Makefile.vusb
0. Edit **matrix.c** to use your pin configuration. See doc/HHKB.txt for detail. Program [USBaspLoader] on MCU with AVR programmer like [AVRISPmkII] and tool like [avrdude].
1. Edit **keymap.c** to use your favoirte keymap. You can programs with [avrdude] once you have programmed [USBaspLoader] on MCU.
$ make -f Makefile.vusb program
2. Edit **usbconfig.h** to configure V-USB options. [AVRISPmkII]: http://www.atmel.com/tools/AVRISPMKII.aspx
[avrdude]: http://www.nongnu.org/avrdude/
3. Edit **Makefile.vusb** to define `MCU` and `F_CPU`.
4. Build firmware binary file:
`$ make -f Makefile.vusb`
5. Program MCU with AVR programmer like AVRISPmkII. If you already have [USBaspLoader] on MCU just run:
`$ make -f Makefile.vusb program`
[V-USB]: http://www.obdev.at/products/vusb/index.html
[USBaspLoader]: http://www.obdev.at/products/vusb/usbasploader.html
###How to Customize Keymap ##How to Customize
Later... See [tmk_keyboard] documents.
See **keymap.c**.
##Hardware ##Hardware
You have some options for hardware. Development boards with USB AVR family(ATMega32U4, AT90USB1286) like Teensy will work while MegaAVR with V-USB library is also cheapear option for DIY.
###Teensy++ installation ###1. TMK Alt Controller Board
Angled USB mini B adapter is used to install Teensy++ laterally. TMK designed [Keyboard Controller Board for HHKB Pro2(KiCad project)](https://github.com/tmk/HHKB_controller).
See [this post](http://geekhack.org/index.php?topic=12047.msg948923#msg948923).
![Image of Teensy install](hhkb/doc/HHKB_img/teensy_install.jpg)
Bread baord wires are used to connect Teensy++.
![Image of Teensy wiring](hhkb/doc/HHKB_img/teensy_wiring.jpg)
![Image of Connector](hhkb/doc/HHKB_img/connector_contact.jpg)
###PJRC Teensy++ 2.0 connection ###2. PJRC Teensy++ 2.0 connection
+---------------+ +---------------+
| Teensy++ | | Teensy++ |
| | | |
| | HHKB | | HHKB pro HHKB pro2
| | ~~~~ | | ~~~~~~~~ ~~~~~~~~~
| PB0-2|------->ROW(6-8) | PB0-2|------->ROW (6-8) (5-7)
| PB3-5|------->COL(9-11) | PB3-5|------->COL (9-11) (8-10)
| PB6|------->ENABLE(12) | PB6|------->ENABLE (12) (11)
| PE6|<-------KEY(4) | PE6|<-------KEY (4) (3)
| PE7|------->PREV(5) | PE7|------->PREV (5) (4)
| | | |
| | | | 5V--- (1-3) (1-2)
| | | | GND--- (13-14) (12-13)
+---------------+ +---------------+
- NOTE: PJRC [Teensy](http://www.pjrc.com/teensy/)
[Teensy Loader]: http://www.pjrc.com/teensy/loader.html
###V-USB circuit ###3. V-USB connection
+---+ +---------------+ +---+ +---------------+
USB GND | | ATmega168 | USB GND | | ATmega328p |
~~~ C3 | | ~~~ C3 | |
5V <-------+--------+---|Vcc,AVCC | HHKB 5V <-------+--------+---|Vcc,AVCC | HHKB pro pro2
R1 | | ~~~~ R1 | | ~~~~~~~~ ~~~~
D- <----+--+-----R2-----|INT1 PB2-4|------->ROW(6-8) D- <----+--+-----R2-----|INT1 PB2-4|------->ROW (6-8) (5-7)
D+ <----|---+----R3-----|INT0 PC0-2|------->COL(9-11) D+ <----|---+----R3-----|INT0 PC0-2|------->COL (9-11) (8-10)
Z1 Z2 | PC3|------->ENABLE(12) Z1 Z2 | PC3|------->ENABLE (12) (11)
GND<----+---+-----------|GND PB0|<-------KEY(4) GND<----+---+-----------|GND PB0|<-------KEY (4) (3)
| PB1|------->PREV(5) | PB1|------->PREV (5) (4)
| | | |
GND+-C2--+--|XTAL1 RXD|------->Debug Console GND+-C2--+--|XTAL1 RXD|------->Debug Console
X1 | TXD|<-------Debug Console X1 | TXD|<-------Debug Console
@ -134,5 +150,11 @@ Bread baord wires are used to connect Teensy++.
Z1,Z2: Zener 3.6V Z1,Z2: Zener 3.6V
C1,C2: 22pF C1,C2: 22pF
C3: 0.1uF C3: 0.1uF
X1: Crystal 20MHz(16MHz/12MHz) X1: Crystal 12MHz
SW: Push Switch(Optional for bootloader) SW: Push Switch(for bootloader)
- NOTE: See [V-USB] documentation for more detail of hardware and the USB stack.
- NOTE: [USBaspLoader] is very useful for firmware update.
[V-USB]: http://www.obdev.at/products/vusb/index.html
[USBaspLoader]: http://www.obdev.at/products/vusb/usbasploader.html

View File

@ -54,7 +54,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#endif #endif
/* period of tapping(ms) */ /* period of tapping(ms) */
#define TAPPING_TERM 200 #define TAPPING_TERM 300
/* tap count needed for toggling a feature */ /* tap count needed for toggling a feature */
#define TAPPING_TOGGLE 5 #define TAPPING_TOGGLE 5

View File

@ -30,25 +30,27 @@ Connector Cable
Two PCBs are connected by 15 lines(13 in case of Pro2). Two PCBs are connected by 15 lines(13 in case of Pro2).
Vcc and GND use 3(2) lines each, other 9 lines are for keyboard signaling. Vcc and GND use 3(2) lines each, other 9 lines are for keyboard signaling.
Keyswitch PCB connector Teensy++ pins Keyswitch connector
------------------------------------------------------------------------------- pro pro2 Description Teensy++ pins
1 Vcc(5V) Not exist on Pro2 5V --------------------------------------------------------------------------------------------
2 Vcc(5V) 5V 1 Vcc(5V) Not exist on Pro2 5V
3 Vcc(5V) 5V 2 1 Vcc(5V) 5V
4 TP1684 KEY: Low(0) when key pressed PE6 input(with pullup) 3 2 Vcc(5V) 5V
5 TP1684 KEY_PREV: assert previous key state??? PE7 output 4 3 TP1684 KEY: Low(0) when key pressed PE6 input(with pullup)
6 HC4051 A(bit0) select 8 rows(0 to 7) PB0 output 5 4 TP1684 KEY_PREV: make threshold PE7 output
7 HC4051 B(bit1) PB1 output 6 5 HC4051 A(bit0)\ PB0 output
8 HC4051 C(bit2) PB2 output 7 6 HC4051 B(bit1) > select row(0 to 7) PB1 output
9 LS145 A(bit0) select 8 columns(0 to 7) PB3 output 8 7 HC4051 C(bit2)/ PB2 output
10 LS145 B(bit1) PB4 output 9 8 LS145 A(bit0)\ PB3 output
11 LS145 C(bit2) PB5 output 10 9 LS145 B(bit1) > select column(0 to 7) PB4 output
12 LS145 D(enable) Low(0) enable selected column PB6 output 11 10 LS145 C(bit2)/ PB5 output
13 GND GND 12 11 LS145 D(enable) Low(0) enables selected column PB6 output
14 GND GND 13 12 GND GND
15 GND Not exist on Pro2 GND 14 13 GND GND
15 GND Not exist on Pro2 GND
NOTE: guessing pin5(KEY_PREV) may work for hysteresis of capacitive sensing. NOTE: guessing pin5(KEY_PREV) may work for hysteresis of capacitive sensing.
NOTE: 1KOhm didn't work as pullup resistor on KEY. AVR internal pullup or 10KOhm resistor was OK.
(HHKB_connector.jpg) (HHKB_connector.jpg)

View File

@ -0,0 +1,48 @@
HHKB Power consumption
----------------------
**Power consumption
board clock/prescaler keyswitch power ctrl current
--------------------------------------------------------------------------
tmk 16MHz no no 26.4mA
tmk 16MHz pro1 no 45.1mA
tmk 16MHz/2 no no 18.1mA
tmk 16MHz/2 pro1 no 37.3mA
tmk 8MHz no no 18.9mA
tmk 8MHz pro2 no(w/o FET) 32.1mA
tmk 8MHz pro2 no(w FET) 32.1mA withou POWER_ON/FF
tmk 8MHz pro2 no(w FET) 32.6mA with POWR_ON/OFF
tmk 8MHz pro2 15ms(w FET) 21.3mA with POWR_ON/OFF, enumerated but error -32
tmk 8MHz pro2 60ms(w FET) 13.3mA with POWR_ON/OFF, not enumerated
gh60 16MHz 25.8mA
gh60 16MHz USB suspend w LED breathing 17.6-29.1mA
gh60 16MHz USB suspend w/o LED 0.2mA(0.231-0.276mA)
Poker 5.6mA
Poker USB suspend 0.3mA(0.301mA)
gh60 16MHz stock firmware by komar 26.8mA
HHKB pro2 Over All 139.4mA
HHKB pro2 Controller 115.1mA
HHKB pro1 Controller 25.9mA
keyswitch power consumption:
pro1: 45.1-26.4=18.7mA
37.3-18.1=19.2mA
pro2: 32.1-18.9=13.2mA
**Low Freq Crystal or Prescaler?
No advantage of Low Freq Crystal against Prescaled.
Clock routing
X'tal --+---->Prescaler-------> System Clock
|
+---------------------> USB PLL
Design Decision: Install 16MHz crystal on board with using clock rescaler.

View File

@ -15,6 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <avr/io.h>
#include "stdint.h" #include "stdint.h"
#include "led.h" #include "led.h"
@ -22,5 +23,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* HHKB has no LEDs */ /* HHKB has no LEDs */
void led_set(uint8_t usb_led) void led_set(uint8_t usb_led)
{ {
if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
DDRD |= (1<<6);
PORTD |= (1<<6);
} else {
DDRD |= (1<<6);
PORTD &= ~(1<<6);
}
} }

View File

@ -63,7 +63,7 @@ static matrix_row_t _matrix1[MATRIX_ROWS];
PORTE |= (1<<6); \ PORTE |= (1<<6); \
} while (0) } while (0)
#define KEY_SELECT(ROW, COL) (PORTB = (PORTB & 0xC0) | \ #define KEY_SELECT(ROW, COL) (PORTB = (PORTB & 0xC0) | \
(((COL) & 0x07)<<3) | \ (((COL) & 0x07)<<3) | \
((ROW) & 0x07)) ((ROW) & 0x07))
#define KEY_ENABLE() (PORTB &= ~(1<<6)) #define KEY_ENABLE() (PORTB &= ~(1<<6))
#define KEY_UNABLE() (PORTB |= (1<<6)) #define KEY_UNABLE() (PORTB |= (1<<6))
@ -73,6 +73,50 @@ static matrix_row_t _matrix1[MATRIX_ROWS];
#define KEY_POWER_ON() #define KEY_POWER_ON()
#define KEY_POWER_OFF() #define KEY_POWER_OFF()
#elif defined(__AVR_ATmega32U4__)
// Ports for my designed Alt Controller PCB
// row: PB0-2
// col: PB3-5,6
// key: PD7(pull-uped)
// prev: PB7
// power: PD4(L:off/H:on)
#define KEY_INIT() do { \
DDRB = 0xFF; \
PORTB = 0x00; \
DDRD &= ~0x80; \
PORTD |= 0x80; \
/* keyswitch board power on */ \
DDRD |= (1<<4); \
PORTD |= (1<<4); \
KEY_UNABLE(); \
KEY_PREV_OFF(); \
} while (0)
#define KEY_SELECT(ROW, COL) (PORTB = (PORTB & 0xC0) | \
(((COL) & 0x07)<<3) | \
((ROW) & 0x07))
#define KEY_ENABLE() (PORTB &= ~(1<<6))
#define KEY_UNABLE() (PORTB |= (1<<6))
#define KEY_STATE() (PIND & (1<<7))
#define KEY_PREV_ON() (PORTB |= (1<<7))
#define KEY_PREV_OFF() (PORTB &= ~(1<<7))
#define KEY_POWER_ON()
#define KEY_POWER_OFF()
/*
#define KEY_POWER_ON() do { \
KEY_INIT(); \
PORTD |= (1<<4); \
_delay_ms(1); \
} while (0)
#define KEY_POWER_OFF() do { \
PORTD &= ~(1<<4); \
DDRB &= ~0xFF; \
PORTB &= ~0xFF; \
DDRB &= ~0x80; \
PORTB &= ~0x80; \
} while (0)
*/
#elif defined(__AVR_ATmega328P__) #elif defined(__AVR_ATmega328P__)
// Ports for V-USB // Ports for V-USB
// key: PB0(pull-uped) // key: PB0(pull-uped)
@ -130,7 +174,6 @@ uint8_t matrix_cols(void)
void matrix_init(void) void matrix_init(void)
{ {
#ifdef DEBUG #ifdef DEBUG
print_enable = true;
debug_enable = true; debug_enable = true;
debug_keyboard = true; debug_keyboard = true;
#endif #endif
@ -170,9 +213,21 @@ uint8_t matrix_scan(void)
uint8_t last = TIMER_RAW; uint8_t last = TIMER_RAW;
KEY_ENABLE(); KEY_ENABLE();
// Wait for KEY_STATE outputs its value. // Wait for KEY_STATE outputs its value.
// 1us was ok on one HHKB, but not worked on another. // 1us was ok on one HHKB, but not worked on another.
_delay_us(10); // no wait doesn't work on Teensy++ with pro(1us works)
// no wait does work on tmk PCB(8MHz) with pro2
// 1us wait does work on both of above
// 1us wait doesn't work on tmk(16MHz)
// 5us wait does work on tmk(16MHz)
// 5us wait does work on tmk(16MHz/2)
// 5us wait does work on tmk(8MHz)
// 10us wait does work on Teensy++ with pro
// 10us wait does work on 328p+iwrap with pro
// 10us wait doesn't work on tmk PCB(8MHz) with pro2(very lagged scan)
_delay_us(5);
if (KEY_STATE()) { if (KEY_STATE()) {
matrix[row] &= ~(1<<col); matrix[row] &= ~(1<<col);
} else { } else {