本工作在本站大佬 @ljbfly 的工作基础上改进而来
详细见帖子:CH552 版 CMSIS-DAP v2 https://whycan.com/t_3732.html
基本大框架没有动,使用汇编优化了SWD时序,高速提供IO模拟的SWD时序,也提供一个硬件SPI的尝鲜。
完全重写C+汇编混和优化了虚拟串口部分,有效减小串口丢包,发送中断问题,提高效率
只使用v2版本的免驱动bulk模式,不兼容V1版本的hid,提供一个虚拟串口
目前空间占用,rom用了7k多,ram基本都榨干了,xram全部是缓存,iram剩余字节数也不多
开源代码、编译好的固件、PCB工程获取途径:https://github.com/posystorage/CH55x_HS_DAP-Link-v2
优化思路参考了 @metro大佬的工作,参见:
【重开旧坑】8051上的CMSIS-DAP调试器——TinyDAP开发过程记录 https://whycan.com/t_6114.html
晒一下CH558跑的CMSIS-DAP v2调试器,下载速度可以达到70KB/s(Flash)和300KB/s(SRAM) https://whycan.com/t_3766.html
和@metro大佬比起来,本人的目标是实现高速的SWD优化,暂时不打算涉猎JTAG\SWO\文件拖拽下载\兼容HID等这些功能,主要应用方向是做板载调试器(例如使用CH552E实现串口+SWD),在开发板上非常方便的调试芯片,减少接线
比如说挖坑的这个做数字锁相放大器的板子,由CH552负责通讯+SWD调试单片机+JTAG调试FPGA,全部集成。当然这坑啥时候能填完又是另说了。
回归正题
硬件实现 我这个板子可以选3.3V供电或者5V,我考虑的是选5V可以跑24M主频(实测32M也稳定可跑),然后IO电平用两颗1T45转换成3.3V,顺便负责SWDIO的换向,板子体积非常小。
如果是板载调试器的话,用3.3V供电跑16M也还是足矣,可以节约不少外围。
@ljbfly大佬编写的代码是全C实现的,由于编译器问题,SWD底层部分在频繁的搬数据,时序效果看起来占空比非常高,而且SWD输入的时候直接使用推挽读取(让我一开始非常迷惑),实测下来有的单片机如果SWD脚驱动不强的话可能兼容性不太好。
所以整个SWD时序创建了一个汇编文件,全部用汇编优化。网上写的8051如何C和汇编混合编程,也是写的乱七八糟的,互相抄来抄去,东拼西凑。我研究了好久才让这玩意稳定工作()可能还是因为太菜了吧
优化后 经过计算软IO模拟的话,12个处理器周期可以刷一个SWD时钟,3.3V下16M主频时钟1.66M,5V下24M主频时钟2M.
3.3V下IO模拟读取时序:
3.3V下IO模拟写时序:
16M主频下看起来SWD接口的占空比比较大,实际研究后,间隔时间五分之二是ch552在处理,五分之三是上位机比较慢,上位机驱动不改的话,下位机处理DAP指令还是有不少的优化空间(从xram倒腾数据过程非常多),不过考虑到我头发有限,目前就暂时不弄了。
串口优化:原版的串口驱动只能说叫有,但是基本没什么优化,串口发送是cpu在硬等,数据量一大就丢包。目前优化后使用256字节的xram做串口发送大fifo,(这样的好处是写入写出指针用8位刚好可以,处理fifo的满和空非常简单),串口接收由于usb带宽远高于串口,所以用64字节缓存足矣,收到串口数据只要有usb端点空闲就直接丢给usb(基本上1-2个字节就会发一次),总体没什么压力。
发送大于256字节的串口数据,usb会发四次包直到缓存塞满。usb发包的时候确实会打断串口中断,以后可以优化以下用中断嵌套,使得串口优先级更高。
但是fifo的处理涉及到可能会两个中断同时访问,还需要掉些头发。
可以看到swd和串口一起工作的时候的状态,波特率干到500000
如果没有要复杂处理的usb中断,swd是不影响串口的
降低波特率到115200
硬件spi优化
使用硬件spi刷写swd部分的固定字节。8-bit的command和32bit的数据可以直接切换到spi刷
优化占比可以达到(8+32)/(8+5+32+1)≈87%
既然用了spi 就可以调速度,以5V下跑24M主频为例,swd速度可调100KHz~12MHz,当然只调节spi刷的部分,软件部分改不了的。
100K
1M
实际上是6M,12M逻辑分析仪抓不到了,但是也可以正常通讯。我还玩了下主频32M跑鸡血16M时钟,也没什么问题。
开源了PCB工程文件和电路图,代码开源了软件模拟io,因为spi硬件刷新的我测下来兼容性并不是太好,有点挑MCU,有时候会莫名其妙报错,所以我回头在研究研究,就先不拿出来献丑了。提供几个编译好的固件大家可以试试。
欢迎找bug,提交改进意见~
禁止用于商业用途
离线
大佬牛哇!简直造福人类。希望后面越来越好用。
另外问下,CH551是不是装不上这个固件?
我没做限制,大小才8K,没用串口1,应该是没问题
离线
支持,CH552用于做板载调试器成本低,DAPLink的JTAG调试FPGA?这个需要上位机支持吧,还是说自己在调试器中实现FPGA的一套JTAG协议?
切换使用不就行了 usbblaster+daplink 用按键一键切换
离线
我的天,都是大佬!一套成本得多少?
不超过10元 这个芯片很便宜的(特别是涨价前)
离线
大佬太强了!手里有几片多年前立创撸的CH554T,看DS说554只是比552/1多了USB Host功能,是不是也可以搞这玩意儿
可以用 都一样的
离线
CH552性能上限太低了,而且现在也并不便宜
ch552e ssop10封装的还是很香的,在开发板上板载一个 得到串口+swd
离线
有计划支持 rs-flash 吗?
请问这是什么东西 没听说过
离线
posystorage 说:taotieren 说:有计划支持 rs-flash 吗?
请问这是什么东西 没听说过
https://github.com/probe-rs/cargo-flash
https://github.com/probe-rs/probe-rs
我简单看了下,有点没太看懂,这个不就是个上位机软件吗?
离线
@gddddd
可能是因为有些是汇编代码 受影响吧?我回头有空看看
离线
请问,如果用SPI的话,是需要用2线半双工模式来作为SWDIO口吗?或者用其它方法来解决双向的问题?
用的全双工SPI,将两个IO并起来用。ch552的半双工SPI有问题,速度提不到最快
离线
大佬,我试着复刻了一下pcb,发现了一个矛盾的地方,readme中提示P1.6和P1.7需要并联,但是在原理图中P1.6又和P1.5通过一个0欧电阻相连,甚是疑惑,是我什么地方存在理解错误吗,希望能够得到解答,感谢。
readme 写错了 按原理图为准
离线
大佬,我烧了你编译出来的固件,设备管理器里面能看到一个串口和一个CMSIS-DAP V2设备,但是Keil里面检测不到,想问一下是需要装专门的驱动还是对Keil版本有要求啊,我的Keil是5.23版本
keil版本太老了 识别不到v2版本的daplink 升级下keil
或者替换这个dll文件 在Keil_mdk_c51\ARM\BIN下
CMSIS_DAP.zip
离线
大佬,这个编译的固件试了一下,串口不稳定啊,3.3V供电,115200波特率,串口接受误码很厉害
3.3V下主频只有16MHz,跑115200波特率偏差非常大的
Fsys / 16 / 波特率
波特率应该111111
离线
@Meski
Cannot Load Flash Programming Algorithm这个是你keil设置问题,和daplink没关系 这个是没有设置下载算法
离线
感谢楼主分享的源码,我这几天正在学习usb,计划把它移植到CH583上,下一步使用蓝牙做一个无线的DAP。
支持你,SWD速度优化建议你重写官方原装的SWD时序代码
离线
@EListen
端点2和3应该是串口缓存buff,使用256字节空间做fifo的,你看下汇编部分就会发现
离线
@EListen
时间长了 有点忘了。我看了下 是这样的
EP1缓存是串口用的缓冲,收发各使用了64字节
Main_Usb.C
UINT8X Ep1BufferO[THIS_ENDP0_SIZE] _at_ 0x0040; //端点1 OUT双缓冲区,必须是偶地址 Not Change!!!!!!
UINT8X Ep1BufferI[THIS_ENDP0_SIZE] _at_ 0x0080; //端点1 IN双缓冲区,必须是偶地址 Not Change!!!!!!
串口文件下有两个缓存,在内部的是RX缓存,64字节,在外部的是TX缓存,256字节
Uart.c
UINT8I UART_RX_Data_Buff[ENDP1_SIZE];
UINT8X UART_TX_Data_Buff[256]_at_ 0x0300;
void UART_Get_USB_Data(UINT8 Nums)负责把Ep1BufferO搬到发送fifo UART_TX_Data_Buff里面
void memcpy_TXBUFF_USBBUFF(UINT8 data_len)负责把UART_RX_Data_Buff搬到Ep1BufferI
串口这部分的buff是没混用的
EP2是PC下发DAP数据给CH552
这里的缓存是这样用的,写满了就直接+64
Main_Usb.C
case UIS_TOKEN_OUT | 2: //endpoint 2# 端点批量下传 DAP-CMD
if (U_TOG_OK) // 不同步的数据包将丢弃
{
Ep2Oi += 64;
UEP2_DMA_L = Ep2Oi;
}
break;
EP3也是同理,好了直接换缓存,这样不用一直等USB
Main_Usb.C
if (Endp3Busy != 1 && Ep3Ii != Ep3Io)
{
Endp3Busy = 1;
UEP3_T_LEN = Ep3Is[0];//Ep3Io>>6];
UEP3_DMA_L = Ep3Io;
UEP3_CTRL = UEP3_CTRL & ~MASK_UEP_T_RES | UEP_T_RES_ACK; //有数据时上传数据并应答ACK
Ep3Io += 64;
}
这里有FIFO缓存的使用
DAP.c
void DAP_Thread(void)
{
UINT8I num;
if (Ep2Oi != Ep2Oo)
{
PUINT8 req = &Ep2BufferO[Ep2Oo];
PUINT8 res = &Ep3BufferI[Ep3Ii];
Ep2Oo += 64;
........
Ep3Is[0]/*(Ep3Ii>>6)]*/ = num + 1;
Ep3Ii += 64;
}
}
离线
我感觉是不需要这么大的buffer的,楼主这么写应该是为了汇编好写 直接DPH固定了
不过这XRAM不用白不用对吧hhh
哈哈 被你发现了 就是汇编偷懒 你说得对,而且这部分代码还是之前在别的工程上用的 我直接搬过来偷懒了
离线
@815794369
这么点信息不足以分析出问题在哪里,这个要抓包swd+usb才容易看出来。话说你测试了5V情况下能稳定工作吗?
离线
@815794369
振铃我觉得主要是杜邦线不好,以及接地屏蔽不完善造成的,建议不要撕开杜邦线
离线
CH552下载不了STM32的是什么情况
我这边测试是可以的 你要不看看低速下行不行
离线
@posystorage 楼主楼主 在单独接下载器没有接32的时候 在Keil中检测下载器状态的时候 debugger settings里的 有出现RDDI-DAP Error的情况不
发个截图看看。另外 接stm32的时候能用吗?
离线
大佬威武,ch551/552的资源够用的话,是不是也能拿cy7c68013/cbm9002这种芯片弄一个下载器?
我估计可以?
离线
有大佬进行了更新,解决了一些bug,可以看这里
https://oshwhub.com/jdsuchen/ch552-cmsis-dap
离线