zoukankan      html  css  js  c++  java
  • USB学习笔记连载(二十一):CY7C68013A进行数据传输(一)

      官方手册中给出了bulkloop参考例程,此例程是PC从端口2发送出数据,然后从端口6接收到数据,那么根据这个思想,可以进行修改,使得PC机接收到的数据不是从EP2发送过来的,而是从外部逻辑,比如FPGA处送来的数据。那么如何进行修改呢?

    //=============================================

    void TD_Init(void)             // Called once at startup
    {
       BYTE dum;                    // For the LEDS
       CPUCS = ((CPUCS & ~bmCLKSPD) | bmCLKSPD1) ;    // 48 MHz CPU clock
       // Turn off all 4 LEDS
       dum = D2OFF;
       dum = D3OFF;
       dum = D4OFF;
       dum = D5OFF;

    // EP2CFG & EP6CFG configure our two endpoints, EP2-OUT and EP6-IN
    // b7:        Valid
    // b6:        DIR (0=OUT, 1=IN)
    // b[5:4]    Type (01=ISO, 10=BULK, 11=INT)
    // b3:        Size (0=512, 1=1024 bytes)
    // b2:        0
    // b[1:0]    Buffering (00=quad, 10=double, 11=triple)       
    //

      EP2CFG = 0xA2;    // Valid, BULK-OUT, 512 byte buffer, double-buffered
      SYNCDELAY;        // Some regs take longer to update, see TRM Section 15.14.                   
      EP6CFG = 0xE2;    // Valid, BULK-IN, 512 byte buffer, double-buffered
      SYNCDELAY;                   

      // OUT endpoints do not come up armed
      // Since the endpoint is double buffered we must write dummy byte counts twice
      EP2BCL = 0x80;      // arm EP2OUT by writing byte count w/skip.
      SYNCDELAY;                   
      EP2BCL = 0x80;    // again
      SYNCDELAY;                   
      // enable dual autopointer feature
      AUTOPTRSETUP |= 0x01;

      USBIE |= bmSOF;                // Enable the SOF IRQ to serve as LED timers
      EPIE = bmEP6IRQ | bmEP2IRQ;    // Enable EP6 and EP2 Interrupts to turn on transfer LEDS
    }

    //=============================================

    void TD_Poll(void)              // Called repeatedly while the device is idle
    {
      WORD i;
      WORD count;
    //  BYTE dummy_LED2;        // ***For the LED
      BYTE waiting_inpkts;

    #ifdef ENABLE_7_SEG_DISPLAY
    if(start_7_seg_display)
    {
    // update 7-seg readout with number of IN packets waiting for transfer to the host
      waiting_inpkts = (EP6CS & 0xF0)>>4;
      EZUSB_WriteI2C(LED_ADDR, 0x01, &(Digit[waiting_inpkts]));
      EZUSB_WaitForEEPROMWrite(LED_ADDR);
    }
    #endif

    // Transfer EP6-OUT buffer to EP2-IN buffer when there is a packet in one of the EP6-OUT buffers, AND
    // there is an available EP2-IN buffer. The FIFO status flags update after full packets are transferred.
    // Therefore EP2-OUT "Not Empty" means a packet is available, and "EP6-IN "Not Full" means there is an
    // available buffer. Using the flags this way handles any packet size and takes multiple buffering
    // into account.  

        if(!(EP2468STAT & bmEP2EMPTY))        // Is EP2-OUT buffer not empty (has at least one packet)?
        {
            if(!(EP2468STAT & bmEP6FULL))    // YES: Is EP6-IN buffer not full (room for at least 1 pkt)?
             {
            APTR1H = MSB( &EP2FIFOBUF );
            APTR1L = LSB( &EP2FIFOBUF );
            AUTOPTRH2 = MSB( &EP6FIFOBUF );
            AUTOPTRL2 = LSB( &EP6FIFOBUF );

            count = (EP2BCH << 8) + EP2BCL;

            // loop EP2OUT buffer data to EP6IN
            for( i = 0; i < count; i++ )
            {
                EXTAUTODAT2 = EXTAUTODAT1;    // Autopointers make block transfers easy...
            }
            EP6BCH = EP2BCH;        // Send the same number of bytes as received 
            SYNCDELAY; 
            EP6BCL = EP2BCL;        // arm EP6IN
            SYNCDELAY;                   
            EP2BCL = 0x80;          // arm EP2OUT
         }
      }
    }

    上面程序是bulkloop中的TD_POLL()中的程序,此代码执行的就是EP6从EP2中取出数据,再发送到PC机,之前也有提及到,在TD_POLL()中的程序是供用户控制外部设备使用,那么将TD_POLL()中的所有代码去除掉,就不会执行从EP2数据发送到EP6数据中了。

      上述还有一个地方需要注意,若是定义某个端点为输出,那么在初始化时需要进行2次初始化,如下:

    image   如果是4缓冲,那么这里就要初始化四次。

      对于 摄像头 ----》 FPGA -----》USB架构,那么将USB定义为slave FIFO模式,相关初始化参数如下:

    void TD_Init(void)              // Called once at startup
    {
        // set the CPU clock to 48MHz, Default 12MHz(Page 333)
        //CPUCS = 0x02;  //12MHZ CLKOUT ENALBE   
      //CPUCS = 0x0a;  //24MHZ CLKOUT ENALBE 
      CPUCS = 0x12;  //48MHZ CLKOUT ENALBE,时钟不反向,CLKOUT PIN驱动,有时钟输出;     
        SYNCDELAY;    
        
    //Interface Configure(Page 334)
        IFCONFIG =0x03;    //选择为外部时钟,且时钟频率为30MHz,且为同步slaveFIFO模式,输入IFCLK(5~48MHz)(0000_0011)
        //IFCONFIG =0x0B;//选择为外部时钟,且为异步slaveFIFO模式,不需要IFCLK
        SYNCDELAY;
        
    //Configure REVCTL for Chip Revision Control(Page 344)
        REVCTL = 0x03;        //Cypress highly recommends setting both bits to 1
        SYNCDELAY;
    
        Rwuen = TRUE; // Enable remote-wakeup
    
    //--------------------------------------------------------
    //Set  FIFO端点0-3状态: EP2CFG、EP4CFG、EP6CFG、EP8CFG(只用到EP2CFG,选择512B/1024B,输入)
        EP1OUTCFG = 0xA0;     // default values(Page 346)
        SYNCDELAY;          
        EP1INCFG = 0xA0;      // default values(Page 346)
        SYNCDELAY;          
        EP2CFG = 0xE0;            // enabled, quad buffered, 512B, IN, bulk fifo, 4 buffer(Page 347)
    //    EP2CFG = 0xE8;        // enabled, quad buffered, 1024B, IN, bulk fifo, 4 buffer
        SYNCDELAY;         
        EP4CFG = 0x60;             // disabled...
        SYNCDELAY;         
        EP6CFG = 0x60;             // disabled...
        SYNCDELAY;          
        EP8CFG = 0x60;             // disabled...
        SYNCDELAY;
        
    //--------------------------------------------------------    
    //Configure the EPxFIFOCFG(Page 349)
        EP2FIFOCFG = 0x08;     // autoin, 8 Bit Wide
    //    EP2FIFOCFG = 0x09;     // autoin, 16 Bit Wide
        SYNCDELAY;             
        EP4FIFOCFG = 0x00;    // no-autoOUT, bytewide
        SYNCDELAY;                     
        EP6FIFOCFG = 0x00;     // no-autoOUT, bytewide
        SYNCDELAY;                     
        EP8FIFOCFG = 0x00;    // no-autoOUT, bytewide
        SYNCDELAY;    
        
    //--------------------------------------------------------
    //Configure PIN Polarity
        PORTACFG |= 0x40;    //IFCOG[1:0] = 11(Slave FIFO Mode), Set PORTACFG[6] to USE PA7-SLCS (Page 375)
        SYNCDELAY;    
        FIFOPINPOLAR = 0x04;    //BIT[5:0] = {PKTEND, SLOE, SLRD, SLWR, EMPTY, FULL}
                                                    //Set SLWR High Valid; PKTEND,SLOE,SLRD EMPTY, FULL Low Active(Page 342)
        SYNCDELAY;
        
        
    //--------------------------------------------------------
    //设置为Autoin时的自动传输包大小(Page 351)
        SYNCDELAY;
         EP2AUTOINLENH = 0x02; // EZ-USB automatically commits data in 512-byte chunks
    //     EP2AUTOINLENH = 0x04; // EZ-USB automatically commits data in 1024-byte chunks
        SYNCDELAY;
         EP2AUTOINLENL = 0x00;
        SYNCDELAY;
    
    //Set Autopointer, enable dual autopointer(Page 328)
        AUTOPTRSETUP |= 0x01;  
    
    
    //FLAGA - User-Programmable Level; FLAGB - FIFO Full, FLAGC - FIFO Empty: (L: Valid)(Page 338)
        PINFLAGSAB = 0x00;//0x8a;
        SYNCDELAY;  
        PINFLAGSCD = 0x00;//0x08;
        SYNCDELAY;             
    
    
        //复位FIFO,先复位端点,再清空端点(Page 340)
        SYNCDELAY;
        FIFORESET = 0x80;// activate NAK-ALL to avoid race conditions
        SYNCDELAY;
        FIFORESET = 0x02;// reset, FIFO 2
        SYNCDELAY;
         FIFORESET = 0x04;// reset, FIFO 4
        SYNCDELAY;
        FIFORESET = 0x06;// reset, FIFO 6
        SYNCDELAY;
      FIFORESET = 0x08;// reset, FIFO 8
        SYNCDELAY;
        FIFORESET = 0x00;// deactivate NAK-AL
        SYNCDELAY;
  • 相关阅读:
    C++编程入门题目--No.5
    C++编程入门题目--No.4
    C++编程入门题目--No.3
    C++编程入门题目--No.2
    C++入门编程题目 NO.1
    深度使用魅族16T后的评价(本人魅友,绝对客观公正,不要盲目的为手机厂商辩护,想想从当初到现在,魅族正在一步步背离自己的信仰,有问题,解决问题才能有更好的发展)
    ACM及各类程序竞赛专业术语
    python刷LeetCode:3.无重复字符的最长子串
    python刷LeetCode:2.两数相加
    python刷LeetCode:1.两数之和
  • 原文地址:https://www.cnblogs.com/raymon-tec/p/5378299.html
Copyright © 2011-2022 走看看