如果你不理解USB協(xié)議,那么協(xié)議棧部分建議你別去修改.否則很麻煩.控制傳輸部分按照我們的程序去做就可以了.如果設備驅動都沒有安裝成功,你抓取的數(shù)據(jù)是沒有意義的.除非你有比較低層的USB總線分析儀.
請問在端點0的SETUP階段時,端點0需要發(fā)送18個字節(jié),那么數(shù)據(jù)送入發(fā)送緩沖區(qū)后,如何通知芯片開始傳輸?發(fā)送8個字節(jié)后,緩沖區(qū)會不會清空?在發(fā)送前后與之相關的寄存器有哪些變化?因為我發(fā)現(xiàn)中斷標志寄存器的BIT_IF_TRANSFER 位一直為1,不知道是什么問題?
(1)數(shù)據(jù)送入發(fā)送緩沖區(qū)后,則等待PC發(fā)送IN事務來取,單片機端不需要關系何時傳輸,緩沖區(qū)不會清空 (2)REG_INTER_FLAG、REG_USB_STATUS會有變化,BIT_IF_TRANSFER表示傳輸完成,即CH374已收到或發(fā)送數(shù)據(jù),如果有數(shù)據(jù)數(shù)據(jù)收發(fā),那么為1是正常的,下載CH374EVT.ZIP,參考例程就可以了。
先說下現(xiàn)在的具體情況,那就是打印機連上PC后,收到主機一個中斷,這時按照USB協(xié)議,應該返回18個字節(jié)的數(shù)據(jù),說明現(xiàn)在設備的狀態(tài),但是在發(fā)送完8個字節(jié)之后卻沒有任何中斷了。由于編程環(huán)境是在Linux下,中斷程序在邏輯功能上是按Device.c設計的,會不會跟硬件有關?同時用調試信息跟蹤發(fā)現(xiàn)中斷標志寄存器中的數(shù)據(jù)為0xd9,清中斷之后還是為0xd9,這是什么原因?
實際上這8個字節(jié)是沒有發(fā)出去的,如果發(fā)出去,則一定會產(chǎn)生端點0上傳完成中斷.沒有上傳完成有可能SETUP包沒有應答好.或者端點0上傳沒有啟動.基本也就是這兩個問題. else if ( l <= RAM_ENDP0_SIZE ) { // 上傳數(shù)據(jù) Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 ) ), l ) | BIT_EP0_TRAN_TOG ); // DATA1 } 這句話有沒有進去執(zhí)行呢?
這句話有寫,不知道有沒有執(zhí)行。不過有個疑問那就是清中斷之前中斷標志寄存器中的數(shù)據(jù)為0xd9,清中斷之后還是為0xd9,這是什么原因?
如果是這個中斷,那前面的SETUP包是怎么接收到的呢?明顯設備掛起了. 首先你務必確??梢哉5淖x寫寄存器.否則初始話都不正確.建議你驗證一下. 你把代碼以附件的形式貼出來,看看代碼流程有沒有問題.另外你檢測一下,產(chǎn)生中斷的順序是什么.
寄存器的讀寫都是正確的,程序改了,完全是按示例程序寫的,有個問題一直存在就是不能清除中斷
你的CH374的UEN引腳(第5腳)是怎么接的,我們提供的例程當中,對應的UEN引腳是懸空的
該引腳(pin5)我們是接了3.3V的電壓,整個芯片是3.3V供電的
你用的是CH374T 應該沒有什么問題。檢查你的程序的流程,或者把程序發(fā)到技術支持信箱tech@wch.cn
static void usbRX_Handler(int irq, void *dev_id, struct pt_regs *regs) { unsigned char s = 0; unsigned char *tmpBuf; unsigned short retLen;
s=Read374Byte( REG_INTER_FLAG ); if (s & BIT_IF_BUS_RESET ) { // Reset device irq flag // USB總線復位
Write374Byte( REG_USB_ADDR, 0x00 ); Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) ); Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( 0 ) ); Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( 0 ) ); Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_INTER_FLAG ); // 清所有中斷標志 CH_BusReset(); } else if (s & BIT_IF_TRANSFER) { switch( s & BIT_STAT_PID_ENDP ) { // USB設備中斷狀態(tài) case USB_INT_EP2_OUT: { // 批量端點下傳成功 CH374_ep02_rx(); break; } case USB_INT_EP2_IN: { // 批量端點上傳成功,未處理 CH374_ep02_tx(); break; } case USB_INT_EP1_IN: { // 中斷端點上傳成功,未處理 CH374_ep01_tx(); break; } case USB_INT_EP0_SETUP: { // 控制傳輸 Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 )), 0x08)|BIT_EP0_TRAN_TOG ); // DATA1 Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER ); break; } case USB_INT_EP0_IN: { struct usb_endpoint_instance *endpoint; endpoint = ep_endpoints[0]; tmpBuf = endpoint->tx_urb->buffer + endpoint->last; retLen = CH374_WriteEndpoint(USB_INT_EP0_IN,tmpBuf,endpoint->tx_urb->actual_length-endpoint->last); endpoint->last += retLen; Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 ) ), retLen ) ^ BIT_EP0_TRAN_TOG ); // DATA1 Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER ); break; } case USB_INT_EP0_OUT: { break; } default: { break; } } Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER ); // 清中斷標志 } else if (s & BIT_IF_USB_SUSPEND) { Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_USB_SUSPEND ); // 清中斷標志 Write374Byte( REG_SYS_CTRL, Read374Byte( REG_SYS_CTRL ) | BIT_CTRL_OSCIL_OFF ); // 時鐘振蕩器停止振蕩,進入睡眠狀態(tài) }
else if (s & BIT_IF_WAKE_UP) { Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_WAKE_UP ); // 清中斷標志 usbd_device_event(udc_device, DEVICE_BUS_ACTIVITY, 0);
} else { // 意外的中斷,不可能發(fā)生的情況,除了硬件損壞 //對照ch374添加 Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_INTER_FLAG ); // 清中斷標志 } }
case USB_INT_EP0_SETUP: { // 控制傳輸 Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 )), 0x08)|BIT_EP0_TRAN_TOG ); // DATA1 Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER ); break; } 這邊怎么沒有上傳數(shù)據(jù)?你要把數(shù)據(jù)寫到緩沖區(qū)里面啊,怎么沒有寫數(shù)據(jù)直接就傳了,那上傳什么樣的數(shù)據(jù)呢?程序中好象看不到
原來是這樣的 case USB_INT_EP0_SETUP: { // 控制傳輸 struct usb_endpoint_instance *endpoint; endpoint = ep_endpoints[0]; endpoint->ep0_interrupts++; Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 )), 0x08)|BIT_EP0_TRAN_TOG ); // DATA1 Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER ); break; }
endpoint->ep0_interrupts++;
//在這里你讀一下RAM_ENDP0_TRAN這個緩沖區(qū),看看數(shù)據(jù)是否被你寫進去了.
Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 )), 0x08)|BIT_EP0_TRAN_TOG ); // DATA1 USB控制傳輸部分我們已經(jīng)寫好了,而且流程正確,建議不要這樣修改,會您的浪費時間.你你這樣寫還要加很多代碼. 前面已經(jīng)告訴你,你只要把374讀寫完成,直接用我們提供的函數(shù)就可以了.不會有什么問題的.如果數(shù)據(jù)根本沒有寫進去的話,PC上會出現(xiàn)無法識別的設備.懷疑你這種方式是怎么寫進去數(shù)據(jù)的.