Skip to content

hhkb_ble

joric edited this page Oct 4, 2022 · 63 revisions

zmk-nicenano-hhkb

Disclaimer

The nRF52840-based HHKB-BLE QMK firmware is still in progress. The work is based on the discovery by /u/yangdigi (geekhack) ("I found it could work with 3.3v while the working current 18ma"). HHKB JP still needs a capacitor to handle inrush current. Apparently, no 5V step-up regulators (boost converters) needed. Bluetooth module used in YDKB controller is mdbt40 (nrf51-based), with Adafruit Bluefruit LE UART Friend firmware.

It's NOT recommended to build QMK nrf52 branch (doesn't work), use ZMK: https://github.com/kanru/hhkb-nicenano-zmk

Related links

Mind that nRFMicro revision 0.03 (and HHKB-BLE firmware) lacks power saving mosfet (see hhkb-ble branch). You can solder your own mosfet to the GND line for now (see Hasu Alt controller schematic, it uses pin D4 and N-mosfet to disconnect external GND). Current firmware does not use it.

Firmware

Pro Micro

Regular Pro Micro wired version works just great.

I've ported Hasu pin handling code from bitmasks and AVR registers to an arbitrary pinout (Hbar):

#define HHKB_PINS_HBAR { B2, B3, D7, B1, C6, F7, D4, F6, F5 } (see hhkb_avr.h)

nRFMicro

Wireless HHKB firmware (nRFMicro-compatible alpha version, in progress).

Note that matrix_scan_impl is declared as a weak symbol, so it can be overriden in your implementation without editing the global makefile.

The rest is copied from AVR version almost verbatim. I've commented out the microsecond timer code in matrix.c:

// needs 20us timer here! // joric
//if (TIMER_DIFF_RAW(TIMER_RAW, last) > 20/(1000000/TIMER_RAW_FREQ)) {
//    matrix[row] = matrix_prev[row];
//}

It (almost) works, but there are series of trailing 22222 after each key, e.g. when I type qwerty I get something like q222w222e22r2222t222y222222), see the following video:

Video

It's not bluetooth-related because I'm using wired USB connection for debug, it's just timings (bluetooth works, and behaves the same way). Tried this:

uint32_t last = NRF_RTC0->COUNTER; // or app_timer_cnt_get() or nrf_drv_rtc_counter_get()
// ... key reading code ...
if (NRF_RTC0->COUNTER > last) { // RTC timer resolution is about 30us (32kHz)
    matrix[row] = matrix_prev[row];
}

But it just got worse. Running microsecond timer instead of RTC might also be a problem for power saving. I think I don't really need a microsecrond timer, 20us per key is just 60*20=1200us=1.2ms for the whole matrix, I can scan it in a critical section so there will be no interrupts. It still doesn't work though, probably nrf52 fork-specific but I can't locate the issue.

The '2' key appears to be COL0/ROW0 but when I try to reset it it just repeats the nearest key (qqq, wwww and so on).

    Pro/Pro2(8x8):
      COL 0     1       2       3       4       5       6       7
    ROW ---------------------------------------------------------------
      0|  2     q       w       s       a       z       x       c
      1|  3     4       r       e       d       f       v       b
      2|  5     6       y       t       g       h       n       _NONE_
      3|  1     Esc     Tab     Control LShift  LAlt    LMeta   Space
      4|  7     8       u       i       k       j       m       _NONE_
      5|  \     `       Delete  Return  Fn      RShift  RAlt    RMeta
      6|  9     0       o       p       ;       l       ,       _NONE_
      7|  -     +       ]       [       '       /       .       _NONE_

Yangdigi's comment:

The magic 2. NOT any other keys, only KEY 2.
I've come across a few times with it.
When reading key state is not stable, the magic 2 comes.
But not like your video shows that several 2 come together,
I just get one extra KEY 2 a time.

Another comment (haven't tried it yet):

I've got a board and took a quick test with your code.
matrix.c 129 to 131.
Code:
            //if (matrix_prev[row] & (1<<col)) {
                KEY_PREV_ON();
            //}
The keys should work without "222"  problem now.
Hope this helps.

Upd. checked, it does not fix the problem, unfortunately, the issue stays the same.

Microsecond timer setup

HBAR pinout

I am using a specific pinout coined by Hbar from Geekhack (Hbar pinout for short). I've decided to use it because it's tidy and allows soldering JST connector directly to the side of Pro Micro:

JST 13 Hasu Hbar Usage
1 5V 5V 5V
2 5V 5V 5V
3 PD7 B2 KEY
4 PB7* B3 HYS
5 PB0* D7 ROW_BIT0
6 PB1 B1 ROW_BIT1
7 PB2 C6 ROW_BIT2
8 PB3 F7 COL_BIT0
9 PB4 D4 COL_BIT1
10 PB5 F6 COL_BIT2
11 PB6 F5 COL_SELECT
12 GND GND GND
13 GND GND GND
  • PB7 is not supported on Pro Micro
  • PB0 is occupied by Pro Micro RX LED
controller (top view)
(VCC) 1 [ ... ] 13 (GND)
switchboard

See https://github.com/tmk/tmk_keyboard/blob/master/keyboard/hhkb/doc/HHKB.txt

Pictures

References

Clone this wiki locally