CH375做為設(shè)備方式,外部固件不能枚舉的問(wèn)題

CH375做為設(shè)備方式,使用外部固件方式,上電后通過(guò)USB線和PC連通,通過(guò)bus hound只攔截到集線器類的命令,PC都沒(méi)有給CH375設(shè)備發(fā)出Get_descriptor,這是什么原因??? 我首先復(fù)位CH375,然后Set_Usb_mode(DEV_Ext_Firmware),這時(shí)就會(huì)有0x07的usb總線復(fù)位狀態(tài)中斷,然后就沒(méi)有中斷發(fā)生了。PC說(shuō)未知設(shè)備。 怎么會(huì)連第一個(gè)Get_descriptor都不出現(xiàn)???? 改為內(nèi)部固件方式時(shí),PC會(huì)發(fā)出Get_descriptor,能夠正確枚舉。

(1)外置固件,需要用戶處理所有的中斷,復(fù)位中斷是如何處理的?接收復(fù)位中斷后,要解鎖 (2)CH372EVT.ZIP中\(zhòng)PUB\XFIRM\C\下有完整C語(yǔ)言示例


有unlock_usb,PC還是不發(fā)送Get_descriptor。 Bus Hound 5.04 capture on Windows XP Service Pack 2. Complements of www.perisoft.net

Device - Device ID (followed by the endpoint for USB devices) (21) USB Root Hub (24) Unknown Device Phase - Phase Type CTL USB control transfer IN Data in transfer Data - Hex dump of the data transferred Descr - Description of the phase Cmd... - Position in the captured data

