CH374S读取描述符

操作USB的代码是CH374EVT中的HOST.C程序,当程序运行到HostTransact374()函数的M_IS_HOST_IN_DATA( s )语句时,结果总为0。查看CH374INC.H头文件时,发现这个宏的定义如下 #define M_IS_HOST_IN_DATA( status ) ( ( (status) & BIT_STAT_DEV_RESP & ~ ( DEF_USB_PID_DATA0 ^ DEF_USB_PID_DATA1 ) )== ( DEF_USB_PID_DATA0 & DEF_USB_PID_DATA1 ) ),其中status的值为USB SETUP阶段得到的0x14,而其余的值在头文件中均有定义,但如果status的值为0x14的话,此宏的结果必为0,因而也无法得到所需的描述符值,麻烦请问该如何解决这一问题,谢谢!

刚才搞错了,根据程序可以得知,读取描述符需要执行两次HostTransact374()函数,第一次为PID == DEF_USB_PID_SETUP时,此时得到的REG_USB_STATUS值为0x92,HostTransact374()的值为0x14,而当第二次执行HostTransact374()时,得到的REG_USB_STATUS值为0x8e,HostTransact374()的值为0x2e,与所需的设备描述符值0x14不一致。所以想请教出现这种情况的原因是什么?


第一次和第二次发送HostTransact374(),两次读取的都是什么描述符,是不是一样的描述符?


两次HostTransact374()都是在HostCtrlTransfer374()里通过WaitHostTransact374()调用的,第一次是PID == DEF_USB_PID_SETUP时调用,HostTransact374()得到的结果为0x14,第二次是当PID == DEF_USB_PID_IN时调用的,HostTransact374()得到的结果为0x2e.代码如下: uint8_t HostCtrlTransfer374( puint8_t ReqBuf, puint8_t DatBuf, puint8_t RetLen )

{ uint8_t s, len, count, total; uint8_t tog; Write374Block( RAM_HOST_TRAN, 8, ReqBuf ); Write374Byte( REG_USB_LENGTH, 8 ); mDelayuS( 100 ); s = WaitHostTransact374( 0, DEF_USB_PID_SETUP, 0, 200 ); //第一次通过WaitHostTransact374()调用HostTransact374() if ( s == USB_INT_SUCCESS ) { tog = 1; total = *( ReqBuf + 6 ); if ( total && DatBuf ) { len = total; if ( *ReqBuf & 0x80 ) { while ( len ) { mDelayuS( 100 ); s = WaitHostTransact374( 0, DEF_USB_PID_IN, tog, 200 ); //第二次调用 if ( s != USB_INT_SUCCESS ) break; count = Read374Byte( REG_USB_LENGTH ); Read374Block( RAM_HOST_RECV, count, DatBuf ); DatBuf += count; if ( count <= len ) len -= count; else len = 0; if ( count == 0 || ( count & ( UsbDevEndpSize - 1 ) ) ) break; tog = tog ? 0 : 1; } tog = 0; } else { while ( len ) { mDelayuS( 100 ); count = len >= UsbDevEndpSize ? UsbDevEndpSize : len; Write374Block( RAM_HOST_TRAN, count, DatBuf ); Write374Byte( REG_USB_LENGTH, count ); s = WaitHostTransact374( 0, DEF_USB_PID_OUT, tog, 200 ); if ( s != USB_INT_SUCCESS ) break; DatBuf += count; len -= count; tog = tog ? 0 : 1; } tog = 1; } total -= len; } if ( s == USB_INT_SUCCESS ) { Write374Byte( REG_USB_LENGTH, 0 ); mDelayuS( 100 ); s = WaitHostTransact374( 0, ( tog ? DEF_USB_PID_IN : DEF_USB_PID_OUT ), 1, 200 ); if ( tog && s == USB_INT_SUCCESS ) { if ( Read374Byte( REG_USB_LENGTH ) ) s = USB_INT_BUF_OVER; } } } if ( RetLen ) *RetLen = total; return( s ); }


你是想获取描述符?如果是这样的话,发送HostCtrlTransfer374后如果成功的话,不需要发IN令牌读取数据,数据已经在DatBuf中


谢谢您的回答!将IN令牌读取数据去掉后, GetDeviceDescr()和SetUsbAddress()运行正确,但是当执行到GetConfigDescr()时,HostCtrlTranact374的返回值为0x20,表示USB反应超时,所以想请教一下,这种问题会不会是由USB设备的描述符不正确造成的?现在的描述符是: uint8_t SetupGetDevDescr[] = { 0x80, 0x06, 0x00, 0x01, 0x00, 0x00, 0x12, 0x00 };

uint8_t SetupGetCfgDescr[] = { 0x80, 0x06, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00 };

uint8_t SetupSetUsbAddr[] = { 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 };

uint8_t SetupSetUsbConfig[] = { 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };


描述符要根据实际设备的种类修改的,你获取配置备描述的请求是正确的,如果你能获取设备描述符,那么获取配置描述符的可能性非常大,因为两者没有什么区别,除非你BUF数据传入到形参中有问题,或者BUF赋值的有问题


谢谢您的回答,GetDeviceDescr()和GetConfigDescr()的参数buf都是没有赋值和初始化的,只是将其定义为一个uint8_t的数组变量,程序中的声明是这样的: uint8_t buf[64]; 除此之外,主函数并没有其他的对buf的操作,而且GetDeviceDescr()可以读取的话,那GetConfigDescr()也应该可以的,并且如果我将buf初始化为0x00后,那么程序HostCtrlTranact374()直接返回0x17,表示buf太长,此时甚至GetDeviceDescr()都无法读取。所以我怀疑可能是其他方面的原因,不知道贵公司的工程师有没有碰到过这中问题,还请不吝赐教啦! 谢谢


初始化BUF会对您获取设备描述符产生影响?这个不会的,除非你的BUF类有问题。你监测下在获取配置描述符时,WaitHostTransact374返回的S值是多少(看SETUP有没有成功)?顺便把你的硬件原理图发送至我邮箱


是的,初始化后会执行if ( len < ( (PUSB_SETUP_REQ)SetupGetDevDescr ) -> wLengthL ) s = USB_INT_BUF_OVER; 从而s的值变为0x17。现在无法获取配置描述符,WaitHostTransact374返回0x20,而在获取设备描述符和设定USB地址时,WaitHostTransact374返回0x14,usb的硬件原理图已发送。 谢谢!


Write374Block( RAM_HOST_TRAN, 8, ReqBuf ); 这个函数之后调用下这个函数: UINT8 buf[8]; Read374Block( RAM_HOST_TRAN, 8, buf ); 看下buf里面的数据是什么样的数据,是不是你写进去的数据。


你自己想想初始化BUF会对获取设备描述符有影响,可能么?!BUF只是用来装设备返回的数据的,初始化与不初始化,对设备是否返回数据是没有影响的,你最好先把这个问题解决。len值是多少?


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