没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
s3c2440 提供了 USB 主机接口,它与 OHCI v1.0 完全兼容。要使用该功能,
就必须熟悉 OHCI v1.0 规范;而要熟悉 OHCI v1.0 规范,那么还必须先熟悉
USB v1.1 协议。因此涉及到该部分的内容较多,要想正确使用 s3c2440 所提供
的 USB 主机接口也不是一件容易的事情。在这里,我主要介绍 USB 设备枚举
过程中所涉及到的一些知识,并给出具体的实现程序。
OHCI(Open HCI)是目前使用比较广泛的三种 USB 主机控制器规范之一。
USB 体系结构是由四个主要部分组成:客户软件/USB 驱动,主机控制器驱动
(HCD),主机控制器(HC)和 USB 驱动。前两者由软件实现,后两者由硬
件实现。而 OHCI 就是规范了主机控制器驱动和主机控制器之间的接口,以及
它们的基本操作。在主机控制器驱动和主机控制器之间,有两个通信通道,第
一个是应用位于 HC 的一套可操作寄存器,它们包括控制寄存器、状态寄存器
和列表指针寄存器;另一个通道是应用称为主机控制器通信域(HCCA)的共
享内存。
USB 定义了四种数据传输类型:控制传输、批量传输、中断传输和同步传
输。在 OHCI 规范中把数据传输类型分为两类:周期传输和非周期传输。同步
传输和中断传输属于周期传输,控制传输和批量传输属于非周期传输。USB 定
义了每帧的周期为 1.0 毫秒,为了保证每一帧都能发生周期传输和非周期传输,
一般地,OHCI 把每一帧的带宽分为四个部分,首先是发送 SOF,然后是非周
期传输,紧接着是周期传输,如果周期传输完毕后,还有时间,则剩余的时间
仍然留给非周期传输。
端点描述符(ED)和传输描述符(TD)是两个最基本的通信模块。ED 包
含了一个端点的信息,它被 HC 用来管理使用端点。ED 的典型参数包括端点地
址、传输速度、最大数据包大小,另外 ED 还提供了 TD 链表的停靠地(锚点)。
TD 是一个依赖于 ED 的内存缓存区,用于与端点之间进行数据传输。当 HC 存
取一个 ED,并且找到一个有效的 TD 地址时,则 HC 就完成了一个简单的与端
点之间的传输任务,这个端点是由 ED 确定,而所存取的数据内存地址由 TD 指
定。当所有的被 TD 所定义的数据传输完毕后,TD 就从 ED 中解链出来,并链
接到完成列表中。这个完成列表能够被 HCD 所处理,以提供一些完成信息。
ED 的数据结构长度为 16 字节,它的数据域有:
FA:USB 的功能地址;
EN:USB 功能内的端点地址;
D:数据流的传输方向,是 IN,OUT,还是有 TD 来决定传输方向;
S:速度,全速还是低速;
K:用于设置跳过当前 ED;
F:链接于 ED 的 TD 的形式,是通用 TD 格式还是同步 TD 格式;
MPS:数据传输的最大字节大小;
TailP:TD 列表的尾指针;
H:用于停止当前 TD 列表的处理;
C:数据翻转进位位;
HeadP:TD 列表的头指针;
NextED:下一个要处理的 ED 指针。
根据上述说明,我们可以定义 ED 为下面的数据类型:
typedef struct _ED {
volatile unsigned int Control;
volatile unsigned int TailP;
volatile unsigned int HeadP;
volatile unsigned int NextEd;
} ED, *P_ED;
由于 ED 必须是 16 字节地址对齐形式,因此我们必须用下面的形式来声明
它的变量:
__align(16) ED ed;
我们可以用下面的函数来创建一个 ED:
__inline void CreateEd(
unsigned int EDAddr, //ED 地址指针
unsigned int MaxPacket, //MPS
unsigned int TDFormat, //F
unsigned int Skip, //K
unsigned int Speed, //S
unsigned int Direction, //D
unsigned int EndPt, //EN
unsigned int FuncAddress, //FA
unsigned int TDQTailPntr, //TailP
unsigned int TDQHeadPntr, //HeadP
unsigned int ToggleCarry, //C
unsigned int NextED) //NextED
{
P_ED pED = (P_ED) EDAddr;
pED->Control = (MaxPacket << 16) | (TDFormat << 15) |(Skip << 14) | (Speed
<< 13)
| Direction << 11) | (EndPt << 7) | FuncAddress;
pED->TailP = (TDQTailPntr & 0xFFFFFFF0);
pED->HeadP = (TDQHeadPntr & 0xFFFFFFF0) | (ToggleCarry << 1);
pED->NextEd = (NextED & 0xFFFFFFF0);
}
TD 共有两种类型:通用 TD 和同步 TD。通用 TD 用于中断、控制和批量端
点,同步 TD 用于同步传输。在这里,我们只给出通用 TD 的数据结构和定义。
通用 TD 的数据结构长度也是 16 字节,它的数据域有:
R:缓存凑整,用于设置是否需要最后一个数据包的长度与所定义的
长度一致;
DP:方向,是 IN,OUT,还是 SETUP;
DI:延时中断;
T:数据翻转;
EC:传输错误计数;
CC:条件码,为上一次企图传输的状态;
CBP:将要被传输的数据内存物理地址;
NextTD:下一个 TD;
BE:将要被传输的数据内存物理末字节地址;
根据上述说明,我们可以定义通用 TD 为下面的数据类型:
typedef struct _TD {
volatile unsigned int Control;
volatile unsigned int CBP;
volatile unsigned int NextTD;
volatile unsigned int BE;
} TD, *P_TD;
由于通用 TD 必须是 16 字节地址对齐形式,因此我们必须用下面的形式来
声明它的变量:
__align(16) TD td[4];
剩余18页未读,继续阅读
资源评论
- ydcr1682013-03-07确实是,没怎么入门,还要进一步学习。
- vans882014-05-05代码不完整需要,但提供了基本思路,可以继续完成
- omnbmh912018-09-28确实是,没怎么入门,还要进一步学习。
- ddicode2013-12-19可惜代码不完整了
- andy010101012012-07-27下来了,太难了,还没怎么看懂!
guiguiyiha
- 粉丝: 6
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功