megi's PinePhone Development Log RSS

Surgenons in Gaza Surgeons in Gaza

2021–05–26: PinePhone keyboard

I did some analysis of Pinephone keyboard prototype's schematics, components and firmware. Here are some of my observations.

Parts

First let's look at major parts of the keyboard, and what features they have.

Charging controller – IP5209

The chip is designed for use in power banks with optional LED flashlight.

It takes input from a 5V power supply or the battery and provides 5V output using a boost step-up DC-DC converter.

It has some other minor features, like LED indication, and timed key input (long/short press of the key do different things).

It also has rather detailed control of its functionality over I2C bus:

Charger/output control:

GPIO:

ADC:

This is quite a lot of useful functionality for Pinephone keyboard's use case!

Resources:

USB microcontroller – EM85F684A

This is rather generic and simple microcontroller with USB bus support. There is nothing really remarkable about it.

It uses 8051 instruction set, and has 32768 bytes of flash memory for code with 10,000 write/erase cycles. 2048 bytes of XRAM and 256 bytes of RAM.

Pin change wakeup is available on ports 5, 6, 9. There's a I2C slave peripheral, that is connected via POGO pins to Pinephone.

It has low power mode, that allows disabling CPU clock. Remaining features are not useful for the keyboard use case.

Documentation for the basic features is available on the Elan microelectronics website.

Resources:

Pinephone keyboard schematic

Keyboard schematic is rather simple:

Resources:

Proprietary firmware written in C was sent to some developers, incl. me, and I was able to compile it using Keil C. Firmware is half C code, half „bootloader“ distributed in binary object form. So it's possible and rather easy to modify the firmware. The issue will be with flashing it.

At this time, only sure way to program this microcontroller is to have a HW programmer from Elan microelectronics, install a windows driver and software, and use some windows GUI tool to flash the firmware over pads exposed on the PCB inside the keyboard.

There's also a possibility of flashing the firmware over USB, but the protocol is not documented, and there's no non-proprietary program available to do it.

This flashing method currently depends on proprietary bootloader, and cooperation of the existing keyboard firmware with entering the flashing mode. So if a broken application code is flashed, it will not be possible to re-flash it again using this method.

At my request, TL Lim sent me a Windows flashing tool for the keyboard's firmware. I've started reverse engineering it, and at this time I have the basic protocol reverse engineered, and I should be able to communicate with the keyboard using /dev/hidraw# device. I don't have the keyboard prototype HW, so I can't do much more at this time.

Next step is to get a capture of USB communication of the original flashing tool for Windows using usbpcap and cross-check the reverse engineering data with the actual communication and then write a Linux port of the flashing tool. This will allow me to create a better firmware updating mechanism for the keyboard controller, and experiment with key scanning routines. Looks like there should be no limit to how many keys can be pressed at the same time. :)

It would be nice if people with the keyboard prototype did the capture, otherwise the development will stall until I receive the prototype, too.

Pinephone charging/battery circuit schematic

Charging circuit can not be controled over I2C bus, because I2C bus from Pinephone is not connected to it. This is rather limiting.

Resources:

Suggested modifications

  1. Connect IP5209 to the i2c bus, instead of using 4 LEDs for charge indication.
  2. Revise the charger schematic according to the suggested reference circuit from the manufacturer of the chip. Add the current sensing resistor.
  3. (keyboard v2?) Add support for a lid switch.
  4. (myabe with optional mod/soldering bridge) Allow to share interrupt lines with keyboard controller and charge controller (not share by default)

Open questions