310 likes | 451 Views
USB 實驗. 實驗. 實驗目的 瞭解 USB HOST 相關知識 瞭解 USB DEVICE 相關知識 瞭解 S3C2410X 的 USB HOST 及 Device 控制器 實驗內容 通過 USB Device 下載資料 通過 USB HOST 存取 USB 設備. USB 基礎. 通用串列匯流排協定 USB ( Universal Serial Bus ) 是由 Intel 、 Compaq 、 Microsoft 等公司聯合提出的一種新的串列匯流排標準 主要用於 PC 機與週邊設備的互聯 1994 年 11 月發佈第一個草案
E N D
實驗 • 實驗目的 • 瞭解USB HOST相關知識 • 瞭解USB DEVICE相關知識 • 瞭解S3C2410X的USB HOST及Device控制器 • 實驗內容 • 通過USB Device下載資料 • 通過USB HOST存取USB設備
USB基礎 • 通用串列匯流排協定USB(Universal Serial Bus) • 是由Intel 、Compaq、Microsoft等公司聯合提出的一種新的串列匯流排標準 • 主要用於PC機與週邊設備的互聯 • 1994年11月發佈第一個草案 • 年2月發佈第一個規範版本1.0,2000年4月發佈高速模式版本2.0 • 對應的設備傳輸速度也從1.5Mb/s的低速和12Mb/s的全速提高到如今的480Mb/s的高速
USB 特色 • 支持即插即用 • 允許外設在主機和其他外設工作時進行連接配置使用及移除。 • 傳輸速度快 • USB支援三種設備傳輸速率 • 低速設備1.5 Mb/s、中速設備12 Mb/s和高速設備480 Mb/s。 • 連接方便 • USB可以通過串列連接或者使用集線器Hub連接127個USB設備 • 從而以一個串列通道取代PC上其他I/O埠如串列埠、並行埠等,使PC與外設之間的連接更容易。 • 獨立供電 • USB介面提供了內置電源。 • 低成本 • USB使用一個4限插頭作為標準插頭,通過這個標準插頭 • 採用菊花鏈形式可以把多達127個的USB外設連接起來 • 所有的外設通過協議來共用USB的頻寬
客戶軟體 應用 USB系統軟體 USB邏輯設備 USB主機控制器 USB匯流排界面 邏輯通信流 實際通信通道 USB通訊
USB 組成 • USB規範中將USB分為五個部分 • 控制器(Host Controller) • 主要負責執行由控制器驅動程式發出的命令 • 如位於PC主板的USB控制晶片 • 控制器驅動程式(Host Controller Driver) • 在控制器與USB設備之間建立通信通道 • 一般由作業系統或控制器廠商提供 • 設備驅動程式(Client Driver) • 驅動USB設備的程式 • 一般由USB設備製造商提供 • USB晶片驅動程式(USB Software) • 提供對USB晶片的支援 • 設備上的韌體(Firmware) • USB設備(USB Device) • 包括與PC相連的USB週邊設備
USB傳輸方式 • USB四種不同的資料傳輸方式 • 1) 同步傳輸(Isochronous) • 該方式用來聯接需要連續傳輸資料,且對資料的正確性要求不高而對時間極為敏感的外部設備 • 如麥克風、嗽叭以及電話等 • 同步傳輸方式以固定的傳輸速率 • 連續不斷地在主機與USB 設備之間傳輸資料,在傳送資料發生錯誤時,USB並不處理這些錯誤,而是繼續傳送新的資料 • 同步傳輸方式的發送方和接收方都必須保證傳輸速率的匹配,不然會造成資料的丟失。 • 2) 中斷傳輸(Interrupt) • 該方式用來傳送資料量較小,但需要及時處理,以達到即時效果的設備,此方式主要用在偶然需要少量資料通信,但服務時間受限制的鍵盤、滑鼠以及操縱杆等設備上。
USB傳輸方式 • 3) 控制傳輸(Control) • 該方式用來處理主機到USB設備的資料傳輸,包括設備控制指令、設備狀態查詢及確認命令 • 當USB設備收到這些資料和命令後,將依據先進先出的原則處理到達的資料 • 主要用於主機把命令傳給設備、及設備把狀態返回給主機。任何一個USB設備都必須支援一個與控制類型相對應的端點0 • 4) 批量傳輸(Bulk) • 該方式不能保證傳輸的速率,但可保證資料的可靠性,當出現錯誤時,會要求發送方重發 • 通常印表機、掃描器和數位相機以這種方式與主機聯接
USB主機(Host) • 控制 • 匯流排上所有USB設備 • 和所有集線器的資料通信過程 • 一個USB系統中 • 只有一個USB主機 • 每一毫秒產生一框資料 • 同時對匯流排上的錯誤進行管理和恢復
USB設備(Device) • 通過匯流排 • 與USB主機相連 • USB設備接收 • USB匯流排上的所有資料包 • 根據資料包的位址域來判斷是否接收 • 接收後 • 回應USB主機的資料包 • 並與USB主機進行資料傳輸
端點(Endpoint) • 與USB主機進行通信的基本單元 • 每個設備有多個端點 • 主機只能通過端點與設備進行通訊 • USB系統中唯一的位址 • 設備位址和端點號構成 • 每個端點都包含一些屬性 • 傳輸方式、匯流排訪問頻率、頻寬、端點號、資料包的最大容量等 • 控制端點0通常用於設備初始化參數 • 除控制端點0 • 其他端點必須在設備配置後才能生效 • USB晶片中 • 每個端點就是一個一定大小的資料緩衝區。
管道(Pipe) • 是USB設備和USB主機之間 • 資料通信的邏輯通道 • 一個USB管道 • 對應一個設備端點 • 各端點通過自己的管道與主機通信 • 所有設備支援端點0的控制管道 • 主機可以獲取USB設備的資訊 • 包括設備類型、電源管理、配置、端點描述等
USB設備開發 • USB晶片負責 • 管理和實現USB物理層差分信號 • 通過配置和管理暫存器初始化設備 • 提供連接的端點 • 電源管理 • 通過暫存器管理端點 • USB晶片驅動程式 • 提供多個標準的端點 • 每個端點都支援單一的匯流排傳輸方式 • 端點0支援控制傳輸 • 其他端點支援同步傳輸、批量傳輸或中斷傳輸中的任意一種 • 管理和使用這些端點 • 就是通過操作相應的控制暫存器、狀態暫存器、中斷暫存器和資料暫存器來實現
S3C2410X的USB 功能 • USB Host • 支援兩個USB host 通訊埠 • 符合OHCI 1.0 協定規範 • 符合USB 1.1 協定規範 • 同時支援USB低速和全速(12M/S)設備的連接 • USB Device • 符合USB 1.1 協定規範 • 支援控制,中斷和DMA大量(bulk)資料傳送方式 • 整合了5個可配置節點的64比特FIFO存儲收發器 • 整合了USB收發器 • 支援暫停(Suspend)和遠端喚醒(Remote Wakeup)功能
USB Device Main • void Main(void) • { • BoardInitStart(); //系統初始化,MMU初始化 • SystemClockInit(); //系統時鐘初始化 • MemCfgInit(); //設置NAND FLASH的配置寄存器 • PortInit(); //S3C2410X的GPIO初始化 • SerialSwitch(0); //選擇串口0 • SerialChgBaud(115200); //波特率115200 • EnableInt(); //允許中斷 • while( 1 ) • { • printf("FS2410XP USB DEVICE Download File Test,please Enter 'ESC' to exit\n"); • LoadFileFromUsb(0,0,0,0);//USB DEVICE下載函數 • } • }
USB Device - LoadFileFromUsb • int LoadFileFromUsb(U32 a1, U32 a2, U32 a3, U32 a4) • { • puts("USB download file\n"); • return BoardUsbDownload(0, 0); • }
static int BoardUsbDownload(U32 addr, U32 run) { U8 fun; int len; rGPHCON = rGPHCON&~(0xf<<18)|(0x5<<18); //To enhance the USB signal quality. //CLKOUT 0,1=OUTPUT to reduce the power consumption. rGPGCON &= 0xfff3ffff; //GPG9 input fun = 1; UsbdInit(fun); Delay(100); rGPGCON |= 0x00040000; rGPGDAT |= 0x0200; //GPG9 ouput 1 pISR_USBD =(unsigned)IsrUsbd; ClearPending(BIT_USBD); EnableIrq(BIT_USBD); len = WaitDownload(addr); DisableIrq(BIT_USBD); rGPGCON &= 0xfff3ffff; //GPG9 input if(len>0) { printf("\nPress any key to continue...\n"); getch(); if(run) {//getyorn()) { //void (*fun)(void) = (void (*)(void))download_addr; //CacheDisable(); //CacheFlush(); rINTMSK = BIT_ALLMSK; Delay(100); //(*fun)(); call_linux(0, 193, download_addr); } } return len; } USB Device - BoardUsbDownload
static int WaitDownload(U32 addr) { …. /*******************************/ /* Test program download */ /*******************************/ checkSum = 0; downPt = tempMem; //This address is used for receiving first 8 byte. download_addr = addr; //_RAM_STARTADDRESS; download_len = 0; puts("Press Esc key to exit\n"); while(!isUsbdSetConfiguration) { if(getkey()==ESC_KEY) return -1; } puts("USB connected\n"); j=0; while(download_len==0) { if(j%0x50000==0) LedSet(0xf); if(j%0x50000==0x28000) LedSet(0x0); j++; if(getkey()==ESC_KEY) { puts("USB download aborted.\n"); return -1; } if(isUsbdSetConfiguration) { if(!UsbConnected) puts("Now, USB is connected."); UsbConnected = 1; } } USB Device - WaitDownload
#if USBDMA ClearEp3OutPktReady(); //中斷處理讀完第一個包後未清OutPktReady位,在此清掉 if(download_len>EP3_PKT_SIZE) { if(download_len<=(0x80000)) ConfigEp3DmaMode(download_addr+EP3_PKT_SIZE-8,download_len-EP3_PKT_SIZE); else ConfigEp3DmaMode(download_addr+EP3_PKT_SIZE-8,0x80000-EP3_PKT_SIZE); totalDmaCount=0; } else // download_len < EP3_PKT_SIZE totalDmaCount=download_len; #endif printf("\nNow, Downloading [ADDRESS:%xh,TOTAL:%d]\n", download_addr, download_len); j=0x80000; USB Device - WaitDownload
#if USBDMA while(totalDmaCount<download_len) { if((rDCDST2-(U32)download_addr+8)>=j) { /* static int led = 0x0; led ^=2; Led_Display(led);*/ putch('d'); j+=0x80000; } if(getkey()==ESC_KEY) { int i; ConfigEp3IntMode(); DisableIrq(BIT_DMA2); DbgOut("\nReceive process aborted.\n"); DbgOut("Received %d bytes\n", totalDmaCount); for(i=0; i<32;i++) { printf("0x%x = %x\n", download_addr+i*0x100000, *(U32 *)(download_addr+i*0x100000)); } return -1; } } #else while(((U32)downPt-download_addr)<(download_len-8)) { if(((U32)downPt-download_addr)>=j) { static int led = 0x0; led ^= 2; Led_Display(led); putch('i'); j+=0x80000; } if(getkey()==ESC_KEY) { int i; DbgOut("\nReceive process aborted.\n"); DbgOut("Received %d bytes\n", (U32)downPt-download_addr); for(i=0;i<48;i++) { printf("0x%x = %x\n", download_addr+i*0x100000, *(U32 *)(download_addr+i*0x100000)); } return -1; } } #endif USB Device - WaitDownload
USB Device - WaitDownload • #if USBDMA • /*******************************/ • /* Verify check sum */ • /*******************************/ • … • #else • //checkSum was calculated including dnCS. So, dnCS should be subtracted. • checkSum=checkSum - *((unsigned char *)(download_addr+download_len-8-2)) • - *( (unsigned char *)(download_addr+download_len-8-1) ); • #endif • //PollRxEnd: • dnCS=*((unsigned char *)(download_addr+download_len-8-2))+ • (*((unsigned char *)(download_addr+download_len-8-1))<<8); • if(checkSum!=dnCS) • { • printf("Error!!! MEM:%x DN:%x\n", checkSum, dnCS); • return -1; • } • printf("Ok\n"); • download_len-=10; • return download_len; • } • #endif
USB驅動程式移植 • 驅動程式分為 • 主機控制器驅動程式(Host Controller Driver) • 設備端驅動程式(Slave Device Driver) • Linux提供對USB主機控制器 • 開放主機控制器介面(OHCI) • 通用主機控制器介面(UHCI) • S3C2410X的USB主機控制器 • 完全符合OHCI規範
USB驅動程式移植 • 在Linux中USB驅動需要如下: • (1)暫存器位址設置 • 在driver/usb/usb-ohci-s3c2410.c • 主機控制器暫存器的起始位址(0x49000000)UBSHOST_CTL_BASE • 是通過函數hc_add_ohci來註冊的 • (2)主機控制器中斷設置 • 在driver/usb/usb-ohci-s3c2410.c • 主機控制器的中斷向量IRQ_USBH(26) • 是通過函數hc_add_ohci來註冊的 • (3)還有一些與其他相關的部分,要進行設置
USB隨身碟驅動 • 安裝USB隨身碟驅動; • 安裝SCSI驅動sd_mod.o; • 插入USB隨身碟,觀察終端有無設備插入的反饋資訊; • 在命令行輸入掛載USB隨身碟的命令; • 在USB隨身碟和掛載目錄之間進行檔的複製,注意在何種情況下需要進行同步操作; • 卸載USB隨身碟;
USB隨身碟驅動 • ①安裝V4L(Video for Linux)支援模組videodev.o • ②安裝USB視頻驅動模組usbvideo.o • ③安裝USB攝影機驅動模組ov511.o • ④插入USB攝影機到USB HOST0介面,觀察終端有無熱拔插設備的反饋資訊 • ⑤啟動攝影機視頻捕捉程式 • ⑥更改攝影機視頻捕捉的頻率,觀察視頻的重播速率與USB1.1傳輸速度的關係。
USB鍵盤實驗 • ①安裝USB鍵盤驅動usbkbd.o • ②安裝鍵盤設備驅動 keybdev.o • ③插入USB鍵盤,觀察終端有無熱拔插設備的反饋資訊 • ④試一試通過USB鍵盤進行各個按鍵的輸入 • ⑤卸載USB鍵盤驅動usbkbd.o • ⑥修改USB鍵盤驅動原始檔案usbkbd.c中的鍵盤掃描碼索引表,重新編譯驅動,然後再安裝該驅動模組,這時再按被修改的掃描碼所對應按鍵,觀察螢幕上輸出的字元。由此可瞭解USB鍵盤驅動的中斷處理是如何完成將鍵盤傳來的按鍵資料轉換為掃描碼的。