Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pro S RGB Support #1

Open
44 of 50 tasks
hansemro opened this issue May 31, 2022 · 24 comments
Open
44 of 50 tasks

Pro S RGB Support #1

hansemro opened this issue May 31, 2022 · 24 comments

Comments

@hansemro
Copy link
Collaborator

hansemro commented May 31, 2022

  • Holtek HT32F1654 (Cortex-M3)
  • GigaDevice 25Q40CT
  • 3x Macroblock MBIA043GP (1 per channel)

CN2 header:

  • pin 1: 3v3
  • pin 2: SWDIO
  • pin 3: SWCLK
  • pin 4: nRST
  • pin 5: GND

SEL1 header:

  • pin 1: BOOT0
  • pin 2: GND

SEL2 header:

  • pin 1: GND
  • pin 2: BOOT1

So far, very similar to POK3R RGB. I will update with more details as I find them.

Tasks:

@hansemro
Copy link
Collaborator Author

hansemro commented Jun 1, 2022

Raspberry Pi 4 : ProS

  • pin 9 : GND
  • pin 12 : nRST
  • pin 18 : SWDIO
  • pin 22 : SWCLK
  • NC : 3v3 (power supplied by usb)

Rebased openocd-ht32 with latest commits to fix some issues with raspberry pi: https://github.com/hansemro/openocd-ht32/tree/ht32f165x-dev

Build:

git clone -b ht32f165x-dev-v0.12.0-rc2 https://github.com/hansemro/openocd-ht32.git
cd openocd-ht32
./bootstrap
./configure --enable-bcm2835gpio --enable-sysfsgpio
make
sudo make install

openocd.cfg:

adapter driver bcm2835gpio
transport select swd

### for RPi4
bcm2835gpio peripheral_base 0xFE000000
bcm2835gpio speed_coeffs 236181 60

## Pi pin 18 (GPIO24) : SWDIO
adapter gpio swdio 24
## Pi pin 22 (GPIO25) : SWCLK
adapter gpio swclk 25

## Pi pin 12 (GPIO18) : nRST
adapter gpio srst 18

## dont forget pin 9 for Ground

## HT32F1654
set HT32_SRAM_SIZE 0x8000
set HT32_FLASH_SIZE 0x10000

## HT32F52352
#set HT32_SRAM_SIZE 0x8000
#set HT32_FLASH_SIZE 0x20000

