re-posting from the other thread, I wrote some simple C routines to adjust the actuation height via the on-board digipot;
Just to confirm, does either controller (USB / BT) have 3 available GPIO ports? It appears that they do, looking at the images in the OP post, but I'd just like to confirm first.
It turned out to be a lot simpler than I had originally thought (my naive approach before looking at the datasheet was that it would require using the I2C driver, but it's just simple serial), and I can share the code (or potentially fork the tmk/qmk repo if I can successfully get it working), but I'd have to purchase a controller first. 3 wires would be required between the controller and main-board, either via solder or perhaps some clever approach that involves pressure-connecting to 3 of the 4 "calibration point" pads using spring-type connections, fastened to the case. Right now it uses a simple atmel development board (328 xmini) external to the keyboard that I just have wires connecting through.
To summarize how each of the features work:
R/W mode must be enabled with two different "commands" - the digipot is by default in read mode, but must be changed to write mode to write memory or wiper, and changed back to read.
Commands are sent via 16-bit words, started with the chip select signal low, as well as a low-starting high-ending rising-edge clock which data is synced to via the DIO pin.
To put the controller in write-mode, I send 0xA300 (MSB-first) to the controller, and I've confirmed it working with a clock period of 4us. For read mode, I use 0xA000. The rightmost byte in this scenario really doesn't matter, as I believe the controller would normally check it for an address.
To read the wiper, the digipot must be in read-mode, meaning either it's been sent read-mode as a command or it has been just powered (defaults to read mode). Afterward, the command 0xAB00 is used. The DIO line is then changed to a read-input, then the next 8 bits are read. These 8 bits are sent in order of D0-D7, with the final bit D7 being irrelevant. This value is the current step value. This gives a total of 128 different steps, of which a sub-section can be used for adjusting the height, as some resistance values are too low and some are too high. In my case, the default value is 0x27, which is stored in memory and recalled whenever the board turns on.
If this is added as a feature, I would suggest writing to the wiper with the controller on-boot and storing this in the controller's EEPROM, rather than overwriting the digipot's EEPROM, to reduce risk. I'm curious if the default value is different for some users, and that 0x27 (measured ~29.97k ohms on board) is calibrated just for my board. I would need someone to check resistance between the two small test points to the side of the digipot chip to confirm, after the board is powered.
To write to the wiper, two 16-bit words are required. I first send the command 0xA600 (sent via MSB first order) which constitutes the command (0xA6) and an irrelevant memory address (so I use 0x00, could be anything). To save on complexity, I reverse the "step" number binary that I want to send, so that its LSB is now MSB (in other words, D0 is required before D1..D7), as the serial write sends MSB first. I then shift 8 bits left as an empty byte is required after. For example, if I wanted to write step 1/127 to the board, I would send 0xA600 to indicate wiper write, then 0x8000 (I think). Step 2/127 would be 0xA600 then 0x4000 if I'm doing the math right. This should immediately write the wiper position to step*100k/127 ohms, I think. For posterity I do two more clock cycles (the chip ignores these, I believe). Then pull ~CS high, and disable writing to the chip, same as with the other commands.
I haven't tried writing to the EEPROM yet, just in case. I don't think there's much danger in doing so, as I can just re-write the original calibrated value, but I'd much prefer leaving the default value there just in case anything goes wrong. As mentioned previously, I don't think there would be much danger in simply writing the wiper position every time the board turns on using the controller, since there's a default value in the chip. I haven't checked to see if the chip recommends a low number of writes, but I doubt it.
Ideally adjusting the distance dynamically would have to be done in a way that doesn't lock the user out (after setting it one step too low), so that the user has the ability to fix it. Perhaps there would need to be a way to confirm that the current setting is possible to type on.
If anyone has questions, please let me know!