Device Phase Data Description Cmd.Phase.Ofs(rep) ------ ----- ------------------------ ---------------- ------------------ 21 IN 1.1.0 21.0 CTL a3 00 00 00 01 00 04 00 GET STATUS 2.1.0(2) 21.0 IN 00 01 01 00 .... 2.2.0 21.0 CTL 23 01 10 00 01 00 00 00 CLEAR FEATURE 4.1.0 21.0 CTL a3 00 00 00 01 00 04 00 GET STATUS 5.1.0 21.0 IN 00 01 00 00 .... 5.2.0 21.0 CTL a3 00 00 00 02 00 04 00 GET STATUS 6.1.0 21.0 IN 00 01 00 00 .... 6.2.0 21 IN 7.1.0 21.0 CTL a3 00 00 00 01 00 04 00 GET STATUS 8.1.0(2) 21.0 IN 01 01 01 00 .... 8.2.0 21.0 CTL 23 01 10 00 01 00 00 00 CLEAR FEATURE 10.1.0 21.0 CTL a3 00 00 00 01 00 04 00 GET STATUS 11.1.0(2) 21.0 IN 01 01 00 00 .... 11.2.0 21.0 CTL 23 03 04 00 01 00 00 00 SET FEATURE 13.1.0 21 IN 14.1.0 21.0 CTL a3 00 00 00 01 00 04 00 GET STATUS 15.1.0 21.0 IN 03 01 10 00 .... 15.2.0 21.0 CTL 23 01 14 00 01 00 00 00 CLEAR FEATURE 16.1.0 21.0 CTL a3 00 00 00 01 00 04 00 GET STATUS 17.1.0(3) 21.0 IN 03 01 00 00 .... 17.2.0 21.0 CTL 23 03 04 00 01 00 00 00 SET FEATURE 19.1.0(2) 21 IN 20.1.0(2) 21.0 CTL a3 00 00 00 01 00 04 00 GET STATUS 21.1.0(2) 21.0 IN 03 01 10 00 .... 21.2.0 21.0 CTL 23 01 14 00 01 00 00 00 CLEAR FEATURE 22.1.0(2) 21.0 CTL 23 01 01 00 01 00 00 00 CLEAR FEATURE 28.1.0 21.0 CTL a3 00 00 00 02 00 04 00 GET STATUS 29.1.0 21.0 IN 00 01 00 00 .... 29.2.0 21 IN 30.1.0 21.0 CTL a3 00 00 00 01 00 04 00 GET STATUS 31.1.0(2) 21.0 IN 00 01 01 00 .... 31.2.0 21.0 CTL 23 01 10 00 01 00 00 00 CLEAR FEATURE 33.1.0 21.0 CTL a3 00 00 00 01 00 04 00 GET STATUS 34.1.0 21.0 IN 00 01 00 00 .... 34.2.0 21.0 CTL a3 00 00 00 02 00 04 00 GET STATUS 35.1.0 21.0 IN 00 01 00 00 .... 35.2.0 21 IN 36.1.0 21.0 CTL a3 00 00 00 01 00 04 00 GET STATUS 37.1.0(2) 21.0 IN 01 01 01 00 .... 37.2.0 21.0 CTL 23 01 10 00 01 00 00 00 CLEAR FEATURE 39.1.0 21.0 CTL a3 00 00 00 01 00 04 00 GET STATUS 40.1.0(2) 21.0 IN 01 01 00 00 .... 40.2.0 21.0 CTL 23 03 04 00 01 00 00 00 SET FEATURE 42.1.0 21 IN 43.1.0 21.0 CTL a3 00 00 00 01 00 04 00 GET STATUS 44.1.0 21.0 IN 03 01 10 00 .... 44.2.0 21.0 CTL 23 01 14 00 01 00 00 00 CLEAR FEATURE 45.1.0 21.0 CTL a3 00 00 00 01 00 04 00 GET STATUS 46.1.0(3) 21.0 IN 03 01 00 00 .... 46.2.0 21.0 CTL 23 03 04 00 01 00 00 00 SET FEATURE 48.1.0(2) 21 IN 49.1.0(2) 21.0 CTL a3 00 00 00 01 00 04 00 GET STATUS 50.1.0(2) 21.0 IN 03 01 10 00 .... 50.2.0 21.0 CTL 23 01 14 00 01 00 00 00 CLEAR FEATURE 51.1.0(2) 21.0 CTL 23 01 01 00 01 00 00 00 CLEAR FEATURE 57.1.0 21.0 CTL a3 00 00 00 02 00 04 00 GET STATUS 58.1.0 21.0 IN 00 01 00 00 .... 58.2.0 21 IN 59.1.0 21.0 CTL a3 00 00 00 01 00 04 00 GET STATUS 60.1.0(2) 21.0 IN 00 01 01 00 .... 60.2.0 21.0 CTL 23 01 10 00 01 00 00 00 CLEAR FEATURE 62.1.0 21.0 CTL a3 00 00 00 01 00 04 00 GET STATUS 63.1.0 21.0 IN 00 01 00 00 .... 63.2.0 21.0 CTL a3 00 00 00 02 00 04 00 GET STATUS 64.1.0 21.0 IN 00 01 00 00 .... 64.2.0 都是集線器的命令。


應(yīng)該還是程序上的原因,不妨貼出來(lái)看看


首先一個(gè)就是在你程序一上來(lái)需要延時(shí)50MS以上,然后設(shè)置模式1,這個(gè)時(shí)候主機(jī)就會(huì)發(fā)送相應(yīng)的請(qǐng)求下來(lái).


