4、链路初始化与握手:上电顺序与复位、链路状态机、握手协议与能力交换

各位同学,咱们今天聊一个非常关键的话题——链路初始化与握手。说白了,就是两块芯片之间怎么“打招呼”,怎么确认对方准备好了,然后怎么开始干活。

我记得刚入行那会儿,总觉得这步很简单,不就是上电、复位、然后开始传数据吗?结果第一次调MIPI接口的时候,折腾了整整三天,最后发现是上电顺序搞反了。嗯,从那以后,我再也不敢小看这个环节了。

4.1 上电顺序与复位

先说说上电顺序。这玩意儿看着不起眼,但坑特别多。

为什么要有上电顺序?因为芯片内部有不同电压域。比如核心电压1.2V,IO电压1.8V,PLL电压2.5V。如果先给IO上电,核心还没起来,IO引脚可能会处于不确定状态,导致漏电甚至闩锁。

我个人习惯的做法是:

  • 先上核心电压,让内部逻辑先稳定
  • 再上IO电压,让接口电路准备好
  • 最后上PLL电压,时钟生成模块最后启动

每个电压之间,我建议至少留100微秒的延迟。别问我为什么,这是血的教训换来的。

⚠️ 注意: 上电顺序搞反了,轻则芯片不工作,重则直接烧毁。我曾经见过一个项目,因为上电顺序没处理好,流片回来的芯片有一半都挂了。

复位呢?复位信号一般有两种:

  • 硬复位:直接拉低复位引脚,强制所有寄存器回到默认值
  • 软复位:通过写寄存器触发复位,只复位部分逻辑

我建议在链路初始化之前,先做一次硬复位,确保所有状态机都回到初始态。然后再用软复位去控制具体的模块。

4.2 链路状态机

链路状态机,说白了就是一套“握手流程”。它定义了从“没电”到“正常传数据”之间要经过哪些状态。

常见的状态机包括:

状态 含义 说明
Reset 复位态 所有逻辑复位,等待上电完成
Detect 检测态 检测对方是否在线,有没有接上
Training 训练态 发送训练序列,调整参数
Lock 锁定态 时钟和数据对齐,锁定链路
Active 工作态 正常传输数据

你想想看,如果两个芯片直接跳到Active态,那肯定不行。得一步一步来,就像两个人握手,得先伸手、再握住、再晃两下,对吧?

💡 关键点: 每个状态之间都有超时机制。比如在Detect态等了1毫秒还没检测到对方,那就得报错或者重试。我一般把超时时间设成硬件能容忍的最大值,再留20%的余量。

我在项目中遇到过一个问题:链路状态机在Training态反复跳转,就是进不了Lock态。查了半天,发现是训练序列的长度不够,导致对方收不到完整的同步头。后来把训练序列从16个符号改成32个,问题就解决了。

4.3 握手协议与能力交换

握手协议,说白了就是“你支持什么?我支持什么?咱们取个交集”。

能力交换一般包括:

  • 速率能力:你最高能跑多少?我最高能跑多少?
  • 通道数:你支持1通道还是4通道?
  • 数据格式:RGB还是YUV?8位还是10位?
  • 特殊功能:支不支持CRC?支不支持ECC?

握手的过程通常是这样的:

  1. 发送端先发一个“能力请求”包
  2. 接收端收到后,回复一个“能力响应”包
  3. 发送端根据响应,调整自己的配置
  4. 双方确认后,进入Active态
🔧 小技巧: 我建议在能力交换阶段,把双方的能力都打印出来。这样调试的时候一眼就能看出哪里不匹配。有一次我发现接收端回复的速率是2.5Gbps,但发送端只能跑1.5Gbps,结果链路一直训练失败。嗯,这种低级错误其实挺常见的。

握手协议里还有一个容易忽略的点——ACK/NACK机制。发送端发了能力请求,如果接收端没回复,或者回复了NACK,那发送端就得重发。重发次数一般设3次,超过3次就报错。

我曾经遇到过一个案例:接收端的缓存满了,导致NACK一直回复。发送端傻乎乎地一直重发,结果链路初始化花了整整10秒。后来加了一个“忙等待”机制,接收端忙的时候就回复一个“Busy”状态码,发送端等一会儿再试,效率就高多了。

4.4 实际调试中的坑

最后,我给大家总结几个实际调试中容易踩的坑:

  • 上电顺序搞反:这个前面说过了,一定要按datasheet来
  • 复位时间不够:有些芯片需要至少10毫秒的复位时间,别偷懒
  • 训练序列不匹配:发送端和接收端的训练序列长度、格式要一致
  • 超时时间太短:尤其是在低速模式下,超时时间要适当放宽
  • 能力交换没做容错:万一对方回复了一个非法值,你得能处理

嗯,今天就先聊到这儿。链路初始化这部分,说白了就是“慢工出细活”。你前期把上电顺序、状态机、握手协议都搞清楚了,后面调数据通道就顺风顺水。否则,你可能会像我当年一样,在实验室里对着示波器发呆三天。

下一节咱们聊聊数据通道的同步与对齐,到时候会讲一些更具体的波形分析技巧。