CH569 USB3.0 BULK出現(xiàn)復(fù)位
UINT32?UVC_EP1_In(void?*p)
{
????UINT8?nump?=?0;
????UINT8?numWait?=?0;
????UINT32?remaindNump?=?0;?????//最后一包數(shù)據(jù)的長度
????static?UINT8?needTransfer?=?DEF_UVC_BURST_MAX;??//最大是4包數(shù)據(jù)

????nump?=?USB30_IN_Nump(ENDP_1);???????//讀出當前已經(jīng)發(fā)出的數(shù)據(jù)包
????if?(nump?>=?DEF_UVC_BURST_MAX)
????{
????????printf("nump?%d?err\r\n",?nump);
????????numWait?=?0;
????????USB30_IN_ClearIT(ENDP_1);
????????return?2;
????}
????else
????{
????????numWait?=?DEF_UVC_BURST_MAX?-?nump;?//計算當前需要發(fā)送的數(shù)據(jù)包
????}

????if?(Iso_Flag_PackHasVideo)??????//有有效數(shù)據(jù)包
????{
????????remaindNump?=?1024;

????????if?((DEF_UVC_BURST_MAX?==?numWait)?||?(needTransfer?==?numWait))????????//數(shù)據(jù)包接收完成
????????{
????????????nump?=?DEF_UVC_BURST_MAX;
????????????Iso_PackSeqNum?+=?DEF_UVC_BURST_MAX;?/*計算當前USB微幀的發(fā)送包數(shù)量*/

????????????if?(Iso_PackSeqNum?>=?Iso_PackTotalNum)?????//全部數(shù)據(jù)包已經(jīng)發(fā)完,一般是45K
????????????{
????????????????UVC_BufInfo.isFull[isFullIndex]?=?0;
????????????????Iso_PackSeqNum?=?0;
????????????????Iso_Flag_PackHasVideo?=?0;
????????????????needTransfer?=?DEF_UVC_BURST_MAX;
????????????????UVC_BufInfo.RemainCount--;
????????????????isStop?=?1;
????????????}
????????????else?if?(Iso_PackSeqNum?+?DEF_UVC_BURST_MAX?>=?Iso_PackTotalNum)
????????????{
????????????????nump?=?Iso_PackTotalNum?-?Iso_PackSeqNum;
????????????????remaindNump?=?Iso_LastPackLen;
????????????}

????????????if?(Iso_PackSeqNum?<?Iso_PackTotalNum)
????????????{
????????????????Iso_Tx_DataAddr?+=?(DEF_UVC_BURST_MAX?<<?10);?//地址每次遞增4k
???????????????
????????????}
????????????needTransfer?=?nump;
????????}
????????else
????????{
????????????if?(numWait?<?DEF_UVC_BURST_MAX)????????//如果4包數(shù)據(jù)沒有發(fā)完,則重新計算需要發(fā)送的包數(shù)
????????????{
????????????????nump?=?DEF_UVC_BURST_MAX?-?numWait;
????????????????needTransfer?=?nump;
????????????}
????????????else
????????????{
????????????????nump?=?needTransfer;
????????????}
????????}

????????USBSS->UEP1_TX_DMA?=?Iso_Tx_DataAddr;
????????USB30_IN_ClearIT(ENDP_1);
????????if?(isStop?==?1)
????????{
????????????USB30_IN_Set(ENDP_1,?ENABLE,?NRDY,?0,?0);?//整包數(shù)據(jù)完成,發(fā)送NRDY
????????}
????????else
????????{
????????????USB30_IN_Set(ENDP_1,?ENABLE,?ACK,?nump,?remaindNump);
????????????USB30_Send_ERDY(ENDP_1?|?IN,?nump);
????????}
????}
????return?0;
}

//該函數(shù)在main中運行
void?UVC_Start_transform(UINT8?idx)
{
????UINT32?packNum?=?DEF_UVC_BURST_MAX;
????UINT32?lastLen?=?1024;

????if?(isStop?==?1)
????{
????????Iso_Flag_PackHasVideo?=?0x01;
????????Iso_PackTotalNum?=?UVC_BufInfo.Length[idx]?>>?10;???//計算包個數(shù)
????????Iso_LastPackLen?=?UVC_BufInfo.Length[idx]?&?0x3FF;??//計算最后一包數(shù)據(jù)的長度
????????UVC_BufInfo.Length[idx]?=?0;

????????Iso_Tx_DataAddr?=?(UINT32)UVC_USBDMA_Addr[idx];?????//切換地址

????????if?(Iso_LastPackLen)
????????{
????????????Iso_PackTotalNum++;
????????}
????????else
????????{
????????????Iso_LastPackLen?=?1024;
????????}

????????if?(Iso_PackTotalNum?<=?DEF_UVC_BURST_MAX)??????//總共不足4包
????????{
????????????packNum?=?Iso_PackTotalNum;
????????????lastLen?=?Iso_LastPackLen;
????????}

????????if?((packNum?==?0)?||?(lastLen?==?0))
????????{
????????????printf("start?err\r\n");
????????????isStop?=?1;
????????????return;
????????}

????????HSPI_Signal_RxReady();??????//拉GPIO

????????isStop?=?0;
????????inEp1_IRQ?=?0;
????????USBSS->UEP1_TX_DMA?=?Iso_Tx_DataAddr;????????????????//DMA地址偏移?需重重置
????????USB30_IN_Set(ENDP_1,?ENABLE,?ACK,?packNum,?lastLen);
????????USB30_Send_ERDY(ENDP_1?|?IN,?packNum);

????????UVC_dotTick?=?UVC_dotTick?/?2;
????????if?((UVC_dotTick?<?33)?&&?(UVC_dotTick?!=?0))???????//每幀圖像間延遲
????????{
????????????mDelaymS(33?-?UVC_dotTick);
????????????UVC_dotTick?=?0;
????????}
????}
}



