歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

S3C2440 USB 設備控制器

s3c2440 soc集成了一個usb1.1設備控制器,可以進行全速/低速的控制,中斷與批量傳輸。除了端點0,具有四個端點,每個端點都可以作為中斷與批量的端點,每個端點具有128 byte的FIFO,所以端點最大packet可以設置成128byte。並且支持DMA傳輸。任何一種設備控制器對於軟件來說都是一組寄存器:數據,狀態,控制。usb 設備控制器也不例外。設置好相應的控制寄存器,並且在數據來時讀取數據寄存器,需要發送數據的時候將數據寫入輸出寄存器。而這種數據的通信建立在對狀態寄存器的讀取上,往往還會有中斷與DMA的操作。s3c2440 usb設備控制器的寄存器分為以下幾組:(1):電源管理寄存器
        PWR_REG 負責USB設備掛起等電源設置
(2):地址寄存器
        存儲USB設備的地址,當主機枚舉設備設備的時候設置
(3):中斷控制寄存器
        EP_INT_REG    端點中斷狀態寄存器,每當一個端點事件發生的時候,相應的位就會置1
        USB_INT_REG   設備中斷狀態寄存器,主要有三個中斷:喚醒,復位,掛起
        EP_INT_EN_REG  端點中斷使能寄存器
        EP_INT_EN_REG  設備中斷使能寄存器
(4):編號寄存器
        因為USB 設備控制器有五個端點,並且五個端點寄存器大同小異,所以硬件設計上使用了編號寄存器:名字相同但物理寄存器不同。有一個INDEX_REG寄存器,它裡面的值指示了具體的哪組物理寄存器。這樣的寄存器有七個分別是:
        MAXP_REG: 端點最大信息包大小
        IN_CSR1_REG
        IN_CSR2_REG
        OUT_CSR1_REG
        OUT_CSR2_REG
        OUT_FIFO_CNT1_REG
        OUT_FIFO_CNT2_REG
(5):FIFO寄存器
        EPO_FIFO_REG
        EP1_FIFO_REG
        EP2_FIFO_REG
        EP3_FIFO_REG
        EP4_FIFO_REG
(6):DMA寄存器
        端點1~4,每個端點六個,用於設置端點的DMA傳輸。
        USB設備控制器處理了大部分的USB傳輸細節,並產生相應的中斷。所以對USB設備控制器的編程,最關鍵的部分就是中斷處理的部分。比如端點每收到一個token以及後面的數據包,就會產生相應的中斷。軟件只需要在中斷處理程序中讀取數據,並且清除中斷標志。USB設備控制器就會自動發送應答包。現在網上比較流行的操作s3c2440 usb 設備控制器的程序就是移植到u-boot裡面的usb下載程序。因為在u-boot的環境下所以調試起來沒有在裸機上來的方便,所以我將這個程序移植到了裸機上,編譯環境arm-linux-gcc。下面大體介紹以下這個程序的流程:

        這個程序主要是完成了USB設備的枚舉,與批量OUT傳輸,並且開啟了DMA,OUT傳輸用的端點是端點3。這個程序首先從init_usb_slave() 開始:這個函數主要是設置usb slave的引腳以及控制寄存器,設置中斷處理程序的入口,以及開啟中斷。

  1. void usb_init_slave(void)  
  2. {  
  3.         struct s3c24x0_gpio * const gpioregs = s3c24x0_get_base_gpio();  
  4.         char *mode;  
  5.   
  6.         Delay(10);  
  7.   
  8.         Usb_Isr_Init();    
  9.       //設置中斷處理程序的入口,需要兩個中斷USBD與DMA2,USBD用於處理USB事務,DMA2用於處理DMA傳輸   
  10.          writel((readl(&gpioregs->MISCCR) & ~((1<<3) | (1<<13))), &gpioregs->MISCCR);  
  11. // USBD is selected instead of USBH1    
  12. // USB port 1 is enabled.   
  13. //   
  14. //  USBD should be initialized first of all.   
  15. //   
  16.         isUsbdSetConfiguration=0;  
  17.   
  18.         UsbdMain(); //主要配置函數   
  19.         Delay(10);  
  20.   
  21.         writel((readl(&gpioregs->GPCDAT) | (1<<5)), &gpioregs->GPCDAT);  
  22.         //這個操作和Mini2440開發板有關,在USB 設備的信號線上D+上接上了一個GPC5的一個上拉電阻,當GPC5輸出高電平的時候,主機的集線器才能檢測到設備,從而給復位信號   
  23.   
  24.  /* enable USB Device, thisway.diy */  
  25. #if USBDMA   
  26.         mode="DMA";     
  27. #else   
  28.         mode="Int";  
  29. #endif   
  30.         download_run=0; //The default menu is the Download & Run mode.   
  31.         printk("USB slave is enable!\n");  
  32.         //printk是我自己編寫的打印函數   
  33. }  
        在配置完設備後,給GPC5一個高電平,主機就開始枚舉設備的過程了。能不能開始這個過程關鍵是看設備是否配置正確。這就是要看UsbMain()這個函數了。他在usbmain.c中,如下:
  1. void UsbdMain(void)  
  2. {  
  3.     InitDescriptorTable();  
  4.     ConfigUsbd();   
  5.     PrepareEp1Fifo();   
  6. }  
Copyright © Linux教程網 All Rights Reserved