大家好,好久不见了,距离上次发文章都有两个多星期了,非常高兴同时也非常感谢你们能一直关注我。之前在公众号上收到网友的消息,其大概意思就是问我能不能出点USB干货,为此我就把第二篇——解密USB2.0数据传输机理推迟,先行为大家奉上沉甸甸的干货,希望大家在看完后能多多提建议。

  本期文章的主题是CY7C68013A固件程序开发,首先我会简要介绍一下CY7C68013A这款芯片以及官方提供的开发包,然后拿出开发包中的一个例程为大家详细剖析固件程序的整个框架,这些内容主要是为之后的功能实现打基础。

  CY7C68013A是Cypress公司FX2LP系列的一款USB2.0控制器,该款芯片以8051内核(是不是想到了STC 51单片机了)为核心,配合USB硬件实现,再加上高速的对外并行接口GPIF(SlaveFIFO),简直是FPGA与PC之间的高速公路,这也正是我选择这款芯片的原因。

  CY7C68013A的主要特点有:

  ◆  增强型8051内核,48MHz/24MHz/12MHz可选的CPU时钟,扩展的中断系统

  ◆  I2C、USART

  ◆  16KB 片上代码/数据RAM

  ◆  支持USB2.0 高速和全速传输

  ◆  4个可编程的批量/中断/同步传输端点,一个控制传输专用端点0,一个可编程64字节批量/中断端点

  ◆  8位/16位GPIF(SlaveFIFO)接口

  ◆  USB和GPIF二级中断向量

  ◆  4个专用于USB大量数据传输的端点FIFO

✦1 CY7C68013A功能框图

  图1是CY7C68013A的功能框图,其实我们可以把它们分类成4块:

  1)       8051内核和RAM:任务调度和数据处理,初始化各个模块;

  2)       I2C主控:配置I2C从机,主要还是从(往)EEPROM读(写)代码和数据,用来固化程序;

  3)       GPIF和FIFO:与外部高速设备交换数据,当我们和FPGA连接时,通常工作在SlaveFIFO模式;

  4)       USB2.0高速/全速收发器和USB1.1/2.0智能引擎:USB2.0协议的硬件实现,简化了我们的开发工作,我们只需操作端点FIFO就能实现与PC的数据交换。

  针对FX2LP系列USB2.0控制器,Cypress公司为我们提供了一个强大的开发包。这是开发包的下载地址:http://china.cypress.com/documentation/development-kitsboards/cy3684-ez-usb-fx2lp-development-kit。下载后直接安装,当提示选择安装类型,选择Complete就行。在安装过程中会顺便安装两个工具:Keil uVision2和GPIF Designer,Keil就是编写固件程序的IDE,而GPIF Designer是专用于设计GPIF波形的工具。图2所示是安装后FX2LP_SDK的所有文件。Bin文件夹中只包含一个用于文件转换的工具——Hex2bix。Documentation是FX2LP_SDK所有的文档,有兴趣的朋友可以看看。Drivers包含FX2LP系列的windows驱动。Firmware是官方提供的固件程序例程,这些例程非常具有参考价值,能节省我们大量的时间,这也是我们最需要的。GPIF_Designer是GPIF波形编辑工具,在使用SlaveFIFO时用不上。Hardware是该套件的硬件设计资料,主要是给PCB设计人员使用的。Target包含的主要是我们编程所需的库文件。Updater是开发包更新工具。Utilities包含的是Hex2bix的Visual Studio工程。uV2_4K是Keil uVision2的安装路径。Windows Applications包含的是一些进行USB传输测试的上位机程序(Visual Studio工程)。

✦2 FX2LP_SDK中的文件

  开发固件程序使用的是Keil,开发包内的是比较老的uVision2版本,各位如果不想用它可以到网上下载更新的版本。下面我就以Firmware文件夹下的Bulkloop为例,来讲解固件程序的框架。

  首先找到Bulkloop例程,打开该工程,打开后如图3所示。

✦3 Bulkloop例程

  在该工程下有5个文件:fw.c是固件框架的主体,bulkloop.c集中了可供用户调度的函数,dscr.a51是一个包含了描述符的汇编文件,USBJmpTb.OBJ是由一个包含了二级中断向量表的汇编文件生成的OBJ文件,EZUSB.LIB是FX2LP自带的静态库文件。我们需要编辑的通常只有bulkloop.c和dscr.a51。不过为了介绍固件程序给我们提供的框架,还是要以fw.c为重点来了解。

  看到一个C程序,第一步就是找到它的main函数。在main函数中,首先定义了4个状态变量Sleep、Rwuen、Selfpwr、GotSUD,分别反映的是睡眠状态、唤醒状态、是否自我供电、是否接收到了Setup数据,在后面它们还会用到。紧接着是一个TD_Init()函数,该函数是给用户进行初始化的地方。再接下来是定位描述符的地址,这里有两种情况,一种是描述符存放在外部RAM,另一种是存放在内部RAM,当然了一般CY7C68013A是不会外接RAM的。再接下来是使能中断,这里的中断既有一级中断,又有二级中断。再接下来是进行重枚举和连接,重枚举就是枚举成非默认USB设备,也就是使用用户固件程序指定描述符进行枚举。如果是从EEPROM启动,那么默认就会进行重枚举。至此初始化部分就结束了。

  从while(TRUE)开始是任务调度部分。首先调用的TD_Poll()函数,该函数是用户进行任务调度的函数。然后判断GotSUD,这是一个状态变量(前面见过),当该变量值为TRUE时说明Setup数据已经接收到了,这时就可以进行枚举过程,也就是调用SetupCommand()函数来响应主机的请求。接下来是判断Sleep变量,以此决定是否要进入睡眠模式,当进入睡眠模式后一直等待唤醒信号,唤醒时调用库函数EZUSB_Resume进行唤醒,同时还提供了TD_Resume给用户使用。

  固件框架最大的贡献是帮我们完成了枚举过程(SetupCommand()函数),在SetupCommand()函数中处理了各种由主机发出的标准设备请求。那么既然是针对设备请求进行响应,先来看看设备请求是什么样的。如图4所示,设备请求有8字节,其中bmRequestType指定了请求类型、方向、接收者,bRequest是请求码(参考图5),还有6字节由具体的设备请求来确定。

✦4 8字节设备请求

✦5 CY7C68013A的标准设备请求和厂商请求

  设备请求的8字节被USB设备(CY7C68013A)接收到后就会存入到8字节的SETUPDAT寄存器中,固件程序的SetupCommand函数就是根据SETUPDAT中的数据来进行响应的。首先需要判断的是请求码(也就是SETUPDAT[1]),固件框架响应的请求有:Get Descriptor、SC_GET_INTERFACE、SC_SET_INTERFACE、SC_SETCONFIGURATION、SC_GET_CONFIGURATION、SC_GET_STATUS、SC_CLEAR_FEATURE、SC_SET_FEATURE,除此之外对于不是标准设备请求的厂商请求(参考图5),专门给用户提供其响应函数DR_VendorCmnd()。如果请求不能正确响应,那么就需要调用EZUSB_STALL_EP0()函数来将端点0挂起。关于每种请求应该如何响应,可以参考FX2LP_SDK中的EZ-USB® Technical Reference Manual文档,在该文档的第2章Endpoint Zero中有详细的说明。在SetupCommand()函数的最后调用了这条语句:EP0CS |= bmHSNAK,这条语句非常重要,它的作用就是往EP0CS的HSNAK位写1清0,以此来完成一次完整的控制传输,否则这次的控制传输就不会结束,那么主机就会处于等待状态或者直接就是枚举失败。

  固件框架中还有一个比较重要的就是中断系统,尤其是USB二级中断(见图6)。中断服务函数绝大多数在bulkloop.c中(唯一的例外是唤醒中断,该中断并不交给用户使用),这些中断服务函数中有一部分是空函数,有语句需要执行的只有几个USB二级中断,其中比较典型的有ISR_Sudav()和ISR_Susp()。ISR_Sudav()在接收到Setupdata数据并且可用的情况下就会触发,我们可以看到GotSUD = TRUE这条语句就是在这时候执行,这正好和前面讲的呼应了。ISR_Susp()与之类似,当有睡眠信号发生时就会触发,并且将Sleep变量赋值为TRUE,那么在while(TRUE)循环中就会调用进入睡眠的函数。需要用到的USB二级中断服务函数都会执行下面两条语句:EZUSB_IRQ_CLEAR();USBIRQ = bmSUSP;,它们的作用就是清除USB一级中断请求位以及相应的二级中断请求位,清除之后才能再次触发中断。

✦6 USB二级中断

  最后,还剩下一个dscr.a51文件,这里存放的就是USB设备的描述符信息,这些描述符会在枚举的过程(SetupCommand()函数)中提交给主机。有关描述符以及本篇文章中其他的USB协议的概念需要等到解密USB2.0数据传输机理这篇文章发布时再做介绍。

  再次感谢大家对大熊FPGA的关注,持续关注还能收到更多的干货哟!

庖丁解牛——CY7C68013A开发框架的更多相关文章

  1. Enterprise Solution 3.1 企业应用开发框架 .NET ERP/CRM/MIS 开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    行业:基于数据库的制造行业管理软件,包含ERP.MRP.CRM.MIS.MES等企业管理软件 数据库平台:SQL Server 2005或以上 系统架构:C/S 开发技术 序号 领域 技术 1 数据库 ...

  2. 从零开始编写自己的C#框架(27)——什么是开发框架

    前言 做为一个程序员,在开发的过程中会发现,有框架同无框架,做起事来是完全不同的概念,关系到开发的效率.程序的健壮.性能.团队协作.后续功能维护.扩展......等方方面面的事情.很多朋友在学习搭建自 ...

  3. CRL快速开发框架系列教程十三(嵌套查询)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  4. CRL快速开发框架系列教程十二(MongoDB支持)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  5. CRL快速开发框架系列教程十一(大数据分库分表解决方案)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  6. CRL快速开发框架系列教程十(导出对象结构)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  7. CRL快速开发框架系列教程九(导入/导出数据)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  8. CRL快速开发框架系列教程七(使用事务)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  9. CRL快速开发框架系列教程六(分布式缓存解决方案)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

随机推荐

  1. Easyui设置动态表格,动态导出数据实例,附Dome

    最近碰到一个需求,需要提供一个弹出页面选择列表页面需要显示的列,页面确认之后需要修改列表页面显示的表格,导出的数据也需要同步变化. 下面直接上代码 1.设置需要显示的列columus为全局对象,用于子 ...

  2. 使用jQuery修改动态修改超链接

    以下是修改a元素标签的href链接和文字的代码: <script type="text/javascript" src="jquery-1.9.1.min.js&q ...

  3. nodejs 字符串全排列 和 去重

    以前写了个java版的 现在写个nodejs 版的 var list = sort('CCAV');var noRepeat = {};for(var i in list){ noRepeat[lis ...

  4. 遇到build的问题

    可以打开C/C++BUILD里面把build直接改成cmd,cmd   path是有的

  5. panic和recover的使用规则

    转自个人博客 chinazt.cc 在上一节中,我们介绍了defer的使用. 这一节中,我们温习一下panic和recover的使用规则. 在golang当中不存在tye ... catch 异常处理 ...

  6. Android studio出现Error:Unable to tunnel through proxy. Proxy returns "HTTP/1.1 400 Bad Reques的解决办法

    最近更新了一下Android Studio,在导入新项目之后出现Error:Unable to tunnel through proxy. Proxy returns "HTTP/1.1 4 ...

  7. haproxy+tomcat集群搭建

    web1和web2的部署可参考我之前的文章<Tomcat集群搭建>,这里就省去该过程了. #安装haproxy- .tar.gz cd haproxy-/ make TARGET=linu ...

  8. 基于Centos开启samba服务

    1.安装samba服务: yum -y install samba samba-common samba-client2.查看samba服务状态: service smb status: 正常状态是: ...

  9. pc端的企业网站(IT修真院test8)详解1-3

    一,base.css基础样式表的意义 我昨天,整理了一下代码规范. 发现现在这个程度的页面还原.有必要创建一个规范的base.css库和framework.css库 而且也要为日后的工作整理一些常用的 ...

  10. python基础(6):列表和字典类型

    前面我们所接触的数据类型都是存单个值,今天我们来看看可以存多个值的列表和字典. 预习: 1.有列表data=['alex',49,[1900,3,18]],分别取出列表中的名字,年龄,出生的年,月,日 ...