Hacking Keyboard Touchpad with Zephyr RTOS 🪁 — Part 1: I2C Shell
In this blog, we will discover how to verify I2C Interface of Keyboard Touchpad using Zephyr I2C Shell.

Introduction:
I am one of those people who love to take things apart out of curiosity. So, I had a wireless Bluetooth keyboard lying around collecting dust, which had not been working for a while. I decided to tear it down to see if I could fix the problem, and in the process, I discovered a touchpad integrated into the keyboard. This article is written in a way that if you keep scrolling, the images will guide you through everything.

The keyboard is made up of three main components.
- QWERTY Mechanical Keypad
- Touchpad
- Bluetooth Controller with Battery
Later, we will focus more on the touchpad and dive deeper into its technical aspects.

After taking a closer look at touchpad, I discovered that it had a capacitive touch sensor controller, the ekt2101. This low-cost 8-bit RISC architecture MCU supports both SPI and I2C interfaces. At this point, I wasn’t sure whether the OEM used it in SPI or I2C mode, so I decided to test it with the I2C interface first. If that didn’t work, I planned to switch to SPI. Reference ekt2101 datasheet.

With a bit of reverse engineering, I traced the Vcc and GND pins on the test pad exposed on the PCB. Using my soldering skills, I successfully soldered wires onto the test pad. Now that the hardware is set up, it’s time to move on to testing, and this is where Zephyr RTOS comes into play.

Zephyr I2C Shell
The Zephyr RTOS provides shell module which is a lightweight, Unix-like command-line interface designed for embedded systems. It offers a range of features that make it highly functional and efficient for embedded device interaction, debugging, and system control.


For this demo I’ll be using an STM32f3 discovery board and the Zephyr basic/minimal sample. We need to add a Kconfig that enables GPIO, I2C, and the related Zephyr shell.
prj.conf
CONFIG_GPIO=y
CONFIG_I2C=y
CONFIG_SHELL=y
CONFIG_I2C_SHELL=y
I’m using an STM32f3 discovery board with the i2c1
pin PB6(SCL) and PB7(SDA).
Build:
$ west build -b stm32f3_disco samples/basic/minimal
$ west flash
The I2C shell supports scanning, bus recovery, I2C read and write operations.
uart:~$ i2c -h
i2c - I2C commands
Subcommands:
scan :Scan I2C devices
recover :Recover I2C bus
read :Read bytes from an I2C device
read_byte :Read a byte from an I2C device
write :Write bytes to an I2C device
write_byte :Write a byte to an I2C device
uart:~$ device list
devices:
- rcc@40021000 (READY)
- reset-controller (READY)
- interrupt-controller@40010400 (READY)
- gpio@48001400 (READY)
- gpio@48001000 (READY)
- gpio@48000c00 (READY)
- gpio@48000800 (READY)
- gpio@48000400 (READY)
- gpio@48000000 (READY)
- serial@40004c00 (READY)
- serial@40004400 (READY)
- serial@40013800 (READY)
- i2c@40005800 (READY)
- i2c@40005400 (READY)
uart:~$
uart:~$ i2c scan i2c@40005400
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- --
10: 10 -- -- -- -- -- -- -- -- 19 -- -- -- -- 1e --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
3 devices found on i2c@40005400
uart:~$
The default I2C address of the touchpad controller is 0x10. From the output of our I2C scan, we have successfully verified the connection to the device.

In the next blog, I will proceed with implementing a Zephyr driver for the touchpad controller to enable full interaction and control. Until next time, go out and explore Zephyr shells.