S3C2440 USB 设备控制器
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的引脚以及控制寄存器,设置中断处理程序的入口,以及开启中断。
- void usb_init_slave(void)
- {
- struct s3c24x0_gpio * const gpioregs = s3c24x0_get_base_gpio();
- char *mode;
- Delay(10);
- Usb_Isr_Init();
- //设置中断处理程序的入口,需要两个中断USBD与DMA2,USBD用于处理USB事务,DMA2用于处理DMA传输
- writel((readl(&gpioregs->MISCCR) & ~((1<<3) | (1<<13))), &gpioregs->MISCCR);
- // USBD is selected instead of USBH1
- // USB port 1 is enabled.
- //
- // USBD should be initialized first of all.
- //
- isUsbdSetConfiguration=0;
- UsbdMain(); //主要配置函数
- Delay(10);
- writel((readl(&gpioregs->GPCDAT) | (1<<5)), &gpioregs->GPCDAT);
- //这个操作和Mini2440开发板有关,在USB 设备的信号线上D+上接上了一个GPC5的一个上拉电阻,当GPC5输出高电平的时候,主机的集线器才能检测到设备,从而给复位信号
- /* enable USB Device, thisway.diy */
- #if USBDMA
- mode="DMA";
- #else
- mode="Int";
- #endif
- download_run=0; //The default menu is the Download & Run mode.
- printk("USB slave is enable!\n");
- //printk是我自己编写的打印函数
- }
- void UsbdMain(void)
- {
- InitDescriptorTable();
- ConfigUsbd();
- PrepareEp1Fifo();
- }
|
评论暂时关闭