tp-compact-keyboard icon indicating copy to clipboard operation
tp-compact-keyboard copied to clipboard

Swap FN and CTRL on Trackpoint II keyboard

Open thanhtacles opened this issue 3 years ago • 13 comments

Practically everywhere you go, every review and every lenovo thread, about the trackpoint 2 keyboard, there's this persistent issue of being unable to swap the FN and CTRL keys somehow, which is amazing as that just flew under their radar for making the second edition keyboard. Link

It would be a hell of a lot of help if the same hex edit miracle was pulled for the trackpoint ii as it was for the trackpoint 1

thanhtacles avatar Mar 26 '21 09:03 thanhtacles

Now there's a solution to change every key except for the FN-Key. Which is kind of hilarious given the time I invested.

I will give a detailed explanation with the hopes somebody else can work from that or can give me some hints.

Let's start from the beginning:

Getting the binary:

  • Once the PCB is accessed, partially remove the double-sided sticky tape and solder 4 wires to the PCB (3V3, SWDIO, SWDCLK, GND) (In theory the PCB doesn't need to be removed since the back of the keyboard mold has dedicated holes, which give you access to those pins. Practically to do that, the label sticker and the double-sided sticky tape which holds the pcb in place has to be pierced to get contact to those pins. I thought that's rather unreliable - given the fact that you want to be sure to have an uncorrupted binary.) esp-32-swd

  • Get a nRF5x-compatible swd programmer and dump the flash (the NRF52832 is not locked) (e.g an ESP32 with ESP32 nRF52SWD Flasher - many thanks to @atc1441.) (I dumped the flash twice and diffed the binarys - just to be sure.) My dump differs in some places from the one @krysoft posted here So it can be suspected that the FWs are somewhat unique - but I can't proof that

Inspecting the binary:

  • First of all: backup your original binary.
  • Then open a copy of the binary with an hex-editor of your choice. (e.g. GHex or HxD)
  • There are 2 look-up-tables in the binary which translate the matrix-inputs into Usage IDs. -- The first Look-Up-Table seem to start at 0x2CBF0 and ends at 0x2CC49. -- The second Look-Up-Table starts at 0x4A6FA and ends at 0x4A779 -- The first LUT is used when the keyboard is connected via Bluetooth. -- The second LUT is used when the Keyboard is connected via the 2.4GHz-USB-Dongle. (Information about Usage IDs: https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf -> Page 53)

Modifying the binary:

