電腦重啟后,但注冊(cè)的HID設(shè)備沒有重啟,導(dǎo)致設(shè)備失效不能工作,請(qǐng)問(wèn)如何解決?

我的芯片用的是CH549L,注冊(cè)成HID設(shè)備下的第0x0C項(xiàng)consumer類型應(yīng)用。目的是通過(guò)旋鈕調(diào)節(jié)電腦音量。

正常使用都沒有問(wèn)題。但是有一個(gè)BUG是,部分時(shí)候電腦關(guān)機(jī)以后重啟,這時(shí)候設(shè)備就不能工作了,必須要重新插拔一下HID設(shè)備才行。

通過(guò)大量測(cè)試后初步判斷,是因?yàn)殡娔X重啟時(shí),整個(gè)過(guò)程中電腦的USB口沒有斷電,以至于重新開機(jī)以后,HID設(shè)備并沒有重啟。電腦這邊枚舉的USB設(shè)備的數(shù)據(jù)已經(jīng)清空了,但是我這個(gè)HID設(shè)備卻還記著之前枚舉的信息,這時(shí)候電腦沒有檢測(cè)到重新插入的USB設(shè)備的信號(hào),就不會(huì)自動(dòng)的重新枚舉。導(dǎo)致舊的信息不能用了,以至于失效。

我嘗試了一個(gè)簡(jiǎn)單的辦法,就是人工判斷設(shè)備失效以后,按一下一下我的板上的一個(gè)按鈕,然后在程序里直接goto到程序的最開始,直接重新初始化,但是不能夠解決這個(gè)問(wèn)題。

所以我想問(wèn)問(wèn),有沒有什么能夠檢測(cè)到USB通信失效了的變量啊之類的?還有檢測(cè)到失效以后,又如何通過(guò)軟件重新讓電腦枚舉我的設(shè)備?

----------------------------

我的代碼主要修改自給的demo代碼里面的“CompositeKM.C”文件。上面附上我的描述符,USB中斷服務(wù)函數(shù)沒敢改。

/*設(shè)備描述符*/

UINT8C DevDesc[] = {

? ? 0x12, ?// bLength。描述符長(zhǎng)度(18字節(jié),十六進(jìn)制為0x12),就是標(biāo)志描述符數(shù)據(jù)結(jié)構(gòu)的長(zhǎng)度。

? ? 0x01, ?// bDescriptorType。描述符類型。0x01為設(shè)備描述符

? ? 0x00,0x02, ?// bcdUSB。設(shè)備使用的USB協(xié)議版本。表示形式0xJJMN版本JJ.M.N(JJ-主要版本號(hào),M-次要版本號(hào),N-次要版本)。

? ? ? ? ? ? ? ? // 例子:如果是USB2.0,寫成:0200H。如果是USB1.1,寫成。0110H 如果是USB3.11,寫成:0311H。

? ? ? ? ? ? ? ? // 注意是小端模式,所以低字節(jié)寫在前面

? ? 0x00, ?// bDeviceClass。類代碼。表示設(shè)備類型。為0時(shí)指示用接口描述符來(lái)標(biāo)識(shí)類別。詳見https://www.usb.org/defined-class-codes

? ? 0x00, ?// bDeviceSubClass。子類型。

? ? 0x00, ?// bDeviceProtocol。設(shè)備使用的協(xié)議。

? ? THIS_ENDP0_SIZE, ?// bMaxPackeSize0。端點(diǎn)一次最大傳多少個(gè)字節(jié)。

? ? 0x86,0x1a, ?// idVender。廠商ID。

? ? 0xe1,0xe6, ?// idProduct。產(chǎn)品ID。

? ? 0x00,0x01, ?// bcdDevice。產(chǎn)品版本號(hào)。

? ? 0x01, ?// iManufacturer。描述廠商的字符串的索引。

? ? 0x02, ?// iProduct。描述產(chǎn)品的字符串的索引。

? ? 0x00, ?// iSerialNumber。描述產(chǎn)品序列號(hào)字符串的索引.

? ? 0x01 ?// bNumConfigurations。指示設(shè)備有多少個(gè)配置

? ? };