可以在所有調(diào)用以下兩個函數(shù)的地方,在之前將包數(shù)量和長度打印出來監(jiān)控下,是否有意外的情況。

以及是否存在連續(xù)調(diào)用的情況,這是不被允許的。

或者調(diào)用之后,還沒有進入IN_Callback就意外調(diào)用IN_ClearIT,導(dǎo)致芯片狀態(tài)異常

image.png

其次,要注意數(shù)據(jù)本身是否復(fù)合相關(guān)協(xié)議對格式、收發(fā)數(shù)量和速度的要求,可能無法上傳是因為上位機主動停止了。

可以借助bus hound來看下是否有錯誤信息,可能可以根據(jù)bus hound顯示的信息在網(wǎng)上找到一些相關(guān)的信息。

測試該類問題的時候,應(yīng)當想辦法規(guī)避上位機問題,確保上位機一直在請求數(shù)據(jù),使用libusb直接加載該設(shè)備是比較合適的方法。


我這個是攝像頭設(shè)備,讀數(shù)據(jù)是從PC上直接打開攝像頭測試的,所以上位機應(yīng)該是沒問題。


在發(fā)送NRDY時包數(shù)和數(shù)據(jù)長度是0沒關(guān)系吧?其他的我再看看

image.png



攝像頭屬于UVC類,是比較復(fù)雜的class,數(shù)據(jù)流有一定的格式要求,存在時間戳、幀號等概念,都要保證不能出錯。

應(yīng)答狀態(tài)為NRDY時,包數(shù)量和長度不被關(guān)心。
需要注意當前端點配置,是被配置位同步傳輸端點還是批量傳輸端點:

void USB30_ISO_Setendp(UINT8 num,FunctionalState Status );


image.png

1、這個是我抓的log,程序連續(xù)運行到6406秒以后USB數(shù)據(jù)就沒有中斷觸發(fā)了,主機在請求RESET,在這以前沒有出現(xiàn)過重復(fù)調(diào)用IN_set、數(shù)據(jù)長度為0的情況。

2、IN_ClearIT只有在UVC_EP1_In函數(shù)中調(diào)用,這個是中斷的回調(diào)函數(shù),也只會在中斷觸發(fā)后運行。

3、初始化時沒有調(diào)USB30_ISO_Setendp,這樣就是BULK傳輸端點了吧。而且在描述符里設(shè)置的也是BULK傳輸

4、如果這個問題避免不了,有沒有什么接口可以自動恢復(fù)通訊?


根據(jù)USB3.0 SPEC,主機在某種情況下會出現(xiàn)放棄ERDY的情況,可以根據(jù)tERDYTimeout,超時后,通過重新發(fā)送ERDY來嘗試恢復(fù)通訊。

image.png


這個超時判斷和重發(fā)ERDY用什么接口呢?


可以自行設(shè)計,這個超時不是非常嚴格500毫秒。


1、我試了超時600ms重發(fā)ERDY,無法恢復(fù)通訊。然后試著在超時后加了RESET USB才能恢復(fù),這樣就類似于USB斷線重連,這樣實際使用中也不能這樣。是否有其他辦法呢?

2、我在用bushound抓數(shù)據(jù)時還發(fā)現(xiàn)偶爾數(shù)據(jù)會亂掉,但是很快自動就正常了,如下圖。出現(xiàn)USB無法發(fā)出數(shù)據(jù)和這個是否有關(guān)呢?

image.png



已解決


現(xiàn)在通訊中斷的問題解決了,但是還是會出現(xiàn)丟數(shù)據(jù)的情況,如25樓中貼出來的bushound抓到的數(shù)據(jù)。這個在部分PC上出現(xiàn)的概率更高。我通過測試(發(fā)送特定有規(guī)律的數(shù)據(jù)),出現(xiàn)這種情況是某次傳輸沒有將4k數(shù)據(jù)發(fā)完,這樣就造成數(shù)據(jù)錯亂。請問,這個要怎么規(guī)避


看截圖,似乎是多個長度460800byte的傳輸,怎么大數(shù)據(jù)量的傳輸多半還是代碼邏輯上的問題。重點監(jiān)控IN_CALLBACK進入次數(shù)吧


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

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