From the binary and the Usage-ID I derived a keyboard matrix. It is based on the on matrix @federvieh posted for the wired keyboard on reddit. As you can see the keyboard matrix of the wireless keyboard differs on column 10-15 from the matrix of the wired keyboard.

  |---+----+--------+-----+----+----+------+----+----+----+----+-------+------+-------+------+--------------+-----------+--------|
  |   |    |      0 | 1   | 2  | 3  | 4    | 5  | 6  | 7  | 8  |     9 |    10|   11  | 12   | 13           | 14        | 15     |
  |   | LUT|    0xE | 0x0 | 0x4| 0x2| 0x1  | 0x3| 0x6| 0x7| 0x5|   0xF |   0xD|  0x9  | 0xC  | 0xA          | 0x8       | 0x0B   | <-offset_byte
  |---+----+--------+-----+----+----+------+----+----+----+----+-------+------+-------+------+--------------+-----------+--------|
  | 0 |  5 |        | ESC | h  | F4 |      | g  |    | '" | F6 |       | LALT |       | UP   |              | F5        |        |
  | 1 |  0 |        | `~  | 6  | F2 | F1   | 5  | F8 | -_ | =  | LCTRL |      | Insert|      |Delete forward| F9        | PgUp   |
  | 2 |  2 |        | q   | u  | e  | w    | r  | o  | p  | i  |       |      |       |      |              |           |        |
  | 3 |  1 |        | 1   | 7  | 3  | 2    | 4  | 9  | 0  | 8  |       |PrtScr| F12   | END  | F11          | F10       | PgDown |
  | 4 |  4 |        | a   | j  | d  | s    | f  | l  | ;: | k  |       |      |       |      |              | \ PIPE    |        |
  | 5 |  6 | RSHIFT | z   | m  | c  | x    | v  | .  |    | ,  | RCTRL |      |       |      |              | RETURN    |        |
  | 6 |  7 |        |     | n  |    |      | b  |    | /? |    |       | RALT | RIGHT | LEFT | DOWN         | SPACE     |        |
  | 7 |  3 | LSHIFT | TAB | y  | F3 | CAPS | t  | F7 | [  | ]  |       |      |       |      |              | DEL/BKSPC | WIN    |
  |---+----+--------+-----+----+----+------+----+----+----+----+-------+------+-------+------+--------------+-----------+--------|
         ^offset_bit

If you want to know the address of a key. Calculate: start_address_of_lut + offset_byte (column) * byte (0x08) + off_set_bit (row).

  • e.g., if you want to know the address of the PgDn-Key in the first LUT (Bluetooth) calculate: 0x2CBF0 + 0xB (offset_byte) *0x8 (byte) + 0x1 (offset_bit)-> 0x2CC49

The value of address 0x2CC49 is 0x4E, which is a PgDn-Command (see Usage-ID PDF Page 55)

  • e.g., if you want to know the address of the PgUp-Key in the second LUT (2.4GHz-Dongle) calculate: 0x4A6FA + 0xB (offset_byte) *0x8 (byte) + 0x0 (offset_bit)-> 0x4A752

The value of address 0x4A752 is 0x4B, which is a PgUp-Command (see Usage-ID PDF Page 55)

If you replace a value with 0x00 the corresponding key will be deactivated. If you insert other Usage-IDs in there, the key will become the command represented by the new usage-id.

But what about the FN-Key? In the wireless version of the keyboard the FN-Key has a dedicated IO. Which is PIN 8 (P0.06); pulled up - active low. (PIN 18 on the ZIF-Connector (see picture - the trace with the via right next to the ZIF-Connector) Meaning the FN-Key is not part of the keyboard matrix. A simple replacement with another Usage-ID (e.g. LSHIFT - 0xE0) seems not possible. One approach would be to look for pieces in the binary where the P0.06 is read and find a solution from there. But at the moment I didn't fully understand how that works. (E.g. The data in PIN_CNF[6] @ 0x718 make no sense to me.)

So I'm out of ideas... I found the tables by staring at the binary for hours and searching for logical usage id strings. The use of a disassembler would be useful, but I'm not familiar with that.
zif-io-closeup

juggernautjulian avatar Dec 04 '21 16:12 juggernautjulian

This looks promising. @juggernautjulian could you share the dumped binary?

boryspoplawski avatar Dec 06 '21 13:12 boryspoplawski

@boryspoplawski you can download the binary from @krysoft here: https://github.com/lentinj/tp-compact-keyboard/issues/32#issuecomment-911400144

juggernautjulian avatar Dec 06 '21 13:12 juggernautjulian

@juggernautjulian you are my hero! Thank you for such amazing work!

lgg avatar Dec 20 '21 22:12 lgg

In the wireless version of the keyboard the FN-Key has a dedicated IO. Which is PIN 8 (P0.06); pulled up - active low. (PIN 18 on the ZIF-Connector (see picture - the trace with the via right next to the ZIF-Connector) Meaning the FN-Key is not part of the keyboard matrix. A simple replacement with another Usage-ID (e.g. LSHIFT - 0xE0) seems not possible. One approach would be to look for pieces in the binary where the P0.06 is read and find a solution from there. But at the moment I didn't fully understand how that works. (E.g. The data in PIN_CNF[6] @ 0x718 make no sense to me.)

@juggernautjulian Could the FN key switch to different LUTs?

I think there should be at least 2 of them, and more likely 4, as the key functions depends on the Android/Windows toggle switch: it's explained on https://download.lenovo.com/consumer/options/trackpoint_keyboard_II_user_guide_en.pdf :

" For Android (8, 9, or later) enabled device: Press any F1-F12 function key to invoke the default function as shown in the following table."

The table is on page 9, and you can see for example that the physical F4 key should send MicMute in Windows, but have no function in android - likewise for Fn+PrintScreen or with the keys S P K B 4 (ex: Fn+P= send Pause)

The simplest way to support the full functionality all these would be to map the keys with 4 LUTs: if Fn is wired to a dedicated IO, I would expect the Android/Windows toggle switch to be similarly wired to a dedicated IO, and have the actual LUT used depend on the matrix of the 4 possible states for the Fn key (on,off) and the Android switch (on,off) combination.

This is because, if the physical F4 key is pressed:

  • Fn pressed+Android toggle on mapping F4 to nothing,
  • Fn pressed + Android toggle on mapping F4 to F4
  • Fn off + Android toggle on mapping F4 to nothing
  • Fn off Android toggle off mapping F4 to MicMute

Given the documentation, you could test if my hypothesis is correct by searching for LUTs that would have the predicted correspondences.

FYI, my goal is to alter these LUTs so that:

  • toggling the "android" switch makes F1-F12 work as normal F1-F12 keys, thus removing any special android mapping/disabled key (I want F4 to work!)
  • pressing the Fn key sends keycode 163, just like on old thinkpad keyboards ( cf https://www.autohotkey.com/board/topic/282-fn-key-on-a-notebook/ ) so that it can be used for an extra layer of software mappings

csdvrx avatar Jun 19 '22 02:06 csdvrx

For those, who consider to just disassemble wireless Trackpoint keyboard and resolder Fn and Ctrl buttond: do not mess with it. It is quite easy to open the housing, but the top part with keys is assembled with about 50 (and likely 20 or 30 more under those glued metal plates) molten plastic rivets. Even if it will be possible to resolder Fn and Ctrl, I can not imagine how to keep the same rigidity of the keyboard after reassembly.

What I consider now is to put an MCU between keys and motherboard to mock key press. Could somebody help me to determine exact type of ZIF connector? Connector on photo is 32 pin, 0.8 mm pitch made by Aces, acesconn.com.

TrackPoint Keyboard II over TrackPoint Keyboard II rivet close-up

DSC10025

WNMW avatar Jul 15 '22 01:07 WNMW

anything happened here? its too bad that there seems no solution. Im ready to do anything tho. some guy in the lenovo forum rewired the keys with conductive paint but says that the Fn key is not working properly anymore. Which may be an acceptable tradeoff.

bgi avatar Nov 10 '22 23:11 bgi

no real solutions here either. i am currently using powertoys to remap caps to control.

sideone avatar Nov 16 '22 03:11 sideone

Maybe is possible to flash it with a QMK or ZMK image and not only swap ctrl/fn without changing any hardware but also get all the benefits of a open source programmable keyboard? QMK seems to have NRF52 support: https://github.com/joric/nrfmicro/wiki/QMK , and there is also ZMK support (maybe better for bluetooth?).

There is also this open source keyboard firmware with explicit nRF52832 support: https://github.com/jpconstantineau/BlueMicro_BLE

Maybe is only a matter of configuring the pinout in the firmware headers, compile and flash the kb?

nahuel avatar Mar 04 '23 18:03 nahuel

Aren't this firmwares compatible with only some kb controllers that well documented or even open source? Was it ever installed instead of a proprietary firmware? I bet it's not viable. Even if main controller is supported you should know what other hardware do. The only lucky exception I see is that it's already uses QMK, ZMK, BlueMicro or other, you could get firmware from wired version and ask at specific forum. Or google whether Lenovo contributed this modified software to open source. I found compatible FFC and connector so at some point I'll check how keys are polled. I hope before updated keyboard will be released :D

WNMW avatar Mar 04 '23 21:03 WNMW

Well, software/firmware solution would be the best one for Lenovo TTK II but I am loosing any hope that this will happen because this kbc is quite long on the market and still no solution (and taking into account ridiculous Lenovo approach when they said they will do nothing with this problem). I am using this kbc only on my nV Shield when I am sitting in front of TV on the couch. In this scenario lack of CTRL-FN swap in not such huge pain in the neck but this keyboard is a crap for everyday work in front of PC.

KlosiakMK avatar Mar 05 '23 14:03 KlosiakMK

@WNMW The BlueMicro_BLE supports the nRF52832, exactly the same chip the TTKII uses. That chip is a SoC (system-on-a-chip) who includes the bluetooth hardware, bluetooth is already supported in the firmware without any effort. I don't know what the other chips are in the PCB (the photo is blurry), but probably they are shift registers used to multiplex GPIO's or chips used for some sort of battery control.

Usually the only effort needed to port an open source firmware to a proprietary keyboard with a supported chip is to discover which keyboard matrix lines map to which keyboard pins and what's the matrix layout (a work partially done by @juggernautjulian), by modifing a couple of .h files and recompiling. Check this (the BlueMicro_BLE docs are very detailed):

http://bluemicro.jpconstantineau.com/docs/configure_keyboard http://bluemicro.jpconstantineau.com/docs/configure_hardware

Currently I don't have a TTK II keyboard to try this, but I think it can be a good shot.

nahuel avatar Mar 05 '23 14:03 nahuel

Please check better photo of the top side. In Dekra's certification pdf you could check bottom side of the PCB, Lenovo is even so kind that they even silcscreended the layout. TSOP on the right is a USB controller, Holtek HT66FB540, QFN on the left I can't google, but it looks like it's connected only to the trackpoint. I've googled whether BlueMicro was ever installed instead of OEM firmware but with no avail. Have you ever seen that? Matrix pinout is not completely clear at first glance, but aligning both layers should help, and I'll recheck it anyway. If needed, I could download the firmware, but I will not upload a third-party firmware to my keyboard. But still for me it looks easier to embed extra IC between keyboard and PCB P.S. github do not replace images with previews and a full-size images are loaded. I've tried to put photos inside collapsible section, but it preloaded anyway, so it make no sense. Please let me know whether there is a proper solution to this issue.


Top side

Bottom side from pdf, markings are mine: image

N52832_res

DSC10018_res

HT66FB540

WNMW avatar Mar 05 '23 23:03 WNMW