USB入门的{dy}个例子,肯定是bulkloop了,装好驱动,开发包后,在开发包下....Cypress\USB\Examples\FX2LP\Bulkloop就是bulkloop例子。 我之所以从bulkllop开始说,也是深有体会的。想当初刚开始学USB的时候,抱着协议闷头看楞是看不出个所以然,后来从例子开始学,才慢慢搞懂了USB,说实话,我到现在对USB协议类的DD还是一知半解,不过并不妨碍我进行USB的开发不是,所以说,Cypress的固件架构是个好东东,我们可以偷懒了。开发包里例子是基于Cypress的一块开发板的,我想很少有人能弄到吧,而bulkloop就简单了,什么外围都不需要,一块68013,加个cyconsole interface就可以看到效果了.可以说,看懂了bulkloop,USB也就算正式入门了,剩下的要做的就是触类旁通,然后再不停的回过头去看USB协议,就会恍然大悟“然来是这样”。 首先,看bulkloop文件夹下的readme.txt文件,告诉我们这个固件主要实现的功能。 数据从EP2OUT->EP6IN ,从端点2 out缓冲区到端点6的in缓冲区。数据流向为: ◆PC端(console软件)设定要传输的数据 ◆PC端发起端点2out传输,数据到达68013端点2的out缓冲区 ◆bulkloop固件查询到端点2的out缓冲区有数据,于是将数据发往端点6的IN缓冲区 ◆PC端发起端点6 IN传输,于是68013的端点6 IN缓冲区中的数据被读到PC机显示 这就是整个bulkloop过程,EP4->EP8同理。 然后看固件,看一个固件总是从TD_Init()开始的: CPUCS = ((CPUCS & ~bmCLKSPD) | bmCLKSPD1) ; IFCONFIG |= 0x40; 这两句设定CPU工作状态以及端口的工作模式。bmCLKSPD,bmCLKSPD1是一个预定义,在FX2.H文件中有定义,keil应该都会用的,直接go to definition...跳到定义处查看;至于语法,使用了与或操作,用来进行位操作,置1或清0,编程语言中常用的技巧,C语言不要太差哦~然后寄存器每位的意义,我们在TRM中可以查到,这两句告诉我们:设定68013 CPU时钟为48M,端口工作模式为普通的IO口。 EP1OUTCFG = 0xA0; 这几行代码进行端点的配置EP2,EP4为out端点,512×2缓冲;EP6,EP8为in端点,512×2缓冲。 例如EP2CFG=0XA2=1010 0010,看TRM对该寄存器的解释,b7(第8位)=1-该端点有效;b6=0,该端点为out传输;b5b4=10,该端点进行bulk传输;b3=0,端点为512缓冲;b2=0,只读;b1b0=10,该端点缓冲区倍率为双重,即512×2.其他同理。 SYNCDELAY; 这段代码对端点计数器进行初始化,注意这里两个端点都写了两次,那是因为我们设置的端点缓冲为512×2,假如缓冲倍率为4,即512×4的话,那么这里初始化要写4次。 // enable dual autopointer feature 这端代码告诉我们可以使用自动指针,也就是AUTOPTRHx两个自动指针,这两个自动指针使用方便,可以自动指向端点缓冲区。 然后是TD_POLL();在这里处理相关数据传送,USB在空闲的时候会自动调用这里面的代码。
if(!(EP2468STAT & bmEP2EMPTY)) 首先,查询端点2的EMPTY标志,如果不为1,说明有数据,然后查询端点6的FULL标志,如果不为1,说明端点6 FIFO为空,可以接收数据。至于bmEP2EMPTY,bmEP6FULL,自行go to definition... 当检查到端点2 out fifo有数据且端点6 in fifo为空时,就可以将ep2的数据"copy"到ep6.使用自动指针直接更换2者的指针,实现数据传送: APTR1H = MSB( &EP2FIFOBUF ); //取端点2 FIFO指针 AUTOPTRH2 = MSB( &EP6FIFOBUF ); //取端点6 fifo指针 count = (EP2BCH << 8) + EP2BCL; //计数器 // loop EP2OUT buffer data to EP6IN 完毕后,重置计数器,以进行下次传输: EP6BCH = EP2BCH; 以上即时bulkloop的整个工作过程,可以在interface中方便的看到结果,板子不在身边,就懒的贴图了。 【谷】
|