程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 基於OHCI的USB主機 —— 中斷處理程序

基於OHCI的USB主機 —— 中斷處理程序

編輯:關於C語言

在OHCI的體系下,判斷數據是否傳輸完畢是需要通過中斷程序來判斷的,當USB主機設置了HcControl和HcCommandStatus寄存器開始傳輸數據後,AM9200 自動開始數據傳輸,並且定期的檢查HcDoneHead寄存器的內容,並且將其轉移到HCCA.DoneHead。然後產生中斷,觸發中斷處理程序。   在中斷處理程序中,需要檢查HcInterruptStatus寄存器的內容,判斷WDH位是否為1,以便確定是否有TD被處理完畢。一般來說,其余的中斷狀態位不用理會。當發現有TD被處理完畢,則還需要判斷已經完成的TD是否是當前傳輸命令的最後一個TD,如果是則標志命令執行結束,上層程序可以進行後續處理。   /**  * OHCI中斷處理程序  */ void AT91F_UHP_Handler(void) {     unsigned int status;     unsigned char idx;     unsigned char cc;     //unsigned int control;         //得到HcInterruptStatus寄存器的內容     status = ohciGetIntrStatus();     //檢查WDH位,判斷是否有TD傳輸完畢     if ((status & OHCI_HC_INTR_WDH) != 0)     {        //根據當前執行的命令類型,確定TD的數量        switch(usbCmdState.cmdType)        {        case USB_CMD_TYPE_BULK_WRITE:        case USB_CMD_TYPE_BULK_READ:            idx = 3;            break;                   case USB_CMD_TYPE_CTRL_READ:            idx = 2;            break;                   case USB_CMD_TYPE_CTRL_WRITE:            idx = 1;            break;                   default:            usbCmdState.state = USB_CMD_OVER;            ohciClearIntrStatus();            return ;        }               //取得當前完成的TD的Complete Code值        cc = getTdCC(ohciGetHccaDoneHead());        //判斷當前完成的TD是否是命令的最後一個TD        if (ohciGetHccaDoneHead() == usbGetLastTdAddr(idx))        {            usbCmdState.cmdResult = cc;            usbCmdState.state = USB_CMD_OVER;        }        else        {            //當前TD不是最後一個TD,但是執行失敗,不會繼續處理TD列表,因此需要返回            if (cc)            {               usbCmdState.cmdResult = cc;               usbCmdState.state = USB_CMD_OVER;            }            else               //當前TD不是最後一個TD,等待繼續處理               usbCmdState.state++;        }     }     //清除HcInterruptStatus寄存器的內容,以便能夠產生新的中斷     ohciClearIntrStatus(); }   在最初的代碼中,不是通過中斷來判斷TD數據是否處理完畢的,而是直接調用ohciGetIntrStatus()函數並判斷返回值的,但是實際調試時發現這樣不能正確得到TD數據處理完畢的信息。通過對中斷程序的實際調試發現,因為ED會帶有多個TD,AM9200在處理的時候可能是處理速度的原因,會產生1個或多個中斷,因此在中斷處理程序中需要判斷當前結束的TD是否是當前命令的最後一個TD,這樣才能確保整個ED處理完畢。   說實話,我不認為上面的判斷ED隊列執行完畢的方法是好的方法,本來我一直以為會有一個寄存器,在ED隊列處理完畢的時候會跳出來告訴我說隊列執行完畢了,可是找了半天也沒有找到,只好采用這個笨方法了。

本文出自 “rainman” 博客,請務必保留此出處http://lancelot.blog.51cto.com/393579/261181

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved