diff --git a/keyboards/fc980c/config.h b/keyboards/fc980c/config.h new file mode 100644 index 0000000000..a79f6f57b3 --- /dev/null +++ b/keyboards/fc980c/config.h @@ -0,0 +1,84 @@ +/* +Copyright 2017 Balz Guenat + +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 . +*/ + +#ifndef CONFIG_H +#define CONFIG_H + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x980C +#define DEVICE_VER 0x0100 +#define MANUFACTURER QMK +#define PRODUCT Leopold FC980C with QMK +#define DESCRIPTION Leopold FC980C with Hasu alternative controller using QMK + +/* key matrix size */ +#define MATRIX_ROWS 8 +#define MATRIX_COLS 16 + +// #define MATRIX_ROW_PINS { B0, B2, B4, B5, B6 } +// #define MATRIX_COL_PINS { F5, B1, F0, F1, F4, B3, D7, D6, D4, D5, D3, D2, D1, D0 } +// #define UNUSED_PINS + +#define DIODE_DIRECTION CUSTOM_MATRIX + +/* define if matrix has ghost */ +//#define MATRIX_HAS_GHOST + +/* number of backlight levels */ +// #define BACKLIGHT_LEVELS 1 + +/* mapping backlight LEDs to correct Pin */ +// #define BACKLIGHT_PIN B7 + +/* Set 0 if debouncing isn't needed */ +#define DEBOUNCING_DELAY 0 +#define TAPPING_TERM 175 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +// #define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +// #define LOCKING_RESYNC_ENABLE + +/* key combination for command */ +#define IS_COMMAND() ( \ + keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ +) + + + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +/* disable debug print */ +//#define NO_DEBUG + +/* disable print */ +//#define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION + +#endif diff --git a/keyboards/fc980c/fc980c.c b/keyboards/fc980c/fc980c.c new file mode 100644 index 0000000000..b782431054 --- /dev/null +++ b/keyboards/fc980c/fc980c.c @@ -0,0 +1,58 @@ +/* +Copyright 2017 Balz Guenat + +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 "fc980c.h" + +void matrix_init_kb(void) { + // put your keyboard start-up code here + // runs once when the firmware starts up + + matrix_init_user(); +} + +void matrix_scan_kb(void) { + // put your looping keyboard code here + // runs every cycle (a lot) + + matrix_scan_user(); +} + +bool process_record_kb(uint16_t keycode, keyrecord_t *record) { + // put your per-action keyboard code here + // runs for every action, just before processing by the firmware + + return process_record_user(keycode, record); +} + +void led_set_kb(uint8_t usb_led) { + if (usb_led & (1<. +*/ +#ifndef FC980C_H +#define FC980C_H + +#include "quantum.h" +// #include "quantum_keycodes.h" + +/* +---------------------------------------------------------------------------------------------------------------------- +| K0D | | K2D | K5D | K3D | K6D | | K7D | K7F | K7E | K7C | | K72 | K71 | K70 | K73 | | K74 | K76 | K77 | K75 | +---------------------------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------------------------- +| K0A | K69 | K59 | K58 | K5B | K6F | K5F | K5E | K6C | K5C | K52 | K51 | K50 | K55 | | K54 | K56 | K57 | K65 | +---------------------------------------------------------------------------------------------------------------------- +| K6A | K39 | K68 | K6B | K3B | K3F | K6E | K3E | K3C | K62 | K61 | K60 | K33 | K53 | | K64 | K66 | K67 | | +---------------------------------------------------------------------------------------------------------------| K25 | +| K3A | K29 | K38 | K28 | K2B | K2F | K2E | K2C | K1C | K32 | K31 | K20 | K63 | | K24 | K26 | K27 | | +---------------------------------------------------------------------------------------------------------------------- +| K2A | K18 | K08 | K1B | K0B | K1F | K1E | K0E | K22 | K11 | K21 | K30 || K34 || K14 | K16 | K17 | | +---------------------------------------------------------------------------------------------------------------| K15 | +| K1A | K09 | K19 | K0F | K02 | K01 | K10 || K00 | K04 | K06 || K07 | K05 | | +---------------------------------------------------------------------------------------------------------------------- +*/ + +#define KEYMAP( \ + K0D, K2D,K5D,K3D,K6D,K7D,K7F,K7E,K7C,K72,K71,K70,K73, K74,K76,K77,K75, \ + K0A,K69,K59,K58,K5B,K6F,K5F,K5E,K6C,K5C,K52,K51,K50,K55, K54,K56,K57,K65, \ + K6A,K39,K68,K6B,K3B,K3F,K6E,K3E,K3C,K62,K61,K60,K33,K53, K64,K66,K67,K25, \ + K3A,K29,K38,K28,K2B,K2F,K2E,K2C,K1C,K32,K31,K20, K63, K24,K26,K27, \ + K2A, K18,K08,K1B,K0B,K1F,K1E,K0E,K22,K11,K21, K30, K34, K14,K16,K17,K15, \ + K1A,K09,K19, K0F, K02,K01,K10, K00,K04,K06, K07,K05 \ +) { \ + { K00, K01, K02, KC_NO,K04, K05, K06, K07 , \ + K08, K09, K0A, K0B, KC_NO,K0D, K0E, K0F }, \ + { K10, K11, KC_NO,KC_NO,K14, K15, K16, K17 , \ + K18, K19, K1A, K1B, K1C, KC_NO,K1E, K1F }, \ + { K20, K21, K22, KC_NO,K24, K25, K26, K27 , \ + K28, K29, K2A, K2B, K2C, K2D, K2E, K2F }, \ + { K30, K31, K32, K33, K34, KC_NO,KC_NO,KC_NO , \ + K38, K39, K3A, K3B, K3C, K3D, K3E, K3F }, \ + { KC_NO,KC_NO,KC_NO,KC_NO,KC_NO,KC_NO,KC_NO,KC_NO , \ + KC_NO,KC_NO,KC_NO,KC_NO,KC_NO,KC_NO,KC_NO,KC_NO }, \ + { K50, K51, K52, K53, K54, K55, K56, K57 , \ + K58, K59, KC_NO,K5B, K5C, K5D, K5E, K5F }, \ + { K60, K61, K62, K63, K64, K65, K66, K67 , \ + K68, K69, K6A, K6B, K6C, K6D, K6E, K6F }, \ + { K70, K71, K72, K73, K74, K75, K76, K77 , \ + KC_NO,KC_NO,KC_NO,KC_NO,K7C, K7D, K7E, K7F } \ +} +/* +KEYMAP( + _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,_______,_______,_______, + _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,_______,_______,_______, + _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,_______,_______,_______, + _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______, _______,_______,_______, + _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______,_______,_______, + _______,_______,_______, _______, _______,_______,_______, _______,_______,_______, _______,_______ +) +*/ + +#endif diff --git a/keyboards/fc980c/keymaps/coloneljesus/README.md b/keyboards/fc980c/keymaps/coloneljesus/README.md new file mode 100644 index 0000000000..d00c57e682 --- /dev/null +++ b/keyboards/fc980c/keymaps/coloneljesus/README.md @@ -0,0 +1 @@ +# My FC980C keymap diff --git a/keyboards/fc980c/keymaps/coloneljesus/config.h b/keyboards/fc980c/keymaps/coloneljesus/config.h new file mode 100644 index 0000000000..596198be10 --- /dev/null +++ b/keyboards/fc980c/keymaps/coloneljesus/config.h @@ -0,0 +1,24 @@ +/* Copyright 2017 Balz Guenat + * + * 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 . + */ + +#ifndef CONFIG_USER_H +#define CONFIG_USER_H + +#include "config_common.h" + +// place overrides here + +#endif diff --git a/keyboards/fc980c/keymaps/coloneljesus/keymap.c b/keyboards/fc980c/keymaps/coloneljesus/keymap.c new file mode 100644 index 0000000000..d82a616ebb --- /dev/null +++ b/keyboards/fc980c/keymaps/coloneljesus/keymap.c @@ -0,0 +1,39 @@ +/* +Copyright 2017 Balz Guenat + +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 "fc980c.h" + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = KEYMAP( + KC_ESC, KC_F1,KC_F2,KC_F3,KC_F4,KC_F5,KC_F6,KC_F7,KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_INS, KC_PGUP,KC_PGDN, + KC_GRV, KC_1,KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,KC_EQL, KC_BSPC, KC_NLCK,KC_PSLS,KC_PAST,KC_PMNS, + KC_TAB, KC_Q,KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC,KC_RBRC,KC_BSLS, KC_P7, KC_P8, KC_P9, KC_PPLS, + MO(1) , KC_A,KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_P1, KC_P2, KC_P3, KC_PENT, + KC_LCTL,KC_LGUI,KC_LALT, KC_SPC, KC_RALT,KC_RCTL,MO(1), KC_LEFT,KC_DOWN,KC_RGHT, KC_P0, KC_PDOT + ), + [1] = KEYMAP( + _______, _______,_______,_______,_______,_______,_______, _______, _______,_______,_______,_______,_______, _______,_______,KC_HOME,KC_END, + _______,_______,_______,_______,_______,_______,_______,_______, _______, _______,_______,_______,_______,_______, _______,_______,_______,_______, + KC_CAPS,KC_MPRV,KC_VOLU,KC_MNXT,KC_PGUP,KC_INS,KC_HOME, LCTL(KC_LEFT),LCTL(KC_RGHT),KC_END, KC_PSCR,KC_SLCK,KC_PAUS,_______, _______,_______,_______,_______, + _______,KC_MUTE,KC_VOLD,KC_MPLY,KC_PGDN,KC_DEL,KC_LEFT, KC_DOWN, KC_UP, KC_RGHT,_______,_______, _______, _______,_______,_______, + _______, _______,_______,_______,_______,_______,LCTL(KC_BSPC),LCTL(KC_DEL), _______,_______,_______, _______, KC_PGUP, _______,_______,_______,_______, + _______,_______,_______, _______, _______,KC_APP, _______, KC_HOME,KC_PGDN,KC_END, _______,_______ + ), +}; + +const uint16_t PROGMEM fn_actions[] = { +}; diff --git a/keyboards/fc980c/keymaps/default/README.md b/keyboards/fc980c/keymaps/default/README.md new file mode 100644 index 0000000000..103a1efc13 --- /dev/null +++ b/keyboards/fc980c/keymaps/default/README.md @@ -0,0 +1,5 @@ +# The default keymap for the FC980C + +Emulates original keymap. + +![](https://i.imgur.com/bQBXPkY.jpg) diff --git a/keyboards/fc980c/keymaps/default/config.h b/keyboards/fc980c/keymaps/default/config.h new file mode 100644 index 0000000000..596198be10 --- /dev/null +++ b/keyboards/fc980c/keymaps/default/config.h @@ -0,0 +1,24 @@ +/* Copyright 2017 Balz Guenat + * + * 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 . + */ + +#ifndef CONFIG_USER_H +#define CONFIG_USER_H + +#include "config_common.h" + +// place overrides here + +#endif diff --git a/keyboards/fc980c/keymaps/default/keymap.c b/keyboards/fc980c/keymaps/default/keymap.c new file mode 100644 index 0000000000..4a1872ad0b --- /dev/null +++ b/keyboards/fc980c/keymaps/default/keymap.c @@ -0,0 +1,39 @@ +/* +Copyright 2017 Balz Guenat + +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 "fc980c.h" + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = KEYMAP( + KC_ESC, KC_F1,KC_F2,KC_F3,KC_F4,KC_F5,KC_F6,KC_F7,KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_INS, KC_PGUP,KC_PGDN, + KC_GRV, KC_1,KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,KC_EQL, KC_BSPC, KC_NLCK,KC_PSLS,KC_PAST,KC_PMNS, + KC_TAB, KC_Q,KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC,KC_RBRC,KC_BSLS, KC_P7, KC_P8, KC_P9, KC_PPLS, + KC_CAPS,KC_A,KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_P1, KC_P2, KC_P3, KC_PENT, + KC_LCTL,KC_LGUI,KC_LALT, KC_SPC, KC_RALT,KC_RCTL,MO(1), KC_LEFT,KC_DOWN,KC_RGHT, KC_P0, KC_PDOT + ), + [1] = KEYMAP( + _______, _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______,_______, _______,_______,KC_HOME,KC_END, + _______,_______,_______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______,_______, _______,_______,_______,_______, + _______,_______,_______,_______,_______,_______,_______,_______,KC_PSCR, KC_SLCK, KC_PAUS, _______,_______,_______, _______,_______,_______,_______, + _______,_______,_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, _______,_______,_______, + _______, _______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, KC_PGUP, _______,_______,_______,_______, + _______,_______,_______, _______, _______,KC_APP, _______, KC_HOME,KC_PGDN,KC_END, _______,_______ + ), +}; + +const uint16_t PROGMEM fn_actions[] = { +}; diff --git a/keyboards/fc980c/matrix.c b/keyboards/fc980c/matrix.c new file mode 100644 index 0000000000..906fec29ae --- /dev/null +++ b/keyboards/fc980c/matrix.c @@ -0,0 +1,228 @@ +/* +Copyright 2017 Balz Guenat +based on work by Jun Wako + +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 . +*/ + +/* + * scan matrix + */ +#include +#include +#include +#include "print.h" +#include "debug.h" +#include "util.h" +#include "timer.h" +#include "matrix.h" +#include "led.h" +// #include "fc980c.h" + + +// Timer resolution check +#if (1000000/TIMER_RAW_FREQ > 20) +# error "Timer resolution(>20us) is not enough for HHKB matrix scan tweak on V-USB." +#endif + + +/* + * Pin configuration for ATMega32U4 + * + * Row: PD4-6, PD7(~EN) + * Col: PB0-3 + * Key: PC6(pull-uped) + * Hys: PC7 + */ +static inline void KEY_ENABLE(void) { (PORTD &= ~(1<<7)); } +static inline void KEY_UNABLE(void) { (PORTD |= (1<<7)); } +static inline bool KEY_STATE(void) { return (PINC & (1<<6)); } +static inline void KEY_HYS_ON(void) { (PORTC |= (1<<7)); } +static inline void KEY_HYS_OFF(void) { (PORTC &= ~(1<<7)); } +static inline void KEY_INIT(void) +{ + /* Col */ + DDRB |= 0x0F; + /* Key: input with pull-up */ + DDRC &= ~(1<<6); + PORTC |= (1<<6); + /* Hys */ + DDRC |= (1<<7); + /* Row */ + DDRD |= 0xF0; + + KEY_UNABLE(); + KEY_HYS_OFF(); +} +static inline void SET_ROW(uint8_t ROW) +{ + // PD4-6 + PORTD = (PORTD & 0x8F) | ((ROW & 0x07) << 4); +} +static inline void SET_COL(uint8_t COL) +{ + // PB0-3 + PORTB = (PORTB & 0xF0) | (COL & 0x0F); +} + +static uint32_t matrix_last_modified = 0; + +// matrix state buffer(1:on, 0:off) +static matrix_row_t *matrix; +static matrix_row_t *matrix_prev; +static matrix_row_t _matrix0[MATRIX_ROWS]; +static matrix_row_t _matrix1[MATRIX_ROWS]; + + +__attribute__ ((weak)) +void matrix_init_quantum(void) { + matrix_init_kb(); +} + +__attribute__ ((weak)) +void matrix_scan_quantum(void) { + matrix_scan_kb(); +} + +__attribute__ ((weak)) +void matrix_init_kb(void) { + matrix_init_user(); +} + +__attribute__ ((weak)) +void matrix_scan_kb(void) { + matrix_scan_user(); +} + +__attribute__ ((weak)) +void matrix_init_user(void) { +} + +__attribute__ ((weak)) +void matrix_scan_user(void) { +} + + +void matrix_init(void) +{ + debug_enable = true; + debug_matrix = true; + + KEY_INIT(); + + // LEDs on NumLock, CapsLock and ScrollLock(PB4, PB5, PB6) + DDRB |= (1<<4) | (1<<5) | (1<<6); + PORTB |= (1<<4) | (1<<5) | (1<<6); + + // initialize matrix state: all keys off + for (uint8_t i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0x00; + for (uint8_t i=0; i < MATRIX_ROWS; i++) _matrix1[i] = 0x00; + matrix = _matrix0; + matrix_prev = _matrix1; + matrix_init_quantum(); +} + +uint8_t matrix_scan(void) +{ + matrix_row_t *tmp; + + tmp = matrix_prev; + matrix_prev = matrix; + matrix = tmp; + + uint8_t row, col; + for (col = 0; col < MATRIX_COLS; col++) { + SET_COL(col); + for (row = 0; row < MATRIX_ROWS; row++) { + //KEY_SELECT(row, col); + SET_ROW(row); + _delay_us(2); + + // Not sure this is needed. This just emulates HHKB controller's behaviour. + if (matrix_prev[row] & (1< 20/(1000000/TIMER_RAW_FREQ)) { + matrix[row] = matrix_prev[row]; + } + + _delay_us(5); + KEY_HYS_OFF(); + KEY_UNABLE(); + + // NOTE: KEY_STATE keep its state in 20us after KEY_ENABLE. + // This takes 25us or more to make sure KEY_STATE returns to idle state. + _delay_us(75); + } + if (matrix[row] ^ matrix_prev[row]) { + matrix_last_modified = timer_read32(); + } + } + matrix_scan_quantum(); + return 1; +} + +inline +matrix_row_t matrix_get_row(uint8_t row) { + return matrix[row]; +} + +void matrix_print(void) +{ +#if (MATRIX_COLS <= 8) + print("r/c 01234567\n"); +#elif (MATRIX_COLS <= 16) + print("r/c 0123456789ABCDEF\n"); +#elif (MATRIX_COLS <= 32) + print("r/c 0123456789ABCDEF0123456789ABCDEF\n"); +#endif + + for (uint8_t row = 0; row < MATRIX_ROWS; row++) { + +#if (MATRIX_COLS <= 8) + xprintf("%02X: %08b%s\n", row, bitrev(matrix_get_row(row)), +#elif (MATRIX_COLS <= 16) + xprintf("%02X: %016b%s\n", row, bitrev16(matrix_get_row(row)), +#elif (MATRIX_COLS <= 32) + xprintf("%02X: %032b%s\n", row, bitrev32(matrix_get_row(row)), +#endif +#ifdef MATRIX_HAS_GHOST + matrix_has_ghost_in_row(row) ? "