/*字符串描述符*/

// 語(yǔ)言ID描述符

UINT8C ?MyLangDescr[] = {

? ? 0x04, ?// bLength。描述符長(zhǎng)度。

? ? 0x03, ?// bDescriptorType。描述符類型。語(yǔ)言ID描述符也是字符串描述符,類型為0x03。

? ? 0x09, 0x04 ?// wLANGID[0]。要支持的語(yǔ)言ID號(hào)。

? ? // wLANGID[n]。有可能會(huì)支持多種語(yǔ)言。但是這里沒寫了。

? ? };

// 廠家信息描述符

UINT8C ?MyManuInfo[] = {

? ? 0x0E, ?// bLength。描述符長(zhǎng)度。

? ? 0x03, ?// bDescriptorType。描述符類型。字符串描述符類型為0x03。

? ? 'C', 0, 'S', 0, 'Y', 0, '.', 0, 'U', 0, 'S', 0, 'B', 0 ?// bString。UNICODE編碼的字符串。

? ? };

// 產(chǎn)品信息描述符

UINT8C ?MyProdInfo[] = {

? ? 0x0C, ?// bLength。描述符長(zhǎng)度。

? ? 0x03, ?// bDescriptorType。描述符類型。字符串描述符類型為0x03。

? ? 'A', 0, 'u', 0, 'd', 0, 'i', 0, 'o', 0 ?// bString。UNICODE編碼的字符串。

? ? };


/*HID類報(bào)表描述符*/

UINT8C ConsumerRepDesc[] =

{

? ? 0x05,0x0C, ?// Usage Page (Consumer)

? ? 0x09,0x01, ?// Usage(Consumer Control)

? ? 0xA1,0x01, ?// Collection (Application), ? ? ? ? ? ? ? ?Main Items —— Collection —— Application

? ? ? ? 0x15,0x00, ?// Logical Minimum (0), ? ? ? ? ? ? ? ? ? ? Global Items —— Logical Minimum —— 0

? ? ? ? 0x25,0x01, ?// Logical Maximum (1), ? ? ? ? ? ? ? ? ? ? Global Items —— Logical Maximum —— 1

? ? ? ? 0x75,0x01, ?// Report Size (1), ? ? ? ? ? ? ? ? ? ? ? ? Global Items —— Report Size —— 1

? ? ? ? 0x95,0x01, ?// Report Count (1), ? ? ? ? ? ? ? ? ? ? ? ?Global Items —— Report Count —— 1


? ? ? ? 0x09,0xCD, ?// Usage(Play/Pause),開始暫停

? ? ? ? 0x81,0x06, ?// Input (Data, Value, Relative),

? ? ? ? 0x09,0xB5, ?// Usage(Scan Next Track),下一曲

? ? ? ? 0x81,0x06, ?// Input (Data, Value, Relative),

? ? ? ? 0x09,0xB6, ?// Usage(Scan Previous Track),上一曲

? ? ? ? 0x81,0x06, ?// Input (Data, Value, Relative),

? ? ? ? 0x09,0xE2, ?// Usage(Mute),靜音

? ? ? ? 0x81,0x06, ?// Input (Data, Value, Relative),

? ? ? ? 0x09,0xE9, ?// Usage(Volume Increment),音量+

? ? ? ? 0x81,0x06, ?// Input (Data, Value, Relative),

? ? ? ? 0x09,0xEA, ?// Usage(Volume Decrement),音量-

? ? ? ? 0x81,0x06, ?// Input (Data, Value, Relative),

? ? ? ? 0x09,0xB3, ?// Usage(Fast Forward),快進(jìn)

? ? ? ? 0x81,0x02, ?// Input (Data, Value, Absolute),

? ? ? ? 0x09,0xB4, ?// Usage(Rewind),倒帶

? ? ? ? 0x81,0x02, ?// Input (Data, Value, Absolute),



? ? 0xC0 ?// End Collection, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Main Items —— End Collection

};


