關(guān)于CH376作HOST的問題請教

最近幾天正在學(xué)習(xí)CH376T模塊,因任務(wù)需要,要實現(xiàn)作為HOST需要和CDC類設(shè)備進(jìn)行通信;作為Device能和電腦進(jìn)行數(shù)據(jù)往來。使用硬件SPI與CH376進(jìn)行控制。首先,在進(jìn)行驗證CH376作為HOST時,設(shè)置的為主機(jī)模式6,已經(jīng)能夠正常通過EP0端點收到并成功分析和保存了各種描述符信息,也將CDC設(shè)備的數(shù)據(jù)收/發(fā)接口的端點進(jìn)行保存。然后是嘗試進(jìn)行往CDC設(shè)備發(fā)送數(shù)據(jù),發(fā)送函數(shù)摘自打印機(jī)例程,代碼如下

void send_data( uint8_t len, uint8_t *buf )
{ ?
?? ?uint8_t l, s;
?? ?while( len ) ???????? /* 連續(xù)輸出數(shù)據(jù)塊給USB打印機(jī) */

????{
?? ??? ?toggle_send( tog_send );? ????????? /* 數(shù)據(jù)同步 */
?? ??? ?l = len>endp_out_size?endp_out_size:len;????? /* 單次發(fā)送不能超過端點尺寸 */
?? ??? ?WR_USB_DATA( l, buf );? ????????????/* 將數(shù)據(jù)先復(fù)制到CH375芯片中 */
?? ??? ?issue_token( 0X40, ( endp_out_addr << 4 ) | DEF_USB_PID_OUT );?? //endp_out_addr = 0x03 ???
?? ??? ?s = wait_interrupt();? ??????????????? ? /* 請求CH375輸出數(shù)據(jù) */
?? ??? ?if ( s == USB_INT_SUCCESS )????? /* CH375成功發(fā)出數(shù)據(jù) */
?? ??? ?{ ?
?? ??? ??? ?tog_send = ~ tog_send;???????? /* 切換DATA0和DATA1進(jìn)行數(shù)據(jù)同步 */
?? ??? ??? ?len-=l;? ?????????????????????????????????? /* 計數(shù) */
?? ??? ??? ?buf+=l;? ????????????????????????????????? /* 操作成功 */
?? ??? ?}
?? ??? ?else if ( s== 0x2A)
?? ??? ?{? /* USB打印機(jī)正忙,如果未執(zhí)行SET_RETRY命令則CH375自動重試,所以不會返回USB_INT_RET_NAK狀態(tài) */
?? ??? ??? ?/* USB打印機(jī)正忙,正常情況下應(yīng)該稍后重試 */
?? ??? ??? ?/* s=get_port_status( );? 如果有必要,可以檢查是什么原因?qū)е麓蛴C(jī)忙 */
?? ??? ??? ?printf("USB is Busy\r\n");
?? ??? ?}
?? ??? ?else ????????????????/* 操作失敗,正常情況下不會失敗 */
?? ??? ?{?
?? ??? ??? ?clr_stall( endp_out_addr );????????? /* 清除打印機(jī)的數(shù)據(jù)接收端點,或者 soft_reset_print() */
/*?? ??? ??? ?soft_reset_print();? 打印機(jī)出現(xiàn)意外錯誤,軟復(fù)位 */

????????????tog_send = 0;? ????????????????????????????/* 操作失敗 */


?? ??? ???? CH376_WriteCmd(CMD_UNLOCK_USB);??????? //此行為我自行添加,猜測當(dāng)前端點的緩存區(qū)未被釋放?

?? ??? ????
?? ??? ?//?? ?printf("USB never Back data, and over time\r\n");
?? ??? ?}
/* 如果數(shù)據(jù)量較大,可以定期調(diào)用get_port_status()檢查打印機(jī)狀態(tài) */
?? ?}
}

遇到的問題:

1、往發(fā)送端點發(fā)送數(shù)據(jù),中斷查詢返回一直為0x28的數(shù)據(jù),請問通常遇到此類通信錯誤的問題,解決的點在哪?

2、另外的疑惑,在命令列表中,有看到端點0、端點1和端點2的相關(guān)設(shè)置命令,對于其他端點的操作該如何進(jìn)行?

3、對于端點的發(fā)送數(shù)據(jù),都提到了端點數(shù)據(jù)同步的命令操作,但對于命令,也僅設(shè)計涉及到端點0、端點1、端點2,對設(shè)備其他的端點,如端點3,該怎么進(jìn)行數(shù)據(jù)同步?

發(fā)送的數(shù)據(jù)通過BUS HOUND抓取自CDC的設(shè)備,為上位機(jī)與設(shè)備的握手?jǐn)?shù)據(jù)。



你好:

  1. ?一般返回“0x28”,表示設(shè)備沒有應(yīng)答響應(yīng),那么有以下幾種原因:

    -> 你發(fā)的命令有問題,不在可接受范圍(一般應(yīng)該返回 0x2e STALL)

    -> 發(fā)送數(shù)據(jù)的端點號寫錯了,不是設(shè)備的端點

    -> 你 發(fā)送的端點已關(guān)閉或異常,需要恢復(fù),要發(fā)響應(yīng)命令。

    自己先找下原因,分清處于什么情況。

  2. 你看到的命令列表如果有寫端點0/1/2,那么肯定是USB設(shè)備模式的命令,主機(jī)模式下只有一組端點(上傳和下傳),發(fā)送數(shù)據(jù)要填寫發(fā)送給設(shè)備的端點號,自己填入的。你描述中的"endp_out_addr"

  3. 不知道你說是數(shù)據(jù)同步指的什么?如果是DATA0和DATA1這種的話,和端點號是沒有關(guān)系的。


你好:


另外“CH376_WriteCmd(CMD_UNLOCK_USB);??”這是設(shè)備模式的命令,不要和主機(jī)命令混用。

命令參考CH376DS1、CH376DS2 數(shù)據(jù)手冊,沒有的命令不要用。



邏輯分析儀抓的發(fā)送數(shù)據(jù)如下圖

圖片.png

圖片.png

圖一發(fā)送的數(shù)據(jù)能對應(yīng)上,發(fā)送端點能對應(yīng)上 0x03? OUT。圖二bmRequestType = 0x02,到端點;Data direction = NO data; Type = Standard, Recipient = Endpoint。


非常謝謝您的解答。



解決了查詢中斷回復(fù)0x28的問題,原因是在分析各描述符過程中給CH376配置了一個錯誤的地址,重新設(shè)置地址為0后,主機(jī)查詢中斷返回0x14,應(yīng)該能夠正常發(fā)送。

感謝技術(shù)大佬的解疑。

此外,我使用的是硬件SPI作主機(jī)控制CH376,CDC設(shè)備使用的是串口轉(zhuǎn)USB的控制方式,請問是否也需要將CH376設(shè)置波特率?


?你好:


你這操作不對吧,一把上電后,

  1. 總線復(fù)位;

  2. 主機(jī)以地址0,端點0,要設(shè)備描述符,得到端點0的最大包大小;

  3. 分配設(shè)備地址X;

  4. 之后主機(jī)都以地址X和設(shè)備通訊

所以,你到現(xiàn)在還再以地址0通訊,那么前面肯定步驟有問題。

建議參考例程?http://wch.cn/public/uploads/file/20170407/1491551116488367.rar CH376操作CH341設(shè)備看看流程是怎么做的。



此外,我使用的是硬件SPI作主機(jī)控制CH376,CDC設(shè)備使用的是串口轉(zhuǎn)USB的控制方式,請問是否也需要將CH376設(shè)置波特率?”?

這個問題,CH376和你的CDC不是USB通訊嗎?哪里涉及到波特率了(串口)?如果你要控制CDC設(shè)備的另外一端串口收發(fā)波特率改變,肯定是需要CH376通過USB口配置CDC的。



是的,之前的步驟確實有誤,在設(shè)置USB地址時只進(jìn)行了主機(jī)地址的設(shè)置,從機(jī)地址并未設(shè)置,導(dǎo)致后面出現(xiàn)0x28?,F(xiàn)在將主機(jī)和從機(jī)的地址都設(shè)置后,再進(jìn)行發(fā)送,并未出現(xiàn)中斷異常的狀況,但設(shè)備仍未進(jìn)行響應(yīng)。已經(jīng)在串口調(diào)試助手驗證過發(fā)送的命令能夠得到設(shè)備響應(yīng)。邏輯分析儀抓包有OUT事務(wù),但從抓的包上看,發(fā)送的端點和數(shù)據(jù)都能匹配上,但地址仍是0x00。

我的程序步驟:

????->連接設(shè)備,獲得設(shè)備描述符

????->設(shè)置地址 0x05,復(fù)位

????->獲取配置描述符,取得配置描述符的長度,再次獲取設(shè)備描述符,分析保存 端點號

????->開始發(fā)送數(shù)據(jù)


圖片.png

上圖邏輯分析儀抓的發(fā)送包,發(fā)現(xiàn)Address仍是0x00,這是地址沒被修改成功嗎?

程序的步驟中有將得到的配置描述符中的bConfigurationValue值進(jìn)行配置。


圖片.png

上圖是設(shè)置地址抓取的數(shù)據(jù),設(shè)置地址0x05


另外,寫了一個接收函數(shù),在CDC設(shè)備設(shè)置重復(fù)發(fā)送數(shù)據(jù)。遇到的現(xiàn)象是寫入接收同步控制能夠返回0x00,ACK就緒,但再往下發(fā)出同步令牌的OUT事務(wù)后,得不到CH376的INT中斷的響應(yīng),引腳一直是高電平狀態(tài)。

