4 Replies Latest reply on Nov 20, 2018 7:19 PM by zhro_2919396

    Can not return back to alternate interface setting 0 correctly

      Hi all,

       

      I am trying to use isoc transfer in CY7C68013. I have 2 interface settings: alt-0 for bulk transfer and alt-1 for isoc transfer.

      After device plugged in PC, the default setting alt-0 works. Then I select alt-1 and it also works. But when I select altl-0 again, the transfer failed.

      I tested this using CYStreamer and ControlCenter. I also used Bus hound to capture all the transfer, as following figure.

       

      捕获1.png

      I can not figure out why it cannot get the endpoint back to alt-1 setting correctly. What may be the reason?

       

      I am using the following two functions (set_ep2_isoc_mode and set_ep2_bulk_mode) to set the interface in DR_SetInterface.

      Here is the code snippet.

       

       

      BOOL DR_SetInterface(void)    

      {

        AlternateSetting = SETUPDAT[2];

      SYNCDELAY;

      switch(AlternateSetting)

      {

      case alt0_bulk_in:

      set_ep2_bulk_mode();

      break;

      case alt1_isoc_in:

      set_ep2_isoc_mode();

      break;

      }

         return(TRUE);         

      }

       

      // for alt-setting-0

      void set_ep2_bulk_mode(void)

      {

      // only use EP-1 out and EP-2 in, disable EP1_IN and EP4.6.8.

      EP1INCFG &= 0x7F;

      SYNCDELAY;

      EP4CFG &= 0x7F;     // EP4 not valid

      SYNCDELAY;

      EP6CFG &= 0x7F;     // EP6 not valid

      SYNCDELAY;

      EP8CFG &= 0x7F;     // EP8 not valid

      SYNCDELAY;

      // configure EP-1 bulk-out mode

      EP1OUTCFG = 0xA0; // valid, bulk

        SYNCDELAY;

      EP1OUTBC = 0x40; // arm the EP1 OUT endpoint by writing to the byte count

      SYNCDELAY;

      // configure EP-2 as bulk-IN

      EP2CFG = 0xE8; // BULK-IN, 0xE0: 512*4 bufferred, 0xE8: 1K*4 bufferred

      SYNCDELAY;

      // Clear out any committed packets

      FIFORESET = 0x80; // reset all FIFOs

      SYNCDELAY;

      FIFORESET = 0x82;

      SYNCDELAY;

      FIFORESET = 0x84;

      SYNCDELAY;

      FIFORESET = 0x86;

      SYNCDELAY;

      FIFORESET = 0x88;

      SYNCDELAY;

      FIFORESET = 0x00; // clear NAKALL bit to resume normal operation

      SYNCDELAY;

      EP2FIFOCFG = 0x0C; // b3:AUTOIN=1, b2:ZEROLEN=1, b0:WORDWIDE=0

      SYNCDELAY;

      EP2AUTOINLENH = 0x02; // Auto-commit 0x0200 = 512B, 0x0400=1KB

      SYNCDELAY;

      EP2AUTOINLENL = 0x00;

      SYNCDELAY;

      // Reset data toggle to 0

      TOGCTL = 0x12;  // EP2 IN

      TOGCTL = 0x32;  // EP2 IN Reset

      return;

      }

       

       

      // for alt-setting-1

      void set_ep2_isoc_mode(void)

      {

      // only use EP-1 out and EP-2 in, disable EP1_IN and EP4.6.8.

      EP1INCFG &= 0x7F;

      SYNCDELAY;

      EP4CFG &= 0x7F;     // EP4 not valid

      SYNCDELAY;

      EP6CFG &= 0x7F;     // EP6 not valid

      SYNCDELAY;

      EP8CFG &= 0x7F;     // EP8 not valid

      SYNCDELAY;

      // configure EP-1 bulk-out mode

      EP1OUTCFG = 0xA0; // valid, bulk

        SYNCDELAY;

      EP1OUTBC = 0x40; // arm the EP1 OUT endpoint by writing to the byte count

      SYNCDELAY;

      // configure EP-2 as isoc-IN

      EP2CFG = 0xD8;  // ISOC-IN, SIZE=1024, BUF=4x

      SYNCDELAY;

      FIFORESET = 0x80; // reset all FIFOs

      SYNCDELAY;

      FIFORESET = 0x82;

      SYNCDELAY;

      FIFORESET = 0x84;

      SYNCDELAY;

      FIFORESET = 0x86;

      SYNCDELAY;

      FIFORESET = 0x88;

      SYNCDELAY;

      FIFORESET = 0x00; // clear NAKALL bit to resume normal operation

      SYNCDELAY;

      EP2FIFOCFG = 0x0C; // b3:AUTOIN=1, b2:ZEROLEN=1, b0:WORDWIDE=0

      SYNCDELAY;

      EP2AUTOINLENH = 0x04; // Auto-commit

      SYNCDELAY;

      EP2AUTOINLENL = 0x00;

      SYNCDELAY;

      EP2ISOINPKTS = 0x83; //b7 = AADJ

      SYNCDELAY;

      return;

      }

       

      Any help will be appreciated.

       

      Thanks,

      Zheng

        • 1. Re: Can not return back to alternate interface setting 0 correctly
          SrinathS_16

          Hello Zheng,

           

          - Please share the screenshot of failure from the USB Control Center.

          - Kindly, test using the CYStream example firmware that comes with the CY3684 DVK and check if the behavior exists. When using this example, make sure that the EZUSB_WriteI2C() and EZUSB_ReadI2C() APIs are commented out.

           

          Best regards,

          Srinath S

          • 2. Re: Can not return back to alternate interface setting 0 correctly

            Hi Srinath,

             

            1. The following picture show the failure when I tried to get back to bulk transfer mode. I can  not get back to the alt-setting 0 for bulk-in transfer. I have to reset the device. Any clue?

            cc.PNG

             

            2. I tried  CYStreamer firmware with my device, and it works well. It can transit between bulk and isoc mode correctly.

             

            If necessary, I can provide more information.

             

            Thanks for your help.

             

            Best regards,

            Zheng

            • 3. Re: Can not return back to alternate interface setting 0 correctly
              SrinathS_16

              Hello Zheng,

               

              - Please modify the DR_SetInterface() function

               

              BOOL DR_SetInterface(void)

              {

              BYTE    updateDisplay = TRUE;

              AlternateSetting = SETUPDAT[2];

               

                  // ...FX2 in high speed mode

                  if( EZUSB_HIGHSPEED( ) )

                  {

                      // Change configuration based upon the Alt. Interface selected

                      switch (AlternateSetting)

                      {

                          case Alt0_BulkIN:

                                      // Only using endpoint 2, zero the valid bit on all others

                                      // Just using endpoint 2, zero the valid bit on all others

                                      EP2CFG = 0xE0;  // EP2 is DIR=IN, TYPE=BULK, SIZE=512, BUF=4x

                                      SYNCDELAY;

               

                                      EP1OUTCFG = 0xA0;

                              SYNCDELAY;

                                

                              EP1INCFG = (EP1INCFG & 0x7F);

                              SYNCDELAY;

                              EP4CFG = (EP4CFG & 0x7F);

                              SYNCDELAY;

                              EP6CFG = (EP6CFG & 0x7F);

                              SYNCDELAY;

                              EP8CFG = (EP8CFG & 0x7F);

                              SYNCDELAY;

                

                              // Clear out any committed packets

                              FIFORESET = 0x80;

                              SYNCDELAY;

                              FIFORESET = 0x02;

                              SYNCDELAY;

                              FIFORESET = 0x00;

                              SYNCDELAY;

                                    

                              EP1OUTBC = 0xFF;

                              SYNCDELAY;

                                    

                              // Reset data toggle to 0

                              TOGCTL = 0x12;  // EP2 IN

                              TOGCTL = 0x32;  // EP2 IN Reset

                

                          break;

                    

                          case Alt1_IsocIN:

                              // Only using endpoint 2, zero the valid bit on all others

                              EP2CFG = 0xD8;  // EP2 is DIR=IN, TYPE=ISOC, SIZE=1024, BUF=4x

                              SYNCDELAY;

                            

                              EP1OUTCFG = 0xA0;

                              SYNCDELAY;

                                

                              EP1INCFG = EP4CFG = EP6CFG = EP8CFG = 0x00;

                              SYNCDELAY;

                

                              // Clear out any committed packets

                              FIFORESET = 0x80;

                              SYNCDELAY;

                              FIFORESET = 0x02;

                              SYNCDELAY;

                              FIFORESET = 0x00;

                              SYNCDELAY;

                                    

                              EP1OUTBC = 0xFF;

                              SYNCDELAY;

                                

                              // This register sets the number of Isoc packets to send per

                              // uFrame.  This register is only valid in high speed.

                              EP2ISOINPKTS = 0x01;

                

                          break;

                      }

                  }

              ...

              ...

              }

               

              - Modify the TD_Poll() function block as follows:

               

              // ...FX2 in high speed mode

                  if( EZUSB_HIGHSPEED( ) )

                  {

                      // Perform USB activity based upon the Alt. Interface selected

                       switch (AlternateSetting)

                      {

                          case Alt0_BulkIN:

                              // Send data on EP2

                              while(!(EP2468STAT & bmEP2FULL))

                              {

                                  EP2FIFOBUF[0] = LSB(mycount);

                                  EP2FIFOBUF[1] = MSB(mycount);

                                  EP2FIFOBUF[2] = USBFRAMEL;

                                  EP2FIFOBUF[3] = USBFRAMEH;

                                  EP2FIFOBUF[4] = MICROFRAME;

                 

                                  EP2BCH = 0x02;

                                  EP2BCL = 0x00;

                 

                                  mycount++;

                              }

                          break;

                 

                          case Alt1_IsocIN:

                              // Send data on EP2

                              while(!(EP2468STAT & bmEP2FULL))

                              {

                                  EP2FIFOBUF[0] = LSB(mycount);

                                  EP2FIFOBUF[1] = MSB(mycount);

                                  EP2FIFOBUF[2] = USBFRAMEL;

                                  EP2FIFOBUF[3] = USBFRAMEH;

                                  EP2FIFOBUF[4] = MICROFRAME;

                 

                                  EP2BCH = 0x04;

                                  EP2BCL = 0x00;

                 

                                  mycount++;

                              }

                          break;

                     }

                    

                  }

              ...

              ...

              }

               

              - I have attached the descriptor file that I have used.

               

              Please make these changes in your firmware and let me know if it's working fine.

               

              Best regards,

              Srinath S

              1 of 1 people found this helpful
              • 4. Re: Can not return back to alternate interface setting 0 correctly

                Thanks Srinath for your help.

                Finally I fixed the issue by modifying the EP FIFO reset code snippet.

                Not all the EPs are required to be reset. Reset EP-2 only.

                FIFORESET = 0x02;

                 

                Best regards,

                Zheng