1433 字
7 分钟
自制妙控板(思路)
WARNING

这篇文章没有任何实操教程,纯粹是我的个人研究记录

CAUTION

实用派用户请关闭本文,在我看来研究和折腾的乐趣比做出这个产品更重要

前言#

首先我是一个很多年的 Hackintosh 用户 (马上就不是了)
众所周知,macOS 对触控板的优化非常好,甚至好过鼠标 @Apple 什么时候改一下你那个反人类的鼠标滚轮方向
而且鼠标还有一个问题:它必须工作在一个平整的平面上,还要给鼠标移动和手腕留出空间,非常的不适合冬天在被窝里玩电脑

我想到了苹果的 Magic TrackPad,然后一看价格,告辞
不过呢也不是完全没有希望,因为我发现 Macbook 的拆机触控板模块极其便宜,大概十几块钱一个,用的是 USB 和 SPI 协议。于是我想到一个思路是:通过一个单片机,将触控板的 SPI 报文实时翻译为 HID 报文传递给 Host。

在此不得不感谢 Apple 的设计理念,给一块触控板加入了极其逆天的硬件配置,但是又在系统里处处限制
(这就不得不提新款 Macbook 拿角度传感器检测屏幕开合的设计了)

选型#

我准备用 Macbook 2017 15寸的原装拆机触控板为基础进行改造,原因如下:

  1. 这块触控板的面积是真的大,差不多150cm2150 cm^2
  2. Macbook 2017 是最后一代没有 T2 芯片的 Macbook Pro,系统是直接和触控板交互的,而不需要去跟 T2 芯片掰扯一堆加密协议
  3. 它的硬件配置极其逆天:四个高精度压力传感器,一组 Tapic Engine,大面积玻璃触控面
  4. 它只要 15 块钱还包邮
CAUTION

不要试图研究 2018 年后的触控板,T2 芯片的水很深的。Apple Silicon 系列的 MacBook 更是想都别想,苹果真的往死里加密的。

研究方向#

基于其硬件功能,我提出三个研究方向

  1. 将触控板模拟为 Magic TrackPad,并在 macOS(原生驱动)和 Windows(使用PTP驱动)中完美工作
  2. 将触控板模拟为标准 HID 协议的数位板,低成本实现压感和倾斜感应,甚至还能做出绘画时的力度反馈
  3. 什么?你说一块触控板面积太小不适合画画,那我们就多来几块组阵列(这点是我在做白日梦,忽略就好)

目前难点#

总体#

  1. Apple 是不会告诉我任何协议内容的
  2. 触控板模块用的是不常见的 1.8V1.8V 电平,需要加转换芯片
  3. Tapic Engine 瞬时启动电流较大,可能干扰 MCU 运行
  4. 我真的很菜

数位板模式#

  1. 不会有人拿手指画画的,所以需要配无源电容笔
  2. 手指和电容笔是完全不同的力学模型,触控板自己算出来的压力和倾极大概率是不准的
  3. 面积太小
  4. 误触

优势#

  1. 15 块钱的东西你要什么自行车,觉得不准右转 Apple Pencil
  2. 数位板只认专用的数位笔,这玩意可是能认手指的
  3. 原生压力感应+倾斜感应
  4. 能做出绘画时的力反馈

协议研究#

得益于 Linux 内核已经完整支持了 Macbook 系列的内建触控板,我们很容易从 Linux 源码树中得到其 SPI 报文格式
drivers/input/keyboard/applespi.c:

/**
* struct tp_finger - single trackpad finger structure, le16-aligned
*
* @origin: zero when switching track finger
* @abs_x: absolute x coordinate
* @abs_y: absolute y coordinate
* @rel_x: relative x coordinate
* @rel_y: relative y coordinate
* @tool_major: tool area, major axis
* @tool_minor: tool area, minor axis
* @orientation: 16384 when point, else 15 bit angle
* @touch_major: touch area, major axis
* @touch_minor: touch area, minor axis
* @unused: zeros
* @pressure: pressure on forcetouch touchpad
* @multi: one finger: varies, more fingers: constant
* @crc16: on last finger: crc over the whole message struct
* (i.e. message header + this struct) minus the last
* @crc16 field; unknown on all other fingers.
*/
struct tp_finger {
__le16 origin;
__le16 abs_x;
__le16 abs_y;
__le16 rel_x;
__le16 rel_y;
__le16 tool_major;
__le16 tool_minor;
__le16 orientation;
__le16 touch_major;
__le16 touch_minor;
__le16 unused[2];
__le16 pressure;
__le16 multi;
__le16 crc16;
};
/**
* struct touchpad_protocol - touchpad message.
* message.type = 0x0210
*
* @unknown1: unknown
* @clicked: 1 if a button-click was detected, 0 otherwise
* @unknown2: unknown
* @number_of_fingers: the number of fingers being reported in @fingers
* @clicked2: same as @clicked
* @unknown3: unknown
* @fingers: the data for each finger
*/
struct touchpad_protocol {
u8 unknown1[1];
u8 clicked;
u8 unknown2[28];
u8 number_of_fingers;
u8 clicked2;
u8 unknown3[16];
struct tp_finger fingers[];
};

代码告诉我们,触控板会直接返回按压力度,手指倾斜角度等信息
注意到了吗,struct tp_fingerpressure的数据类型是__le16
也就是手指的压力等级是 16 位无符号整数,意味着压力的取值范围是[0,65535][0,65535]
而主流的 Wacom 数位板也才 8192 级压感!(当然,这只是理论精度,实际上一定是有不可忽略的误差,但只要做好滤波,精度不会比 Wacom 差多少)
更重要的是,触控板内部为我们解决了手指角度问题@orientation: 16384 when point, else 15 bit angle,我们甚至不需要自己实现算法

硬件设计#

略微分析了一下 A1707 的原理图,画了一张驱动板,用 ESP32-S3 做 MCU 来翻译数据包和包装 HID 报文
正在等年后嘉立创发货…
开什么玩笑,第一次正儿八经画板子就要我画这么难吗

To be continued#

这其实是我一个不成熟的前期想法,这个项目可能会在我大学四年中慢慢研究,也可能成为一个废案,不要抱太大希望,万一是 ADHD 的三分钟热度呢。
但研究的过程总是很有趣的,于是我选择记录下来。

自制妙控板(思路)
https://fuwari.vercel.app/posts/diy-magic-trackpad/
作者
秋奈Akina
发布于
2026-02-10
许可协议
CC BY-NC-SA 4.0