关于CH565W单片机中USB3.0的开发

我最近想用CH565W的spi采集芯片数据,然后再通过USB3.0将数据发送出来,但是官方例程看不懂,不知道该如何发送数据。请问各位大神有没有例程和上位机的例程,小弟感激不尽。

该贴用于说明函数库使用相关,将不定期删除无效、无关、不具有价值的回复信息

===================================分隔符=====================================

CH569EVT中已经包含了USB3.0厂商类型设备和电脑收发数据的程序,包含电脑端程序(USB3.0TestDemo.zip)和单片机程序(CH372Device)。

image.png

其次,芯片的SPI接口速度和USB3.0速度不在一个数量级,如果只是转发SPI接口速度,USB2.0也可满足。


捕获.JPG意思是我是用USB30_IN_ClearIT();和USB30_OUT_Set();和USB30_Send_ERDY();这三个函数就可以实现单纯发送功能了吗?


USB30_IN_ClearIT();清除的是IN事务完成中断标志

USB30_OUT_Set();配置芯片对OUT事务的响应状态

USB30_Send_ERDY();发送ERDY包通知电脑


结合USB3.0协议中数据收发的应答状态流转,结合主机的事务请求,才能实现收发。


我们示例程序虽然注重演示效果,效率不高,但是传输速度也在百兆字节每秒级别,如果不明白USB底层,可以直接在示例程序交互流程上(一发一收),只对缓冲区数据修改,实现上层协议的叠加。


捕获.JPG是对这里进行修改吗?


图中对标准EVT代码(CH372Device)做了一些修改,帮助理解。

image.png

在EP?_OUT_Callback(void)回调函数的 if(nump == 0)条件中,即红框中就是对收到(PC->MCU)数据(OUT)处理的部分。

如果不关心底层逻辑,那就记住一点:只修改蓝色框中部分代码,记住收到的数据在endp1RTbuff[4096]中,数据处理完,回传数据还是放在endp1RTbuff[4096]中。

===========================分割线====================================

在EP?_IN_Callback(void)回调函数的 if(nump == 0)条件中,即指示上传(MCU->PC)数据(IN)完成,通常不需处理,保持默认代码,数据主要处理在OUT_CALLBACK中处理。

image.png

=========================分割线=====================================

按照上面图中代码,就可以实现1号端点的:

下传4096字节,上传4096字节

下传4096字节,上传4096字节

下传4096字节,上传4096字节

下传4096字节,上传4096字节

。。。。。。。。。。。循环

在这个4096字节中去叠加自定义的交互协议

当然,需要电脑端在一个线程中,等到下传(PC->MCU)的4096字节完成,才能启动上传(MCU->PC)4096字节,等到上传4096字节完成,才能启动下一次下传。这样才能上下位机实现同步,保持传输。


下图中的EP2_OUT_Callback(void)写法,能够实现端点2的连续下传,每次下传4096字节。image.png

同样,在蓝色框的范围内对收到的数据进行处理。

================================分割线=============================

下图中的代码将EP3_IN_Callback(void)写法可以实现端点3的连续上传,每次上传4096字节。

image.png

        但是片面的说,上传(其实下传也是)是个被动的过程,进到IN_Callback的时候传输已经结束了,所以单向端点3在第一次上传需要提前准备好buff中的数据(端点1因为是双向的,且人为约定了第一包是下传,处理上逻辑会通一点),因为是单向端点,数据的发送比较难从交互逻辑上和电脑同步,也就是不知道什么电脑会来取走数据。所以需要提前在初始化的时候将端点响应配置好,当然初始化包括前面的端点1、端点2的响应状态。在USB30D_init( )函数中,我们需要对端点响应进行配置,以及端点缓冲区的配置。


        对于上面说的这个“被动”,不必要要在看这部分文字的时候彻底搞明白,有机会就多试试,收发几次找到数据交互的规律就自然而然明白了。光说不练是不行的。


绿色框:端点的收、发使能

红色框:端点收、发DMA地址配置

蓝色框:端点响应状态配置

