ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CY7C68013A固件烧录与EEPROM启动全流程实战指南

CY7C68013A固件烧录与EEPROM启动全流程实战指南 1. 为什么CY7C68013A的固件烧录值得单独写一篇CY7C68013A这颗芯片在USB外设开发圈子里算是老面孔了FX2LP系列8051内核加USB 2.0高速控制器最高480Mbps的传输速率放在今天看参数不算亮眼但胜在资料多、生态成熟、价格便宜很多数据采集卡、逻辑分析仪、工业相机的USB接口方案里都能见到它。我最早接触这颗芯片是做一台自制逻辑分析仪的USB前端当时以为固件烧录就是点一下下载按钮的事结果前前后后折腾了将近一周才把枚举和EEPROM配置彻底搞明白。问题出在哪儿CY7C68013A的启动方式跟常见的STM32、ESP32完全不一样。它上电后先看I2C总线上有没有EEPROM如果有就尝试从EEPROM加载VID/PID和固件代码如果没有或者EEPROM内容无效就退回到内部默认的USB描述符以Cypress默认的VID/PID04B4/8613枚举成一个未配置的设备。这个机制决定了你不能像烧STM32那样直接连SWD就能下载得先让芯片以某种方式“活”过来才能把固件写进去。所以这篇内容主要面向三类人第一类是刚拿到CY7C68013A开发板、不知道怎么把固件烧进去的新手第二类是已经能烧录但枚举不稳定、VID/PID改不对的调试者第三类是想把EEPROM启动流程彻底搞清楚、方便做批量生产的工程师。我会从启动原理讲起把EEPROM的配置结构、烧录工具的选型、固件下载的完整流程、以及我踩过的那些坑都摊开来说。2. CY7C68013A的启动逻辑与EEPROM的角色拆解2.1 上电后的三种启动路径CY7C68013A内部有一块8KB的RAM用来存放8051的固件代码。上电复位后芯片的启动逻辑大致分三种情况第一种I2C总线上挂了一片EEPROM且EEPROM的第一个字节是0xC0或0xC2。0xC0表示EEPROM里只存了VID/PID和DID/VID配置不存固件代码芯片会用这些描述符去枚举但8051执行的仍然是内部固化的默认程序0xC2表示EEPROM里既有配置描述符又有完整的固件代码芯片会把固件从EEPROM搬到内部RAM然后跳转执行。第二种EEPROM存在但第一个字节不是0xC0或0xC2或者I2C读写失败。芯片会忽略EEPROM直接用内部默认描述符枚举VID/PID是Cypress的04B4/8613。第三种I2C总线上没有EEPROM。跟第二种一样走内部默认枚举。这个逻辑听起来简单但实际调试时最容易出问题的就是第一种情况里的0xC2模式。因为一旦EEPROM里写了0xC2和固件代码芯片每次上电都会从EEPROM加载如果固件本身有bug导致USB枚举失败你就没法通过USB口重新烧录了只能把EEPROM拆下来用编程器擦除或者短接I2C的SCL/SDA引脚强制芯片走默认枚举。注意如果你用的是带EEPROM的开发板第一次烧录前先确认EEPROM是空的或者第一个字节不是0xC2。如果不确定可以用i2c扫描工具读一下0x51地址CY7C68013A默认EEPROM地址的第一个字节。2.2 EEPROM里到底存了什么CY7C68013A支持的EEPROM是I2C接口的常见型号是24LC64、24LC128、24LC256这些容量从8KB到32KB不等。EEPROM里的数据结构是固定的第一个字节是配置标志后面跟着VID/PID/DID和配置描述符再后面才是固件代码。具体来说0xC2模式下的EEPROM布局是这样的第一个字节0xC2然后是一个字节的EEPROM容量代码接着是VID2字节、PID2字节、DID2字节再后面是配置描述符和固件代码。0xC0模式更简单只有第一个字节0xC0、容量代码、VID、PID、DID没有固件代码。这里有个细节很多人会忽略EEPROM的容量代码不是随便填的它决定了芯片从EEPROM读取固件时的地址宽度。比如24LC64是13位地址24LC128是14位地址24LC256是15位地址。如果容量代码填错了芯片读固件时地址会错位表现就是固件加载后跑飞或者USB枚举失败。我一般用24LC256容量代码填0x07对应15位地址。这个对应关系在Cypress的官方文档里有表格但文档写得比较散我整理了一下常见型号的对应关系EEPROM型号容量地址位宽容量代码24LC648KB13位0x0524LC12816KB14位0x0624LC25632KB15位0x0724LC51264KB16位0x082.3 为什么VID/PID不能随便改VID和PID是USB设备的身份证主机靠这两个值来匹配驱动。CY7C68013A的默认VID/PID是04B4/8613这个值在Cypress的驱动里是认的但如果你把VID/PID改成自己的就必须同时提供对应的驱动或者INF文件否则Windows会提示“未知USB设备”。我见过有人把VID/PID改成跟某个知名品牌一样想蹭现成的驱动结果主机加载了那个品牌的驱动但设备实际功能对不上通信直接失败。所以VID/PID要么用Cypress默认的要么用自己的合法VID不要乱蹭。另外EEPROM里的DIDDevice ID字段在FX2LP里其实对应的是版本号或者设备变体标识有些驱动会检查这个值。如果你改了VID/PID但没改DID驱动可能会加载失败。我一般把DID设成0x0001表示第一个版本。3. 烧录工具选型与驱动安装的实操细节3.1 官方工具还是第三方工具Cypress官方提供了一套开发工具叫FX3 SDK或者EZ-USB FX2LP SDK里面包含了一个叫CyConsole的工具可以通过USB口把固件下载到芯片的RAM里也可以烧录到EEPROM。这个工具的好处是稳定、官方支持坏处是界面比较老旧而且安装包比较大。第三方工具里比较常用的是fx2lp-tools这是一个开源项目提供了命令行方式的固件下载和EEPROM读写功能。我平时调试更喜欢用命令行工具因为可以脚本化批量生产时特别方便。如果你只是偶尔烧一两次用CyConsole就够了。如果要批量烧录或者集成到自动化测试流程里建议用fx2lp-tools或者自己写一个基于libusb的小工具。3.2 驱动安装的坑CY7C68013A在未烧录固件时以Cypress默认的VID/PID枚举Windows会识别到一个“Cypress USB Device”或者“Unknown Device”。这时候需要安装Cypress的通用驱动或者用Zadig工具把WinUSB驱动绑定上去。我遇到过好几次驱动装不上的情况排查下来通常是这几个原因一是USB线质量差只供电不传数据二是芯片的I2C总线上挂了EEPROM但EEPROM内容无效芯片反复尝试加载导致枚举不稳定三是Windows的驱动签名强制开启Cypress的老驱动没有签名。实操心得如果驱动装不上先把EEPROM拆掉或者短接SCL/SDA让芯片走默认枚举然后用Zadig把WinUSB驱动绑上去。绑定成功后设备管理器里会显示“WinUSB Device”这时候就可以用libusb工具通信了。3.3 硬件连接的最小系统CY7C68013A的最小系统其实很简单除了电源和晶振主要就是USB接口和I2C上拉电阻。晶振一般用24MHzUSB的D和D-差分线要等长走线阻抗控制在90欧姆左右。I2C的SCL和SDA需要4.7K的上拉电阻接到3.3V。如果你用的是现成的开发板这些都已经做好了直接插USB就行。如果是自己画的板子第一次上电前一定要检查晶振有没有起振USB差分线有没有短路。我有一块板子就是因为D和D-画反了芯片一直枚举失败查了两天才发现是原理图符号的引脚定义搞错了。4. 固件烧录的完整流程与参数配置4.1 从RAM下载到EEPROM烧录的两步走CY7C68013A的固件烧录分两步第一步是把固件下载到芯片的RAM里让芯片先跑起来第二步是通过跑起来的固件把配置数据和固件代码写到EEPROM里。为什么不能直接写EEPROM因为芯片上电后如果EEPROM是空的它走的是内部默认程序这个程序只支持基本的USB控制传输不支持I2C读写。所以你必须先下载一个支持I2C读写和EEPROM烧录的固件到RAM里用这个固件去操作EEPROM。Cypress官方提供了一个叫vend_ax.hex的固件就是干这个用的。这个固件下载到RAM后芯片会枚举成一个Cypress的设备然后你可以通过CyConsole或者命令行工具发送特定的USB控制传输命令让固件去读写EEPROM。4.2 用CyConsole烧录的详细步骤打开CyConsole选择“FX2LP”设备然后点击“Download”按钮选择vend_ax.hex文件。下载成功后设备会重新枚举这时候在CyConsole里能看到一个新的设备。接下来点击“EEPROM”按钮选择“Write EEPROM”。在弹出的对话框里你需要指定三个东西EEPROM的I2C地址默认0x51、要写入的数据文件通常是你的固件hex文件加上配置头、以及EEPROM的容量。这里有个关键点CyConsole写入EEPROM时会自动在数据前面加上0xC2和容量代码。但如果你用的是第三方工具需要自己构造这个头部。我一般用Python脚本生成EEPROM的二进制文件头部格式是0xC2 容量代码 VID_L VID_H PID_L PID_H DID_L DID_H 配置描述符 固件代码。4.3 用命令行工具批量烧录批量生产时我用的是一套基于fx2lp-tools的脚本。核心命令是fx2lp-download -d 04b4:8613 vend_ax.hex fx2lp-eeprom -d 04b4:8613 -a 0x51 -w firmware_with_header.bin第一条命令把vend_ax.hex下载到RAM第二条命令把构造好的EEPROM二进制文件写入0x51地址。写入完成后断电重新上电芯片就会从EEPROM加载固件。注意写入EEPROM后不要马上断电等工具提示写入完成后再等两秒。I2C写入是页写模式每页最多64字节写完一页需要等待5ms左右的内部写周期。如果断电太快最后一页可能没写进去。4.4 固件代码的编译与hex文件生成如果你要自己写固件需要用Keil C51或者SDCC编译。Cypress官方提供了FX2LP的固件框架里面包含了USB描述符、端点配置、中断处理等基础代码。你只需要在框架里添加自己的功能代码然后编译生成hex文件。编译时要注意内存模型的选择。CY7C68013A的8051内核有128字节的idata和8KB的xdata固件代码默认放在xdata里。如果代码量超过8KB就需要用分页机制这个比较复杂新手建议先把代码控制在8KB以内。生成的hex文件不能直接写EEPROM需要用工具转换成二进制格式然后加上配置头。我一般用hex2bin工具转换然后用Python脚本加头。5. 常见问题排查与避坑经验实录5.1 枚举失败的问题排查枚举失败是最常见的问题表现是设备管理器里显示“未知USB设备”或者设备反复断开重连。排查思路是这样的先确认EEPROM是不是空的。如果EEPROM里有0xC2但固件有bug芯片会一直尝试从EEPROM加载然后失败。这时候把EEPROM的SCL或者SDA对地短接让I2C通信失败芯片就会走默认枚举。然后确认USB差分线有没有接反。CY7C68013A的D和D-是固定引脚不能交换。如果接反了芯片会枚举成全速设备而不是高速设备或者直接枚举失败。最后确认晶振有没有起振。用示波器测24MHz晶振的引脚应该有稳定的正弦波。如果没有检查晶振的负载电容是不是匹配一般用12pF到22pF。5.2 EEPROM写入失败的几种情况EEPROM写入失败通常有三种表现写入后读出来是0xFF、写入后读出来是0x00、写入后读出来部分正确部分错误。读出0xFF说明I2C通信根本没成功检查上拉电阻和I2C地址。CY7C68013A默认的EEPROM地址是0x51但有些EEPROM的地址引脚接法不同地址可能是0x50。读出0x00说明EEPROM被写保护了检查WP引脚是不是接了高电平。部分正确部分错误说明页写边界处理有问题需要按64字节对齐写入。我遇到过一次写入后读出全0xFF的情况查了半天发现是EEPROM的型号不对板子上焊的是24LC64但容量代码填的是24LC256的0x07导致地址错位。换成0x05就正常了。5.3 固件跑飞后的恢复方法如果固件有bug导致芯片跑飞USB完全没反应恢复方法是断电把EEPROM的SCL引脚对地短接然后上电。这时候芯片检测到I2C通信失败会走默认枚举你就可以重新下载vend_ax.hex去擦除EEPROM。如果板子上的EEPROM是焊死的短接不方便可以用镊子或者跳线帽临时短接。我一般会在PCB上预留一个跳线专门用来短接SCL到地方便调试。5.4 常见问题速查表现象可能原因解决方法设备管理器显示未知设备驱动未安装或EEPROM内容无效安装WinUSB驱动或短接SCL走默认枚举枚举成全速设备D上拉电阻未接或USB线质量差检查D的1.5K上拉电阻EEPROM写入后读出全0xFFI2C地址错误或上拉电阻缺失确认地址为0x51检查4.7K上拉EEPROM写入后读出全0x00WP引脚被拉高将WP引脚接地或悬空固件加载后USB无反应固件代码有bug或容量代码错误短接SCL恢复检查容量代码批量烧录时部分设备失败USB Hub供电不足使用带外部供电的USB Hub6. 一些不太常见但很有用的经验6.1 用I2C读写EEPROM的Verilog实现思路有些场景下你可能需要在FPGA里直接读写CY7C68013A的EEPROM比如做批量烧录工装。这时候可以用Verilog实现一个I2C主机控制器。核心是一个状态机处理起始条件、地址发送、数据收发、停止条件。I2C的时钟频率不能太高24LC256支持400KHz但实际调试时建议先用100KHz稳定后再提速。状态机的关键是要处理ACK/NACK如果EEPROM没有应答要能超时退出而不是死等。6.2 USB抓包分析枚举过程如果枚举一直失败可以用USB抓包工具看看主机和设备之间到底发生了什么。Windows上可以用USBPcap加WiresharkLinux上直接用tcpdump抓usbmon。重点看设备描述符请求和配置描述符请求的响应如果设备返回的描述符长度不对或者内容不对主机就会枚举失败。我遇到过一次设备描述符里bMaxPacketSize0填成了64但芯片实际只支持8导致主机枚举失败。抓包一看就发现了改回8就好了。6.3 批量生产时的EEPROM预烧录方案批量生产时如果每块板子都通过USB烧录EEPROM效率太低。更好的方案是先用编程器把EEPROM预烧录好然后贴片。这样板子一上电就能从EEPROM加载固件不需要额外的烧录步骤。预烧录的EEPROM文件就是前面说的带0xC2头部的二进制文件。编程器可以用通用的24系列编程器也可以用FPGA加I2C控制器自己搭一个。我见过一个工装一次能烧16片EEPROM效率很高。6.4 关于USB总线频率和高速握手的补充CY7C68013A支持USB 2.0高速模式但高速握手需要D和D-上的匹配电阻和正确的上拉。如果握手失败设备会退回到全速模式带宽从480Mbps降到12Mbps。对于数据采集应用来说这个差距是致命的。高速握手的流程是设备上电后先以全速模式枚举主机发送高速握手请求设备检测到后切换D的上拉电阻从1.5K切换到45欧姆然后重新枚举为高速设备。如果45欧姆的电阻没接或者阻值不对握手就会失败。我在实际项目中遇到过因为USB线太长导致高速握手失败的情况换了一根短一点的优质USB线就解决了。所以调试阶段尽量用短的、带屏蔽的USB线排除线材的干扰。7. 最后分享几个实操中的小技巧第一个技巧是关于EEPROM的擦除。如果你想把EEPROM里的内容全部清掉不需要用编程器直接用vend_ax.hex下载后发送一个I2C写命令往EEPROM的0x00地址写0xFF就行。芯片下次上电读到0xFF就不会走0xC2模式了。第二个技巧是关于固件调试。在开发阶段建议先把固件下载到RAM里调试确认功能正常后再烧录到EEPROM。因为RAM下载不需要断电调试效率高很多。CyConsole的Download功能就是干这个的。第三个技巧是关于VID/PID的修改。如果你改了VID/PID记得同时更新INF文件里的VID/PID否则Windows会提示驱动不匹配。INF文件里的VID/PID是十六进制字符串注意大小写和格式。第四个技巧是关于EEPROM的容量选择。如果你的固件代码不超过8KB用24LC64就够了便宜而且好买。如果代码超过8KB就需要用24LC256或者更大的同时注意容量代码要对应修改。这些经验都是我在实际项目中一点点积累的有些是踩坑踩出来的有些是跟同行交流学到的。CY7C68013A这颗芯片虽然老但只要你把EEPROM的启动逻辑和烧录流程搞清楚了用起来还是很顺手的。
返回列表