第一次把MAX9295和MAX9296焊上板子,上电后I2C扫描能读到解串器,但GMSL链路怎么都不LOCK。当时我以为是线缆问题,换了三根同轴线还是一样,最后才发现是初始化顺序里漏了远端串行器的PHY配置。做车载摄像头、ADAS域控、环视系统的人,几乎都会碰到GMSL SerDes这条链路,MAXIM(现在归到ADI)的MAX9295串行器和MAX9296解串器是这套方案里非常经典的一对。这篇文章就把GMSL2链路的硬件设计、寄存器配置、POC供电、联调排障完整过一遍,适合正在做MAX9296+MAX9295方案,或者准备在自研板卡上接入GMSL2摄像头的工程师参考。
1. GMSL2链路是怎么串起来的:MAX9295与MAX9296的分工
1.1 链路两端各干什么
GMSL2链路本质上是把MIPI CSI-2数据从摄像头传感器搬到SoC或ISP。MAX9295放在摄像头端,是串行器,负责把sensor输出的MIPI CSI-2信号打包成一路GMSL2高速串行信号,通过同轴电缆或者屏蔽双绞线送出去。MAX9296放在主机端,是解串器,负责接收这串信号,再还原成MIPI CSI-2给SoC。
这里有一个容易忽略的点:GMSL2不是裸的差分电平直传,它有自己的帧格式。MAX9295并不是简单地把MIPI信号幅度放大然后送出去,而是把MIPI packet重新封装成GMSL2帧,附加了同步头、错误校验、控制通道等信息。MAX9296要做的是从一串高速比特流里恢复时钟、对齐帧、做CRC校验、解包,再生成MIPI CSI-2时序。所以两个芯片不是“物理层转发”的关系,而是协议层加物理层的SerDes链路。
MAX9296是双通道解串器,一颗芯片能同时接两路摄像头,输出端可以配置成单路CSI-2口或双路CSI-2口。实际项目中常见做法是两路摄像头进同一颗MAX9296,MIPI输出到SoC时用虚拟通道号区分。这样做能省一颗解串器,但也带来一个问题:两路sensor必须共享同一组CSI-2 data lane,初始化时得把两路的Virtual Channel、Data Type、lane分配全部理顺,否则一路正常一路黑屏是家常便饭。
1.2 为什么车载摄像头几乎离不开SerDes
把sensor直接通过MIPI CSI-2接到SoC不是不行,但距离一长就完蛋。MIPI CSI-2是源同步高速并串接口,PCB走线超过十几厘米就要开始担心损耗、串扰、参考平面断裂。在一台车上,摄像头可能装在车头、后视镜、侧视镜,到域控的距离动辄1米到3米以上,直接拉MIPI线缆既不现实,EMC也过不了。
GMSL2的价值就是把高速并行数据变成单线传输的视频干线。一根同轴线同时搞定三件事:前向视频流、反向I2C/UART控制、远端供电。MAX9295和MAX9296之间天然支持远程I2C访问,也就是说SoC在主机端可以直接通过MAX9296去读远端MAX9295后面的sensor寄存器,不需要在摄像头上额外拉一条I2C线。这也是GMSL方案在车上长期存在的原因。
用一个不太恰当的类比:MIPI CSI-2像是市内多车道短途运输,车道多、距离短;GMSL2像跨城高速干线,把货物重新装进集装箱,一辆车拉过去,到了目的地再拆箱恢复原样。串行器就是装箱站,解串器就是拆箱站。
1.3 一帧数据从sensor到SoC的完整路径
从软件配置角度看,理解数据路径比记住寄存器更重要。一条完整链路分为四段:
- Sensor到MAX9295:MIPI CSI-2 TX,sensor侧要打开MIPI输出,配置lane数、时钟频率、Data Type。
- MAX9295内部:把MIPI packet转成GMSL2 frame,配置参考时钟、输出速率、PHY驱动强度。
- 线缆段:同轴或STP,信号在这里损耗、反射、受干扰。
- MAX9296到SoC:GMSL2 frame恢复成MIPI CSI-2,再进SoC的MIPI RX。
前两段在远端(摄像头端),后两段在主机端,中间通过GMSL2 link连接。排查问题时,我会习惯先把这条路径拆成四段,一段一段确认:sensor有没有MIPI波形、MAX9295有没有收到、link是否锁定、MAX9296有没有CSI-2输出。绝大多数难查问题,最后都能归到某一段上。
2. 硬件设计先别急着画板:这几处细节决定后面好不好调
2.1 电源域和上电时序
MAX9295和MAX9296都是混合信号芯片,数字核心、模拟PHY、MIPI IO、GMSL2 PHY通常对应不同的电源域。画原理图时一定要以具体选型手册为准,但有一个通行的经验:模拟电源和数字电源不要直接乱连,建议用磁珠或π型滤波隔开;去耦电容要靠近对应电源引脚。
上电顺序也很重要。很多工程师在软件里折腾半天LOCK不上,最后发现是某个电源域没按要求先上电,或者电压到了但时序不对导致芯片处于不确定状态。我调试时会先把复位引脚拉低,等所有电源稳定后再释放复位,让芯片以一个干净的状态完成内部上电初始化。
调试阶段建议在板子上留几个关键的测试点:每路电源电压测试点、GMSL2同轴信号测试点、MIPI差分测试点、LOCK状态GPIO测试点。不要嫌占位置。实际调试时,能直接拿示波器探头点上去看波形,比反复猜寄存器快得多。
2.2 MIPI差分对与GMSL2传输线的PCB布线
MAX9295和MAX9296都有两类高速接口:一类是MIPI CSI-2差分线,一类是GMSL2同轴/STP传输线。两类线在PCB上的处理方式不一样。
MIPI CSI-2走的是PCB上的差分对,要求100Ω差分阻抗,等长、等间距、连续参考地,尽量不打孔换层。如果连接到FPC连接器,要控制好连接器处的stub。MIPI信号速率通常做到几百Mbps到1.5Gbps per lane,布线如果太随意,信号完整性在源头就已经坏了,后面GMSL再厉害也救不回来。
GMSL2如果走同轴,是50Ω单端信号;如果走STP,是一对差分,100Ω阻抗。在板上从芯片引脚到连接器这段,要严格按照50Ω或100Ω阻抗来拉线。同轴连接器座子的选型也很关键,尽量选专门为高速信号设计的FAKRA或Mini-FAKRA连接器,接触可靠、阻抗连续性有保障。普通SMA座子在低频段可能看不出差异,上到3Gbps以后一个不连续点就可能让眼图变差。
2.3 POC偏置器:GMSL2功能实现里最容易踩坑的环节
POC全称Power over Coax,意思是用同轴电缆的中心导体同时传视频信号和直流供电。这个功能不是芯片单个引脚就能实现的,需要外部做Bias-T电路,也就是“高频信号通路+直流供电通路”的合成与分离。
从功能上理解,摄像头端和主机端各有一个Bias-T:
- 主机端:电源通过一个大电感加到同轴中心导体,视频信号通过一个隔直电容耦合到同轴线,两者在同一节点汇合后上电缆;接收时同样用电感和电容把直流和信号分开。
- 摄像头端:同轴线上来的直流通过电感提取出来给MAX9295和sensor供电,GMSL2信号则通过电容进入MAX9295的PHY。
POC电路里两个核心器件最容易选错:一个是串联在直流路径上的电感,一个是串联在信号路径上的电容。
电感的选型要看三点:DCR、额定电流、自谐振频率SRF。DCR决定了在远端摄像头电流下来之后的压降,DCR太大,摄像头端电压不够,链路就是不稳定。额定电流要覆盖“MAX9295功耗+sensor功耗”的总电流,最好留1.5到2倍裕量。SRF必须避开GMSL2信号频段,否则电感在信号频率上会呈现很高的阻抗或变成容性谐振,直接把信号带歪。很多LDO输出不稳、摄像头端电压跌落的故障,最后根因都是电感DCR太高。
电容要用高频特性好的陶瓷电容,容值不是越大越好。容值过大的MLCC自谐振频率很低,对GMSL2的高频分量来说可能已经不是通路而是阻塞;容值太小又会造成低频成分丢失、眼图畸变。我一般会在评估板参考电路的电容值基础上做小范围调整,改完一定看眼图和CRC,不能拍脑袋。
2.4 I2C地址、复位和中断引脚预留
MAX9295和MAX9296的I2C从机地址是由外部引脚电平决定的。画原理图时不要把这些引脚直接固定死,最好留0Ω跳线或上拉/下拉电阻位,可以在板子上灵活切换。多路摄像头同时挂在同一I2C bus上时,地址冲突是出现频率很高的问题。比如两颗MAX9296如果地址配置一样,I2C扫描会看到两个设备回同一个地址,读写行为完全错乱。
还有一个值得预留的是LOCK状态输出或中断脚。MAX9296能把GMSL2链路锁定、CRC错误、远端I2C请求等事件映射到GPIO或中断引脚。调试时把这些信号引到SoC的一个GPIO上,软件里可以实时判断链路状态,而不是每次靠读寄存器轮询。实际项目中这对稳定性问题定位帮助很大,因为CRC丢包往往是瞬间发生的,靠人工看屏抓不到。
3. 初始化顺序和寄存器配置:先把链路点亮再谈图像
3.1 一个经过验证的初始化顺序
GMSL2链路初始化最怕的是顺序混乱。我见过有人在还没有配置MAX9296的CSI-2输出时就去操作远端sensor,结果远端I2C一直不通,花了一下午排查,其实只是链路根本没建立起来。
推荐按这个顺序走:
- 给MAX9296和MAX9295上电,拉复位。
- 用I2C读MAX9296的DEV_ID/REV_ID寄存器,确认芯片在跑。
- 配置MAX9296本地寄存器:GMSL2速率、PHY均衡、CSI-2输出lane数、时钟极性。
- 使能GMSL2链路,等待LOCK状态位置位。
- 链路锁定后,使能远端I2C访问通道。
- 通过远端I2C配置MAX9295:输入MIPI lane数、参考时钟、输出驱动强度等。
- 通过远端I2C配置sensor:MIPI输出使能、分辨率、帧率、Data Type。
- 开启MAX9296的CSI-2输出,让SoC端开始收图。
这个顺序看起来平淡,但每一步都是后一步的前提。特别是第4步,很多人以为使能link后立刻就能访问远端,实际上要等LOCK位置位才行。在代码里要做一个带超时的循环等待,不要一下去读远端寄存器发现失败就放弃。
3.2 代码层面怎么组织初始化
下面这段是伪代码,体现的是操作思路,具体寄存器地址和位域请以你手里的datasheet为准:
static int gmsl_link_init(void) { u8 dev_id = 0; /* 1. 确认本端MAX9296存在 */ dev_id = i2c_read(des_addr, REG_DEV_ID); if (dev_id != DES_EXPECT_ID) return -ENODEV; /* 2. 配置解串器本地PHY和MIPI输出 */ i2c_write(des_addr, REG_CSI2_LANE, CSI2_4LANE); i2c_write(des_addr, REG_CSI2_VIRTUAL_CH, VC_ID); i2c_write(des_addr, REG_CSI2_CONTROL, MIPI_ENABLE); /* 3. 使能GMSL2链路并等待LOCK */ i2c_write(des_addr, REG_LINK_ENABLE, 1); for (i = 0; i < TIMEOUT; i++) { status = i2c_read(des_addr, REG_GMSL_STATUS); if (status & LOCK_MASK) break; usleep(1000); } if (!(status & LOCK_MASK)) return -ETIMEDOUT; /* 4. 使能远端访问,配置远端MAX9295 */ i2c_write(des_addr, REG_REMOTE_I2C_EN, 1); ser_reg_write(ser_addr, REG_MIPI_RX_LANE, MIPI_4LANE); ser_reg_write(ser_addr, REG_PHY_DRIVE, DRIVE_STRENGTH); return 0; }里面ser_reg_write是“通过MAX9296的远端寄存器访问窗口”实现的,本质上还是往MAX9296的某个寄存器里写入目标地址和值,再由它通过GMSL2反向通道转发给MAX9295。这也是为什么链路没LOCK时,远端访问一定失败的原因。
3.3 CSI-2配置比想象中麻烦
MAX9296的MIPI输出配置里,比较关键的有这么几项:
- Lane数:实际只用了2 lane就不能在软件里配成4 lane,否则SoC端收不到数据。
- Lane极性:PCB布线有没有把差分正负交叉,如果交叉了,可以通过寄存器翻转极性,不需要改板。
- 连续时钟/非连续时钟:sensor输出是非连续时钟的话,MAX9296和SoC都要做对应配置。
- Virtual Channel:两路摄像头共用同一MIPI口时,Virtua Channel必须错开,SoC端也是按VC区分数据流的。
- Data Type:RAW10、RAW12、YUV422这些格式要让MAX9296确认,某些模式下需要设置特定字节顺序。
实际调试中,链路LOCK正常但SoC端没有图像,大概率就是上面这几项里某一项没对齐。
4. 联调排障:现象、根因、验证链路
GMSL2调试有个特点:问题往往不是“完全不通”,而是“时好时坏”。下面我把最常见的几类故障整理成一张表,后面再逐个展开。
| 现象 | 可能原因 | 第一排查动作 |
|---|---|---|
| I2C扫描不到MAX9296 | 电源没上、复位拉死、I2C地址不对、上拉缺失 | 测电源和复位,核对地址引脚 |
| 链路一直不LOCK | 线缆损坏/过长、远端供电不足、EQ参数不对、速率不匹配 | 换短电缆,读链路状态,调整EQ |
| LOCK了但MIPI无输出 | CSI-2 lane数/极性/VC/DT配置不对 | 检查MAX9296 MIPI TX设置与SoC接收设置 |
| 画面花屏或偶发黑帧 | 信号裕量不足、线缆接头松动、POC电源纹波大 | 查CRC计数器,换线缆,看供电 |
| 单路正常,双路同时开就出问题 | 两路VC冲突、电源耦合、CSI-2带宽不足 | 单独关闭一路,再逐项打开 |
4.1 链路无法LOCK的完整排查链路
这是一个值得单独说的场景。链路不LOCK,90%不是芯片坏了,而是链路信号质量或远端供电出了问题。
我的排查顺序是固定的:
第一步,换一根短的同轴线。如果短电缆能LOCK,长电缆不LOCK,说明线缆损耗接近极限或连接器接触有问题;如果短电缆也不LOCK,问题在板子侧。
第二步,量远端电源。在摄像头端供电节点上用示波器看电压幅值和纹波。很多POC方案远端电压标称3.3V,但实际启动瞬间电流大,电感DCR压降加LDO压差,远端电压可能掉到2.8V以下。MAX9295和sensor在欠压状态下不会明确告诉你“我欠压”,表现就是链路时好时坏或不LOCK。
第三步,确认GMSL2速率设置是否匹配。MAX9296和MAX9295两端必须使用同一链路速率,一端是3Gbps、另一端是6Gbps,永远LOCK不上。这个配置在初始化时必须明确写出来,不能依赖默认值。
第四步,看锁定状态寄存器和中断寄存器。MAX9296会有锁定状态位,也会有CRC错误等状态。如果链路能LOCK但CRC错误持续增加,说明信号已经到临界状态了,这时候先调整接收端均衡器。
4.2 LOCK之后黑屏,优先查CSI-2配置
LOCK成功说明GMSL2物理链路已经通了,远端MAX9295应该也能访问。这时候如果SoC端仍然没有图像,不要再去折腾GMSL2链路,转向CSI-2配置检查。
先看MAX9296输出的MIPI差分对有没有波形。用示波器触发MIPI时钟脚,正常应该能看到持续时钟信号。如果完全没波形,说明MAX9296的MIPI TX没有真正使能,或配置后没有执行软件复位。如果波形有但SoC不认,大概率是lane数据和SoC的MIPI RX配置不匹配。
再查一遍Virtual Channel和Data Type。这里有个小技巧:先把SoC的MIPI RX配置成“lane数自适应、VC不校验”的宽松模式(有些SoC支持),等图像出来了再逐步收紧。如果SoC不支持这样做,就先从sensor端固定一种最简单的RAW8或YUV422格式,把链路跑通再换高带宽格式。
4.3 远端I2C不通的隐蔽原因
远端I2C访问是GMSL2最有用的功能,也是最容易出问题的功能。除了链路没LOCK这个基础原因,还有几个隐蔽因素:
一是远端I2C通道没有使能。MAX9296的远程I2C功能通常有自己的总开关,不打开的话,即使链路LOCK了,远端寄存器也读不到。
二是远端设备地址冲突。远端sensor的原始地址如果和本地某个设备地址相同,I2C路由会乱。解决方案是把远端设备映射成一个本地不冲突的别名地址,也就是在MAX9296的设备地址映射表里做“地址翻译”。
三是I2C速率过高。GMSL2反向控制通道的带宽不是无线的,通常比本地I2C慢。本地I2C跑400kHz没问题,但转发到远端后sensor可能响应不及时。如果发现远端I2C偶发超时,先把I2C时钟降到100kHz试试。
5. 信号质量和EMI调优:均衡器、驱动强度、POC器件选择
5.1 接收端均衡器EQ怎么调
GMSL2信号在线缆上走一段距离后,高频分量衰减比低频严重。接收端的均衡器就是用来补偿这个高频衰减的。MAX9296内部会有可调的均衡强度设置,有些设计还可以自适应。
调试时先把EQ设成一个中间档位,看LOCK和CRC;再往高和低各试几个档位。不要一开始就拉到最高,因为EQ在补偿高频损耗的同时也会放大高频噪声。线缆短时EQ过高,眼图反而会变差。长线缆时EQ不够则明显表现为无法LOCK或CRC递增。
理想情况下,调EQ要有示波器和眼图。没有眼图也没关系,以CRC错误计数和长期稳定性为准。我通常会让系统连续跑一个晚上,如果整晚CRC错误为0或极少,说明信号裕量够用。白天看起来正常但晚上开始偶发花屏的场景,往往就是裕量不足,不是软件问题。
5.2 MAX9295侧驱动强度:不是越大越好
MAX9295的输出摆幅、预加重或者压摆率,通常会提供一个或几个配置项。驱动力太弱,长线缆接收端余量不足;驱动力太强,会产生过冲和振铃,辐射也会变大。
在EMC预测试阶段,如果发现GMSL2相关频点辐射超标,第一步不是加屏蔽,而是试着降低驱动强度或压摆率。很多情况下信号实际不需要那么大的摆幅,调低之后辐射下降,接收端CRC并没有变差。注意每调一次必须重新验证接收端裕量,不能为了过EMC把信号调到临界值,否则产线上一定返工。
5.3 屏蔽和接地
GMSL2通常走屏蔽线缆,但屏蔽层怎么接地是有讲究的。同轴线的屏蔽层一般作为信号回流路径的一部分,同时也起到屏蔽电场的作用。如果屏蔽层悬空,链路很可能会出现“手摸一下线材图像变化”的诡异现象,因为人体改变了屏蔽层电位,干扰直接耦合进信号。
STP线缆的屏蔽层处理要看系统设计,常见做法是在两端或单端接连接器外壳,形成360度环接。不要用一根细细的飞线去“象征性接地”,高频下细飞线电感太大,等于没接。
调试中还有一个容易忽略的接地问题:连接器接触不良。FAKRA连接器扣合不到位,会直接导致屏蔽层断开,症状和线缆断裂很像。遇到时好时坏的GMSL2链路,先重新插拔连接器,听到“咔哒”声再继续。
5.4 POC器件选型的进一步细节
前面说了电感选型要看DCR、额定电流、SRF。实际在layout上,POC电感和电容的摆放也影响高频性能。电感到连接器之间的走线要短,电容的接地过孔要靠近焊盘。如果POC节点上的直流电源走线绕了很远,会在GMSL2频段形成一个额外的分支stub,对信号完整性非常不利。
电容并联合成的时候,小容值电容负责高频通路,大容值电容负责低频和直流隔离。可以放一个100nF和一个1nF甚至更小的C0G并联,扩展通带。调试时看到高频滚降严重,可以试着在小容值电容两端并联一个几十pF的电容,往往眼图会有肉眼可见的改善。但每次改完都要重新做CRC验证。
6. 调试经验和习惯,最后说几点实在的
做GMSL2这套东西,说难不难,说简单也不简单。最难的不是某一个寄存器,而是“链路没锁定时你根本不知道是电气问题还是配置问题”的那种无力感。我后来形成了一套习惯:
第一,手边一定留一根质量可靠的短同轴线,不超过0.5米。所有问题先用它排除线缆因素,这个动作能把排查时间缩短一半。
第二,初始化代码里把每一步的寄存器读写都打点。比如“读取DEV_ID成功”“链路已使能”“LOCK等待完成”“远端I2C访问成功”这些关键节点全部打印出来。产线或者现场出问题时,只看日志就能定位在哪个阶段,不用连上示波器才能猜。
第三,调一个问题只改一个变量。调整EQ时不要顺便改驱动强度,改驱动强度时不要顺便改POC电容。GMSL2链路的影响因素太多,同时改两个参数,出了问题你根本不知道是谁引起的。
第四,永远先看LOCK和CRC,再看图像。LOCK和CRC是链路健康的硬指标,图像只是最终表现。很多间歇性故障在图像上表现为“偶尔闪一下”,如果不看CRC计数器,很难判断严重程度。把MAX9296的CRC错误状态读出来,连续运行一段时间看统计,比盯屏幕靠谱得多。
最后再说一个小技巧:如果项目时间紧张,先把厂家评估板跑通,再移植到自己的板子上。移植时不要只看原理图,要把评估板的初始化脚本完整拿过来,对比寄存器配置,再针对自己的线缆长度和电源方案做差异调整。这样看起来多了一步,实际上能避开大量“低级但致命”的坑。