微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > s3c2440的USB主机控制器

s3c2440的USB主机控制器

时间:11-19 来源:互联网 点击:
可编程数值,以确定HC在什么时间开始执行周期队列;
HcLSThreshold:11位数值,用于确定是否在EOF之前执行最大8位LS包传输;
HcRhDescriptorA:第一个对跟集线器进行描述的寄存器;
HcRhDescriptorB:第二个对跟集线器进行描述的寄存器;
HcRhStatus:包括集线器状态域和集线器状态更改域;
HcRhPortStstus[1:NDP]:用于控制和报告每个端口上的事件,在s3c2440中,NDP为2

下面给出OHCI的初始化,它都是基于寄存器的。根据OHCI规范,HCD应该完成下列初始化步骤:
●初始化HCCA数据内存单元
●初始化可操作寄存器,以匹配当前设备数据状态
●设置HcHCCA
●设置HcInterruptEnable
●设置HcControl
●设置HcPeriodicStart

结合本文所介绍的实际内容,OHCI的初始化函数为:
void OHCIInit( )
{
unsigned int fminterval;

//复位
rHcControl = 0;
//写HCCA
rHcHCCA = (volatile unsigned )&hcca;

//设置帧间隔
fminterval = 0x2edf;
rHcFmInterval =((((fminterval - 210) * 6) / 7) < 16)| fminterval;
rHcPeriodicStart= (fminterval * 9) / 10;

//初始化HcDoneHead
rHcDoneHead = 0x00;
hcca.HccaDoneHead = 0x0000;

//设置HC为运行状态
rHcControl = 0x80;
}

主机对USB设备的识别过程称为设备枚举,因此枚举对于USB至关重要。在本文,只进行下列简单的5步枚举过程:
1、主机要求得到设备描述符,SETUP数据包为:0x80, 0x06,0x00,0x01,0x00,0x00,0x40,0x00,得到的数据长度最大为0x40;
2、第二个SETUP包是为设备分配一个地址,内容一般为:0x00,0x05,0x02,0x00,0x00,0x00,0x00,0x00。其中的02表示为设备分配的地址为0x02,以后我们再对该设备操作时,就只能使用0x02这个地址值;
3、主机用新的地址再次获取设备描述符,SETUP包为:0x80,0x06,0x00,0x01,0x00,0x00,0x12,0x00,与上次不同,这次得到数据长度时实际的数据长度0x12;
4、主机读取设备全部配置描述符,SETUP包为:0x80,0x06,0x00,0x02,0x00,0x00,0x40,0x00,由于主机不知道设备描述符的长度,因此这里只要求得到0x40个字节;
5、主机发送SETUP数据包:0x00,0x09,0x01,0x00,0x00,0x00,0x00,0x00,用以设置配置,允许所有端点进入工作状态。
对USB设备枚举我们只做了简单的介绍,关于枚举的其他步骤以及SETUP数据包各个字节的具体含义,请阅读USB协议的第9章。

下面我们就主要介绍OHCI规范是如何完成USB设备枚举的。前面我们已经介绍过了,OHCI数据传输主要依靠ED和TD,其中TD是挂靠在ED上的。ED主要用来设置传输的各种参数,TD则主要负责具体的数据传输。根据USB协议,USB的设备枚举只涉及控制传输。控制传输最少有两个事务阶段:建立和状态,控制传输可以有选择性地包括建立和状态阶段之间的数据阶段。在这里,控制写传输不需要数据阶段,而控制读需要在建立和状态之间添加主机要读取到的数据。一般来说,完成一次控制写传输需要3个TD:第一个发送Setup包,第二个用于接收握手或零长度的数据包,第三个用于发送状态;而完成一次控制读传输需要4个TD:第一个发送Setup包,第二个用于接收数据,第三个用于发送一个零长度的数据包,,第四个用于接收状态。

下面给出具体的USB设备枚举的函数。在进行枚举之前,主机一定要确认有USB设备的存在。正确情况下,在确认过程中,如果在一段给定时间没有检测到设备,则主机认为没有USB设备。“一段给定的时间”应该由定时器来完成。在这里,为了简化程序,我们只用计数来代替定时。
int USB_Enum()
{
int i;
//判断有无USB设备
for(i=0;i<100000;i++)
{
if (rHcRhPortStatus1 & 0x01)
{
rHcRhPortStatus1 = (1 < 4);//端口复位
while (rHcRhPortStatus1 & (1 < 4))
;//等待复位结束
rHcRhPortStatus1 = (1 < 1);//使能该端口
break;
}
else if (rHcRhPortStatus2 & 0x01)
{
rHcRhPortStatus2 = (1 < 4);//端口复位
while (rHcRhPortStatus2 & (1 < 4))
;//等待复位结束
rHcRhPortStatus2 = (1 < 1);//使能该端口
break;
}
}

if (i>90000)
return 0x44;

//第一步,主机得到设备描述符
CreateEd(
(unsigned int) &ed,// ED Address
64,// Max packet
0,// TD format
0,// Skip
0,// Speed
0x0,// Direction
0x0,// Endpoint
0x0,// Func Address,初始为0
(unsigned int) &td[3],// TDQTailPointer
(unsigned int) &td[0],// TDQHeadPointer
0,// ToggleCarry
0x0);// NextED

//建立PID
CreateGenTd(
(unsigned int) &td[0],// TD Address
2,// Data Toggle
0x2,// DelayInterrupt
0x0,// Direction
1,// Buffer Rounding
(unsigned int) pSetup1,// Current Buffer Pointer,定义的

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top