Browse Source

Update TODO and I2C interface description

Ondrej Jirman 1 year ago
  1. 32
  2. 43
  3. 33
  4. 6


@ -35,6 +35,7 @@ General ranges: @@ -35,6 +35,7 @@ General ranges:
bit 1: Flashing mode
bit 2: Self-test features
bit 3: Stock firmware flag (only stock firmware should have this set)
bit 4: Charger register read/writes are supported
0x06: bits 3-0: number of rows, bits 7-4 number of cols
0x07: CRC8 of keyboard data from 0x08-0x13
@ -44,29 +45,28 @@ General ranges: @@ -44,29 +45,28 @@ General ranges:
0x20: System configuration
bit 0: disable KB scanning (1: scanning disabled, 0: scanning enabled)
bit 1: poll mode
1: don't rely on row change detection, poll the matrix periodically
(prevents MCU power down)
0: power down the MCU when no key is pressed, and rely on change
detection on row inupts to wake the MCU up
bit 2: enable USB debug interface
bit 1: enable USB debug interface
1: enabled
0: disabled
0x21: System command
0x21: Charger register address
0x22: Charger register value
0x23: System command
Writing values into this register causes the firmware to perform
certain one-shot actions:
0x52 ('R') - reset the MCU
0x63 ('c') - run a column self-test
0x72 ('r') - run a row self-test
(results for both tests will be stored in test-result
0x72 ('r') - reset the MCU
0x69 ('i') - jump to USB bootloader
0x74 ('t') - run a self-test
(results are as a text in debug log)
0x91 - read charger register
0xA1 - write charger register
The register is set to 0x00 or 0xff after the operation completes.
0xff means error.
0x22: Writing value 0x53 ('S') to this register stops the main app from
0x24: Writing value 0x53 ('S') to this register stops the main app from
jumping to the user app.
@ -147,7 +147,7 @@ is flashed. @@ -147,7 +147,7 @@ is flashed.
After MCU powerup or reset, stock firmware will listen for 1s on I2C interface,
before passing control to the user firmware. If 0x53 is not written to register
0x22 during that time, this will prevent execution of the user's firmware.
0x24 during that time, this will prevent execution of the user's firmware.
If the user firmware execution is not prevented in this way, stock firmware
will redirect interrupt vectors from 0x0000+offset to 0x4000+offset and jump
@ -172,12 +172,12 @@ Flashing steps: @@ -172,12 +172,12 @@ Flashing steps:
... repeat 1-5 for all memory locations to be flashed
6) Write command 0x43 to reg 0xf4
7) Poll 0xf4 for result (either 0x00 or 0xff)
8) Reset the MCU by writing command 0x52 to reg 0x21
8) Reset the MCU by writing command 0x72 to reg 0x23
1) Write command 'r' or 'c' to reg 0x21
1) Write command 't' to reg 0x23
2) Read repeatedly from register 0xff to get the self-test results
in human readable text form


@ -0,0 +1,43 @@ @@ -0,0 +1,43 @@
Firmware testing
Situations/features to test:
- factory firmware
- USB debugging
- is disabled by default after start
- can be enabled/disabled at runtime
- via I2C
- if Pine + F + U is pressed (status is reflected over I2C
in a control register)
- scanning block works
- switching it on/off works at runtime
- no interrupts are fired when blocked
- no keys appear pressed during a block
- USB bootloader jump works
- if Pine + F + B is pressed
- via USB debugger mode
- via I2C command
- reset over I2C works
- I2C debug log readout works
- selftest works
- shows result via I2C debug log
- exposed GPIOs are accessible over I2C
- direction configuration works
- readout/setting works
- interrupt
- 10us pulse visible on logical probe capture
- POGO interrupt is received on the SoC
- charger
- I2C A communication works
- I2C A timeout mechanism works when the bus is blocked
- user firmware
- flashing works
- reading works
- deletion works
- is not jumped to unless it's commited after flashing
- can be executed
- starts automatically unless Pine+F+H is held on powerup


@ -1,37 +1,22 @@ @@ -1,37 +1,22 @@
- allow to stay in factory FW by holding a key combo on powerup
- choose combo
- document
- check that the charger's INT pin is high prior to I2C A communication
and return error if it is not (P87 must have pull-up enabled, and
it is low if charger is free to communicate)
- test I2C interface using FX2
- trigger POGO interrupt on P84 (open drain mode)
- implement special key combos:
- Pine + F + H (stay in main FW if pressed during powerup)
- Pine + F + U (enable USB debugger)
- Pine + F + B (jump to USB bootloader)
- first I2C TX after switch to USER firmware after flashing over I2C fails,
subsequent ones work
- also power consumption indicates power consumption of the sotck firmware
so maybe we just sleep in stock instead of switching after flashing?
- implement I2C configuration options
- disable keyboard matrix scanning
- only enable USB in stock FW upon request over I2C (idling USB stack takes
about 0.6mA on top of 1.8mA baseline)
Charger behavior
- does the charger turn off VOUT after some period of low load?
- does it enable it again to see if there's a need for it?
- this auto-off behavior will kill the power to the keyboard
controller, so we need a way to detect it and power the controller
from the pinephone side by enabling VBUS.
- tricky!
- or make the user keep pressing the kb power button to use the
keyboard for a while, like in a train conductor has to in a train :)
- not good!
Userspace input device daemon


@ -48,10 +48,10 @@ @@ -48,10 +48,10 @@
#define REG_SYS_COMMAND 0x23