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. }  
  • 1
  • 2
  • 3
  • 4
  • 下一页

相关内容