HHKB YDKB Yang BT Controller (#15759)
Co-authored-by: Drashna Jaelre <drashna@live.com>
This commit is contained in:
		
							parent
							
								
									0eab24be26
								
							
						
					
					
						commit
						f439fe6055
					
				
					 11 changed files with 1028 additions and 0 deletions
				
			
		
							
								
								
									
										130
									
								
								keyboards/hhkb/yang/config.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								keyboards/hhkb/yang/config.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,130 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2020 Kan-Ru Chen <kanru@kanru.info>
 | 
			
		||||
Copyright 2012 Jun Wako <wakojun@gmail.com>
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "config_common.h"
 | 
			
		||||
 | 
			
		||||
/* USB Device descriptor parameter */
 | 
			
		||||
#define VENDOR_ID 0x4848   // HH = happy hacking
 | 
			
		||||
#define PRODUCT_ID 0x0001  // ANSI HHKB
 | 
			
		||||
#define DEVICE_VER 0x0104
 | 
			
		||||
#define MANUFACTURER YANG
 | 
			
		||||
#define PRODUCT HHKB BLE Keyboard
 | 
			
		||||
 | 
			
		||||
/* key matrix size */
 | 
			
		||||
#define MATRIX_ROWS 8
 | 
			
		||||
#define MATRIX_COLS 8
 | 
			
		||||
 | 
			
		||||
/* matrix power saving */
 | 
			
		||||
#define MATRIX_POWER_SAVE_TIMEOUT_MS 10000
 | 
			
		||||
#define MATRIX_POWER_SAVE_TIMEOUT_L2_MS 1800000
 | 
			
		||||
#define MATRIX_POWER_SAVE_TIMEOUT_L3_MS 7200000
 | 
			
		||||
 | 
			
		||||
#define LED_CAPS_LOCK_PIN F4
 | 
			
		||||
 | 
			
		||||
#ifdef BLUETOOTH_ENABLE
 | 
			
		||||
#    define OUTPUT_DEFAULT OUTPUT_AUTO
 | 
			
		||||
 | 
			
		||||
#    undef SERIAL_UART_BAUD
 | 
			
		||||
#    undef SERIAL_UART_DATA
 | 
			
		||||
#    undef SERIAL_UART_UBRR
 | 
			
		||||
#    undef SERIAL_UART_RXD_VECT
 | 
			
		||||
#    undef SERIAL_UART_TXD_READY
 | 
			
		||||
#    undef SERIAL_UART_INIT
 | 
			
		||||
 | 
			
		||||
#    define SERIAL_UART_BAUD 76800
 | 
			
		||||
#    define SERIAL_UART_DATA UDR1
 | 
			
		||||
#    define SERIAL_UART_UBRR (F_CPU / (8UL * SERIAL_UART_BAUD) - 1)
 | 
			
		||||
#    define SERIAL_UART_RXD_VECT USART1_RX_vect
 | 
			
		||||
#    define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1))
 | 
			
		||||
#    define SERIAL_UART_INIT()                        \
 | 
			
		||||
        do {                                          \
 | 
			
		||||
            cli();                                    \
 | 
			
		||||
            /* baud rate */                           \
 | 
			
		||||
            UBRR1L = SERIAL_UART_UBRR;                \
 | 
			
		||||
            /* baud rate */                           \
 | 
			
		||||
            UBRR1H = SERIAL_UART_UBRR >> 8;           \
 | 
			
		||||
            /* enable TX */                           \
 | 
			
		||||
            UCSR1B |= (0 << TXCIE1) | (1 << TXEN1);   \
 | 
			
		||||
            /* enable RX */                           \
 | 
			
		||||
            UCSR1B |= (1 << RXCIE1) | (1 << RXEN1);   \
 | 
			
		||||
            /* parity: none(00), even(01), odd(11) */ \
 | 
			
		||||
            UCSR1C |= (0 << UPM11) | (0 << UPM10);    \
 | 
			
		||||
            /* 2x speed (error = 0.2%) */             \
 | 
			
		||||
            UCSR1A |= (1 << U2X1);                    \
 | 
			
		||||
            sei();                                    \
 | 
			
		||||
        } while (0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* 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
 | 
			
		||||
 | 
			
		||||
/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
 | 
			
		||||
 * This is useful for the Windows task manager shortcut (ctrl+shift+esc).
 | 
			
		||||
 */
 | 
			
		||||
//#define GRAVE_ESC_CTRL_OVERRIDE
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Force NKRO
 | 
			
		||||
 *
 | 
			
		||||
 * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
 | 
			
		||||
 * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
 | 
			
		||||
 * makefile for this to work.)
 | 
			
		||||
 *
 | 
			
		||||
 * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
 | 
			
		||||
 * until the next keyboard reset.
 | 
			
		||||
 *
 | 
			
		||||
 * NKRO may prevent your keystrokes from being detected in the BIOS, but it is
 | 
			
		||||
 * fully operational during normal computer usage.
 | 
			
		||||
 *
 | 
			
		||||
 * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
 | 
			
		||||
 * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
 | 
			
		||||
 * bootmagic, NKRO mode will always be enabled until it is toggled again during a
 | 
			
		||||
 * power-up.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
//#define FORCE_NKRO
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Bootmagic Lite key configuration */
 | 
			
		||||
//#define BOOTMAGIC_LITE_ROW 0
 | 
			
		||||
//#define BOOTMAGIC_LITE_COLUMN 0
 | 
			
		||||
 | 
			
		||||
//#define DEBUG_MATRIX_SCAN_RATE
 | 
			
		||||
 | 
			
		||||
// Disable debounce
 | 
			
		||||
#define DEBOUNCE 0
 | 
			
		||||
							
								
								
									
										71
									
								
								keyboards/hhkb/yang/info.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								keyboards/hhkb/yang/info.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
{
 | 
			
		||||
  "keyboard_name": "YANG HHKB BLE",
 | 
			
		||||
  "url": "",
 | 
			
		||||
  "maintainer": "qmk",
 | 
			
		||||
  "layouts": {
 | 
			
		||||
    "LAYOUT_60_hhkb": {
 | 
			
		||||
      "layout": [
 | 
			
		||||
        { "label": "Esc", "x": 0, "y": 0 },
 | 
			
		||||
        { "label": "!", "x": 1, "y": 0 },
 | 
			
		||||
        { "label": "@", "x": 2, "y": 0 },
 | 
			
		||||
        { "label": "#", "x": 3, "y": 0 },
 | 
			
		||||
        { "label": "$", "x": 4, "y": 0 },
 | 
			
		||||
        { "label": "%", "x": 5, "y": 0 },
 | 
			
		||||
        { "label": "^", "x": 6, "y": 0 },
 | 
			
		||||
        { "label": "&", "x": 7, "y": 0 },
 | 
			
		||||
        { "label": "*", "x": 8, "y": 0 },
 | 
			
		||||
        { "label": "(", "x": 9, "y": 0 },
 | 
			
		||||
        { "label": ")", "x": 10, "y": 0 },
 | 
			
		||||
        { "label": "_", "x": 11, "y": 0 },
 | 
			
		||||
        { "label": "+", "x": 12, "y": 0 },
 | 
			
		||||
        { "label": "|", "x": 13, "y": 0 },
 | 
			
		||||
        { "label": "~", "x": 14, "y": 0 },
 | 
			
		||||
        { "label": "Tab", "x": 0, "y": 1, "w": 1.5 },
 | 
			
		||||
        { "label": "Q", "x": 1.5, "y": 1 },
 | 
			
		||||
        { "label": "W", "x": 2.5, "y": 1 },
 | 
			
		||||
        { "label": "E", "x": 3.5, "y": 1 },
 | 
			
		||||
        { "label": "R", "x": 4.5, "y": 1 },
 | 
			
		||||
        { "label": "T", "x": 5.5, "y": 1 },
 | 
			
		||||
        { "label": "Y", "x": 6.5, "y": 1 },
 | 
			
		||||
        { "label": "U", "x": 7.5, "y": 1 },
 | 
			
		||||
        { "label": "I", "x": 8.5, "y": 1 },
 | 
			
		||||
        { "label": "O", "x": 9.5, "y": 1 },
 | 
			
		||||
        { "label": "P", "x": 10.5, "y": 1 },
 | 
			
		||||
        { "label": "{", "x": 11.5, "y": 1 },
 | 
			
		||||
        { "label": "}", "x": 12.5, "y": 1 },
 | 
			
		||||
        { "label": "Delete", "x": 13.5, "y": 1, "w": 1.5 },
 | 
			
		||||
        { "label": "Control", "x": 0, "y": 2, "w": 1.75 },
 | 
			
		||||
        { "label": "A", "x": 1.75, "y": 2 },
 | 
			
		||||
        { "label": "S", "x": 2.75, "y": 2 },
 | 
			
		||||
        { "label": "D", "x": 3.75, "y": 2 },
 | 
			
		||||
        { "label": "F", "x": 4.75, "y": 2 },
 | 
			
		||||
        { "label": "G", "x": 5.75, "y": 2 },
 | 
			
		||||
        { "label": "H", "x": 6.75, "y": 2 },
 | 
			
		||||
        { "label": "J", "x": 7.75, "y": 2 },
 | 
			
		||||
        { "label": "K", "x": 8.75, "y": 2 },
 | 
			
		||||
        { "label": "L", "x": 9.75, "y": 2 },
 | 
			
		||||
        { "label": ":", "x": 10.75, "y": 2 },
 | 
			
		||||
        { "label": "\"", "x": 11.75, "y": 2 },
 | 
			
		||||
        { "label": "Return", "x": 12.75, "y": 2, "w": 2.25 },
 | 
			
		||||
        { "label": "Shift", "x": 0, "y": 3, "w": 2.25 },
 | 
			
		||||
        { "label": "Z", "x": 2.25, "y": 3 },
 | 
			
		||||
        { "label": "X", "x": 3.25, "y": 3 },
 | 
			
		||||
        { "label": "C", "x": 4.25, "y": 3 },
 | 
			
		||||
        { "label": "V", "x": 5.25, "y": 3 },
 | 
			
		||||
        { "label": "B", "x": 6.25, "y": 3 },
 | 
			
		||||
        { "label": "N", "x": 7.25, "y": 3 },
 | 
			
		||||
        { "label": "M", "x": 8.25, "y": 3 },
 | 
			
		||||
        { "label": "<", "x": 9.25, "y": 3 },
 | 
			
		||||
        { "label": ">", "x": 10.25, "y": 3 },
 | 
			
		||||
        { "label": "?", "x": 11.25, "y": 3 },
 | 
			
		||||
        { "label": "Shift", "x": 12.25, "y": 3, "w": 1.75 },
 | 
			
		||||
        { "label": "Fn", "x": 14, "y": 3 },
 | 
			
		||||
        { "label": "", "x": 1.5, "y": 4 },
 | 
			
		||||
        { "label": "", "x": 2.5, "y": 4, "w": 1.5 },
 | 
			
		||||
        { "x": 4, "y": 4, "w": 6 },
 | 
			
		||||
        { "label": "", "x": 10, "y": 4, "w": 1.5 },
 | 
			
		||||
        { "label": "", "x": 11.5, "y": 4 }
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										73
									
								
								keyboards/hhkb/yang/keymaps/default/keymap.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								keyboards/hhkb/yang/keymaps/default/keymap.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,73 @@
 | 
			
		|||
/*  -*-  eval: (turn-on-orgtbl); -*-
 | 
			
		||||
 * default HHKB Layout
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2021 Kan-Ru Chen <kanru@kanru.info>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
#include QMK_KEYBOARD_H
 | 
			
		||||
 | 
			
		||||
enum custom_layers {
 | 
			
		||||
    BASE,
 | 
			
		||||
    HHKB,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		||||
 | 
			
		||||
    /* BASE Level: Default Layer
 | 
			
		||||
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
 | 
			
		||||
     | Esc   | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | -     | =   | \     | ` |
 | 
			
		||||
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
 | 
			
		||||
     | Tab   | Q | W | E | R | T | Y | U | I | O | P | [     | ]   | Backs |   |
 | 
			
		||||
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
 | 
			
		||||
     | Cont  | A | S | D | F | G | H | J | K | L | ; | '     | Ent |       |   |
 | 
			
		||||
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
 | 
			
		||||
     | Shift | Z | X | C | V | B | N | M | , | . | / | Shift | Fn0 |       |   |
 | 
			
		||||
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
 | 
			
		||||
 | 
			
		||||
            |------+------+-----------------------+------+------|
 | 
			
		||||
            | LAlt | LGUI | ******* Space ******* | RGUI | RAlt |
 | 
			
		||||
            |------+------+-----------------------+------+------|
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    [BASE] = LAYOUT_60_hhkb( //  default layer
 | 
			
		||||
        KC_ESC, 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_BSLS, KC_GRV,
 | 
			
		||||
        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_BSPC,
 | 
			
		||||
        KC_LCTL, 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_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(HHKB),
 | 
			
		||||
        KC_LALT, KC_LGUI, /*        */ KC_SPC, KC_RGUI, KC_RALT),
 | 
			
		||||
 | 
			
		||||
    /* Layer HHKB: HHKB mode (HHKB Fn)
 | 
			
		||||
      |------+-----+-----+-----+----+----+----+----+-----+-----+-----+-----+-------+-------+-----|
 | 
			
		||||
      | Pwr  | F1  | F2  | F3  | F4 | F5 | F6 | F7 | F8  | F9  | F10 | F11 | F12   | Ins   | Del |
 | 
			
		||||
      |------+-----+-----+-----+----+----+----+----+-----+-----+-----+-----+-------+-------+-----|
 | 
			
		||||
      | Caps |     |     |     |    |    |    |    | Psc | Slk | Pus | Up  |       | Backs |     |
 | 
			
		||||
      |------+-----+-----+-----+----+----+----+----+-----+-----+-----+-----+-------+-------+-----|
 | 
			
		||||
      |      | VoD | VoU | Mut |    |    | *  | /  | Hom | PgU | Lef | Rig | Enter |       |     |
 | 
			
		||||
      |------+-----+-----+-----+----+----+----+----+-----+-----+-----+-----+-------+-------+-----|
 | 
			
		||||
      |      |     |     |     |    |    | +  | -  | End | PgD | Dow |     |       |       |     |
 | 
			
		||||
      |------+-----+-----+-----+----+----+----+----+-----+-----+-----+-----+-------+-------+-----|
 | 
			
		||||
 | 
			
		||||
                 |------+------+----------------------+------+------+
 | 
			
		||||
                 | **** | **** | ******************** | **** | **** |
 | 
			
		||||
                 |------+------+----------------------+------+------+
 | 
			
		||||
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    [HHKB] = LAYOUT_60_hhkb(
 | 
			
		||||
        KC_PWR, 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_INS, KC_DEL,
 | 
			
		||||
        KC_CAPS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, KC_TRNS, KC_BSPC,
 | 
			
		||||
        KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_TRNS, KC_TRNS, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_PENT,
 | 
			
		||||
        KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS,
 | 
			
		||||
        KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS)};
 | 
			
		||||
							
								
								
									
										21
									
								
								keyboards/hhkb/yang/keymaps/kanru/config.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								keyboards/hhkb/yang/keymaps/kanru/config.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
/* Copyright 2021 Kan-Ru Chen <kanru@kanru.info>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#define MOUSEKEY_DELAY 90
 | 
			
		||||
#define MOUSEKEY_INTERVAL 16
 | 
			
		||||
#define MOUSEKEY_MAX_SPEED 4
 | 
			
		||||
#define MOUSEKEY_WHEEL_INTERVAL 50
 | 
			
		||||
							
								
								
									
										126
									
								
								keyboards/hhkb/yang/keymaps/kanru/keymap.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								keyboards/hhkb/yang/keymaps/kanru/keymap.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,126 @@
 | 
			
		|||
/*  -*-  eval: (turn-on-orgtbl); -*-
 | 
			
		||||
 * kanru's HHKB Layout
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2021 Kan-Ru Chen <kanru@kanru.info>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
#include QMK_KEYBOARD_H
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
enum custom_layers {
 | 
			
		||||
    BASE,
 | 
			
		||||
    HHKB,
 | 
			
		||||
    MOUSE,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define BATTERY_FULL 550
 | 
			
		||||
#define BATTERY_EMPTY 326
 | 
			
		||||
 | 
			
		||||
enum my_keycodes { KC_VBAT = SAFE_RANGE };
 | 
			
		||||
 | 
			
		||||
uint32_t adafruit_ble_read_battery_voltage(void);
 | 
			
		||||
 | 
			
		||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		||||
    switch (keycode) {
 | 
			
		||||
#ifdef BLUETOOTH_ENABLE
 | 
			
		||||
        case KC_VBAT:
 | 
			
		||||
            if (record->event.pressed) {
 | 
			
		||||
                char    vbat[8];
 | 
			
		||||
                uint8_t level = (adafruit_ble_read_battery_voltage() - BATTERY_EMPTY) / (float)(BATTERY_FULL - BATTERY_EMPTY) * 100;
 | 
			
		||||
                snprintf(vbat, sizeof(vbat), "%d", level);
 | 
			
		||||
                send_string(vbat);
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
#endif
 | 
			
		||||
        default:
 | 
			
		||||
            return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// clang-format off
 | 
			
		||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		||||
 | 
			
		||||
    /* BASE Level: Default Layer
 | 
			
		||||
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
 | 
			
		||||
     | Esc   | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | -     | =   | \     | ` |
 | 
			
		||||
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
 | 
			
		||||
     | Tab   | Q | W | E | R | T | Y | U | I | O | P | [     | ]   | Backs |   |
 | 
			
		||||
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
 | 
			
		||||
     | Cont  | A | S | D | F | G | H | J | K | L | ; | '     | Ent |       |   |
 | 
			
		||||
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
 | 
			
		||||
     | Shift | Z | X | C | V | B | N | M | , | . | / | Shift | Fn0 |       |   |
 | 
			
		||||
     |-------+---+---+---+---+---+---+---+---+---+---+-------+-----+-------+---|
 | 
			
		||||
 | 
			
		||||
            |------+------+-----------------------+------+------|
 | 
			
		||||
            | LAlt | LGUI | ******* Space ******* | RGUI | RAlt |
 | 
			
		||||
            |------+------+-----------------------+------+------|
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    [BASE] = LAYOUT_60_hhkb( //  default layer
 | 
			
		||||
        LT(MOUSE, KC_ESC), 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_BSLS, KC_GRV,
 | 
			
		||||
        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_BSPC,
 | 
			
		||||
        KC_LCTL, 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_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(HHKB),
 | 
			
		||||
        KC_LALT, KC_LGUI, /*        */ KC_SPC, KC_RGUI, KC_RALT),
 | 
			
		||||
 | 
			
		||||
    /* Layer HHKB: HHKB mode (HHKB Fn)
 | 
			
		||||
      |------+-----+-----+-----+----+----+----+----+-----+-----+-----+-----+-------+-------+-----|
 | 
			
		||||
      | Pwr  | F1  | F2  | F3  | F4 | F5 | F6 | F7 | F8  | F9  | F10 | F11 | F12   | Ins   | Del |
 | 
			
		||||
      |------+-----+-----+-----+----+----+----+----+-----+-----+-----+-----+-------+-------+-----|
 | 
			
		||||
      | Caps |     |     | BAT |    |    |    |    | Psc | Slk | Pus | Up  |       | Backs |     |
 | 
			
		||||
      |------+-----+-----+-----+----+----+----+----+-----+-----+-----+-----+-------+-------+-----|
 | 
			
		||||
      |      | VoD | VoU | Mut |    |    | *  | /  | Hom | PgU | Lef | Rig | Enter |       |     |
 | 
			
		||||
      |------+-----+-----+-----+----+----+----+----+-----+-----+-----+-----+-------+-------+-----|
 | 
			
		||||
      |      |     |     |     |    |    | +  | -  | End | PgD | Dow |     |       |       |     |
 | 
			
		||||
      |------+-----+-----+-----+----+----+----+----+-----+-----+-----+-----+-------+-------+-----|
 | 
			
		||||
 | 
			
		||||
                 |------+------+----------------------+------+------+
 | 
			
		||||
                 | **** | **** | ******************** | **** | **** |
 | 
			
		||||
                 |------+------+----------------------+------+------+
 | 
			
		||||
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    [HHKB] = LAYOUT_60_hhkb(
 | 
			
		||||
        KC_PWR, 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_INS, KC_DEL,
 | 
			
		||||
        KC_CAPS, KC_TRNS, KC_TRNS, KC_VBAT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, KC_TRNS, KC_BSPC,
 | 
			
		||||
        KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_TRNS, KC_TRNS, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_PENT,
 | 
			
		||||
        KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS,
 | 
			
		||||
        KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
 | 
			
		||||
 | 
			
		||||
    /* Layer MOUSE: Mouse Key mode (ESC)
 | 
			
		||||
      |------+------+------+-----+----+----+----+----+----+----+-----+-----+-------+-------+----- |
 | 
			
		||||
      |      |      |      |     |    |    |    |    |    |    |     |     |       |       |     |
 | 
			
		||||
      |------+------+------+-----+----+----+----+----+----+----+-----+-----+-------+-------+-----|
 | 
			
		||||
      |      | BTN1 | WH_U |     |    |    |    |    |    |    |     |     |       |       |     |
 | 
			
		||||
      |------+------+------+-----+----+----+----+----+----+----+-----+-----+-------+-------+-----|
 | 
			
		||||
      |      | BTN2 | WH_D |     |    |    |MS_L|MS_D|MS_U|MS_R|     |     |       |       |     |
 | 
			
		||||
      |------+------+------+-----+----+----+----+----+----+----+-----+-----+-------+-------+-----|
 | 
			
		||||
      |      | BTN3 |      |     |    |    |    |    |    |    |     |     |       |       |     |
 | 
			
		||||
      |------+------+------+-----+----+----+----+----+----+----+-----+-----+-------+-------+-----|
 | 
			
		||||
 | 
			
		||||
                 |------+------+----------------------+------+------+
 | 
			
		||||
                 | **** | **** | ******************** | **** | **** |
 | 
			
		||||
                 |------+------+----------------------+------+------+
 | 
			
		||||
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    [MOUSE] = LAYOUT_60_hhkb(
 | 
			
		||||
        KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
 | 
			
		||||
        KC_TRNS, KC_BTN1, KC_WH_U, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
 | 
			
		||||
        KC_TRNS, KC_BTN2, KC_WH_D, KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_U, KC_MS_R, KC_TRNS, KC_TRNS, KC_TRNS,
 | 
			
		||||
        KC_TRNS, KC_BTN3, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
 | 
			
		||||
        KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS)
 | 
			
		||||
};
 | 
			
		||||
// clang-format on
 | 
			
		||||
							
								
								
									
										173
									
								
								keyboards/hhkb/yang/matrix.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								keyboards/hhkb/yang/matrix.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,173 @@
 | 
			
		|||
/*
 | 
			
		||||
Copyright 2011 Jun Wako <wakojun@gmail.com>
 | 
			
		||||
Copyright 2020 Kan-Ru Chen <kanru@kanru.info>
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "quantum.h"
 | 
			
		||||
 | 
			
		||||
#ifdef BLUETOOTH_ENABLE
 | 
			
		||||
#    include "adafruit_ble.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define RELAX_TIME_US 5
 | 
			
		||||
#define ADC_READ_TIME_US 5
 | 
			
		||||
 | 
			
		||||
uint8_t power_save_level;
 | 
			
		||||
 | 
			
		||||
static uint32_t matrix_last_modified = 0;
 | 
			
		||||
 | 
			
		||||
static inline void key_strobe_high(void) { writePinLow(B6); }
 | 
			
		||||
static inline void key_strobe_low(void) { writePinHigh(B6); }
 | 
			
		||||
static inline bool key_state(void) { return readPin(D7); }
 | 
			
		||||
static inline void key_prev_on(void) { writePinHigh(B7); }
 | 
			
		||||
static inline void key_prev_off(void) { writePinLow(B7); }
 | 
			
		||||
static inline bool key_power_state(void) { return !readPin(D6); }
 | 
			
		||||
 | 
			
		||||
static inline void suspend_power_down_longer(void) {
 | 
			
		||||
    uint8_t times = 60;
 | 
			
		||||
    while (--times) suspend_power_down();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void matrix_power_up(void) {
 | 
			
		||||
    dprint("[matrix_on]\n");
 | 
			
		||||
    // change pins output
 | 
			
		||||
    DDRB  = 0xFF;
 | 
			
		||||
    PORTB = 0x40;
 | 
			
		||||
    // switch MOS FET on
 | 
			
		||||
    setPinOutput(D6);
 | 
			
		||||
    writePinLow(D6);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void matrix_power_down(void) {
 | 
			
		||||
    dprint("[matrix_off]\n");
 | 
			
		||||
    // input with pull-up consumes less than without it when pin is open
 | 
			
		||||
    DDRB  = 0x00;
 | 
			
		||||
    PORTB = 0xFF;
 | 
			
		||||
    // switch MOS FET off
 | 
			
		||||
    setPinOutput(D6);
 | 
			
		||||
    writePinHigh(D6);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void key_select_row(uint8_t row) { PORTB = (PORTB & 0b11111000) | ((row)&0b111); }
 | 
			
		||||
static inline void key_select_col(uint8_t col) { PORTB = (PORTB & 0b11000111) | (((col)&0b111) << 3); }
 | 
			
		||||
static inline bool key_prev_was_on(matrix_row_t matrix[], uint8_t row, uint8_t col) { return matrix[row] & (1 << col); }
 | 
			
		||||
 | 
			
		||||
void matrix_init_custom(void) { power_save_level = 0; }
 | 
			
		||||
 | 
			
		||||
bool matrix_scan_custom(matrix_row_t current_matrix[]) {
 | 
			
		||||
    bool matrix_has_changed = false;
 | 
			
		||||
 | 
			
		||||
    // power on
 | 
			
		||||
    if (!key_power_state()) {
 | 
			
		||||
        matrix_power_up();
 | 
			
		||||
    }
 | 
			
		||||
    for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
 | 
			
		||||
        matrix_row_t last_row_value = current_matrix[row];
 | 
			
		||||
 | 
			
		||||
        key_select_row(row);
 | 
			
		||||
        wait_us(RELAX_TIME_US);
 | 
			
		||||
 | 
			
		||||
        for (uint8_t col = 0; col < MATRIX_COLS; col++) {
 | 
			
		||||
            // Hysteresis control: assert(1) when previous key state is on
 | 
			
		||||
            if (key_prev_was_on(current_matrix, row, col)) {
 | 
			
		||||
                key_prev_on();
 | 
			
		||||
            } else {
 | 
			
		||||
                key_prev_off();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Disable interrupts to encure the ADC timing is correct
 | 
			
		||||
            cli();
 | 
			
		||||
 | 
			
		||||
            // strobe
 | 
			
		||||
            key_select_col(col);
 | 
			
		||||
            key_strobe_high();
 | 
			
		||||
 | 
			
		||||
            // Wait for ADC to outputs its value.
 | 
			
		||||
            // 1us was ok on one HHKB, but not worked on another.
 | 
			
		||||
            // 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)
 | 
			
		||||
            wait_us(ADC_READ_TIME_US);
 | 
			
		||||
 | 
			
		||||
            if (key_state()) {
 | 
			
		||||
                current_matrix[row] &= ~(1 << col);
 | 
			
		||||
            } else {
 | 
			
		||||
                current_matrix[row] |= (1 << col);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            key_strobe_low();
 | 
			
		||||
            sei();
 | 
			
		||||
 | 
			
		||||
            // Make sure enough time has elapsed since the last call
 | 
			
		||||
            // This is to ensure the matrix voltages have relaxed
 | 
			
		||||
            wait_us(RELAX_TIME_US);
 | 
			
		||||
        }
 | 
			
		||||
        if (current_matrix[row] ^ last_row_value) {
 | 
			
		||||
            matrix_has_changed   = true;
 | 
			
		||||
            matrix_last_modified = timer_read32();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Power saving
 | 
			
		||||
    uint32_t time_diff = timer_elapsed32(matrix_last_modified);
 | 
			
		||||
    if (time_diff > MATRIX_POWER_SAVE_TIMEOUT_L3_MS) {
 | 
			
		||||
        power_save_level = 3;
 | 
			
		||||
        suspend_power_down_longer();
 | 
			
		||||
    } else if (time_diff > MATRIX_POWER_SAVE_TIMEOUT_L2_MS) {
 | 
			
		||||
        power_save_level = 2;
 | 
			
		||||
#ifdef BLUETOOTH_ENABLE
 | 
			
		||||
        if (!adafruit_ble_is_connected()) {
 | 
			
		||||
            power_save_level = 3;
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        suspend_power_down_longer();
 | 
			
		||||
    } else if (time_diff > MATRIX_POWER_SAVE_TIMEOUT_MS) {
 | 
			
		||||
        power_save_level = 1;
 | 
			
		||||
        suspend_power_down();
 | 
			
		||||
    } else {
 | 
			
		||||
        if (power_save_level != 0) {
 | 
			
		||||
            power_save_level = 0;
 | 
			
		||||
            suspend_wakeup_init();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return matrix_has_changed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool adafruit_ble_delbonds(void);
 | 
			
		||||
bool adafruit_ble_reconnect(void);
 | 
			
		||||
 | 
			
		||||
bool command_extra(uint8_t code) {
 | 
			
		||||
    switch (code) {
 | 
			
		||||
#ifdef BLUETOOTH_ENABLE
 | 
			
		||||
        case KC_R:
 | 
			
		||||
            adafruit_ble_delbonds();
 | 
			
		||||
            return true;
 | 
			
		||||
        case KC_S:
 | 
			
		||||
            adafruit_ble_reconnect();
 | 
			
		||||
            return true;
 | 
			
		||||
#endif
 | 
			
		||||
        default:
 | 
			
		||||
            return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										135
									
								
								keyboards/hhkb/yang/memo.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								keyboards/hhkb/yang/memo.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,135 @@
 | 
			
		|||
## Hardware Information
 | 
			
		||||
 | 
			
		||||
The YANG HHKB BLE controller design is similiar to hasu's
 | 
			
		||||
controller. Most pins are compatiable.
 | 
			
		||||
 | 
			
		||||
**MCU**: ATmega32U4  
 | 
			
		||||
**Bluetooth**:  MDBT40 (nRF51822-based), with Adafruit Bluefruit LE UART Friend firmware.  
 | 
			
		||||
**Power**: 3.3V  
 | 
			
		||||
**CPU Frequency**: 8MHz  
 | 
			
		||||
**Bootloader**: Lufa MassStorage  
 | 
			
		||||
 | 
			
		||||
## Pin usage
 | 
			
		||||
 | 
			
		||||
| Description                          | HASU pin usage         | YANG mod changed           |
 | 
			
		||||
|:------------------------------------ | ---------------------- | -------------------------- |
 | 
			
		||||
| ~KEY: Lo(0) when key is pressed      | PD7 input(with pullup) |                            |
 | 
			
		||||
| Hysteresis: Hi(1) if key was pressed | PB7 output             |                            |
 | 
			
		||||
| Row selector bit0                    | PB0 output             |                            |
 | 
			
		||||
| Row selector bit1                    | PB1 output             |                            |
 | 
			
		||||
| Row selector bit2                    | PB2 output             |                            |
 | 
			
		||||
| Col selector bit0                    | PB3 output             |                            |
 | 
			
		||||
| Col selector bit1                    | PB4 output             |                            |
 | 
			
		||||
| Col selector bit2                    | PB5 output             |                            |
 | 
			
		||||
| Key unable                           | PB6 output             |                            |
 | 
			
		||||
| Switch power                         | PD4 output             | PD6 output (PMOS FET)      |
 | 
			
		||||
| Bluetooth UART Rx                    | PC4 input              | PD2                        |
 | 
			
		||||
| Bluetooth UART Tx                    | PC5 output             | PD3                        |
 | 
			
		||||
| Bluetooth power                      |                        | PD5 output (low: power on) |
 | 
			
		||||
| LED 0                                |                        | PF4                        |
 | 
			
		||||
| LED 2                                |                        | PF1                        |
 | 
			
		||||
| LED 4                                |                        | PF0                        |
 | 
			
		||||
| Unused for PRO2                      | PC6                    |                            |
 | 
			
		||||
| Unused for PRO2                      | PC7                    |                            |
 | 
			
		||||
| Inner USB power                      |                        | PF7                        |
 | 
			
		||||
 | 
			
		||||
## How to flash LUFA MassStorage bootloader on Linux
 | 
			
		||||
 | 
			
		||||
The FAT filesystem on Linux very often cannot flush the write cache,
 | 
			
		||||
leading to broken firmware in the flash.
 | 
			
		||||
 | 
			
		||||
We can use `dd` to write to the virtual block storage directly to
 | 
			
		||||
bypass the vfs layer.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
dd if=FLASH.bin of=<path of virtual block device> seek=4
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Skip 4 sectors because the default sector size of the virtual device
 | 
			
		||||
and dd is 512 bytes and the emulated flash file starts at 5th sector.
 | 
			
		||||
 | 
			
		||||
## How to find the path of the virtual block device
 | 
			
		||||
 | 
			
		||||
After the keyboard boots into flash mode, on Linux system you should
 | 
			
		||||
be able to find the block device in `dmesg` logs.
 | 
			
		||||
 | 
			
		||||
For exmaple if you type
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
sudo dmesg
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
You should find something like
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
[357885.143593] usb 1-1.4: USB disconnect, device number 24
 | 
			
		||||
[357885.627740] usb 1-1.4: new full-speed USB device number 25 using xhci_hcd
 | 
			
		||||
[357885.729486] usb 1-1.4: New USB device found, idVendor=03eb, idProduct=1962, bcdDevice= 0.01
 | 
			
		||||
[357885.729492] usb 1-1.4: New USB device strings: Mfr=0, Product=0, SerialNumber=0
 | 
			
		||||
[357885.745620] SCSI subsystem initialized
 | 
			
		||||
[357885.746712] usb-storage 1-1.4:1.0: USB Mass Storage device detected
 | 
			
		||||
[357885.746818] scsi host0: usb-storage 1-1.4:1.0
 | 
			
		||||
[357885.746919] usbcore: registered new interface driver usb-storage
 | 
			
		||||
[357885.747689] usbcore: registered new interface driver uas
 | 
			
		||||
[357886.766755] scsi 0:0:0:0: Direct-Access     LUFA     Bootloader       0.00 PQ: 0 ANSI: 0
 | 
			
		||||
[357886.773216] scsi 0:0:0:0: Attached scsi generic sg0 type 0
 | 
			
		||||
[357886.777474] sd 0:0:0:0: [sdx] 134 512-byte logical blocks: (68.6 kB/67.0 KiB)
 | 
			
		||||
[357886.780300] sd 0:0:0:0: [sdx] Write Protect is off
 | 
			
		||||
[357886.780302] sd 0:0:0:0: [sdx] Mode Sense: 00 00 00 00
 | 
			
		||||
[357886.783113] sd 0:0:0:0: [sdx] Asking for cache data failed
 | 
			
		||||
[357886.783114] sd 0:0:0:0: [sdx] Assuming drive cache: write through
 | 
			
		||||
[357886.842676]  sdx:
 | 
			
		||||
[357886.859528] sd 0:0:0:0: [sdx] Attached SCSI removable disk
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `sdx` is the block device name and the full path is at `/dev/sdx`
 | 
			
		||||
The above flash command will become
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
dd if=FLASH.bin of=/dev/sdx seek=4
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Adafruit Bluefruit LE UART configuraton
 | 
			
		||||
 | 
			
		||||
The default baud rate used by the firmware is 76800 although adafruit
 | 
			
		||||
do not recommend using higher baudrates than 9600 because the nRF51
 | 
			
		||||
UART can drop characters.
 | 
			
		||||
 | 
			
		||||
Double speed mode to get more accurate async reading because the F_CPU
 | 
			
		||||
speed is 8MHz.
 | 
			
		||||
 | 
			
		||||
## Power saving mode design
 | 
			
		||||
 | 
			
		||||
Power saving is only enabled when USB is detached and using battery
 | 
			
		||||
power. Here we define several levels of power saving mode, each saves
 | 
			
		||||
more power but takes longer to resume operation.
 | 
			
		||||
 | 
			
		||||
1. Level 1: idle mode is activated after a short configurable time
 | 
			
		||||
   (MATRIX_POWER_SAVE_TIMEOUT_MS) MCU is put into sleep mode and only
 | 
			
		||||
   scan the matrix per 15ms. PORTB pins are set to input with pull-up
 | 
			
		||||
   to save power. Sensing PCB is powered down between scans.
 | 
			
		||||
 | 
			
		||||
2. Level 2: after idling for longer (MATRIX_POWER_SAVE_TIMEOUT_L2_MS)
 | 
			
		||||
   we entry this state. Matrix scan is skipped until the time lapses
 | 
			
		||||
   900ms.
 | 
			
		||||
 | 
			
		||||
2. Level 3: sleep mode is activated after a longer timeout
 | 
			
		||||
   (MATRIX_POWER_SAVE_TIMEOUT_L3_MS) Bluetooth module is powered down.
 | 
			
		||||
 | 
			
		||||
## Battery reading
 | 
			
		||||
 | 
			
		||||
VBAT is connected to AIN6 pin on the MDBT40 module and the AREF pin is
 | 
			
		||||
the reference voltage. Doing a ADC with AT+HWDAC=6 will return the
 | 
			
		||||
difference between VBAT and VREF.
 | 
			
		||||
 | 
			
		||||
It seems when fully charged the ADC read is 550. Likely VREF is 3311mV
 | 
			
		||||
and the fully charged VBAT is thus 3861mV.
 | 
			
		||||
 | 
			
		||||
Enable battery service with AT+BLEBATTEN=1 first then we can update the
 | 
			
		||||
battery level by using AT+BLEBATTVAL=%d
 | 
			
		||||
 | 
			
		||||
## References
 | 
			
		||||
 | 
			
		||||
* https://github.com/joric/qmk/wiki/hhkb_ble
 | 
			
		||||
* https://github.com/tomsmalley/custom-topre-guide
 | 
			
		||||
* https://github.com/abcminiuser/lufa/blob/master/Bootloaders/MassStorage/Lib/VirtualFAT.h
 | 
			
		||||
							
								
								
									
										118
									
								
								keyboards/hhkb/yang/readme.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								keyboards/hhkb/yang/readme.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,118 @@
 | 
			
		|||
# HHKB Alternate Controller (YANG HHKB BLE Mod)
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
An alternative controler for the HHKB designed by YANG (yangdigi)
 | 
			
		||||
based on the hasu controller.
 | 
			
		||||
 | 
			
		||||
* Keyboard Maintainer: [Kan-Ru Chen](https://github.com/kanru)  
 | 
			
		||||
* Hardware Supported: YANG HHKB BLE Controller  
 | 
			
		||||
* Hardware Availability: https://kbdfans.com/products/hhkb-ble-mod-upgrade-module
 | 
			
		||||
 | 
			
		||||
Make example for this keyboard (after setting up your build environment):
 | 
			
		||||
 | 
			
		||||
    make hhkb/yang:default
 | 
			
		||||
 | 
			
		||||
To flash, first boot your keyboard into bootloader (hold ESC and attach usb cable)
 | 
			
		||||
then a virtual USB storage should appear. You can copy the `hhkb_yang_default.bin`
 | 
			
		||||
file to the virtual USB storage and override the `HHKB_BLE.BIN` file in there.
 | 
			
		||||
 | 
			
		||||
Make sure to unmount and eject the virtual USB storage.
 | 
			
		||||
 | 
			
		||||
## Features:
 | 
			
		||||
 | 
			
		||||
- [x] QMK (via USB)
 | 
			
		||||
- [x] Bluetooth (BLE)
 | 
			
		||||
- [x] Power saving mode
 | 
			
		||||
  - [x] Idle mode
 | 
			
		||||
  - [x] Deep sleep mode
 | 
			
		||||
- [x] LEDs
 | 
			
		||||
- [x] Battery service
 | 
			
		||||
- [x] Special commands
 | 
			
		||||
  - [x] Switch BT peer
 | 
			
		||||
 | 
			
		||||
## Entering flash mode
 | 
			
		||||
 | 
			
		||||
Different ways to enter flash mode:
 | 
			
		||||
 | 
			
		||||
* Press and hold the ESC key. Insert the USB cable to enter the flash
 | 
			
		||||
  mode. When the OS shows the drive disk, you can release the key.
 | 
			
		||||
 | 
			
		||||
* Use the magic command LSHIFT+RSHIFT+B to reboot to bootloader then
 | 
			
		||||
  quickly hold the ESC key.
 | 
			
		||||
 | 
			
		||||
If you reflash the wrong firmware or did not reflash successfully, you
 | 
			
		||||
can no longer enter the flash mode, especially the wireless keyboard
 | 
			
		||||
with battery. You need to turn off the keyboard's power switch, and
 | 
			
		||||
re-enter the flash mode, reflash the correct firmware.
 | 
			
		||||
 | 
			
		||||
After entering the bootloader(flash mode), three indicators on the top
 | 
			
		||||
right of the HHKB BLE controller will flash. LED3(green) will flash
 | 
			
		||||
quickly when writing firmware to the controller.
 | 
			
		||||
 | 
			
		||||
If these three leds are not soldered or your hhkb case is black, you
 | 
			
		||||
can't know their status, but you can still see LED3 under the right
 | 
			
		||||
USB port.
 | 
			
		||||
 | 
			
		||||
## How to reliably flash LUFA MassStorage bootloader on Linux
 | 
			
		||||
 | 
			
		||||
The FAT filesystem on Linux very often cannot flush the write cache,
 | 
			
		||||
leading to broken firmware in the flash.
 | 
			
		||||
 | 
			
		||||
We can use `dd` to write to the virtual block storage directly to
 | 
			
		||||
bypass the vfs layer.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
dd if=FLASH.bin of=<path of virtual block device> seek=4
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Skip 4 sectors because the default sector size of the virtual device
 | 
			
		||||
and dd is 512 bytes and the emulated flash file starts at 5th sector.
 | 
			
		||||
 | 
			
		||||
## How to find the path of the virtual block device
 | 
			
		||||
 | 
			
		||||
After the keyboard boots into flash mode, on Linux system you should
 | 
			
		||||
be able to find the block device in `dmesg` logs.
 | 
			
		||||
 | 
			
		||||
For exmaple if you type
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
sudo dmesg
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
You should find something like
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
[357885.143593] usb 1-1.4: USB disconnect, device number 24
 | 
			
		||||
[357885.627740] usb 1-1.4: new full-speed USB device number 25 using xhci_hcd
 | 
			
		||||
[357885.729486] usb 1-1.4: New USB device found, idVendor=03eb, idProduct=1962, bcdDevice= 0.01
 | 
			
		||||
[357885.729492] usb 1-1.4: New USB device strings: Mfr=0, Product=0, SerialNumber=0
 | 
			
		||||
[357885.745620] SCSI subsystem initialized
 | 
			
		||||
[357885.746712] usb-storage 1-1.4:1.0: USB Mass Storage device detected
 | 
			
		||||
[357885.746818] scsi host0: usb-storage 1-1.4:1.0
 | 
			
		||||
[357885.746919] usbcore: registered new interface driver usb-storage
 | 
			
		||||
[357885.747689] usbcore: registered new interface driver uas
 | 
			
		||||
[357886.766755] scsi 0:0:0:0: Direct-Access     LUFA     Bootloader       0.00 PQ: 0 ANSI: 0
 | 
			
		||||
[357886.773216] scsi 0:0:0:0: Attached scsi generic sg0 type 0
 | 
			
		||||
[357886.777474] sd 0:0:0:0: [sdx] 134 512-byte logical blocks: (68.6 kB/67.0 KiB)
 | 
			
		||||
[357886.780300] sd 0:0:0:0: [sdx] Write Protect is off
 | 
			
		||||
[357886.780302] sd 0:0:0:0: [sdx] Mode Sense: 00 00 00 00
 | 
			
		||||
[357886.783113] sd 0:0:0:0: [sdx] Asking for cache data failed
 | 
			
		||||
[357886.783114] sd 0:0:0:0: [sdx] Assuming drive cache: write through
 | 
			
		||||
[357886.842676]  sdx:
 | 
			
		||||
[357886.859528] sd 0:0:0:0: [sdx] Attached SCSI removable disk
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The `sdx` is the block device name and the full path is at `/dev/sdx`
 | 
			
		||||
The above flash command will become
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
dd if=FLASH.bin of=/dev/sdx seek=4
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
**Caution**: if set to incorrect device it may wipe out
 | 
			
		||||
your actual disk.
 | 
			
		||||
 | 
			
		||||
## Help page of original firmware
 | 
			
		||||
 | 
			
		||||
http://help.ydkb.io/doku.php?id=en:kb-mods:hhkb-ble
 | 
			
		||||
							
								
								
									
										27
									
								
								keyboards/hhkb/yang/rules.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								keyboards/hhkb/yang/rules.mk
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
# MCU name
 | 
			
		||||
MCU = atmega32u4
 | 
			
		||||
 | 
			
		||||
# MCU frequency
 | 
			
		||||
F_CPU = 8000000
 | 
			
		||||
 | 
			
		||||
# Bootloader selection
 | 
			
		||||
BOOTLOADER = lufa-ms
 | 
			
		||||
 | 
			
		||||
# Build Options
 | 
			
		||||
#   change yes to no to disable
 | 
			
		||||
#
 | 
			
		||||
BOOTMAGIC_ENABLE = yes      # Enable Bootmagic Lite
 | 
			
		||||
MOUSEKEY_ENABLE = yes       # Mouse keys
 | 
			
		||||
EXTRAKEY_ENABLE = yes       # Audio control and System control
 | 
			
		||||
CONSOLE_ENABLE = no         # Console for debug
 | 
			
		||||
COMMAND_ENABLE = yes        # Commands for debug and configuration
 | 
			
		||||
NKRO_ENABLE = no            # USB Nkey Rollover
 | 
			
		||||
 | 
			
		||||
LAYOUTS = 60_hhkb
 | 
			
		||||
 | 
			
		||||
# Disable bluetooth until the UART code is merged
 | 
			
		||||
BLUETOOTH_DRIVER = BluefruitLE
 | 
			
		||||
 | 
			
		||||
# Custom matrix file for the HHKB
 | 
			
		||||
CUSTOM_MATRIX = lite
 | 
			
		||||
SRC += matrix.c
 | 
			
		||||
							
								
								
									
										118
									
								
								keyboards/hhkb/yang/yang.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								keyboards/hhkb/yang/yang.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,118 @@
 | 
			
		|||
/* Copyright 2021 Kan-Ru Chen <kanru@kanru.info>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "yang.h"
 | 
			
		||||
 | 
			
		||||
extern uint8_t power_save_level;
 | 
			
		||||
 | 
			
		||||
void hhkb_led_on(uint8_t led) {
 | 
			
		||||
    switch (led) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            writePinHigh(F4);
 | 
			
		||||
            break;
 | 
			
		||||
        case 2:
 | 
			
		||||
            writePinHigh(F2);
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            writePinHigh(F0);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void hhkb_led_off(uint8_t led) {
 | 
			
		||||
    switch (led) {
 | 
			
		||||
        case 1:
 | 
			
		||||
            writePinLow(F4);
 | 
			
		||||
            break;
 | 
			
		||||
        case 2:
 | 
			
		||||
            writePinLow(F2);
 | 
			
		||||
            break;
 | 
			
		||||
        case 3:
 | 
			
		||||
            writePinLow(F0);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void keyboard_pre_init_kb(void) {
 | 
			
		||||
    // BT power up
 | 
			
		||||
    setPinOutput(D5);
 | 
			
		||||
    writePinLow(D5);
 | 
			
		||||
 | 
			
		||||
    // Row selectors
 | 
			
		||||
    setPinOutput(B0);
 | 
			
		||||
    setPinOutput(B1);
 | 
			
		||||
    setPinOutput(B2);
 | 
			
		||||
 | 
			
		||||
    // Col selectors
 | 
			
		||||
    setPinOutput(B3);
 | 
			
		||||
    setPinOutput(B4);
 | 
			
		||||
    setPinOutput(B5);
 | 
			
		||||
 | 
			
		||||
    // Key strobe
 | 
			
		||||
    setPinOutput(B6);
 | 
			
		||||
    writePinHigh(B6);
 | 
			
		||||
 | 
			
		||||
    // Key: input with pull-up
 | 
			
		||||
    setPinInputHigh(D7);
 | 
			
		||||
 | 
			
		||||
    // Unused pins on Pro2 ANSI
 | 
			
		||||
    // Input with pull up to save power
 | 
			
		||||
    setPinInputHigh(C6);
 | 
			
		||||
    setPinInputHigh(C7);
 | 
			
		||||
 | 
			
		||||
    // LED pin configuration
 | 
			
		||||
    setPinOutput(F0);
 | 
			
		||||
    setPinOutput(F1);
 | 
			
		||||
    setPinOutput(F4);
 | 
			
		||||
    writePinLow(F0);
 | 
			
		||||
    writePinLow(F1);
 | 
			
		||||
    writePinLow(F4);
 | 
			
		||||
 | 
			
		||||
    // Turn on switch PCB
 | 
			
		||||
    setPinOutput(D6);
 | 
			
		||||
    writePinLow(D6);
 | 
			
		||||
 | 
			
		||||
    keyboard_pre_init_user();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void suspend_power_down_kb(void) {
 | 
			
		||||
    if (power_save_level > 2) {
 | 
			
		||||
        // Disable UART TX to avoid current leakage
 | 
			
		||||
        UCSR1B &= ~_BV(TXEN1);
 | 
			
		||||
        // Power down BLE module
 | 
			
		||||
        writePinHigh(D5);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend_power_down_user();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void suspend_wakeup_init_kb(void) {
 | 
			
		||||
    // Power up BLE module
 | 
			
		||||
    writePinLow(D5);
 | 
			
		||||
    // Enable UART TX
 | 
			
		||||
    UCSR1B |= _BV(TXEN1);
 | 
			
		||||
 | 
			
		||||
    suspend_wakeup_init_user();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
layer_state_t layer_state_set_kb(layer_state_t state) {
 | 
			
		||||
    state = layer_state_set_user(state);
 | 
			
		||||
 | 
			
		||||
    writePin(F1, IS_LAYER_ON_STATE(state, 1));
 | 
			
		||||
    writePin(F0, IS_LAYER_ON_STATE(state, 2));
 | 
			
		||||
 | 
			
		||||
    return state;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								keyboards/hhkb/yang/yang.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								keyboards/hhkb/yang/yang.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
/* Copyright 2021 Kan-Ru Chen <kanru@kanru.info>
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "quantum.h"
 | 
			
		||||
 | 
			
		||||
#define LAYOUT_60_hhkb(                                                        \
 | 
			
		||||
    K31, K30, K00, K10, K11, K20, K21, K40, K41, K60, K61, K70, K71, K50, K51, \
 | 
			
		||||
    K32, K01, K02, K13, K12, K23, K22, K42, K43, K62, K63, K73, K72, K52,      \
 | 
			
		||||
    K33, K04, K03, K14, K15, K24, K25, K45, K44, K65, K64, K74, K53,           \
 | 
			
		||||
    K34, K05, K06, K07, K16, K17, K26, K46, K66, K76, K75, K55, K54,           \
 | 
			
		||||
         K35, K36,           K37,                K57, K56)                     \
 | 
			
		||||
                                                                               \
 | 
			
		||||
{                                                                              \
 | 
			
		||||
    { K00, K01, K02, K03, K04, K05, K06, K07   },                              \
 | 
			
		||||
    { K10, K11, K12, K13, K14, K15, K16, K17   },                              \
 | 
			
		||||
    { K20, K21, K22, K23, K24, K25, K26, KC_NO },                              \
 | 
			
		||||
    { K30, K31, K32, K33, K34, K35, K36, K37   },                              \
 | 
			
		||||
    { K40, K41, K42, K43, K44, K45, K46, KC_NO },                              \
 | 
			
		||||
    { K50, K51, K52, K53, K54, K55, K56, K57   },                              \
 | 
			
		||||
    { K60, K61, K62, K63, K64, K65, K66, KC_NO },                              \
 | 
			
		||||
    { K70, K71, K72, K73, K74, K75, K76, KC_NO }                               \
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue