/* Layer 1: HHKB mode (HHKB Fn) | /* Layer 1: HHKB mode (HHKB Fn) | ||||
* ,-----------------------------------------------------------. | * ,-----------------------------------------------------------. | ||||
* |Pow| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del| | |||||
* |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del| | |||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* |Caps | | | | | | | |Psc|Slk|Pus|Up | |Backs| | * |Caps | | | | | | | |Psc|Slk|Pus|Up | |Backs| | ||||
* |-----------------------------------------------------------| | * |-----------------------------------------------------------| | ||||
* |Gui |Alt |Space |Alt |xxx| | * |Gui |Alt |Space |Alt |xxx| | ||||
* `--------------------------------------------' | * `--------------------------------------------' | ||||
*/ | */ | ||||
KEYMAP(KB_PWR, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_INS, KB_DEL, \ | |||||
KEYMAP(KB_ESC, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, KB_F11, KB_F12, KB_INS, KB_DEL, \ | |||||
KB_CAPS,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_PSCR,KB_SLCK,KB_BRK, KB_UP, KB_NO, KB_BSPC, \ | KB_CAPS,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KB_PSCR,KB_SLCK,KB_BRK, KB_UP, KB_NO, KB_BSPC, \ | ||||
KB_LCTL,KB_VOLD,KB_VOLU,KB_MUTE,KB_NO, KB_NO, KP_ASTR,KP_SLSH,KB_HOME,KB_PGUP,KB_LEFT,KB_RGHT,KB_ENT, \ | KB_LCTL,KB_VOLD,KB_VOLU,KB_MUTE,KB_NO, KB_NO, KP_ASTR,KP_SLSH,KB_HOME,KB_PGUP,KB_LEFT,KB_RGHT,KB_ENT, \ | ||||
KB_LSFT,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KP_PLUS,KP_MINS,KB_END, KB_PGDN,KB_DOWN,KB_RSFT,FN_1, \ | KB_LSFT,KB_NO, KB_NO, KB_NO, KB_NO, KB_NO, KP_PLUS,KP_MINS,KB_END, KB_PGDN,KB_DOWN,KB_RSFT,FN_1, \ |
#include "usb_mouse.h" | #include "usb_mouse.h" | ||||
#include "usb_extra.h" | #include "usb_extra.h" | ||||
#include "usb_keycodes.h" | #include "usb_keycodes.h" | ||||
#include "usb.h" | |||||
#include "layer.h" | #include "layer.h" | ||||
#include "matrix_skel.h" | #include "matrix_skel.h" | ||||
#include "keymap_skel.h" | #include "keymap_skel.h" | ||||
static int mouse_repeat = 0; | static int mouse_repeat = 0; | ||||
bool modified = false; | bool modified = false; | ||||
//bool has_ghost = false; | |||||
int key_index = 0; | int key_index = 0; | ||||
uint8_t mouse_btn = 0; | uint8_t mouse_btn = 0; | ||||
int8_t mouse_x = 0; | int8_t mouse_x = 0; | ||||
matrix_scan(); | matrix_scan(); | ||||
modified = matrix_is_modified(); | modified = matrix_is_modified(); | ||||
if (modified) { | if (modified) { | ||||
if (debug_matrix) matrix_print(); | if (debug_matrix) matrix_print(); | ||||
#ifdef DEBUG_LED | #ifdef DEBUG_LED | ||||
for (int col = 0; col < matrix_cols(); col++) { | for (int col = 0; col < matrix_cols(); col++) { | ||||
if (!matrix_is_on(row, col)) continue; | if (!matrix_is_on(row, col)) continue; | ||||
// TODO: clean code | |||||
uint8_t code = layer_get_keycode(row, col); | uint8_t code = layer_get_keycode(row, col); | ||||
if (code == KB_NO) { | if (code == KB_NO) { | ||||
// do nothing | // do nothing | ||||
} else if (IS_MOD(code)) { | } else if (IS_MOD(code)) { | ||||
usb_keyboard_mods |= MOD_BIT(code); | usb_keyboard_mods |= MOD_BIT(code); | ||||
} else if (IS_FN(code)) { | |||||
fn_bits |= FN_BIT(code); | |||||
} else if (IS_MOUSE(code)) { | } else if (IS_MOUSE(code)) { | ||||
// mouse | |||||
if (code == MS_UP) | |||||
mouse_y -= MOUSE_MOVE_UNIT + MOUSE_MOVE_ACCEL; | |||||
if (code == MS_DOWN) | |||||
mouse_y += MOUSE_MOVE_UNIT + MOUSE_MOVE_ACCEL; | |||||
if (code == MS_LEFT) | |||||
mouse_x -= MOUSE_MOVE_UNIT + MOUSE_MOVE_ACCEL; | |||||
if (code == MS_RIGHT) | |||||
mouse_x += MOUSE_MOVE_UNIT + MOUSE_MOVE_ACCEL; | |||||
if (code == MS_UP) mouse_y -= MOUSE_MOVE_UNIT + MOUSE_MOVE_ACCEL; | |||||
if (code == MS_DOWN) mouse_y += MOUSE_MOVE_UNIT + MOUSE_MOVE_ACCEL; | |||||
if (code == MS_LEFT) mouse_x -= MOUSE_MOVE_UNIT + MOUSE_MOVE_ACCEL; | |||||
if (code == MS_RGHT) mouse_x += MOUSE_MOVE_UNIT + MOUSE_MOVE_ACCEL; | |||||
if (code == MS_BTN1) mouse_btn |= BIT_BTN1; | if (code == MS_BTN1) mouse_btn |= BIT_BTN1; | ||||
if (code == MS_BTN2) mouse_btn |= BIT_BTN2; | if (code == MS_BTN2) mouse_btn |= BIT_BTN2; | ||||
if (code == MS_BTN3) mouse_btn |= BIT_BTN3; | if (code == MS_BTN3) mouse_btn |= BIT_BTN3; | ||||
if (code == MS_BTN4) mouse_btn |= BIT_BTN4; | if (code == MS_BTN4) mouse_btn |= BIT_BTN4; | ||||
if (code == MS_BTN5) mouse_btn |= BIT_BTN5; | if (code == MS_BTN5) mouse_btn |= BIT_BTN5; | ||||
if (code == MS_WH_UP) mouse_vwheel += 1; | |||||
if (code == MS_WH_DOWN) mouse_vwheel -= 1; | |||||
if (code == MS_WH_LEFT) mouse_hwheel -= 1; | |||||
if (code == MS_WH_RIGHT) mouse_hwheel += 1; | |||||
} else if (IS_FN(code)) { | |||||
fn_bits |= FN_BIT(code); | |||||
} else if (code == KB_MUTE) { | |||||
usb_extra_send(AUDIO_MUTE); | |||||
usb_extra_send(0); | |||||
if (code == MS_WH_U) mouse_vwheel += 1; | |||||
if (code == MS_WH_D) mouse_vwheel -= 1; | |||||
if (code == MS_WH_L) mouse_hwheel -= 1; | |||||
if (code == MS_WH_R) mouse_hwheel += 1; | |||||
} | |||||
// audio control & system control | |||||
else if (code == KB_MUTE) { | |||||
usb_extra_audio_send(AUDIO_MUTE); | |||||
usb_extra_audio_send(0); | |||||
_delay_ms(500); | _delay_ms(500); | ||||
} else if (code == KB_VOLU) { | } else if (code == KB_VOLU) { | ||||
usb_extra_send(AUDIO_VOL_UP); | |||||
usb_extra_send(0); | |||||
usb_extra_audio_send(AUDIO_VOL_UP); | |||||
usb_extra_audio_send(0); | |||||
_delay_ms(100); | _delay_ms(100); | ||||
} else if (code == KB_VOLD) { | } else if (code == KB_VOLD) { | ||||
usb_extra_send(AUDIO_VOL_DOWN); | |||||
usb_extra_send(0); | |||||
usb_extra_audio_send(AUDIO_VOL_DOWN); | |||||
usb_extra_audio_send(0); | |||||
_delay_ms(100); | _delay_ms(100); | ||||
} else { | |||||
// normal keys | |||||
} else if (code == KB_PWR) { | |||||
if (suspend && remote_wakeup) { | |||||
usb_remote_wakeup(); | |||||
} else { | |||||
usb_extra_system_send(SYSTEM_POWER_DOWN); | |||||
} | |||||
_delay_ms(1000); | |||||
} | |||||
// normal keys | |||||
else { | |||||
if (key_index < 6) | if (key_index < 6) | ||||
usb_keyboard_keys[key_index] = code; | usb_keyboard_keys[key_index] = code; | ||||
key_index++; | key_index++; | ||||
layer_switching(fn_bits); | layer_switching(fn_bits); | ||||
// TODO: clean code | |||||
// when 4 left modifier keys down | // when 4 left modifier keys down | ||||
if (keymap_is_special_mode(fn_bits)) { | if (keymap_is_special_mode(fn_bits)) { | ||||
switch (usb_keyboard_keys[0]) { | switch (usb_keyboard_keys[0]) { | ||||
print_enable = true; | print_enable = true; | ||||
print("b: jump to bootloader\n"); | print("b: jump to bootloader\n"); | ||||
print("d: debug print toggle\n"); | print("d: debug print toggle\n"); | ||||
print("x: matrix debug toggle\n"); | |||||
print("k: keyboard debug toggle\n"); | print("k: keyboard debug toggle\n"); | ||||
print("m: mouse debug toggle\n"); | print("m: mouse debug toggle\n"); | ||||
print("x: matrix debug toggle\n"); | |||||
print("p: print enable toggle\n"); | |||||
print("v: print version\n"); | print("v: print version\n"); | ||||
print("t: print timer count\n"); | print("t: print timer count\n"); | ||||
print("p: print enable toggle\n"); | |||||
print("r: print registers\n"); | |||||
print("ESC: power down/wake up\n"); | |||||
_delay_ms(500); | _delay_ms(500); | ||||
print_enable = false; | print_enable = false; | ||||
break; | break; | ||||
} | } | ||||
_delay_ms(1000); | _delay_ms(1000); | ||||
break; | break; | ||||
case KB_R: | |||||
usb_keyboard_clear_report(); | |||||
usb_keyboard_send(); | |||||
print("UDIEN: "); phex(UDIEN); print("\n"); | |||||
print("UDINT: "); phex(UDINT); print("\n"); | |||||
_delay_ms(1000); | |||||
break; | |||||
case KB_ESC: | |||||
usb_keyboard_clear_report(); | |||||
usb_keyboard_send(); | |||||
if (suspend && remote_wakeup) { | |||||
usb_remote_wakeup(); | |||||
} else { | |||||
usb_extra_system_send(SYSTEM_POWER_DOWN); | |||||
} | |||||
_delay_ms(1000); | |||||
break; | |||||
} | } | ||||
} | } | ||||
#include "util.h" | #include "util.h" | ||||
#include "controller.h" | #include "controller.h" | ||||
#include "timer.h" | #include "timer.h" | ||||
#include "jump_bootloader.h" | |||||
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) | #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) | ||||
matrix_init(); | matrix_init(); | ||||
matrix_scan(); | matrix_scan(); | ||||
// debug on by pressing down any 4 or more keys during boot time. | |||||
// bootloader comes up when any 4 or more keys are pressed at startup | |||||
if (matrix_key_count() >= 4) { | if (matrix_key_count() >= 4) { | ||||
print_enable = true; | |||||
debug_enable = true; | |||||
} | |||||
/* wait for debug pipe ready */ | |||||
if (print_enable) { | |||||
#ifdef DEBUG_LED | #ifdef DEBUG_LED | ||||
for (int i = 0; i < 6; i++) { | for (int i = 0; i < 6; i++) { | ||||
DEBUG_LED_CONFIG; | DEBUG_LED_CONFIG; | ||||
_delay_ms(500); | _delay_ms(500); | ||||
} | } | ||||
#else | #else | ||||
_delay_ms(6000); | |||||
_delay_ms(5000); | |||||
#endif | #endif | ||||
print_enable = true; | |||||
print("jump to bootloader...\n"); | |||||
_delay_ms(1000); | |||||
jump_bootloader(); // not return | |||||
} | } | ||||
// print description | |||||
print(STR(DESCRIPTION) "\n"); | |||||
while (1) { | while (1) { | ||||
proc_matrix(); | proc_matrix(); |
* THE SOFTWARE. | * THE SOFTWARE. | ||||
*/ | */ | ||||
#include <stdint.h> | |||||
#include <stdbool.h> | |||||
#include <avr/io.h> | #include <avr/io.h> | ||||
#include <avr/pgmspace.h> | #include <avr/pgmspace.h> | ||||
#include <avr/interrupt.h> | #include <avr/interrupt.h> | ||||
#define ENDPOINT0_SIZE 32 | #define ENDPOINT0_SIZE 32 | ||||
bool remote_wakeup = false; | |||||
bool suspend = false; | |||||
// 0:control endpoint is enabled automatically by controller. | // 0:control endpoint is enabled automatically by controller. | ||||
static const uint8_t PROGMEM endpoint_config_table[] = { | static const uint8_t PROGMEM endpoint_config_table[] = { | ||||
// enable, UECFG0X(type, direction), UECFG1X(size, bank, allocation) | // enable, UECFG0X(type, direction), UECFG1X(size, bank, allocation) | ||||
0xC0 // end collection | 0xC0 // end collection | ||||
}; | }; | ||||
// audio controls(consumer page) | |||||
// audio controls & system controls | |||||
// http://www.microsoft.com/whdc/archive/w2kbd.mspx | // http://www.microsoft.com/whdc/archive/w2kbd.mspx | ||||
static uint8_t PROGMEM extra_hid_report_desc[] = { | static uint8_t PROGMEM extra_hid_report_desc[] = { | ||||
0x05, 0x0c, // USAGE_PAGE (Consumer Devices) | 0x05, 0x0c, // USAGE_PAGE (Consumer Devices) | ||||
0x81, 0x06, // INPUT (Data,Var,Rel) | 0x81, 0x06, // INPUT (Data,Var,Rel) | ||||
0x95, 0x05, // REPORT_COUNT (5) | 0x95, 0x05, // REPORT_COUNT (5) | ||||
0x81, 0x07, // INPUT (Cnst,Var,Abs) | 0x81, 0x07, // INPUT (Cnst,Var,Abs) | ||||
0xc0, // END_COLLECTION | |||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop) | |||||
0x09, 0x80, // USAGE (System Control) | |||||
0xa1, 0x01, // COLLECTION (Application) | |||||
0x85, 0x02, // REPORT_ID (2) | |||||
0x19, 0x81, // USAGE_MINIMUM (System Power Down) | |||||
0x29, 0x83, // USAGE_MAXIMUM (System Wake Up) | |||||
0x95, 0x03, // REPORT_COUNT (3) | |||||
0x81, 0x06, // INPUT (Data,Var,Rel) | |||||
0x95, 0x05, // REPORT_COUNT (5) | |||||
0x81, 0x07, // INPUT (Cnst,Var,Rel) | |||||
0xc0 // END_COLLECTION | 0xc0 // END_COLLECTION | ||||
}; | }; | ||||
4, // bNumInterfaces | 4, // bNumInterfaces | ||||
1, // bConfigurationValue | 1, // bConfigurationValue | ||||
0, // iConfiguration | 0, // iConfiguration | ||||
0xC0, // bmAttributes | |||||
0xA0, // bmAttributes | |||||
50, // bMaxPower | 50, // bMaxPower | ||||
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 | // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 | ||||
USB_CONFIG(); // start USB clock | USB_CONFIG(); // start USB clock | ||||
UDCON = 0; // enable attach resistor | UDCON = 0; // enable attach resistor | ||||
usb_configuration = 0; | usb_configuration = 0; | ||||
UDIEN = (1<<EORSTE)|(1<<SOFE); | |||||
UDIEN = (1<<EORSTE)|(1<<SOFE)|(1<<SUSPE); | |||||
sei(); | sei(); | ||||
} | } | ||||
// number selected by the HOST | // number selected by the HOST | ||||
uint8_t usb_configured(void) | uint8_t usb_configured(void) | ||||
{ | { | ||||
return usb_configuration; | |||||
return usb_configuration && !suspend; | |||||
} | |||||
void usb_remote_wakeup(void) | |||||
{ | |||||
UDCON |= (1<<RMWKUP); | |||||
} | } | ||||
intbits = UDINT; | intbits = UDINT; | ||||
UDINT = 0; | UDINT = 0; | ||||
if (intbits & (1<<SUSPI)) { | |||||
suspend = true; | |||||
} else { | |||||
suspend = false; | |||||
} | |||||
if (intbits & (1<<EORSTI)) { | if (intbits & (1<<EORSTI)) { | ||||
UENUM = 0; | UENUM = 0; | ||||
UECONX = 1; | UECONX = 1; | ||||
usb_send_in(); | usb_send_in(); | ||||
return; | return; | ||||
} | } | ||||
#ifdef SUPPORT_ENDPOINT_HALT | |||||
if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE) | |||||
&& bmRequestType == 0x02 && wValue == 0) { | |||||
if (bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE) { | |||||
#ifdef SUPPORT_ENDPOINT_HALT | |||||
if (bmRequestType == 0x02 && wValue == ENDPOINT_HALT) { | |||||
i = wIndex & 0x7F; | i = wIndex & 0x7F; | ||||
if (i >= 1 && i <= MAX_ENDPOINT) { | if (i >= 1 && i <= MAX_ENDPOINT) { | ||||
usb_send_in(); | usb_send_in(); | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
} | |||||
#endif | |||||
if (bmRequestType == 0x00 && wValue == DEVICE_REMOTE_WAKEUP) { | |||||
if (bRequest == SET_FEATURE) { | |||||
remote_wakeup = true; | |||||
} else { | |||||
remote_wakeup = false; | |||||
} | |||||
usb_send_in(); | |||||
return; | |||||
} | |||||
} | } | ||||
#endif | |||||
if (wIndex == KEYBOARD_INTERFACE) { | if (wIndex == KEYBOARD_INTERFACE) { | ||||
if (bmRequestType == 0xA1) { | if (bmRequestType == 0xA1) { | ||||
if (bRequest == HID_GET_REPORT) { | if (bRequest == HID_GET_REPORT) { |
#define USB_H 1 | #define USB_H 1 | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <stdbool.h> | |||||
#include <avr/io.h> | #include <avr/io.h> | ||||
void usb_init(void); // initialize everything | void usb_init(void); // initialize everything | ||||
uint8_t usb_configured(void); // is the USB port configured | uint8_t usb_configured(void); // is the USB port configured | ||||
void usb_remote_wakeup(void); | |||||
#define CDC_SET_LINE_CODING 0x20 | #define CDC_SET_LINE_CODING 0x20 | ||||
#define CDC_GET_LINE_CODING 0x21 | #define CDC_GET_LINE_CODING 0x21 | ||||
#define CDC_SET_CONTROL_LINE_STATE 0x22 | #define CDC_SET_CONTROL_LINE_STATE 0x22 | ||||
// HID feature selectors | |||||
#define DEVICE_REMOTE_WAKEUP 1 | |||||
#define ENDPOINT_HALT 0 | |||||
#define TEST_MODE 2 | |||||
extern bool remote_wakeup; | |||||
extern bool suspend; | |||||
#endif | #endif |
#include <avr/interrupt.h> | #include <avr/interrupt.h> | ||||
#include "usb_extra.h" | #include "usb_extra.h" | ||||
int8_t usb_extra_send(uint8_t bits) | |||||
int8_t usb_extra_send(uint8_t report_id, uint8_t bits) | |||||
{ | { | ||||
uint8_t intr_state, timeout; | uint8_t intr_state, timeout; | ||||
UENUM = EXTRA_ENDPOINT; | UENUM = EXTRA_ENDPOINT; | ||||
} | } | ||||
UEDATX = 1; // report id | |||||
UEDATX = report_id; | |||||
UEDATX = bits; | UEDATX = bits; | ||||
UEINTX = 0x3A; | UEINTX = 0x3A; | ||||
SREG = intr_state; | SREG = intr_state; | ||||
return 0; | return 0; | ||||
} | } | ||||
int8_t usb_extra_audio_send(uint8_t bits) | |||||
{ | |||||
return usb_extra_send(1, bits); | |||||
} | |||||
int8_t usb_extra_system_send(uint8_t bits) | |||||
{ | |||||
return usb_extra_send(2, bits); | |||||
} |
#define EXTRA_SIZE 2 | #define EXTRA_SIZE 2 | ||||
#define EXTRA_BUFFER EP_DOUBLE_BUFFER | #define EXTRA_BUFFER EP_DOUBLE_BUFFER | ||||
// http://www.microsoft.com/whdc/archive/w2kbd.mspx | |||||
#define AUDIO_VOL_UP (1<<0) | #define AUDIO_VOL_UP (1<<0) | ||||
#define AUDIO_VOL_DOWN (1<<1) | #define AUDIO_VOL_DOWN (1<<1) | ||||
#define AUDIO_MUTE (1<<2) | #define AUDIO_MUTE (1<<2) | ||||
#define SYSTEM_POWER_DOWN (1<<0) | |||||
#define SYSTEM_SLEEP (1<<1) | |||||
#define SYSTEM_WAKE_UP (1<<2) | |||||
int8_t usb_extra_send(uint8_t bits); | |||||
int8_t usb_extra_audio_send(uint8_t bits); | |||||
int8_t usb_extra_system_send(uint8_t bits); | |||||
#endif | #endif |