GPIF cannot be restarted after GPIFABORT

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
klbac_1564681
Level 1
Level 1

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

0 Likes
1 Solution
klbac_1564681
Level 1
Level 1

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;

}

View solution in original post

0 Likes
1 Reply
klbac_1564681
Level 1
Level 1

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;

}

0 Likes