1 Reply Latest reply on Jan 22, 2019 9:25 AM by klbac_1564681

    GPIF cannot be restarted after GPIFABORT

    klbac_1564681

      We use a FX2LP to stream data form a camera to USB. GPIF is used to crop some data out of the stream. It's running in an continuos FIFO read mode until the GPIF is stopped by GPIFABORT. But after stopping it, the GPIF cannot be restarted. There are no data coming into the fifo after GPIFABORT and trying to restart. GPIF_DONE is set to one after writing GPIFABORT and it's set to 0 again after restarting the GPIF. But there are no data coming in after restart.

      Even after a reset of the fx2lp, the GPIF isn't working anymore. Only powering off and on again can put it to work again.

       

      Can someone help with this problem?

       

      code used to stop and restart:

      /**
          set gpif crop parameters:
      **/ 
      void vcmd_CROP_PAR(void)
      {
          // disable interrupt while changing gpif
          EA  = 0;
          
          // stop GPIF
          GPIFABORT=0xFF;
          SYNCDELAY;
          // wait until idle
          while (!(GPIFTRIG & 0x80))
          {
              SYNCDELAY;
          }
          
          // set new GPIF data
          //gpifConfig.WaveData[0x41]=SETUPDAT[2];    
          // initialize gpif
          //GpifInit();
          
          // launch GPIF FIFO Read transaction to EP2IN
          GPIFTRIG = GPIFTRIGRD | GPIF_EP2; 
          // re-enable interrupt
          EA = 1;
      }
      

       

      initializing on startup (geckoInit(), MPUinit() are just initializations of a peripheral devices) :
      // Called once at startup
      void TD_Init(void)
      {
        xdata int serial;
      
        // Enable remote-wakeup
        Rwuen = TRUE;
        // 48 MHz CPU clock
        CLOCK48MHZ;
        // stretch value = 0 for fast memory access, T2M=0, Timer 2 is clocked by CLK/12
        CKCON=0;
        SYNCDELAY;
        // REVCTL.0 and REVCTL.1 to set to 1
        REVCTL = 0x03;
      
        // use dual autopointer feature...
        AUTOPTRSETUP=0x07;
        SYNCDELAY;
      
        // reset endpoint FIFOs
        // FIFO for debug output
        RESETFIFO(0x01);
        // fifo for data output (image data and inertial sensor data)
        RESETFIFO(0x02);
      
        // enable extern INT1#, INT#0;
        // INT#0: end of frame signal from image sensor
        // INT#1: new data from inertial sensor
        PORTACFG=0x03;
        SYNCDELAY;
        // detect Interrupt 0,1 on falling edge
        TCON |= 0x05;
        SYNCDELAY;
        // SLWR and SLOE is configured as active HIGH
        // SLWR is used to detect line valid signal from image sensor
        FIFOPINPOLAR = 0x14;
        SYNCDELAY;
      
        // EP2: Valid, DIR in, Type SO, Size 1024 Bytes, Quad Buffered
        // EP2 is used to transfer image data and inertial data
        EP2CFG = 0xD8;
        SYNCDELAY;
      
        // EP1 in: Bulk
        // EP1 is used for transmitting debug messages
        EP1INCFG =0x82;
        SYNCDELAY;
      
        // switch off all other endpoints
        EP1OUTCFG &=0x7F;
        SYNCDELAY;
        EP4CFG &=0x7F;
        SYNCDELAY;
        EP6CFG &=0x7F;
        SYNCDELAY;
        EP8CFG &=0x7F;
        SYNCDELAY;
      
        // This register sets the number of Isoc packets to send per
        // uFrame.  This register is only valid in high speed.
        EP2ISOINPKTS = 0x83;
        SYNCDELAY;
      
        // EP2 FIFO: AUTO IN, NO Zero Length Packets, 8- bit Wide
        EP2FIFOCFG = bmAUTOIN;
        SYNCDELAY;
        // switch off all other FIFOs
        EP4FIFOCFG=0;
        SYNCDELAY;
        EP6FIFOCFG=0;
        SYNCDELAY;
        EP8FIFOCFG=0;
        SYNCDELAY;
        // EP2: Auto-commit 1024-byte packets
        EP2AUTOINLENH = 0x04;
        SYNCDELAY;
        EP2AUTOINLENL = 0x00;
        SYNCDELAY;
      
        // enable PORTD general functions by writing IFCONFIG after WORDWIDE bits in EPxFIFOCFG are all cleared
        // internal ifclk used: slave FIFO enabled, IFCLK inverted, internal IFCLK 48Mhz
        IFCONFIG=0xD3;
        SYNCDELAY;
      
        // FLAGA=PF, FLAGB=FF, FLAGC=EF, FLAGD=EP2PF (Actual FIFO is selected by FIFOADR[0,1] pins)
        // Slave FIFO FLAGA and FLAGB Pin Configuration
        PINFLAGSAB = 0x00;
        SYNCDELAY;
        // Slave FIFO FLAGC and FLAGD Pin Configuration
        PINFLAGSCD = 0x00;
        SYNCDELAY;
      
        // Endpoint 2 / slave FIFO Programmable Flag H
        //  Flag A active on 3 Buffers filled and 4th buffer >0
        //    b7 DECIS = 1
        //    b6 PKSTAT = 0
        //    b5..b3 PKTS = 3
        //    b2 = 0
        //    b1..b0 PFC9..PFC8 = 0
        EP2FIFOPFH=0x98;
        SYNCDELAY;
        // b7..b0 PFC7..PFC0 = 0
        EP2FIFOPFL=0x00;
        SYNCDELAY;
      
        // set SPI CLK to 0
        SPI_CLK=0;
        // deselect Python
        PYTHON_SELECT=1;
        // reset Python trigger
        PYTHON_TRIGGER0=0;
        // deselect IMU
        MPU_SELECT=1;
        // switch leds on
        //IRLED=1;
        // activcate Python
        PYTHON_RESET=1;
        // set PD for output: PD0,PD2,PD3,PD5,PD6,PD7 write
        OED = 0xED;
        WAKEUPCS=0x05;
        // set PA for output: PA3,PA7 write
        OEA=0x88;
        // trigger off
        PYTHON_TRIGGER0=0;
      
        // configure inertial sensor
        MPUinit();
      
        // timer 0: two 8 bit counters, timer 1 16 bit counter, timer 1 is started by mode selection
        // eof signal from image sensor triggers timer 0.
        // Timer 0 interrupt sends USB data (image and inertial values)
        // timer 1 is used to generate an internal 4Mhz timebase
        // timer1 is reset at each microframe
        TMOD=0x13;
        // clear timer 0 overflow flag
        TF0=0;
      
        // enable external interrupt 0,1, timer0
        // INT0: frame valid 0x01
        // INT1: inertial sensor interrupt
        // timer 0: delay after frame end
        IE=0x07;
      
        // enable external interrupt 5,
        // it's used to do sof tasks indirectly ( especially timer snapshot):
        // ISR_Sof triggers ISR_EXTR5
        EIE|=0x08;
      
        // INT0 priority
        PX0=1;
        // INT1 priority
        PX1=1;
        // INT 5 priority
        EIP |= 0x08;
        // USB interrupt priority
        PUSB=1;
      
        // enable USB autovector (AV2), FIFO autovector (AV4), INT4 source is FIFO
        INTSETUP = (bmAV2EN | bmAV4EN | INT4IN);
        // clear sof irq
        USBIRQ = bmSOF;
        // enable sof int
        USBIE |= bmSOF;
        // enable i2c
        EZUSB_InitI2C();
      
        // Enable Global Interrupt
        EA  = 1;
      
        // initialize gpif
        GpifInit();
      
        // initialize gecko
        geckoInit();
      
        // test output
        serial=SERIALNUM
        ;  // ; is in the next line intentionally, to detect it with dos command findstr
        PRINTF("Welcome to EasyCam2 %4d\r\n",serial);
      
        // start gpif by triggering fifo read waveform
      
        // launch GPIF FIFO Read transaction to EP2IN
        GPIFTRIG = GPIFTRIGRD | GPIF_EP2;
      }
      

       

      attached are the gpif configuration files

        • 1. Re: GPIF cannot be restarted after GPIFABORT
          klbac_1564681

          ok, i think i found the problem.

          Apparently in this setup, the Transaction Count Bytes have to be reseted before restarting the gpif. So the following code solved my problem:

           

          /**
            set gpif crop parameters:
            crop length in wValue[0] = SETUPDAT[2]
            ? in wIndex = SETUPDAT[4:5]
          **/
          void vcmd_CROP_PAR(void)
          {
            // disable interrupt while changing gpif
            EA  = 0;
          
            GPIFABORT=0xFF;
          
            SYNCDELAY;
            // wait until idle
            while (!(GPIFTRIG & 0x80))
            {
              SYNCDELAY;
            }
          
          
            // reset transaction count
            GPIFTCB0=01;
            SYNCDELAY;
            GPIFTCB1=00;
            SYNCDELAY;
            GPIFTCB2=00;
            SYNCDELAY;
            GPIFTCB3=00;
            SYNCDELAY;
          
            gpifConfig.WaveData[0x41]=SETUPDAT[2];
            // initialize gpif
            GpifInit();
          
            // launch GPIF FIFO Read transaction to EP2IN
            GPIFTRIG = GPIFTRIGRD | GPIF_EP2;
            // re-enable interrupt
            EA = 1;
          }