image.png


为实现

        ①端点1的下传、上传、下传、上传.........

        ②端点2的下传、下传、下传、下传..........

        ③端点3的上传、上传、上传、上传...........

        我们就只要在EP1_IN_Callback(void)、EP3_IN_Callback(void)、EP1_OUT_Callback(void)、EP2_OUT_Callback(void)总计4个回调函数中对数据进行处理就行了。


这个代码模板应该可以应付很多场景下的自定义数据传输了,这样也就不需要关心USB底层了,其实整个USBSS也就这么几个函数。


对应的代码工程在此

icon_rar.gifEXAM.zip

前文的描述旨在帮助使用CH569/565的USBSS库函数,目的是明白函数都是什么作用,该怎么调用。细节优化有涉及到端点描述符等USB协议内容,这里不展开且不针对进行修改,用户自行研究USB协议部分内容。



那我现在按照你提供的方法更改程序了,我现在是否可以使用贵司提供的CH372DBG软件进行验证?我试过使用该软件,可以端点2下传,点击4次下传后串口有数据打印,但端点2上传没有显示数据。是否我操作失误,或是需要使用其他软件?


贴中代码支持且支持:

        ①端点1的下传、上传、下传、上传.........

        ②端点2的下传、下传、下传、下传..........

        ③端点3的上传、上传、上传、上传...........


上位机建议根据示例代码自行开发

如有难度,可以借助BUS HOUND等第三方软件学习探究。第三方软件使用方式请自行解决。


捕获.JPG请问每个数据包的大小是必须固定为4096吗?我尝试过修改贵司官方demo,使其处于一直接收状态,然后单片机程序单方面将4096改成1024,用USB监控软件发现这样会接收不了数据,改回4096之后又能接收到数据。是否可以通过同时通过修改软件中接收数据包的大小进行更改?例如我程序与电脑接收程序同时改成1024,这样是否能正常通讯?


USB3.0 BULK事务,包长度1024字节。

4096长度概念的产生,是因为芯片支持USB3.0中的BURST,BURST级数为4,简单理解就是一次连续发送4包,4*1024=4096.

CH372示例程序中有突发级数的宏定义。

你截图圈中的仅仅是缓冲区长度定义,通常缓冲区长度和最大突发长度(最大端点长度*最大突发级数)相等,以防RAM访问越界。


我MCU程序中有关缓冲区的大小从贵司例程中的4096改成了200,然后在贵司提供的上位机程序的基础上想修改接收的数据包大小。但是无法修改成只接收200个包,且也只能是使用上位机历程中的“ #define  TEST_DATA_LEN  0x400000”这个值才能接收正常数据。在此我想请问如果我上位机想设置成只接受200个数据我应该怎么修改程序?

1658732874684613.jpg

1658732874515904.jpg



观察函数注释可知,参数nump代表端点能够发送的包数量。如果要上传非满包(<1024),应当将nump改成1。

image.png

额外要注意的,参数lpf在任何时候都应该为1。这已经在1.2版本库中删除了这个参数。


请问下,EP0的SetupRequest OUT方向的data部分应该在哪里取?是否为endp0RTbuff + sizeof(struct SetupRequest)后面的数据?还是说endp0RTbuff有setup阶段,还有data阶段?麻烦解答下,如果有示例,麻烦给一个...


发生控制传输时,SETUP令牌到达DEVICE后,程序会跳入“USB30_StandardReq()”或者“USB30_NonStandardReq()”中由用户处理USB请求。

如果控制传输存在数据阶段,函数库会自动处理数据阶段的应答,在请求处理函数返回之后,OUT事务发生,程序会自动跳入EP0_OUT_Callback()函数。

通过执行"USB30_OUT_Status( )"获取到数据阶段的数据长度“len”。数据存放在“endp0RTbuff”中。

该函数返回值? 0代表数据阶段已经没有后续数据了,非0代表数据阶段没有结束,还有后续数据。


image.png

测试程序:icon_rar.gifsetup-out.zip



只有登录才能回复,可以选择微信账号登录