/*配置描述符集合(必須按照順序)*/

UINT8C CfgDesc[] =

{

? ? // 標(biāo)準(zhǔn)配置描述符

? ? 0x09, ?// bLength。配置本描述符的長(zhǎng)度。

? ? 0x02, ?// bDescriptorType。描述符類型。配置描述符為0x02。

? ? 0x3b,0x00, ?// wTotalLength。配置描述符集合總長(zhǎng)度。

? ? 0x01, ?// bNumInterfaces。當(dāng)前配置下面有多少個(gè)接口。

? ? 0x01, ?// bConfigurationValue。當(dāng)前配置的標(biāo)識(shí)。一個(gè)USB設(shè)備可能有多個(gè)配置,但是當(dāng)前只能選擇一種配置。

? ? 0x00, ?// iConfiguration。描述該配置的字符串的索引值。如果沒有字符串,那這個(gè)值就是0。

? ? 0xE0, ?// bmAttributes。在這個(gè)配置下,設(shè)備的一些特性。

? ? ? ? ? ? ? ? // D7是保留位,默認(rèn)為1;

? ? ? ? ? ? ? ? // D6表示供電方式,0是自供電,1是總線供電;

? ? ? ? ? ? ? ? // D5表示是否支持遠(yuǎn)程喚醒,為1表示設(shè)備支持遠(yuǎn)程喚醒;

? ? ? ? ? ? ? ? // D4~D0保留,默認(rèn)為0。

? ? 0x32, ?// bMaxPower。配置設(shè)備需要的電流。單位是2ma。如果一個(gè)設(shè)備耗電量100ma,那么本字節(jié)設(shè)置為0x32即可。


? ? // 接口描述符(Consumer)

? ? 0x09, ?// bLength。配置本描述符的長(zhǎng)度。

? ? 0x04, ?// bDescriptorType。描述符類型。接口描述符為0x04。

? ? 0x00, ?// bInterfaceNumber。接口編號(hào)。如果一個(gè)配置有多個(gè)接口的話,那么每個(gè)接口的編號(hào)都有一個(gè)獨(dú)立的編號(hào),編號(hào)從0開始遞增。

? ? 0x00, ?// bAlternateSetting。備用接口編號(hào)。一般很少用,設(shè)置為0。

? ? 0x01, ?// bNumEndpoints。該接口使用的端點(diǎn)個(gè)數(shù)。

? ? 0x03, ?// bInterfaceClass。接口類。當(dāng)設(shè)備描述符設(shè)備類型bDeviceClass為0時(shí),也就是指示用接口描述符來(lái)標(biāo)識(shí)類別。

? ? 0x01, ?// bInterfaceSubClass。接口子類。

? ? 0x01, ?// bInterfaceProtocol。接口協(xié)議。

? ? 0x00, ?// iInterface。此接口的字符串索引值。沒有的話一般為0.

? ?

? ? // HID類描述符

? ? 0x09, ?// bLength。配置本描述符的長(zhǎng)度。

? ? 0x21, ?// bDescriptorType。描述符類型。HID描述符為0x21。

? ? 0x11,0x01, ?// bcdHID。HID設(shè)備所遵循的HID版本號(hào),為4位16進(jìn)制的BCD碼。1.0即0x0100,1.1即0x0101,2.0即0x0200。

? ? 0x00, ?// bCountryCode。HID設(shè)備國(guó)家/地區(qū)代碼。

? ? 0x01, ?// bNumDescriptor。HID設(shè)備支持的下級(jí)描述符的數(shù)量。由于HID設(shè)備至少需要包括一個(gè)報(bào)告描述符,故其值至小為0x01,一般的HID設(shè)備也為1,也就是有一個(gè)報(bào)告描述符,物理描述符很少用到。

? ? 0x22, ?// bDescriptorTyep。下級(jí)描述符的類型。下級(jí)描述符第1個(gè)必須是報(bào)告描述符,所以這里存放報(bào)告描述符類型,報(bào)告描述符的類型為0x22。

? ? sizeof(ConsumerRepDesc)&0xFF,sizeof(ConsumerRepDesc)>>8, ?// wDescriptorLength。下級(jí)描述符的長(zhǎng)度

? ?

? ? // 端點(diǎn)描述符(Consumer)

? ? 0x07, ?// bLength。配置本描述符的長(zhǎng)度。

? ? 0x05, ?// bDescriptorType。描述符類型。端點(diǎn)描述符為0x05。

? ? 0x81, ?// bEndpointAddress。

? ? ? ? ? ? ? ? // Bit 3…0: 端點(diǎn)編號(hào);

? ? ? ? ? ? ? ? // Bit 6…4: 保留,默認(rèn)為0;

? ? ? ? ? ? ? ? // Bit 7:如果是控制端點(diǎn)可以忽略,因?yàn)榭刂贫它c(diǎn)有兩個(gè)方向,否則一般表示數(shù)據(jù)傳輸方向,0 = OUT endpoint ? 1 = IN endpoint。

? ? 0x03, ?// bmAttributes。Bits 1..0: 表示傳輸類型

? ? ? ? ? ? ? ? // 00 = Control-控制傳輸

? ? ? ? ? ? ? ? // 01 = Isochronous-同步傳輸

? ? ? ? ? ? ? ? // 10 = Bulk-批量傳輸

? ? ? ? ? ? ? ? // 11 = Interrupt-中斷傳輸

? ? ? ? ? ? ? ? // Bits 7..2: 還沒講

? ? ENDP1_IN_SIZE,0x00, ?// wMaxPackeSize(雙字節(jié))。表示當(dāng)前配置下此端點(diǎn)能夠接收或發(fā)送的最大數(shù)據(jù)包的大小。

? ? 0x0a ?// bInterval。查詢時(shí)間。就是主機(jī)多久和設(shè)備通訊一次。低速和全速稱為幀,一個(gè)值代表1ms。高速稱為微幀,一個(gè)值代表125us。

};