好的,下面是代碼。CH375_init是正常的,set_usb_mode函數(shù)也是好的,HOST_MODE方式我使用過(guò)。 hid_usb_status_handler( )由外部中斷1處理函數(shù)調(diào)用。 main() { res = CH375_init(); CH375_set_ext_slave_mode(); while(P1_1==0); //檢測(cè)usb線接通,上電 InitInt1(1); }

unsigned char CH375_init( ) { unsigned char i; unsigned char ver;

/* test the ch375 */ for (i=5; i!=0; i--) { CH375_write_cmd(CMD_CHECK_EXIST); CH375_write_data(0x55); ver = CH375_read_data(); // isnt version, assign to ver for test only if ( ver== 0xaa ) { break; } CH375_write_cmd(CMD_RESET_ALL); delay_nms(50); } if(i==0) return 0xff; CH375_write_cmd(CMD_GET_IC_VER); ver = CH375_read_data(); return(ver&~0x80); }

unsigned char CH375_set_usb_mode(unsigned char mode) { CH375_write_cmd(CMD_SET_USB_MODE); delay_1us(); CH375_write_data(mode); delay_nus(40); /* wait operate successfully, less than 20us */ if( CH375_read_data()==CMD_RET_SUCCESS) return 0; else return 0xff; }

uint8 CH375_set_ext_slave_mode() reentrant { return CH375_set_usb_mode(DEVICE_ACTIVE_EXT_FIRMWARE); }

typedef struct _tagEP_STATE { unsigned char ep0_in_busy : 1; unsigned char ep0_in_mutex : 1; unsigned char ep1_in_busy : 1; unsigned char ep1_in_mutex : 1; unsigned char ep2_in_busy : 1; unsigned char ep2_in_mutex : 1; unsigned char * ep0_in_ptr; unsigned char ep0_in_len; unsigned char xdata * ep1_in_ptr; unsigned char ep1_in_len; unsigned char xdata * ep2_in_ptr; unsigned char ep2_in_len; } EP_STATE, * PEP_STATE;

unsigned char enum_state; unsigned char remote_wakeup; unsigned char hid_protocol; unsigned char hid_idle;

SETUP setup; EP_STATE ep_state; uint8 configure_value; unsigned char setup_echo[2]; unsigned char hid_report_data[8];

/* In user code, check device is avalibe and idle using while(ep_state.epx_in_mutex==1); == device has no buffer assigned to transfer. while(ep_state.epx_in_busy==1); == device has no data left in tx buffer. then set ep_state.epx_in_mutex = 1; assign ep_state.epx_in_ptr and ep_state.epx_in_len to fire transfer. */ void usb_transmit(unsigned char no) reentrant { if(no==3 && ep_state.ep0_in_len && ep_state.ep0_in_ptr) { ep_state.ep0_in_busy = 1; if(ep_state.ep0_in_len>8) { CH375_write_usb_data(3, ep_state.ep0_in_ptr, 8); ep_state.ep0_in_ptr += 8; ep_state.ep0_in_len -= 8; } else { CH375_write_usb_data(3, ep_state.ep0_in_ptr, ep_state.ep0_in_len); ep_state.ep0_in_ptr = NULL; ep_state.ep0_in_len = 0; ep_state.ep0_in_mutex = 0; } } else if(no==5 && ep_state.ep1_in_len && ep_state.ep1_in_ptr) { ep_state.ep1_in_busy = 1; if(ep_state.ep1_in_len>8) { CH375_write_usb_data(no, ep_state.ep1_in_ptr, 8); ep_state.ep1_in_ptr += 8; ep_state.ep1_in_len -= 8; } else { CH375_write_usb_data(no, ep_state.ep1_in_ptr, ep_state.ep1_in_len); ep_state.ep1_in_ptr = NULL; ep_state.ep1_in_len = 0; ep_state.ep1_in_mutex = 0; } } else if(no==7 && ep_state.ep2_in_len && ep_state.ep2_in_ptr) { ep_state.ep2_in_busy = 1; if(ep_state.ep2_in_len>64) { CH375_write_usb_data(no, ep_state.ep2_in_ptr, 64); ep_state.ep2_in_ptr += 64; ep_state.ep2_in_len -= 64; } else { CH375_write_usb_data(no, ep_state.ep2_in_ptr, ep_state.ep2_in_len); ep_state.ep2_in_ptr = NULL; ep_state.ep2_in_len = 0; ep_state.ep2_in_mutex = 0; } } else return;

}

void hid_usb_status_handler( ) reentrant { uint8 status, len, req_type, usb_addr; uint8 bDescriptor; uint8 bIndexofwValue;

status = CH375_get_status();

switch(status) { case(USB_INT_EP0_SETUP): { SBUF = '1'; len=CH375_read_usb_data((uint8 xdata * )&setup, 8); if( len != 8 ) { CH375_set_endp(3, ENDP_STALL); break; } setup.wValue = ENDIANADJ(setup.wValue); setup.wIndex = ENDIANADJ(setup.wIndex); setup.wLength = ENDIANADJ(setup.wLength); req_type = setup.bmRequestType & USB_REQUEST_TYPE_MASK; switch(req_type) { SBUF = '2'; case(USB_STANDARD_REQUEST): //setup standard request { //一些請(qǐng)求只有在USB設(shè)備處于特定狀態(tài)時(shí)有效,本實(shí)現(xiàn)沒(méi)有實(shí)現(xiàn)狀態(tài)檢測(cè),由USB主控制器保證 //具體請(qǐng)求的有效狀態(tài)參考相關(guān)資料 SBUF = '3'; switch(setup.bRequest) { SBUF = '4'; //本請(qǐng)求只有USB設(shè)備處于地址狀態(tài)和配置狀態(tài)時(shí)才有效 case(DEF_USB_GET_STATUS): { if(setup.bmRequestType & USB_RECIPIENT_MASK == USB_RECIPIENT_DEVICE) { setup_echo[0]=3; // support self-powered and remote wake up setup_echo[1]=0; CH375_write_usb_data(3, setup_echo, 2); } else if(setup.bmRequestType & USB_RECIPIENT_MASK == USB_RECIPIENT_INTERFACE) { setup_echo[0]=0; //應(yīng)該檢測(cè)接口的有效性,同樣由USB主控制器保證 setup_echo[1]=0; CH375_write_usb_data(3, setup_echo, 2); } else //(ep0.setup.bmRequestType & USB_RECIPIENT_MASK == USB_RECIPIENT_ENDPOINT) { setup_echo[0]=0; // not stoped setup_echo[1]=0; //應(yīng)該檢測(cè)端點(diǎn)的有效性,同樣由USB主控制器保證 CH375_write_usb_data(3, setup_echo, 2); } break; } //本請(qǐng)求只有USB設(shè)備處于地址狀態(tài)和配置狀態(tài)時(shí)才有效 case(DEF_USB_CLR_FEATURE): { if( (setup.bmRequestType & USB_RECIPIENT_MASK == USB_RECIPIENT_ENDPOINT) && setup.wValue == USB_FEATURE_ENDPOINT_STALL ) { if(setup.wIndex==0x01) { CH375_set_endp(4, 0x80); CH375_write_usb_data(3, NULL, 0); } else if(setup.wIndex==0x81) { CH375_set_endp(5, 0x8E); CH375_write_usb_data(3, NULL, 0); } else if(setup.wIndex==0x02) { CH375_set_endp(6, 0x80); //清除端點(diǎn)2下傳 CH375_write_usb_data(3, NULL, 0); } else if(setup.wIndex==0x82) { CH375_set_endp(7, 0x8E); //發(fā)命令清除端點(diǎn) CH375_write_usb_data(3, NULL, 0); } else { CH375_set_endp(3, ENDP_STALL); } } else if( (setup.bmRequestType & USB_RECIPIENT_MASK == USB_RECIPIENT_DEVICE) && setup.wValue == USB_FEATURE_REMOTE_WAKEUP) { remote_wakeup = 0; //清0遠(yuǎn)程喚醒標(biāo)志 CH375_write_usb_data(3, NULL, 0); //返回一個(gè)空的數(shù)據(jù)表示執(zhí)行完畢 } else { CH375_set_endp(3, ENDP_STALL); } break; } case(DEF_USB_SET_FEATURE): { CH375_set_endp(3, ENDP_STALL); break; } //地址的設(shè)定應(yīng)該根據(jù)不同的設(shè)備狀態(tài),本實(shí)現(xiàn)不做檢測(cè),直接設(shè)定,正確性由USB主控制器保證 case(DEF_USB_SET_ADDRESS): { usb_addr=(uint8)setup.wValue; CH375_write_usb_data(3, NULL, 0); CH375_set_usb_addr(usb_addr); break; } case(DEF_USB_GET_DESCR): { bDescriptor = MSB(setup.wValue); //讀取請(qǐng)求的描述符類型 if(setup.bmRequestType & USB_RECIPIENT_MASK == USB_RECIPIENT_DEVICE) { switch(bDescriptor) { case(USB_DEVICE_DESCRIPTOR): { while(ep_state.ep0_in_mutex==1); while(ep_state.ep0_in_busy==1); ep_state.ep0_in_mutex = 1; ep_state.ep0_in_ptr = device_descriptor; ep_state.ep0_in_len = sizeof(DEVICE_DESCRIPTOR_STRUCT); usb_transmit(3); break; } case(USB_CONFIGURATION_DESCRIPTOR): { if (setup.wLength > ENDIANADJ(((pUSB_DESCRIPTOR_STRUCT)config_descriptor)->configuration_descriptor.wTotalLength)) setup.wLength = ENDIANADJ(((pUSB_DESCRIPTOR_STRUCT)config_descriptor)->configuration_descriptor.wTotalLength);


貼出來(lái)程序沒(méi)有層次感了。 一執(zhí)行了Set_usb_mode(EXT_SLAVE),就有中斷產(chǎn)生,返回0x07。以后就再也沒(méi)有中斷了。PC上顯示的未知設(shè)備。


main()函數(shù)后面有個(gè)while(1);是我沒(méi)有貼出來(lái)


(1)CH375_read_data()中若是用CMD_RD_USB_DATA讀取數(shù)據(jù),則不需要再調(diào)用CH375_unlock_usb()解鎖,那么解鎖函數(shù)位置錯(cuò)誤。 (2)建議先用我們的外置固件示例程序調(diào)試,理解整個(gè)流程后再移植,同時(shí)也便于我們分析。


噢 好的,我再修改一下試試。不過(guò)我發(fā)現(xiàn)問(wèn)題在于hid_usb_handler可以進(jìn)入,但是switch語(yǔ)句無(wú)法進(jìn)入。直接調(diào)用軟件仿真,會(huì)出現(xiàn)胡亂跳轉(zhuǎn),會(huì)執(zhí)行兩個(gè)平行的case,可能是編譯器將一個(gè)case的語(yǔ)句優(yōu)化掉了,然后又進(jìn)入另一個(gè)case。


向EP0_IN管道里只寫(xiě)ACK,就是寫(xiě)0個(gè)字節(jié),會(huì)不會(huì)引起EP0_IN中斷?為什么我的程序?qū)慉CK總是會(huì)引起EP0——IN中斷?而你們的代碼的ACK我卻沒(méi)有發(fā)現(xiàn)會(huì)引起中斷?到底是怎么回事?


會(huì)的,釋放一下緩沖區(qū)就可以了.


折騰了一周,自己寫(xiě)的HID設(shè)備的代碼,終于能夠正常枚舉了,CH375還真是夠古怪的,搞一次從設(shè)備外部固件方式的開(kāi)發(fā),簡(jiǎn)直就是下一次地獄。還好,終于摸到CH375的脈門(mén)了。感覺(jué)文檔提供的信息太籠統(tǒng)了。


你好,我現(xiàn)在也在做設(shè)備方式的外部固件的程序,也出現(xiàn)了問(wèn)題,你能把你的程序發(fā)給我,借我看一看嗎?謝謝


我們有個(gè)CH375通過(guò)外部固件模式模擬鼠標(biāo)鍵盤(pán)的例子,可以參考: http://www.findthetime.net/bbs/View.asp?S=101&I=19463


使用CH375的外部固件模式時(shí),單片機(jī)接收到0x0c中斷,EP0成功setup后,使用CH375的RD_USB_DATA命令時(shí),每讀取完一個(gè)字節(jié)后,需解鎖一次

如:

ch375_write_cmd(0x28);

ch375_read_byte(&data);

ch375_write_cmd(0x23);

for(i=0;i<8;i++)

{

????ch375_read_byte(buf+i);

????ch375_write_cmd(0x23);

}

使用以上代碼,可以讀取到主機(jī)發(fā)送的8字節(jié)數(shù)據(jù)80 06 00 01 00 00 40 00


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

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