如题,最近写了个基于CH552的通用JTAG适配器。用法如下:
向EP1写入0x00+一个字节:控制电源、FPGA复位等,具体逻辑参见jtag.c的jtag_power()实现。其中0x04位控制JTAG模式还是SPI模式。
向EP1写入0x01+字节数+比特数+0x00+tms序列数组(以字节为单位,lsb先出)+tdi序列数组(同上):输出一个JTAG序列,最多30字节。
向EP1写入0x02+数据:输出一个SPI序列,复用JTAG引脚,最多63字节。
从EP1读取数据:读取JTAG写入时TDO采样得到的数据,字节序和TMS、TDI相同。
支持WCID,可以免驱(但是WinUSB貌似不被PyUSB支持,所以我手工安装了libusb-win32)。
下位机只负责输入输出JTAG序列,具体高层逻辑(TAP状态改变、读写、复位等)完全依赖上位机。
附送Python程序用于加载高云FPGA的比特流。实测GW1NR-LV9可用。
https://github.com/blueskull/CH552-JTAG
最近编辑记录 Blueskull (2020-10-23 15:17:04)
离线
代码仓库更新,新版本支持5倍的下载速度,达到160kBps(1.28Mbps)。等有时间把USB双缓冲搞了,应该能更快。
离线
不错,这个应该是类似于FTDI的MPSSE的思路吧?做得好的话可以实现SWD等协议的模拟。
SWD没有研究过。这个就是bit shifter,具体每个bit啥意义他不管,他只负责把收到的byte拆成bit然后shift出去,然后shift进来另一路数据。
具体的bit定义和再高一层的协议是上位机的事情。就是MPSSE。
离线
请问这个能连接openocd吗?
不能,没做OCD的接口库
离线
挖个坟,代码重构了,C代码文件合并了,函数解耦了,Python代码合并了,模块化了,新增参数解析器。增加了韩同学的CH552 ISP程序。
GitHub链接不变。
离线
这个能用来配置A家和X家的片子吗
硬件能,但是上位机软件我没做。AXL都有公开的配置JTAG指令文档,自己可以去看,然后基于我的Python脚本去改。
另外,X/L家的官方下载器就是FT2232H做的,有大神写的CH552模拟FT2232H,但是只能跑2.5Mbps。具体自己GitHub找。
A家不支持FT2232H,A家官方下载器是基于68013和CPLD的。CH552可以从零开始按照文档写,但是不能直接模拟FT2232H偷懒。
换句话说,X/L可以靠模拟FT2232H实现调试和在线仿真,A家只能下载,而且得自己写上位机。
离线
离线
双缓冲做完了,速度在我目前的电脑上从1.24Mbps提升到了1.47Mbps,逻辑分析仪显示数据之间不再有延迟。
进一步地,SPI读写部分做了条件性循环展开,速度进一步提升到1.64Mbps。
同时,单片机代码基本上完全重构了,上位机程序和协议也完全重构了。
接下来有可能的优化路线是手写汇编处理xdata数据,避免频繁装载DPH/DPL,并利用DPTR自增功能。
这个等我有心情再搞吧,目前我想实现的都实现了。
离线
这单片机频率有的超么 还是跟usb绑定的
速度是受CPU限制的。这个单片机不支持DMA到其他外设,只有USB能DMA。所以USB DMA进来的数据需要使用CPU拷贝到SPI里面,这个是最浪费时间的部分。
因为8051只能寻址256字节idata内存,额外的数据(USB buffer)要放到xdata内存里面,因此需要DPTR操作,这个最费时间。
一个连续地址DPTR操作需要完成五件事,写入DPH,写入DPL,读取数据到ACC,从ACC读取数据到实际目的地,自增DPL。
因为我用的免费编译器SDCC优化不是特别好,我怀疑它没有对这部分进行优化。
如果手写汇编或者使用商业编译器,只要我的数据在一个256字节的页里面,DPH只要写一次,不需要每次都写。
同理,CH552支持DPL自增,每次读取他会自动加一,因此DPL也不用每次读取都自增然后写入。这三个指令优化掉了应该会再快一点。
离线
继续优化,所有xdata指针都显式声明为xdata,这样减少了generic pointer的开销。
其次,对最关键的spi_write和spi_write_read函数,xdata操作部分改为汇编操作,并利用了CH552的DPTR自增以及双DPTR能力。
现在跑到了3.21Mbps,和最初的1.28Mbps相比是之前的2.5倍。
离线
Ch552的spi好像有fifo吧 spi移位的时间里不够从usb buffer转数据吗 另外 如果把spi短路掉 usb那边数据速度测试能到多少
一字节FIFO,就是移位寄存器。纯USB跑到5M+没问题。
离线
接着搞,现在优化了一下数据读写顺序,在SPI传输的时候读取下一字节,实现操作重合,现在带宽跑到了3.45Mbps,初代的2.7倍。
离线
Spi能跑12M吧usb不也是12M能否将usb直接dma给spi
跑不了。SPI最高能跑CPU频率/2,在3.3V下CH552最高能跑16MHz,所以SPI最高能跑8Mbps。
CPU频率设高了则上电一秒内死机,SPI分频设为1则MOSI正常,但是SCK不输出。
另外,USB不能DMA到SPI,也不能DMA到data或者idata。USB的DMA是硬连线到xdata的。
离线
继续提速,把轮询SPI状态改成固定nop延时,现在跑到了4.08Mbps。收工不干啦!
离线
手册不是说能跑到24mhz吗
5V下可以,3.3V只能16MHz。
能否将spi设在4mhz 用nop调延时让实际速率略低于4mhz 这样输出时钟比较均匀 更利于连长线
可以。这个取决于用户需求。我的nop是宏定义的,要几个给几个。SPI降频,nop数跟着降就好了。
我现在没有做环形缓冲,也没有做USB分包,现在是一个USB数据包是一条指令,如果作了分包,就可以高效地发超长或者超短包了。到时候USB利用率还能提升。另外,我现在指令数据没有分离,所以协议需要解析才能发送。以后开个新的端点,只负责SPI数据,带宽还能提升。
但是我不想搞了,等什么时候速度不够了我再弄吧。
离线
离线