uint8_t receive_data(uint8_t *buf)
{
?? ?uint8_t s, len;
?? ?uint8_t tog = 0;
?? ?uint8_t recv_flag = 1;
?? ?
?? ?while(recv_flag)
?? ?{
?? ??? ?toggle_recev(tog);
?? ??? ?issue_token(0x80, (endp_in_addr << 4)| DEF_USB_PID_IN);?? ?//endp_in_addr 0x81
?? ??? ?s = wait_interrupt();
?? ??? ?printf("status is 0x%02x\r\n",s);
?? ??? ?if(s == USB_INT_SUCCESS)
?? ??? ?{
?? ??? ??? ?len = RD_USB_DATA(buf);
?? ??? ??? ?clr_stall( endp_in_addr );
?? ??? ??? ?recv_flag = 0;
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?tog = ~tog;
?? ??? ?//?? ?soft_reset_cdc( );
?? ??? ??? ?clr_stall( endp_in_addr );
?? ??? ??? ?recv_flag = 0;
?? ??? ?}
?? ?}
?? ?return len;
}
CDC設(shè)備中的中斷端點為0x82,這會對接收產(chǎn)生沖突?下面是CDC設(shè)備的部分描述符

??? /*Union Functional Descriptor*/
??? 0x05,?? /* bFunctionLength */
??? 0x24,?? /* bDescriptorType: CS_INTERFACE */
??? 0x06,?? /* bDescriptorSubtype: Union func desc */
??? 0x00,?? /* bMasterInterface: Communication class interface */
??? 0x01,?? /* bSlaveInterface0: Data Class Interface */

??? /*Endpoint 2 Descriptor*/
??? 0x07,?? /* bLength: Endpoint Descriptor size */
??? USB_ENDPOINT_DESCRIPTOR_TYPE,?? /* bDescriptorType: Endpoint */
??? 0x82,?? /* bEndpointAddress: (IN2) */
??? 0x03,?? /* bmAttributes: Interrupt */
??? VIRTUAL_COM_PORT_INT_SIZE,????? /* wMaxPacketSize: */
??? 0x00,
??? 0xFF,?? /* bInterval: */

/*Data class interface descriptor*/
??? 0x09,?? /* bLength: Endpoint Descriptor size */
??? USB_INTERFACE_DESCRIPTOR_TYPE,? /* bDescriptorType: */
??? 0x01,?? /* bInterfaceNumber: Number of Interface */
??? 0x00,?? /* bAlternateSetting: Alternate setting */
??? 0x02,?? /* bNumEndpoints: Two endpoints used */
??? 0x0A,?? /* bInterfaceClass: CDC */
??? 0x00,?? /* bInterfaceSubClass: */
??? 0x00,?? /* bInterfaceProtocol: */
??? 0x00,?? /* iInterface: */
??? /*Endpoint 3 Descriptor*/
??? 0x07,?? /* bLength: Endpoint Descriptor size */
??? USB_ENDPOINT_DESCRIPTOR_TYPE,?? /* bDescriptorType: Endpoint */
??? 0x03,?? /* bEndpointAddress: (OUT3) */
??? 0x02,?? /* bmAttributes: Bulk */
??? VIRTUAL_COM_PORT_DATA_SIZE,???????????? /* wMaxPacketSize: */
??? 0x00,
??? 0x00,?? /* bInterval: ignore for Bulk transfer */
??? /*Endpoint 1 Descriptor*/
??? 0x07,?? /* bLength: Endpoint Descriptor size */
??? USB_ENDPOINT_DESCRIPTOR_TYPE,?? /* bDescriptorType: Endpoint */
??? 0x81,?? /* bEndpointAddress: (IN1) */
??? 0x02,?? /* bmAttributes: Bulk */
??? VIRTUAL_COM_PORT_DATA_SIZE,???????????? /* wMaxPacketSize: */
??? 0x00,
??? 0x00??? /* bInterval */


真的很奇怪,早上過來剛打開電腦進(jìn)行調(diào)試,串口突然能打印收到的一些數(shù)據(jù),程序復(fù)位之后又收不到了。能夠接收前的中斷標(biāo)志是0x23,在清除掉端點緩存后中斷標(biāo)志0x14能接收到一些USB線上的某些數(shù)據(jù)。程序復(fù)位后INT中斷引腳又是持續(xù)的高電平,并不被拉低返回中斷標(biāo)志?!景组_心了】

附上一張串口打印出來的圖,因草率的將程序復(fù)位了,并未能使用邏輯分析儀抓數(shù)據(jù)分析,錯過了

圖片.png

端點0x82設(shè)備的中斷端點


在設(shè)置地址后,將復(fù)位總線命令去除后,這次地址應(yīng)該設(shè)置成功了,在邏輯分析儀抓取的包中,地址不再是0x00,而是自行設(shè)置的地址。

圖片.png


現(xiàn)在知道了為什么時而接收時而不能接收數(shù)據(jù),因設(shè)置的CDC設(shè)備為一直發(fā)送,應(yīng)該是造成了USB總線繁忙了,在將設(shè)備斷電后重新開機(jī)初始化后,CH376主機(jī)能夠接收到數(shù)據(jù),能一直進(jìn)行接收CDC設(shè)備發(fā)送的數(shù)據(jù)。數(shù)據(jù)無誤,證明接收端點配置是正確的。


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

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