Skip to content

Instantly share code, notes, and snippets.

@tmk
Last active August 24, 2023 03:09
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tmk/e0f9f49db619413d1cf45e1aecaea52e to your computer and use it in GitHub Desktop.
Save tmk/e0f9f49db619413d1cf45e1aecaea52e to your computer and use it in GitHub Desktop.
HHKB Professional Classic PD-KB401W - Internals
HHKB Professional Classic PD-KB401W
===================================
2019-12-14
TODO
----
Photo album
-----------
https://imgur.com/a/p9dWvM0
STM32L072RB
-----------
LQFP64 with 128KB Flash(2-bank)
AN4767 On-the-fly firmware update for dual bank STM32
AN3156 USB DFU protocol used in the STM32 bootloader
4 bytes per word
32 words/128 bytes per page
32 pages/4K byes per sector
Memory:
0x0000 0000 Memory space mapped to Flash(0x0800 0000), System memory(0x1FF0 0000) or SRAM
0x0000 0000 top of stack address
0x0000 0004 start of codes reset handler
0x0008 0000 Memory space mapped to EEPROM(0x0808 0000)
0x0800 0000 Flash 128KB
0x0800 0000 Bank1 Flash 64KB
0x0800 FFFF
0x0801 0000 Bank2 Flash 64KB
0x0801 FFFF
0x0808 0000 EEPROM 6K
0x0808 0000 Bank1 EEPROM 3KB
0x0808 0BFF
0x0808 0C00 Bank2 EEPROM 3KB
0x0808 17FF
0x1FF0 0000 System memory 8K - Bootloader
0x1FF0 1FFF
0x1FF8 0000 Option bytes 32 bytes
0x1FF8 001f
0x1FF8 0020 Factory option byte 96 bytes
0x1FF8 007F
0x2000 0000 SRAM 20K
0x2000 4FFF SRAM 0x2000 20c0/0x2000 20b8
0x4000 0000 Peripherals
0x5000 0000 IOPORT
Keymap format in Flash/EEPROM:
------------------------------
Keymap is comprised of 128 bytes and defines 61 keys in first 64 bytes, followed by 64-byte '0x00'.
This is dump of 256 bytes from eeprom, for example. It define 2 layers for HHKB mode.
00000000: 00 8a e6 2c e2 8b 01 e5 38 37 36 10 11 05 19 06 ...,....876.....
00000010: 1b 1d e1 28 34 33 0f 0e 0d 0b 0a 09 07 16 04 e0 ...(43..........
00000020: 4c 30 2f 13 12 0c 18 1c 17 15 08 1a 14 2b 35 31 L0/..........+51
00000030: 2e 2d 27 26 25 24 23 22 21 20 1f 1e 29 00 00 00 .-'&%$#"! ..)...
00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000080: 00 78 e6 2c e2 8b 01 e5 51 4e 4d 10 11 05 19 06 .x.,....QNM.....
00000090: 1b 1d e1 28 4f 50 4b 4a 0d 0b 0a 09 07 16 04 e0 ...(OPKJ........
000000a0: 2a 30 52 48 47 46 18 1c 17 15 08 1a 14 2b 4c 49 *0RHGF.......+LI
000000b0: 45 44 43 42 41 40 3f 3e 3d 3c 3b 3a 29 00 00 00 EDCBA@?>=<;:)...
000000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0 1 2 3 4 5 6 7 8 9 A B C D E F
----------------------------------------------------------------
? RGu RAl spc LAl LGu Fn RSh / . , m n b v c
x z Lsh Ret ' ; l k j h g f d s a Ctl
Del ] [ p o i u y t r e w q Tab ` \
= - 0 9 8 7 6 5 4 3 2 1 Esc ? ? ?
Boot Sequence
-------------
The device is configured with BFB2=0, nBOOT1=1 in option bytes and BOOT0 pin is pulled low(BOOT0=0) and it should boot at Bank1 on Flash memory.
With HHKB STM32 standard Dual bank boot sequence is not enabled(BFB2=0), it boots always from Bank1 and firmware on Bank1 checks Bank2 firmware inegrity and execute it somehow probably.
If Bank2 firmware is not valid Bank1 firmware continues to run anyway instead.
Bank1: original firmware and not updated? firmware linked with 0x0800 0000
Bank2: The latest firmware which usually runs and updated by Bank1 firmeware. firmware linked with 0x0801 0000
PFU firmeare is not compatible with STM32 dual-bank boot sequence by System bootloader
RM0376 3.3.2
When the BFB2 bit is set and the boot pins are configured to boot from Flash memory
(BOOT0 = 0 and BOOT1 = x), the device maps the System memory at address 0. Bootloader runs after reset and check Bank2 first and then Bank1.
When Bank2 is valid Bootloader sets UFB in SYSCFG_CFGR1 to map Bank2 at address 0x0800 0000(bank swap) and jump there.
When Bank2 is not valid and Bank1 is valid Bootloader keeps UFB 0 and jump to Bank1 at 0x0800 0000.
When both banks are not valid Bootloader continues to run for progamming Flash memory.
On-the-fly live update
----------------------
The goal of the live field upgrade is to make the transition to a new code version without
going through the system reset.
Codes in both banks are normally linked to start at address 0x0800 0000: AN4767 3.1.1
By bank swap Bank1 or Bank2 can be mapped at 0x0800 0000 depending on UFB setting.
Concerns about transition of execution from one bank to another: AN4767 4
Both banks have unmodifiable and fixed code section which keeps stack at the lowest as possible to make the transition.
Remember that having identical source code does not implicate that identical binary codes
will be generated. It is better to generate a library to be linked to all future versions, or
preserve an object file, or (perhaps) even carefully edit the resulting binary
Dip Switch
----------
SW1,SW2: Keymap mode
00 HHK: Henkan and Muhenkan on Gui keys, Disables Volume and Power key, Enables Stop key(Cancel)
10 WIN: Disables Volume and Power key, Disables Stop key
01 MAC: Enables Volume and Power key, Disables Stop key
11 N/A: Inhibited.
SW3: Delete/Backspace
SW4: Left Super/Fn
SW5: Alt/Super
SW6: Power saving(Remote wakeup)
Internals
---------
Switch board:
1.6mm thick PCB
CNL1: Connector I-PEX CABLINE-VS 30pin, receptacle: 20455-030E-99, https://www.i-pex.com/product/cabline-vs
U1, U2: LW051A TSSOP 16pin, TI SN74LV4051A, http://www.ti.com/lit/ds/symlink/sn74lv4051a.pdf
U3: Non populated
U4: AYO7A48 10pin, OPA2373AID, OPAmp, https://www.ti.com/lit/ds/symlink/opa2373.pdf
Q8: MOSFET switching 21-Signal
Controller board:
2.0mm thick PCB
Z2 STM32L072RBT6 https://www.st.com/resource/en/datasheet/stm32l072rb.pdf
ADC: AN2668
Bootloader: AN2606
Z2.1 VDD
Z2.2 PC13 (Power Switch for Battery?)
Z2.3 PC14 (Power Switch TPS2065D for Switch board)
Z2.4 PC15 (pull down with 10K)
Z2.5 (Xtal) NP
Z2.6 (Xtal) NP
Z2.7 NRST (to CN3)
Z2.8 PC0 (pull down with 10K)
Z2.9 PC1 (pull down with 10K)
Z2.10 PC2 ?? for JP layout?
Z2.11 PC3 (pull down with 10K)
Z2.14 PA0 (pull down with 10K)
Z2.15 PA1 Signal input
Z2.16 PA2 (pull down with 10K)
Z2.17 PA3 (DIPSW-1)
Z2.18 VSS
Z2.19 VDD
Z2.20 PA4 (DIPSW-2)
Z2.21 PA5 (DIPSW-3)
Z2.22 PA6 (DIPSW-4)
Z2.23 PA7 (DIPSW-5)
Z2.24 PC4 (DIPSW-6)
Z2.25 PC5 (Push button for Bluetooth)
Z2.26 PB0 Row drive
Z2.27 PB1 Row drive
Z2.28 PB2 Row drive
Z2.29 PB10 Row drive
Z2.30 PB11 (Row drive for JP layout?)
Z2.31 VSS
Z2.32 VDD
Z2.33 PB12 COL A
Z2.34 PB13 COL B
Z2.35 PB14 COL C
Z2.36 PB15 U1 ~EN
Z2.37 PC6 U2 ~EN
Z2.38 PC7 OPAmp EN
Z2.39 PC8 Q8.5-gate capacitor discharge
Z2.40 PC9 ??
Z2.41 PA8 ~LED1
Z2.42 PA9 ~LED2
Z2.43 PA10 ??
Z2.44 (USB_DM)
Z2.45 (USB_DP)
Z2.46 (SWIO to CN3)
Z2.47 VSS
Z2.48 VDD_USB 3.3V from regulator
Z2.49 SWCLK (to CN3)
Z2.50 PA15 (to Bluetooth module) pull up with 51K R130
Z2.51 PC10 (pull down with 10K)
Z2.52 PC11 (pull down with 10K)
Z2.53 PC12 (pull down with 10K)
Z2.54 PD2 (to Bluetooth module) pull down with 51K R83 module reset??
Z2.55 PB3 (to Bluetooth module) pull up with 51K R127
Z2.56 PB4 (to Bluetooth module) pull up with 51K R128
Z2.57 PB5 (to Bluetooth module) pull up with 51K R129
Z2.58 PB6 (to Bluetooth module) pull up with 51K R131
Z2.59 PB7 (Battery Voltage Monitor)
Z2.60 BOOT0 pull down with 10K R6
Z2.61 PB8 (Battery Voltage Monitor)
Z2.62 PB9 (Battery Voltage Monitor)
Z2.63 VSS
Z2.64 VDD
Z7 V20 1GY, Voltage Regulator 3.3V
Z8 ?? Voltage monitor for Z7?
Z6 2065 SOT-23-5 TI TPS2065D http://www.ti.com/lit/ds/symlink/tps2065d.pdf
R85 0Ohm connects USB Power(3.3V regulated) and Battery Power for USB only Classic
Z15 Not populated. Power switch between USB power and Battery power
CN5 Not populated. Connector for battery
CN3 SWD Z2.7(NRST), Z2.49(SWCLK), Z2.46(SWDIO)
Z3 Reset IC connected to Z2.7(NRST)
Z5 Boost converter for Battery power
Z12 Voltage Monitor to shutdown Z5 when low voltage?
Z17, Z10, Z11 Voltage Monitor for Battery
Z4 Buck converter?
Switch board connector Controller board connector
1 Row drive 30 Z2.26 PB0
2 U1-4051A.INH(Turns on output with Lo.) 29 Z2.36 PB15
3 U1,U2-4051A.B 28 Z2.34 PB13
4 Row drive 27 Z2.27 PB1
5 U1,U2-4051A.C 26 Z2.35 PB14
6 Row drive 25 Z2.28 PB2
7 U1,U2-4051A.A 24 Z2.33 PB12
8 Row drive 23 Z2.29 PB10
9 U2-4051A.INH(Turns on output with Lo.) 22 Z2.37 PC6
10 NC? Row for JP layout?? 21 Z2.30 PB11(not controlled)
11 ~LED1.Kathode 20 Z2.41 PA8 thr Q6 Digital-Tr
12 ~LED2.Kathode 19 Z2.42 PA9 thr Q2 Digital-Tr
13 Q12.2-gate not populated. ?? Not controlled 18 Z2.40 PC9
14 U4.5,6(OPAmp EnableA,B) 17 Z2.38 PC7
15 NC? 16 Z2.43 PA10 with 510K pull-up
16 Q8.5-gate discharge? before row drive 15 Z2.39 PC8
17 NC?(for JP layout?) 14 Z2.10 PC2
18 GND 13 GND
19,20 AGND 11,12 AGND=GND
21 Signal from OPAmp 10 Z2.15 PA1
22,23 AGND 8,9 AGND=GND
24-26 GND 5-7 GND
27-29 VCC(3.3V) 2-4 Switched by Z6(TPS2065D) Z2.3
30 LED Power(3.3V): through R43, R44 to LED1.Anode, LED2.Anode 1 VCC 3.3V
Scan Key Matrix
===============
Scan matrix takes 4.8ms per 20ms
for (15 colums)
for (4 rows)
Row Drive
Sense keys
Matrix on PCB:
U1 U2
Y0 Y3 Y1 Y2 Y4 Y5 Y6 Y7 Y3 Y0 Y1 Y2 Y4 Y6 Y5
0 1 2 3 4 5 6 7 8 9 a b c d e
------------------------------------------------------------
PB1 Esc 1 2 3 4 5 6 7 8 9 0 - = \ `
PB2 Tab q w e r t g y u i o p [ ] Del
PB10 Ctl a s d c v b h j k l ; ' Ret Fn
PB0 LSh LAl z x LGu f spc n m , . RGu / RSh RAl
Matrix Scan order:
U1 U2
Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7 Y0 Y1 Y2 Y3 Y4 Y5 Y6
0 2 3 1 4 5 6 7 9 a b 8 c e d
-----------------------------------------------------------
PB0 LSh z x LAl LGu f spc n , . RGu m / RAl RSh
PB1 Esc 2 3 1 4 5 6 7 9 0 - 8 = ` \
PB2 Tab w e q r t g y i o p u [ Del ]
PB10 Ctl s d a c v b h k l ; j ' Fn Ret
Col Select
----------
It takes 4.8ms to scan all keys on 4x15 matrix
| |20ms
___ _________________ ............. ___ _____
U1 |_______________| |_______________|
_______________ _______________
U2___| |_________________ ............. ___| |______
| U1.enable |2.5ms
| U2.enable |2.3ms
____ _______ _________
C |_______| |_______|
____ ___ ___ ___ _____
B |___| |___| |___| |___|
_ _ _ _ _ _ _
A______| |_| |_| |_| |_| |_| |_| |_____
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6
| |320us
| |4.8ms
Row Drive
---------
Wave form of drive: https://i.imgur.com/AHe1m27.png
Four rows driven: https://i.imgur.com/paKkbNF.png
_ 3.3V _
| | | |
| | | |
| \ | \
ROW0____| \___________________| \____
| |20us
| |80us
| |320us
_ _
| | | |
| | | |
| \ | \
ROW1__________| \___________________| \____
_ _
| | | |
| | | |
| \ | \
ROW2________________| \___________________| \____
_ _
| | | |
| | | |
| \ | \
ROW3______________________| \___________________| \____
| COL0 | COL1 | ... COL14 |
| |4.8ms
A row driven around 4.8ms(320us*15): https://i.imgur.com/Pg2XIUa.png
A row driven for 15 columns and output of OpAmp: https://i.imgur.com/6cQ6uIg.png
Sense key
---------
0. Select a column
1. Enable OpAmp
2. Discharge capcitor
Sample capacitor C57 retaining voltage of previous key and is dischared?
3. Drive a row
Signal is amplified and stored in capacitor C57?
4. Sensed by Controller
5. Shutdown OpAmp
6. loop 2-5 for rows
Signal for discarging capacitor: https://i.imgur.com/aRtHkPi.png
|| || || || discharge
|| || || ||
|| || || ||
Q8.g __||____||____||____||_____
||7us
Row drive and output from OpAmp: https://i.imgur.com/I91TQpL.png
Row drive and output from OpAmp: https://i.imgur.com/2g2jq8d.png
Row drive and output from OpAmp: https://i.imgur.com/scxqnAv.png
_ _ _ _
| | | | | | | |
| | | | | | | |
| \ | \ | \ | \
ROWn ___| \_| \_| \_| \_
| |20us
| |80us
____ 2.3V(depressed)
| |
| |
| | 600mV(normal)
Sense_--| |-----------------_ output from OpAmp
OPAmp_____ ___ ___ ___ _ enable
| | | | | | | |
| | | | | | | |
| | | | | | | |
|_| |_| |_| |_| shutdown
| |22us
| |53us
USB info
========
/var/log/kern.log:
Dec 14 11:46:49 desk kernel: [774252.335808] usb 3-3.2: new full-speed USB device number 35 using xhci_hcd
Dec 14 11:46:49 desk kernel: [774252.452770] usb 3-3.2: New USB device found, idVendor=04fe, idProduct=0020
Dec 14 11:46:49 desk kernel: [774252.452774] usb 3-3.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
Dec 14 11:46:49 desk kernel: [774252.452776] usb 3-3.2: Product: HHKB-Classic
Dec 14 11:46:49 desk kernel: [774252.452778] usb 3-3.2: Manufacturer: PFU Limited
Dec 14 11:46:49 desk kernel: [774252.475927] input: PFU Limited HHKB-Classic as /devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-3/3-3.2/3-3.2:1.0/0003:04FE:0020.01A4/input/input323
Dec 14 11:46:49 desk kernel: [774252.536337] hid-generic 0003:04FE:0020.01A4: input,hidraw2: USB HID v1.11 Keyboard [PFU Limited HHKB-Classic] on usb-0000:38:00.3-3.2/input0
Dec 14 11:46:49 desk kernel: [774252.543236] input: PFU Limited HHKB-Classic as /devices/pci0000:00/0000:00:08.1/0000:38:00.3/usb3/3-3/3-3.2/3-3.2:1.1/0003:04FE:0020.01A5/input/input324
Dec 14 11:46:49 desk kernel: [774252.600164] hid-generic 0003:04FE:0020.01A5: input,hidraw3: USB HID v1.11 Keyboard [PFU Limited HHKB-Classic] on usb-0000:38:00.3-3.2/input1
Dec 14 11:46:49 desk kernel: [774252.604075] hid-generic 0003:04FE:0020.01A6: hiddev1,hidraw4: USB HID v1.11 Device [PFU Limited HHKB-Classic] on usb-0000:38:00.3-3.2/input2
USB Intefaces
-------------
0: Boot Keyboard EP1IN(6KRO)
1: NKRO Keyboard and Consumer keys EP2IN
Reprot ID 1: Consumer Media keys
Reprot ID 2: NKRO Keyboard(Not used)
Reprot ID 3: Consumer Application Launch/Control keys(Not used)
2: Vendor specific EP3IN, EP4OUT
for keymap/firmware update
USB Descriptor
--------------
https://gist.github.com/tmk/5f22878a7ddca01e9174e5d6224395d2
DFU Bootloader
==============
To kick up System bootloader plugin with pulling up BOOT0 pin.
$ dfu-util -l
dfu-util 0.9
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
Found DFU: [0483:df11] ver=2200, devnum=87, cfg=1, intf=0, path="3-3.2", alt=2, name="@DATA Memory /0x08080000/2*3Ke", serial="164738450000"
Found DFU: [0483:df11] ver=2200, devnum=87, cfg=1, intf=0, path="3-3.2", alt=1, name="@Option Bytes /0x1FF80000/01*032 e", serial="164738450000"
Found DFU: [0483:df11] ver=2200, devnum=87, cfg=1, intf=0, path="3-3.2", alt=0, name="@Internal Flash /0x08000000/1536*128g", serial="164738450000"
Flash
-----
Get Flash content(128KB) through bootloader.
$ dfu-util -a 0 -s 0x08000000 -U hhkb-flash.bin
It is comprised of two memory bank.
First part 64KB
00000 unknown. Programming interface for update keymap and firmware?
: :
0ffff
Second part 64KB
10000 identical to bin part of HHKB401_FW_A426.hfb
: :
1ffff
Firwmware is common for both US and JP layout and has different keymaps for them.
US keymaps is located around 0x0000cd20 while JP is around 0x0000c300.
Version of original firmware
0x0000 c100 0b 04 01 06 B4.1.6 (bank1)
0x0001 c150 0a 04 02 06 A4.2.6 (bank2)
EEPROM
------
It seems like keymap is stored in EEPROM. DIP switch key configuration affects on keymap in EEPROM.
It seems to have key sense calibration data in EEPROM also. After EEPROM broken accidentally some keys never been released. Restoring original EEPROM data cured the issue.
keymaps(128 byte per layer):
0x0000 HHK default
0x0080 HHK Fn
0x0100 MAC default
0x0180 MAC Fn
0x0200 WIN default
0x0280 WIN Fn
Other infos:
0x0300 Keyboard ID and version(A4.2.6)
00000300: aa aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000310: 50 44 2d 4b 42 34 30 31 57 00 00 00 00 00 00 00 PD-KB401W.......
00000320: 00 00 00 00 41 30 00 00 43 31 38 4c 30 30 30 32 ....A0..C18L0002
00000330: 38 39 00 00 00 00 00 00 0a 04 02 06 00 00 00 00 89..............
00000340: 0b 04 01 06 00 00 00 00 00 00 00 00 00 00 00 00 ................
Get EEPROM content through DFU bootloader.
$ dfu-util -a 2 -s 0x08080000 -U hhkb-eeprom.bin
dfu-util 0.9
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/
Opening DFU capable USB device...
ID 0483:df11
Run-time device DFU version 011a
Claiming USB DFU Interface...
Setting Alternate Setting #2 ...
Determining device status: state = dfuIDLE, status = 0
dfuIDLE, continuing
DFU mode device DFU version 011a
Device returned transfer size 2048
DfuSe interface name: "DATA Memory "
Limiting upload to end of memory segment, 6144 bytes
Upload [=========================] 100% 6144 bytes
Upload done.
Option Btyes
------------
The Option bytes are automatically loaded during the boot. They are used to set the content of the FLASH_OPTR
and FLASH_WRPROTx registers. RM0376 3.8
32-byte data
$ dfu-util -a 1 -s 0x1FF80000:32 -U hhkb-opt.bin
00000000: aa 00 55 ff 70 80 8f 7f 00 00 ff ff 00 00 ff ff ..U.p...........
00000010: 00 00 ff ff 00 00 00 00 00 00 00 00 00 00 00 00 ................
FLASH_OPTR: RM0376 3.7.8
0x8070 00aa
nBOOT1: 1
BOR_LEV:0 BOR OFF
BFB2: 0
WPRRMOD:0
RDPROT: 0xAA Protection Level 0
FLASH_WRPROT1: RM0376 3.7.9
0x0000 0000
FLASH_WRPROT2
0x---- 0000
48-bit: flash memroy sector protection configuration up to 192KB(48*4K sector)
0: sector not protected
1: sector protected
HHKB Keymap/Firwamre Update
===========================
Keyboard firmware supports the update feature with interface2 ep3 and 4.
Protocol
--------
Host command format: 0xaa,0xaa,cmd(1-byte),0x00,len(1-byte, length of data),data...
Keyboard response format: 0x55,0x55,cmd(1-byte)
command byte:
01 echo AA,AA,01,00,01,00
response:
55,55,01,00
02 read ID and version AA,AA,02,00,00
response:
55,55,02,00,00,39,(eeprom data at 0x310) - confirmed.
model name and serial number are picked from eeprom at 0x310 while firmware
version come from firmware code itself.
The last byte at end of data indicates integrity of A(Bank2) and the byte
turns 0x01 when the firmware is broken.
eemprom data:
00000310: 50 44 2d 4b 42 34 30 31 57 00 00 00 00 00 00 00 PD-KB401W.......
00000320: 00 00 00 00 41 30 00 00 43 31 38 4c 30 30 30 32 ....A0..C18L0002
00000330: 38 39 00 00 00 00 00 00 0a 04 02 06 00 00 00 00 89..............
00000340: 0b 04 01 06 00 00 00 00 00 .........
Note that version info of 0a 04 02 06 and 0b 04 01 06 in eeprom are not used.
It means firmware version 4.2.6 in A(Bank2) and 4.1.6 in B(Bank1).
05 read DIP Switch AA,AA,05,00,00
response:
55,55,05,00,00,0c,DIP1,DIP2,DIP3,DIP4,DIP5,DIP6,00,00,00,00,00,00
(00: OFF, 01: ON) - confirmed.
06 key config AA,AA,06,00,00
response:
55,55,06,00,00,00(HHK) or 55,55,06,00,00,01(MAC) or 55,55,06,00,00,02(WIN)
87 read keymap(two layers) AA,AA,87,00,02,(key config:[0|1|2]),(layer:[0|1])
response:
55,55,87,00,41,3a,(eeprom data)
55,55,87,00,82,3a,(eeprom data)
55,55,87,00,c3,0c,(eeprom data)
where keymap size: 128 bytes(0x3a+0x3a+0c)
eeprom data: HHK layer.0 at 0x0000
HHK layer.1 at 0x0080
MAC layer.0 at 0x0100
MAC layer.1 at 0x0180
WIN layer.0 at 0x0200
WIN layer.1 at 0x0280
e0 firmware update start? e0,00,00
e1 ?? e1,00,08,22,00,01,00,aa,d7,00,00
e2 e2,00,len,lsb,msb,data(firmware binary) where lsb and msb is sequence number
e3 firmware update end? e3,00,00
HHKB firmware file format .hfb
------------------------------
HHKB401_FW_A426.hfb - Firmware file for PD-KB401 downloaded from PFU site at 2019-12-11
The firmware is identical to 2nd part 64KB of hhkb-flash.bin.
Size: 65570 bytes = 64KB bin file(65536) + pre/postfix 34 bytes
"8f 03" part of Prefix can be located at 0x0370 in eeprom
Prefix:
aa d7 8f 03
Bin(64KB)
Postfix:
ff ff ff ff ff ff ff ff ff ff ff ff ff ff 41 48 48 58 30 31 0a 04 02 06 ff ff ff ff ff ff
.......AHHX01..........
Description below includes vague speculation.
HHKB800_FW_A036.hfb - for Hybrid PD-KB800
Size: 282672 bytes 276KB(282624) + pre/postfix 48bytes???
Prefix:
00000000: 16 c8 ae ad
Postfix:
00045020: 41 48 55 58 30 31 0a 00 03 06 ff ff ff ff ff ff AHUX01..........
+-----------+
| 64KB | firmware for STM32???
+-----------+
| |
| 148KB | ???
| |
+-----------+
| 64KB | ???
+-----------+
HHKB800_FW_JP_A236.hfb - for Hybrid JP PD-KB820
Prefix:
00000000: 48 ad 05 fc
Postfix:
00045020: 41 48 4a 58 30 31 0a 02 03 06 ff ff ff ff ff ff AHJX01..........
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment