
接上篇文章玩转先楫单片机之:使用HPM6P00系列的SEI外设模拟SWD协议,我们使用了HPM6P41的SEI外设模拟SWD协议,虽然在30M时钟下跑出了1700KB左右的速度,但还是不出意料地遇到了一些问题。
在经过评论区疑似hpm人士的大佬指点后,我重新优化了程序,解决了大部分问题。
上回说到,SEI程序中接收到了芯片回应的ACK[0:3]值,存储在DAT_CMD寄存器中,用于程序的条件跳转。但是在SEI的程序结束后,我们还是需要读取到ACK值返回给上层的函数作判断,否则在调试时会出现很多意外的错误。
上次发文时,我误以为ACK的值存储在DAT_1寄存器,读取到了错误的结果。
虽然官方在手册把DAT_CMD排列在DAT_1的位置,它在SEI程序中的的定义值也与DAT_1一致。但是实际上,DAT_CMD寄存器是每个控制器独有的,只有通过CTRL[x].CMD才能正确读取。



上回说到,SEI外设的时钟频率与AHB同频,默认值也是最大值为200MHz。


在官方库中,第一个跳变点(即下降沿)在周期的1/4处,第二个跳变点(即上升沿)在3/4处。

理论上,SWD协议中,芯片端时序只对上升沿敏感,所有数据的收发都在上升沿完成,芯片会在绿色标记处发送数据,我们在蓝色或紫色处都可以接收数据。
但在实际测试中(例如30MHz下),蓝色标记和紫色标记处都收不到数据,需要把采样点向后继续移动几个采样点才能接收到数据。

在高频下,时钟分频值很小,如果要提高延迟周期数,只能将下降沿(p0)和上升沿(p1)同时前移,在上升沿后留出足够空间。所以我们在20M以上频率时,将AHB超频到300M(小超个50%),并按照下图的方法计算采样点,成功将SWD跑到在30MHz。

最后,我们选取多点进行测速,使用群友的openocd测速脚本,多次结果取平均,得到如下的折线图:

相比于低频,高频下速度提升并不成比例,最终呈现的曲线略凸。
HPM的片内FLASH为QSPI形式,虽然每个内核有着32K+32K的巨大cache,但运行速度仍不够极限。
所以我们修改链接脚本,使用ram.icf,由此测试最高速度(但实际上此时的变量默认存放在AXI_RAM,虽然有Cache加持,应该还是比DLM稍慢一点)。

最终在30MHz下达到了1820K的写入速度,1650K的读取速度,距离理论速度30/45*32/8=2.6667M仍有较大差距。
SEI外设功能强大,能够模拟各种同步/异步协议。虽然不是专门为高速通信设计的,但在我们的调教下,最终成功实现了30MHz频率下的通信。
我们仍然对SEI所知甚少,手册中还有很多寄存器没有介绍。
HPM6P00系列的FGPIO更加强大,600M主频下FGPIO的翻转速度能够达到300M。使用FPGIO模拟SWD/JTAG协议有望实现更快的速度。