source [find target/ht32f165x.cfg]
pi@raspberrypi:~ $ sudo openocd
Open On-Chip Debugger 0.12.0-rc2+dev-00964-g9b86c7e5e (2022-11-03-16:13)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
trst_only separate trst_push_pull

Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : BCM2835 GPIO JTAG/SWD bitbang driver
Info : clock speed 12 kHz
Info : SWD DPIDR 0x2ba01477
Info : [ht32f165x.cpu] Cortex-M3 r2p0 processor detected
Info : [ht32f165x.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for ht32f165x.cpu on 3333
Info : Listening on port 3333 for gdb connections
Info : accepting 'telnet' connection on tcp/4444
Warn : [ht32f165x.cpu] Only resetting the Cortex-M core, use a reset-init event handler to reset any peripherals or configure hardware srst support.

@hansemro
Copy link
Collaborator Author

hansemro commented Jun 1, 2022

pro_s_rgb

@hansemro
Copy link
Collaborator Author

hansemro commented Jun 2, 2022

Pro S RGB firmware patch: https://github.com/hansemro/re-masterkeys/blob/Pro_S_RGB/binaries/Pro_S_RGB/patch.txt

FW offset 0x3400

    67fa: ff 28           cmp        r0,#0xff
    67fc: 04 d1           bne        0x00006808
    67fe: 60 68           ldr        r0,[r4,#0x4]
    6800: 3c 21           movs       r1,#0x3c
    6802: 31 e0           b          0x00006868
    6804: 00 bf           nop
    6806: 00 bf           nop

EDIT Sept 8, 2022: Fixed and tested firmware patch

@hansemro
Copy link
Collaborator Author

hansemro commented Jun 2, 2022

Some USB packet captures:

1: Plugging in keyboard
plug-in.zip

2: Firmware upgrade (1.2.2 to 1.2.2) via OEM software
fw-upgrade.zip

3: Firmware upgrade from fake version (1.1.9) to 1.2.2 via OEM software: no major difference
fw_upgrade_from_1.1.9.zip

@hansemro
Copy link
Collaborator Author

hansemro commented Jun 2, 2022

python script to get current firmware version from Pro S: RGB

Dependency: pyusb

get_version.py:

#!/usr/bin/env python3

import usb.core
import usb.util

dev = usb.core.find(idVendor=0x2516, idProduct=0x003c)

if dev is None:
    raise ValueError('CM Pro S not found')
else:
    print("CM Pro S found")

if dev.is_kernel_driver_active(1):
    try:
        dev.detach_kernel_driver(1)
        print("kernel driver detached")
    except usb.core.USBERROR as e:
        print(f"Could not detach kernel driver: {e}")
        exit(1)

try:
    usb.util.claim_interface(dev, 1)
    print("Claimed usb device")
except Exception as e:
    print(f"{e}")
    exit(1)

#ver_req = [ 0x01,0x02,0xdf,0xfc,0x00,0x30,0x00,0x00,0x3d,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0
x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00 ]
ver_req = [ 0x01,0x02 ]

dev.write(0x04, ver_req)

out = dev.read(0x83, 64)
out = "".join(chr(x) for x in out)
print(f"{out[4:9]}")

usb.util.dispose_resources(dev)

output:

$ python3 get_version.py 
CM Pro S found
kernel driver detached
Claimed usb device
1.2.2

@hansemro

This comment was marked as outdated.

@hansemro

This comment was marked as outdated.

@hansemro

This comment was marked as outdated.

@hansemro

This comment was marked as outdated.

@hansemro

This comment was marked as outdated.

@hansemro

This comment was marked as outdated.

@hansemro
Copy link
Collaborator Author

hansemro commented Jun 5, 2022

Protocol is nearly the same as the one descibed in proto_pok3r instead of proto_cykb.

Correction: Pro S RGB seems to implement/borrow functions in pok3r and cykb protocols. For example, [0x3,0x0] from pok3r protocol works to retrieve fw/ver addresses and [0x12,0x20] from cykb protocol works to retrieve version string (like [0x1,0x2]).

@hansemro
Copy link
Collaborator Author

hansemro commented Jun 5, 2022

Good and bad news: erase command works for clearing version and firmware data....

In my attempt to write firmware with flash erase step (in my fork of pok3rtool: https://github.com/hansemro/pok3rtool/tree/cooler-master-dev), I noticed that cooler master can no longer be detected over USB and can not function as a HID device.

I was able to set version successfully, but it seems firmware region could not be written to.

@hansemro
Copy link
Collaborator Author

hansemro commented Jun 5, 2022

Shorting SEL2 to boot into bootloader mode allows the keyboard to be detected, but not with cooler master VID/PID/IPID.

ID 2516:003c Cooler Master Technology Inc. MASTERKEYS PRO S <- firmware mode
ID 2516:003d Cooler Master Technology Inc. USB-HID IAP <- bootloader mode
ID 04d9:8010 Holtek Semiconductor, Inc. <- SEL2 short mode

Not sure what can be done to reprogram firmware without erasing bootloader...

EDIT:
For less confusion: bootloader mode actually refers to IAP firmware that lies at 0x0, and SEL2 short mode refers to bootrom/bootloader at 0x1f000000.

@hansemro
Copy link
Collaborator Author

Modified SVD with some changes to fix overlapping peripheral regions: HT32F1653_54.svd.zip

SVD Source: https://web.archive.org/web/20220827045212/https://mcu.holtek.com.tw/pack/Holtek.HT32_DFP.1.0.41.pack

@hansemro
Copy link
Collaborator Author

hansemro commented Sep 9, 2022

Fixed firmware writing with my fork of pok3rtool with hansemro/pok3rtool@11b822d, managed to dump flash from another Pro S RGB, and recovered my previously dead board with stock bootloader!

Flashing patched firmware (from 1.2.2):

$ pok3rtool_cm -t prosrgb flash 1.2.3 ProSRGB_fw_patched.bin --ok                                                                                
Opened MasterKeys Pro S RGB                                                                                                                                                
Update Firmware: ProSRGB_fw_patched.bin                                                                                                                                    
Reset to Bootloader                                                                                                                                                        
Current Version: 1.2.2                                                                                                                                                     
Clear Version                                                                                                                                                              
Erase...                                                                                                                                                                   
Write...                                                                                                                                                                   
Check...                                                                                                                                                                   
Flashed succesfully                                                                                                                                                        
Clear Version                                                                                                                                                              
Writing Version: 1.2.3                                                                                                                                                     
Reset to Firmware                                                                                                                                                          
true
$ pok3rtool_cm -t prosrgb dump flash.dump                                                                                                        
WARNING: THIS TOOL IS RELATIVELY UNTESTED, AND HAS A VERY REAL RISK OF CORRUPTING YOUR KEYBOARD, MAKING IT UNUSABLE WITHOUT EXPENSIVE DEVELOPMENT TOOLS. PROCEED AT YOUR OW
N RISK.                                                                                                                                                                    
Type "OK" to continue:                                                                                                                                                     
OK                                                                                                                                                                         
Proceeding...                                                                                                                                                              
Opened MasterKeys Pro S RGB                                                                                                                                                
Dump Flash                                                                                                                                                                 
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%                                                                                                            
Out: flash.dump, 65520 bytes
$ xxd flash.dump | head -n 5
00000000: 480d 0020 1901 0000 2501 0000 2501 0000  H.. ....%...%...
00000010: 2501 0000 2501 0000 2501 0000 0000 0000  %...%...%.......
00000020: dff8 0cd0 00f0 30f8 0048 0047 8924 0000  ......0..H.G.$..
00000030: 480d 0020 0168 8d46 4168 0847 4115 0000  H.. .h.FAh.GA...
00000040: 40ea 0103 9b07 03d0 09e0 08c9 121f 08c0  @...............

@hansemro
Copy link
Collaborator Author

Added initial schematic drawing after a few days of tracing: hansemro@35a5ebb

@hansemro
Copy link
Collaborator Author

hansemro commented Oct 6, 2022

Added initial QMK support (key switch and USB support only): https://github.com/hansemro/qmk_firmware/tree/prosrgb_dev

@hansemro
Copy link
Collaborator Author

hansemro commented Oct 11, 2022

MBIA043 RE notes:

These results were discovered from firmware disassembly and testing in QMK.

QMK test branch: https://github.com/hansemro/qmk_firmware/tree/prosrgb_mbia043_testing2
QMK (soon)PR branch: https://github.com/hansemro/qmk_firmware/tree/prosrgb_mbia043_dev

Instructions

Instructions are determined by the number of DCLK rising edges while LE is asserted.

For instructions that read data from shift register, the falling edge of LE must occur shortly after the final data entry gets shifted.

Data Latch: 1 DCLK rising edge

Moves data from shift register to buffer.

Overall Latch: 2 DCLK rising edges

Moves data in buffers to comparators.

(Undocumented) Read Configuration: 4 DCLK rising edges

Moves 10-bit configuration data to shift register.

Configuration:

  MSB     ...     LSB
0b0_0_0_0_0_0_0_0_1_0 (default)
  | | | | | | | | | `-> counter disable (when 1)
  | | | | | | | | `-> unk1
  | | | | | | | `-> unk2
  | | | | | | `-> unk3
  | | | | | `-> unk4 (not saved)
  | | | | `-> unk5 (not saved)
  | | | `-> unk6 (not saved)
  | | `-> unk7 (not saved)
  | `-> unk8
  `-> unk9 (not saved)

(Undocumented) Enable Write Configuration: 18 DCLK rising edges

Enables Write Configuration instruction (if it is the next instruction).

Used by v122 firmware.

(Undocumented) Write Configuration: 8 DCLK rising edges

Moves data from shift register to (undocumented) configuration register.

Used by v122 firmware to configure each MBIA IC to 0b0000001100.

Routines

Shifting data

On every rising edge of DCLK, the shift-register shifts in data from SDI and out of SDO. This includes cases when LE is asserted high (to call an instruction using data in the shift-register).

v122 mbia_shift_data: https://github.com/hansemro/pok3r_re_firmware/blob/8346ba6d6a77e60094a02dcac3b5c8559cb7bf75/disassemble/cmprosrgb/v122/cmprosrgb_v122.txt#L13111-L13145

Sending an instruction

Set LE high until the requisite number of DCLK rising edges has been met, then set LE low. Whatever data is in the shift-register on the final DCLK edge is used for the instruction (and not a DCLK cycle later).

v122 mbia_send_instruction: https://github.com/hansemro/pok3r_re_firmware/blob/8346ba6d6a77e60094a02dcac3b5c8559cb7bf75/disassemble/cmprosrgb/v122/cmprosrgb_v122.txt#L13075-L13108

Setting grayscale values

A grayscale value for each channel must be set (starting from channel 16/OUT15) when updating comparator values. For each channel, a (10-bit) grayscale data is shifted in with LE asserted only for the last bit (Data Latch). After latching data for the final channel, send Overall Latch command.

Note that cascading MBIAs essentially become an extended shift-register, so the same general steps above apply to this case but with N * 10-bit data to shift for each channel.

v122 mbia_shift_RGB_from_sram (writes RGB data to buffers for single row): https://github.com/hansemro/pok3r_re_firmware/blob/8346ba6d6a77e60094a02dcac3b5c8559cb7bf75/disassemble/cmprosrgb/v122/cmprosrgb_v122.txt#L8413-L8490

v122 bftm1_intr (commits buffers to comparators): https://github.com/hansemro/pok3r_re_firmware/blob/8346ba6d6a77e60094a02dcac3b5c8559cb7bf75/disassemble/cmprosrgb/v122/cmprosrgb_v122.txt#L657-L708

Timing

For MBIA043 at 3.3V, DCLK has maximum allowed frequency of 25 MHz, so use the appropriate number of NOP delays to operate below this limit. (e.g. For ARM core running at 72 MHz, 3 NOPs are required to run at/below 24 MHz).

@hansemro
Copy link
Collaborator Author

Dimming test (shortened cycle length to reduce video length) with QMK.

prosrgb_mbia_cycle_test.mp4

@hansemro
Copy link
Collaborator Author

hansemro commented Oct 17, 2022

Per-key lighting on QMK:

prosrgb_mbia_rgb_driver.mp4

@hansemro
Copy link
Collaborator Author

Keyboard (with QMK) hardfaults after enabling Flash Memory Security Protection bit (OB_PP[0]).

@hansemro
Copy link
Collaborator Author

hansemro commented Nov 14, 2022

Added a new openocd branch to enable security bits (which will be used to debug lockup when security is enabled): https://github.com/hansemro/openocd-ht32/tree/ht32f165x-security-test

> # unlocked keyboard
> halt; ht32f165x check_security 0 
[ht32f165x.cpu] halted due to debug-request, current mode: Handler External Interrupt(41)
xPSR: 0x21000039 pc: 0x00000108 msp: 0x20000d18
ht32f165x probe: 128 pages, 0x400 bytes, 0x20000 total
ht32f165x opt byte: ffffffff ffffffff ffffffff ffffffff ffffffff
ht32f165x CPSR: 0xffffffff
ht32f165x OB_CP: 0xffffffff
ht32f165x OB_CK: 0xffffffff
ht32f165x opt byte: ffffffff ffffffff ffffffff ffffffff ffffffff
ht32f165x check_security complete

# relocking keyboard
> halt; ht32f165x enable_security 0
[ht32f165x.cpu] halted due to debug-request, current mode: Handler External Interrupt(41)
xPSR: 0x01000039 pc: 0x00000134 msp: 0x20000d28
ht32f165x probe: 128 pages, 0x400 bytes, 0x20000 total
ht32f165x opt byte: ffffffff ffffffff ffffffff ffffffff ffffffff
ht32f165x programming word 0x0000 @ 0x1ff00000
ht32f165x programming word 0xffffffff @ 0x1ff00004
ht32f165x programming word 0xffffffff @ 0x1ff00008
ht32f165x programming word 0xffffffff @ 0x1ff0000c
ht32f165x programming word 0xfffffffe @ 0x1ff00010
ht32f165x programming word 0xfffffffb @ 0x1ff00020
ht32f165x Security will be set on reset
ht32f165x enable security complete

# confirming keyboard is locked after reset (unplug & plug usb)
> ht32f165x check_security 0
ht32f165x probe: 128 pages, 0x400 bytes, 0x20000 total
ht32f165x opt byte: 0000 ffffffff ffffffff ffffffff fffffffc
ht32f165x CPSR: 0xfffffffc
ht32f165x OB_CP: 0x0000
ht32f165x OB_CK: 0x0000
ht32f165x opt byte: 0000 ffffffff ffffffff ffffffff fffffffc
ht32f165x check_security complete

@hansemro
Copy link
Collaborator Author

hansemro commented Nov 14, 2022

While keyboard is locked, things you can do in openocd:

  • use reset halt command to halt MCU in working state before it faults.
  • set registers (e.g. reg <r0|r1|...|pc> <value>) and step through instructions while in working state.
  • read registers with reg command
  • read from peripheral registers (not thoroughly tested)

Some things you cannot do while locked:

  • Use load instructions to read data from internal program flash (DCODE). Load instructions in firmware will read in 0 (while debugger is attached). Loading from SRAM (0x20000000) works just fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant