庖丁解牛——CY7C68013A开发框架
大家好,好久不见了,距离上次发文章都有两个多星期了,非常高兴同时也非常感谢你们能一直关注我。之前在公众号上收到网友的消息,其大概意思就是问我能不能出点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开发框架的更多相关文章
- 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 数据库 ...
- 从零开始编写自己的C#框架(27)——什么是开发框架
前言 做为一个程序员,在开发的过程中会发现,有框架同无框架,做起事来是完全不同的概念,关系到开发的效率.程序的健壮.性能.团队协作.后续功能维护.扩展......等方方面面的事情.很多朋友在学习搭建自 ...
- CRL快速开发框架系列教程十三(嵌套查询)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- CRL快速开发框架系列教程十二(MongoDB支持)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- CRL快速开发框架系列教程十一(大数据分库分表解决方案)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- CRL快速开发框架系列教程十(导出对象结构)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- CRL快速开发框架系列教程九(导入/导出数据)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- CRL快速开发框架系列教程七(使用事务)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- CRL快速开发框架系列教程六(分布式缓存解决方案)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
随机推荐
- php二进制流文件
<?php $img_file = 'test.png'; // $fp = fopen($img_file, 'rb'); // $content = fread($fp, filesize( ...
- as 快捷键
as 快捷键 Ctrl+G / Ctrl+Alt+Shift+G:查询变量或者函数或者类在哪里被使用或被调用,后者是前者的复杂表现,可以选择查询范围等. Alt+H:查找功能,全局查找 F4:查看类 ...
- php打包文件为ZIP包后下载到本地
这是一个工作中需要打包下载当前产品的所有图片到本地,文件格式为ZIP压缩包,打包下载文件跟图片一样,本程序细节为实际情况,使用需按照自己实际情况书写:<?php/**************** ...
- ListView 介绍
1. 通过继承Activity实现ListView 1.1 在XML布局文件中实现一个ListView <ListView android:layout_width="wrap_con ...
- 如何在家自制LED灯?很简单,我来告诉你!
首先LED分凸头.平头和凹头,当中的凹头是没无方向性. 做示宽灯这类晚间才运用的光源,用凹头就好,它没无方向性,可将整个反光碗照亮. 做转向灯等指示性的光源用,准绳上应该用凸头的,它是个聚光镜,投映的 ...
- 英文版windows7中文软件显示乱码的解决办法
一.打开控制面板,修改语言的归属地为China 修改完成之后重启,一般能解决大部分问题,如果依然有部分显示乱码,就需要去修改注册表
- TCP错误恢复特性之一TCP重传
TCP的错误恢复特性是我们用来定位.诊断并最终修复网络高延迟的最好工具. 常见的TCP错误恢复特性有:TCP重传.TCP重复确认和快速重传 1. TCP重传: 重传数据包是TCP最基本的错误恢复特性之 ...
- jsp实现上一页下一页翻页功能
前段时间一直忙于期末考试和找实习,好久没写博客了. 这段时间做了个小项目,包含了翻页和富文本编辑器Ueditor的两个知识点,Ueditor玩的还不是很深,打算玩深后再写篇博客. 要实现翻页功能,只需 ...
- python基础(3):输入输出与运算符
今天总结一下最基础的输入输出和运算符 输入: python3里都是input("") input() name = input() #输入的值会直接赋值给name name ...
- HDU 1698 Just a Hook(线段树成段更新)
题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1698 题目: Problem Description In the game of DotA, P ...