EZ-USB FX2(68013)固件研究(2)——bulkloop例子_学与玩_百度空间

       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;
EP1INCFG = 0xA0;
SYNCDELAY;                    // see TRM section 15.14
EP2CFG = 0xA2;
SYNCDELAY;                   
EP4CFG = 0xA0;
SYNCDELAY;                   
EP6CFG = 0xE2;
SYNCDELAY;                   
EP8CFG = 0xE0;

         这几行代码进行端点的配置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;                   
EP2BCL = 0x80;                // arm EP2OUT by writing byte count w/skip.
SYNCDELAY;                   
EP2BCL = 0x80;
SYNCDELAY;                   
EP4BCL = 0x80;                // arm EP4OUT by writing byte count w/skip.
SYNCDELAY;                   
EP4BCL = 0x80;
   

        这段代码对端点计数器进行初始化,注意这里两个端点都写了两次,那是因为我们设置的端点缓冲为512×2,假如缓冲倍率为4,即512×4的话,那么这里初始化要写4次。

// enable dual autopointer feature
AUTOPTRSETUP |= 0x01;

         这端代码告诉我们可以使用自动指针,也就是AUTOPTRHx两个自动指针,这两个自动指针使用方便,可以自动指向端点缓冲区。

       然后是TD_POLL();在这里处理相关数据传送,USB在空闲的时候会自动调用这里面的代码。


WORD i;
WORD count;

if(!(EP2468STAT & bmEP2EMPTY))
{ // check EP2 EMPTY(busy) bit in EP2468STAT (SFR), core set's this bit when FIFO is empty
     if(!(EP2468STAT & bmEP6FULL))
     { // check EP6 FULL(busy) bit in EP2468STAT (SFR), core set's this bit when FIFO is full

      首先,查询端点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指针
        APTR1L = LSB( &EP2FIFOBUF );

        AUTOPTRH2 = MSB( &EP6FIFOBUF ); //取端点6 fifo指针
        AUTOPTRL2 = LSB( &EP6FIFOBUF );

        count = (EP2BCH << 8) + EP2BCL; //计数器

        // loop EP2OUT buffer data to EP6IN
        for( i = 0x0000; i < count; i++ )      //传送count字节
        {
           // setup to transfer EP2OUT buffer to EP6IN buffer using AUTOPOINTER(s)
           EXTAUTODAT2 = EXTAUTODAT1;   //APTR1指针赋给APTR2,实现数据传送
        }

完毕后,重置计数器,以进行下次传输:

        EP6BCH = EP2BCH;
        SYNCDELAY;
        EP6BCL = EP2BCL;        // arm EP6IN
        SYNCDELAY;                   
        EP2BCL = 0x80;          // re(arm) EP2OUT
     }
}

以上即时bulkloop的整个工作过程,可以在interface中方便的看到结果,板子不在身边,就懒的贴图了。

                                                                                                                           【谷】



郑重声明:资讯 【EZ-USB FX2(68013)固件研究(2)——bulkloop例子_学与玩_百度空间】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——