Pixayl/ta-typewriter-ifd1-replacement
GitHub: Pixayl/ta-typewriter-ifd1-replacement
基于 Raspberry Pi Pico 的开源固件项目,通过完整逆向 8-pin DIN 串行协议,将 80 年代的 Triumph-Adler / Xerox 菊花轮打字机改造为由电脑控制的打印机。
Stars: 0 | Forks: 0
# IFD-2 — Triumph-Adler / Royal **IF 600 / IFD 1** 接口盒的现代替代方案
将一台 20 世纪 80 年代的 **Triumph-Adler** 菊花轮打字机(及其换牌产品:**Xerox**、Royal、Adler)
变成一台电脑打印机,使用 **Raspberry Pi Pico** 代替早已遗失的原始
接口盒。
本仓库记录了对 **Xerox 575 (Type Y92)** 的 **8-pin DIN 接口**的完整逆向工程 —— 包括引脚定义、握手、命令集和流控 —— 以及可用的 MicroPython 固件。
## 状态
| 功能 | 状态 |
|---|---|
| 握手 / 联机 | ✅ 工作正常(偶尔仍需重试 —— 见 *已知问题*) |
| 打印任意文本 | ✅ 可靠,达到机器的全机械速度(约 14 字符/秒) |
| 硬件流控 | ✅ 通过机器逐字节的 DTR 响应实现 |
| 自动换行、换行符、回车符 | ✅ |
| 字符间距(压缩 / 标准) | ✅ |
| 法语重音字符 | ✅ (`é è à ç ù`) |
| 读取打字机键盘 | ❌ **无法实现** —— 该端口上的机器仅支持接收 |
## 硬件
### 8-pin DIN 插座 (Xerox 575 / Type Y92)
在本台机器上测量。**不同型号的引脚编号可能有所不同 —— 接线前请务必核实您的设备。**
| 信号 | 方向 | 备注 |
|---|---|---|
| **GND** | — | 参考电平 |
| **TX** | 机器 → 主机 | 机器的发送线(状态字节、回显) |
| **RX** | 主机 → 机器 | 打印数据和命令 |
| **DSR** | 主机 → 机器 | 主机存在 / 复位线 |
| **DTR** | 机器 → 主机 | 逐字节响应(约 1 ms 脉冲) |
| +5 V | — | 为原始接口盒供电 |
| +12 V, +42 V | — | ⚠️ **电源轨道 —— 切勿连接至逻辑电路** |
*(在本台设备上,两路电源轨道空载时测得分别为 12 V 和 42 V;SE325 文档中标注为 10 V 和 35 V,即带载测量的相同轨道。)*
### ⚠️ 关键的电气细节
机器的输入端是 **CMOS 电平,阈值约为 3.5 V**(接口正后方有一片 CD4538)。Pico 的 3.3 V 推挽输出**是不够的**,而且串联电阻会以不直观的方式改变高电平,因为机器内部的上拉电阻会通过它将电平拉向 5 V。
**解决方案:以开漏模式驱动机器的输入端。** Pico 只负责拉低电平;机器自身的上拉电阻会提供纯净的 5 V 高电平。
| 配置 | 低电平 | 高电平 | 结果 |
|---|---|---|---|
| 1 kΩ 串联,推挽 | 1.00 V | 3.64 V | 可用,但会出现随机位错误 |
| 100 Ω 串联,推挽 | 0.12 V | 3.34 V | 失败(低于 CMOS 阈值) |
| **开漏** | **0.3 V** | **5.0 V** | ✅ 正确 |
由于 RP2040 的硬件 UART 是推挽式的,**TX 由软件在开漏引脚上进行 Bit-bang**(见固件中的 `_tx()`);硬件 UART 仅用于 RX。
### 接线 (Raspberry Pi Pico)
| Pico | 模式 | → 机器 |
|---|---|---|
| GND | — | GND |
| **GP0** | 开漏,软件 UART TX | **RX**(经由 BAT85 肖特基二极管,可选) |
| **GP1** | 硬件 UART0 RX | **TX**(1 kΩ 串联) |
| **GP2** | 开漏 | **DSR** |
| **GP3** | 输入 | **DTR**(1 kΩ 串联) |
Pico 由 USB 供电。与机器仅共享 **GND** —— 切勿借用其电源轨道。
## 协议
**4800 波特率,8N1,非反相。** 所有命令均为 **两字节**。
### 会话
1. 向 **DSR** 发送脉冲(短暂高电平,空闲低电平) → 机器回复 **`0x01`**。
2. **等待约 1 秒。** 在此之前机器不接受命令。
(空闲时它也会自发发出 `0x01`,因此接收到的 `0x01` 不一定是对您脉冲的回复。)
3. 按顺序发送:`A0 00` (CLEAR清除), `A1 00` (START启动), `A4 00` (ENQ查询), `A2 00` (STX文本开始)。
4. 机器**回显命令字节**,并用一个状态块回复 ENQ ——
利用 `A2` 的回显来确认会话已开启。
会话**在一段时间不活动后失效**;`ENQ` 充当心跳。
### 打印
| 命令 | 含义 |
|---|---|
| `<字轮索引> <0x80 \| 力度>` | 击打字符(`力度` 0–63;位 7 = 前进;位 6 = 左移) |
| `0x01 0x80` | 空格(带前进的空白击打) |
| `0x82 0x03` | 回车 |
| `0x82 0x0F` | 完全位置重置(字车 + 字轮 + 色带) |
| `0xD0 ` | 换行 |
| `0x84 ` | 退格 |
| `0x80 ` | 字符间距 —— 以单位表示的宽度(`0x0F` 标准,`0x0A` 压缩) |
| `0xA3 00` + `0xA0 00` | 脱机 |
⚠️ 这些是**状态转换,不是幂等命令** —— 重新发送它们以“重试”会导致机器死锁。
### 流控
在**每接收到一个字节后**,机器会将 **DTR 拉高约 1 ms**,意思是
*“字节已接收,请发送下一个”*。当其缓冲区满时,该确认信号会被
**延迟**,直到实际击打了一个字符 —— 因此机器会自行控制主机的节奏。
这 1 ms 的脉冲正是 PC 或 Linux SBC 在此面临困难的原因:通过 USB 从用户空间可靠地捕获它实在太难了。而微控制器则能轻松捕获。**这就是使用 Pico 的根本原因。**
移动命令(回车、换行)**没有**确认 —— 发送这些命令时无需流控,并等待机械动作完成即可。
### 字轮
字轮位置是 **从 1 开始的索引**,而不是 ASCII。固件中的表适用于
**Prestige Cubic 10/12(法语,Xerox 零件号 3R96686)**。它与 SE325 字轮匹配,除了十个位置:`12:^ 13:è 14:é 72:ì 74:¨ 75:◊ 80:ç 81:ù 82:ò 83:à`。
**其他字轮会有所不同** —— 使用固件中的 `cal()` 打印 1–100 的索引,并读取您自己的字轮数据。
## 仓库布局
```
pico/main.py MicroPython firmware (the IFD-2 itself)
pico/send_from_pi.py host-side helper: send text to the Pico over USB
tools/ reverse-engineering scripts used along the way
docs/journal.md full lab notebook: every measurement, dead end and fix
```
## 快速开始
```
# 在 Pico 上烧录 MicroPython,然后:
mpremote fs cp pico/main.py :main.py
mpremote repl
```
```
import main
main.start()
main.print_text("Hello from 1985")
```
## 已知问题
- 在某些通电状态下,`start()` 仍然需要尝试几次。机器会自发发出
`0x01` 字节,因此主机可能会将其误认为回复,并在错误的时间点启动初始化。
- 行间距和行长是针对 A4 纸张和压缩间距调整的;请调整
`LF_CMD`、`LINE_UNITS` 和 `PITCH`。
## 致谢
- [`binraker/tweetwronger`](https://github.com/binraker/tweetwronger) — 关于
TA SE325 的先例,以及促成本项目启动的逆向工程笔记。
- *ST Computer* 杂志(1988 年),Gabriele 9009 文章,经
[stcarchiv.de](https://www.stcarchiv.de/) 获取。
## 许可证
MIT — 见 [LICENSE](LICENSE)。
标签:MicroPython, 云资产清单, 协议分析, 嵌入式开发, 打印机驱动, 权限提升, 树莓派Pico, 硬件接口, 逆向工程