有幾個(gè)還需要確認(rèn)的點(diǎn):1、可以在USB中斷函數(shù)中處理控制傳輸(回傳描述符)的地方加個(gè)printf,看一下在開機(jī)時(shí)電腦是否有做枚舉,通常電腦重啟之后會(huì)重新枚舉的。

2、在相同電腦環(huán)境下,其余的鍵盤鼠標(biāo)能不能正常工作,是否有條件對(duì)USB數(shù)據(jù)線進(jìn)行抓包,看一下關(guān)機(jī)到開機(jī)這個(gè)過(guò)程中您的代碼行為和鍵鼠行為的差異。

3、你說(shuō)的當(dāng)出現(xiàn)這種問(wèn)題的時(shí)候goto到開頭重新運(yùn)行,需要先將USB_CTRL清零,延時(shí)一會(huì),在做USB的初始化,目的是撤銷數(shù)據(jù)線上的上拉電阻,然后重新生效。此時(shí)是否能夠正常工作起來(lái)。


4、解決這個(gè)問(wèn)題,可以嘗試使用SOF中斷,通常電腦關(guān)機(jī)后總線會(huì)處于掛起,USB中斷中會(huì)進(jìn)入suspend,以這個(gè)時(shí)間節(jié)點(diǎn)等后續(xù)是否有SOF中斷,如果超過(guò)若干SOF周期還是沒有產(chǎn)生SOF中斷,可以判斷電腦處于關(guān)掉或者不和你通訊的狀態(tài),這個(gè)時(shí)候可以嘗試執(zhí)行3中的操作。具體邏輯可以測(cè)試后修改。


遇到了同樣的問(wèn)題,官方源碼坑好多,難趟啊


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

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