[求助]ch375host讀usb設(shè)備描述符怪事

按照網(wǎng)站例子用get_descr(2獲取配置描述符可以得出一串正確的完整的配置描述符(包括接口、端點等描述符信息)。但用一下語句讀配置描述符本身(不包括接口、端點),rd_usb_data函數(shù)讀出后續(xù)數(shù)據(jù)長度是8不是9,但讀完長度后,讀數(shù)據(jù)時第一字節(jié)(按協(xié)議來說應(yīng)該是配置描述符的長度)卻是9。語句如下:

endp7_mode=0x80; toggle_send(); wr_usb_data(8,get_ctg_des);//get_ctg_des,0x80,0x06,0x00,0x02,0x00,0x00,9,0 status=issue_token(( 0 << 4 ) | DEF_USB_PID_SETUP); if(status==USB_INT_SUCCESS)/* SETUP階段操作成功 */ { endp6_mode=0xc0; toggle_recv(); } else return(0); status=issue_token(( 0 << 4 ) | DEF_USB_PID_IN); if(status==USB_INT_SUCCESS)/* DATA階段操作成功 */ rd_usb_data(RECV_BUFFER); [Emot]13[/Emot]

其實是這樣的,獲取描述符是以控制傳輸通過端點0來獲取的,端點0最大為8個字節(jié),而你想獲取的配置描述符為9個字節(jié),這樣其實就需要兩次傳輸才能將9個字節(jié)獲取上來。


按照這個例子,你應(yīng)該讀取2次才能讀完,也就是說控制端點的端點大小為8字節(jié),一次最多傳輸8字節(jié)的數(shù)據(jù),所以,你讀取到的數(shù)據(jù)長度為9的話,那么,你應(yīng)該讀取2次之后(第一次為8字節(jié),第2次為1字節(jié))就能讀取完數(shù)據(jù)


能不能提供一個51控制375host的外置固件程序呢?


請參考以下程序: unsigned char get_descr_ex() { unsigned char descr_len; unsigned char *p=data_buf; endp7_mode=0x80; toggle_send(); wr_usb_data(8,Request.Req_buf); issue_token(( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt(); if(status==USB_INT_SUCCESS)/* SETUP階段操作成功 */ { endp6_mode=0xc0; toggle_recv(); } else return(0); issue_token(( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt(); if(status==USB_INT_SUCCESS)/* DATA階段操作成功 */ { if(flag_config_2)descr_len=data_buf[2]-rd_usb_data(data_buf); else descr_len=data_buf[0]-rd_usb_data(data_buf); while(descr_len>0) { toggle_recv(); p+=0x08; issue_token(( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt(); if(status==USB_INT_SUCCESS) /* DATA階段操作成功 */ descr_len-=rd_usb_data(p); else return(0); } } else return(0); endp7_mode=0xc0; toggle_send(); wr_usb_data(0,Request.Req_buf); issue_token(( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt(); if(status==USB_INT_SUCCESS)/* 狀態(tài)階段操作成功 */ return(1); else return(0); } void get() /* 獲取配置描述符 */ { unsigned short i;

Request.Req.bmRequestType=0x80; Request.Req.bRequest=0x06; Request.Req.wValue=0x0002; Request.Req.wIndex=0x0000; Request.Req.wLength=0x0900; if(get_descr_ex()==1) { for(i=0;i!=buffer[0];i++) printf("%02x ",(unsigned int)buffer[i]); printf("\n");

} else printf("get config descr failed\n"); printf("config 2\n"); if(buffer[2]>0x09) {flag_config_1=1; Request.Req.bmRequestType=0x80; Request.Req.bRequest=0x06; Request.Req.wValue=0x0002; Request.Req.wIndex=0x0000; Request.Req.wLength=0x0000|((unsigned int)buffer[2]<<8); if(get_descr_ex()==1) { for(i=0;i!=buffer[2];i++) printf("%02x ",(unsigned int)buffer[i]); printf("\n"); flag_config_1=0; } else printf("get device descr again failed\n"); }


再讀一次是成功了,不過疑問又來了,讀一次端點0,難度就一定要返回8個字節(jié),就不可以是一個字節(jié)?通過修改descr_len也不行嗎?


不是這個意思,在USB協(xié)議里面,你發(fā)下去的控制傳輸?shù)拿罾锩?,最?個字節(jié)是你需要獲取的描述符的長度,如果獲取的描述符的長度是小于實際上傳的長度的話(也就是上面的程序),那么,就直接返回你要取的描述符的長度,如果實際的描述符的長度是小于你要獲取的長度的話,那么,就傳輸實際描述符的長度,實際描述符的長度,對于設(shè)備描述符的長度是開始的第一個字節(jié),配置描述符是描述符的第3個字節(jié)。你如果想獲取一個字節(jié)的描述符也可以啊,直接在你發(fā)送控制傳輸?shù)拿罾锩鎸@取描述符的長度改為01就可以了(80 06 00 02 00 00 01 00)。但是實際的描述符的長度還是實際存在一定的長度,只不過你沒有去獲取完。


endp7_mode=0x80; toggle_send(); wr_usb_data(8,get_ctg_des); //讀配置描述符,0x80,0x06,0x00,0x02,0x00,0x00,0x09,0x00 status=issue_token(( 0 << 4 ) | DEF_USB_PID_SETUP); if(status==USB_INT_SUCCESS)/* SETUP階段操作成功 */ { endp6_mode=0xc0; toggle_recv(); } else return(0); status=issue_token(( 0 << 4 ) | DEF_USB_PID_IN); if(status==USB_INT_SUCCESS)/* DATA階段操作成功 */ rd_usb_data(RECV_BUFFER); get_ctg_des[6]=0x01; toggle_recv(); status=issue_token(( 0 << 4 ) | DEF_USB_PID_IN); if(status==USB_INT_SUCCESS)/* DATA階段操作成功 */ rd_usb_data(RECV_BUFFER); 我修改了長度值成1,但第二次讀出還是8個字節(jié),雖然這8個字節(jié)是前8個字節(jié)的后續(xù)


你看一下get_ctg_des[6]里面的數(shù)據(jù),發(fā)出來看一下!!


0x80,0x06,0x00,0x02,0x00,0x00,0x01,0x00


歸根到底還是對usb協(xié)議不熟悉,各位能不能提供一份usb中文協(xié)議呢?,網(wǎng)上搜到的都是同一版本,里面3個壓縮包,第一個打不開。能找到一份完整的就最好了,謝謝各位的幫助


按照你寫的程序,第一個發(fā)送獲取長度為1字節(jié)的描述符的話,那么,在發(fā)送SETUP包的時候,操作成功,在發(fā)送IN包的時候,應(yīng)該也是成功,這個時候讀取數(shù)據(jù)的時候,數(shù)據(jù)長度為1,在發(fā)送IN的時候,就不應(yīng)該有中斷,你應(yīng)該及時的發(fā)送狀態(tài)包,讓設(shè)備給你返回成功


終于知道原因了,第一次獲取是0x80,0x06,0x00,0x02,0x00,0x00,0xff,0x00,所以讀了ff個字節(jié),第2次0x80,0x06,0x00,0x02,0x00,0x00,0x01,0x00,雖然第二次將長度改成1,但還是將前一次命令讀的都讀出來了。我將第一次長度改了9,之后就正常了,謝謝各位耐心指導(dǎo)


還有一個問題就是你們提供的內(nèi)置固件的程序在調(diào)用toggle_recv和toggle_send之前沒有給endp6_mode和endp7_mode賦初值,那么第一次調(diào)用這兩個函數(shù)時endp6_mode和endp7_mode是等于0的,再調(diào)用就成了0x40了。不知道理解對沒有.但看pdf的介紹只說過0x80和0xc0這兩個值,沒有0和0x40這兩個值。應(yīng)該怎樣理解這兩個變量呢? void toggle_recv(void) /* 主機(jī)接收成功后,切換DATA0和DATA1實現(xiàn)數(shù)據(jù)同步 */ { CH375_WR_CMD_PORT( CMD_SET_ENDP6 ); CH375_WR_DAT_PORT( endp6_mode ); endp6_mode^=0x40; delay2us(); }

void toggle_send(void) /* 主機(jī)發(fā)送成功后,切換DATA0和DATA1實現(xiàn)數(shù)據(jù)同步 */ { CH375_WR_CMD_PORT( CMD_SET_ENDP7 ); CH375_WR_DAT_PORT( endp7_mode ); endp7_mode^=0x40; delay2us(); }


endp6_mode 肯定是有初值的,按照我們提供的例子程序,應(yīng)該是: void toggle_recv( BOOL1 tog ) { /* 主機(jī)接收同步控制:0=DATA0,1=DATA1 */ CH375_WR_CMD_PORT( CMD_SET_ENDP6 ); CH375_WR_DAT_PORT( tog ? 0xC0 : 0x80 ); delay2us(); }

void toggle_send( BOOL1 tog ) { /* 主機(jī)發(fā)送同步控制:0=DATA0,1=DATA1 */ CH375_WR_CMD_PORT( CMD_SET_ENDP7 ); CH375_WR_DAT_PORT( tog ? 0xC0 : 0x80 ); delay2us(); }


同步控制到底是在什么情況下需要做的呢,如何操作呢,375的pdf沒有詳細(xì)說


只有登錄才能回復(fù),可以選擇微信賬號登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频