大家好,你们的大熊又回来了。本篇文章我们来重点了解一下USB设备的四大传输方式之一——控制传输。不同于其他三种传输方式,控制传输有其独特的作用和功能,是一个USB设备必须支持的传输方式。控制传输对带宽没有什么要求,但是数据传输的准确性是最有保障的,因此特别适合配置、命令、状态之类的通信,不适合传输大批量数据。之所以控制传输是USB设备不可或缺的,是因为枚举过程就是通过控制传输实现的,而一个USB设备只有经历过枚举过程才有可能被主机识别为“USB设备”。控制传输能传输的数据量太少了,一次控制传输携带的单个数据包能加载的最大数据数目,对于全速设备可以是8、16、32或64字节,对于高速设备是64字节,对于低速设备是8字节。此外,控制传输还有一项其他传输不具有的特点——支持真正的双向传输。尽管其他的传输方式也可以是双向,但是必须事先给端点定义好方向,而在实际工作中只能有一个传输方向,除非重新进行配置。

USB协议规定控制传输分为三个阶段(Stage),分别是Setup Stage、Data Stage、Status Stage。接下来我就以Cy7c68013A为例介绍这三阶段,图1比较具体地描绘了整个控制传输的过程。

✦1 控制传输三阶段

  Setup Stage只有Setup事务,Setup事务由三个数据包构成。SETUP包是控制传输特有的,它指示了一次控制传输的开始。DATA0数据包含有8字节的数据,这8字节的数据对应8字节的请求(如图2),在这8字节中指明了该请求的请求类型、方向、接收者、对应的请求码等等,USB设备在进行请求的响应时需要根据这8字节信息来确定如何做出相应的应答行为。ACK包用来握手,并且告诉主机本阶段正确完成了,如果USB设备发现数据有损坏,则丢弃当前数据并且不进行握手。对于Cy7c68013A来说,在Setup Stage阶段会产生两个中断,当接收到SETUP包时触发SUTOK中断,与此同时EP0CS的HSNAK位会置1,当接收完DATA0数据包时会产生SUDAV中断,固件程序可以在中断服务程序中完成相应的任务。需要注意的是,在上一次的控制传输未完成前,不能让主机再发送Setup包,否则会开启新的传输,而之前的传输就会被打断。除非之前的控制传输遇到了错误,这时才能发送新的Setup包。

✦2 8字节请求的结构

  Data Stage是可选的,当Setup Stage的8字节仍不够我们传输数据时,可以使用数据阶段来传输其余的数据。Data Stage的数据包的方向必须是一致的,该阶段需要传输的数据的个数和方向由Setup Stage决定。如果数据的个数超出了最大包长,则必须分成多个IN或OUT事务来完成。Data Stage的结束发生在两种情况下,其一是接收完了Setup Stage指定数目的数据,其二是当前数据包未达到最大包长。在Data Stage过程中如果传输的数据发现有错误,可以进行重传,如果传输的数据数目超出了Setup Stage指定的数目,那么该端点就会中止。

  Status Stage是控制传输的最后一个阶段,在Data Stage或者Setup Stage完成后就会进入该阶段,该阶段要完成的是本次传输的状态反馈,因此Status Stage的传输方向与Data Stage(也有可能是Setup Stage)相反。当控制传输一切都传输正常的时候,Status Stage产生ACK应答,如果遇到了错误,则产生STALL应答,如果数据接收方正忙,则产生NAK应答。Status Stage遇到错误也可以重传。对于Cy7c68013a,在没有完成数据的处理之前会一直NAK应答,直到固件程序将HSNAK位写1清0,Status State才能正确应答。

以下我们结合代码来理解,从代码A中我们可以看到,这里使用了厂商请求的方式来完成控制传输。之所以使用厂商请求是因为其他的请求都被USB协议规定的标准请求“霸占”了,剩下的厂商请求(也可以是类请求)我们才能使用(具体的哪些是标准请求哪些是厂商请求可以参考EZ-USB技术手册)。

 BOOL DR_VendorCmnd(void)
{
switch (SETUPDAT[])
{
case 0xa1: //读请求
if (SETUPDAT[] != || SETUPDAT[] != )
{
EP0BCH = SETUPDAT[];
SYNCDELAY;
EP0BCL = SETUPDAT[];
SYNCDELAY;
while(EP0CS & bmEPBUSY);
//从EP0BUF中读取数据
} break;
case 0xa2: //写请求
if (SETUPDAT[] != || SETUPDAT[] != )
{
//往EP0BUF中写入数据
EP0BCH = ;
SYNCDELAY;
EP0BCL = cnt;
SYNCDELAY;
while(EP0CS & bmEPBUSY);
}
break;
default:
return(TRUE);
}
return(FALSE);
}

✦A 控制传输代码

  从代码A中可以看到,在Setup Stage完成之后,作为“攻城狮”的我们还有一项任务要做,判断8字节数据(存放在SETUPDAT中)中的wLengthL与wLengthH是否为0,如果是0,则意味着后面的数据阶段是没有的(接下来直接进入Status Stage),此时什么都不用做,如果不是0,那就说明还有数据需要传输,此时我们的任务就是往EP0BCH:L寄存器内加载数据,这样才能开启数据阶段。对于IN传输,我们需要先往EP0BUF中写入数据,再往EP0BCH:L加载数据(指示需要传输数据的个数),等待数据阶段完成(判断EP0CS寄存器的BUSY位)。对于OUT传输,我们需要先往EP0BCH:L加载数据,接下来就是等待数据阶段完成(判断EP0CS寄存器的BUSY位),最后从EP0BUF读取数据。光看文字描述可能会有点晕乎,现在我用一张图来总结CPU、BUSY位、EP0BUF、EP0BCH:L寄存器之间的关系。

✦3 控制传输转换流程

  感谢大家对大熊FPGA的关注!

CY7C68013A控制传输的更多相关文章

  1. TCP(控制传输协议)详解

    1.传输层概述 在OSI参考模型中,网络层是面向通信的最高层但同时也是面向用户程序的最底层. 传输层的主要作用: 复用:在发送端,多个应用程序公用一个传输层: 分用:在接收端,传输层把从网络层接收到的 ...

  2. 【转载】C++:switch红色下划线,Error:控制传输跳过的实例化解决办法

    转载链接:https://blog.csdn.net/figoleon/article/details/50072029

  3. 庖丁解牛——CY7C68013A开发框架

    大家好,好久不见了,距离上次发文章都有两个多星期了,非常高兴同时也非常感谢你们能一直关注我.之前在公众号上收到网友的消息,其大概意思就是问我能不能出点USB干货,为此我就把第二篇--解密USB2.0数 ...

  4. USB传输协议。——Arvin

    问题一:USB的传输线结构是如何的呢? 答案一:一条USB的传输线分别由地线.电源线.D+.D-四条线构成,D+和D-是差分输入线,它使用的是3.3V的电压(注意哦,与CMOS的5V电平不同),而电源 ...

  5. C# 控制CH341进行SPI,I2C读写

    之前看了别人是C++ MFC开发的CH341 I2C,SPI读写flash的软件代码,看上去有点头晕,感觉还是使用C# winform开发更人性化些 C#控制需要调用CH341提供的DLL库,网上多数 ...

  6. 【GMT43智能液晶模块】例程十:DMA实验——存储器到存储器的传输

    实验原理: DMA(直接存储器访问)传输不需要占用CPU,可以在存储器至存储器实现高速的数据 传输.本实验采用DMA2控制器的数据流0,选用通道0进行数据传输.通过液晶控制传输 和结果显示. 示例截图 ...

  7. urb传输的代码分析【转】

    转自:http://blog.csdn.net/zkami/article/details/2503829 urb传输的代码分析 如需引用,请注明出处blog.csdn.net/zkami 作者Zhe ...

  8. 如何确保TCP协议传输稳定可靠?

    TCP,控制传输协议,它充分实现了数据传输时的各种控制功能:针对发送端发出的数据包确认应答信号ACK:针对数据包丢失或者出现定时器超时的重发机制:针对数据包到达接收端主机顺序乱掉的顺序控制:针对高效传 ...

  9. USB小白学习之路(8)FX2LP cy7c68013A——Slave FIFO 与FPGA通信(转)

    此博客转自CSDN:http://blog.csdn.net/xx116213/article/details/50535682 这个博客只对自己理解CY7C68013的配置有一定的帮助,对于配置CY ...

随机推荐

  1. 用caffe一步一步实现人脸检测

    学习深度学习已有一段时间了,总想着拿它做点什么,今天终于完成了一个基于caffe的人脸检测,这篇博文将告诉你怎样通过caffe一步步实现人脸检测.本文主要参考唐宇迪老师的教程,在这里感谢老师的辛勤付出 ...

  2. [luogu P3797] 妖梦斩木棒 [线段树]

    题目背景 妖梦是住在白玉楼的半人半灵,拥有使用剑术程度的能力. 题目描述 有一天,妖梦正在练习剑术.地面上摆放了一支非常长的木棒,妖梦把它们切成了等长的n段.现在这个木棒可以看做由三种小段构成,中间的 ...

  3. 关于线程和junit注入失败的问题

    问题: 在使用spring的时候,通常会使用注释@Autowired或@Resource注入java Bean; 但是在碰到线程类和测试类的时候就不支持注入方式了. 定义: 线程类:继承thread或 ...

  4. 机器学习 —— 类不平衡问题与SMOTE过采样算法

    在前段时间做本科毕业设计的时候,遇到了各个类别的样本量分布不均的问题——某些类别的样本数量极多,而有些类别的样本数量极少,也就是所谓的类不平衡(class-imbalance)问题. 本篇简述了以下内 ...

  5. Android - 基于 Speex 的高度封装语音库,0 耦合使用

    作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...

  6. taskctl实现自定义mysql存储过程作业类型调用

    TASKCTL支持任意作业类型的扩展,但目前TASKCTL 4.1.3版本中并没有内置mysql存储过程的作业插件.通过介绍使TASKCTL支持调度mysql存储过程作业类型的步骤,一方面解决一些朋友 ...

  7. 初学Python(十)——列表生成式

    初学Python(十)--列表生成式 初学Python,主要整理一些学习到的知识点,这次是列表生成式. # -*- coding:utf-8 -*- ''''' 列表生成式 ''' #一行代码表达所有 ...

  8. 用u盘装系统,进入bios后没有usb启动项怎么办

    开机按DEL进入BIOS(现在还这么说吧,不同的主板进入方法不太一样),找到BOOT选项. 选择Boot mood:legacy support(引导模式,逻辑支持) boot priorty:leg ...

  9. java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析

    java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java ...

  10. jQuery基础知识总结二

     * DOM操作 *1 基本操作 * html() - 等价于innerHTML属性 * text() - 等价于textContent属性 * val() - 等价于value属性 * attr() ...