AnsweredAssumed Answered

BF561 PPI via DMA Spurious Interrupt

Question asked by scaine on May 19, 2010
Latest reply on Jul 15, 2010 by scaine

I am using a 2D DMA on a BF561 to transfer data from an ADC connected to the PPI port into on chip memory.

I have set it to interrupt when each row is full so that I can go away and process this row while the next is collecting.

 

The PPI is being clocked at 4MSPS into a buffer made up of 4rows of 1024 samples (X_COUNT = 1024, Y_COUNT=4)

Occasionally I get a spurious second interrupt about 1us after the first one. This causes me problems as I then think that another buffer is ready when it is not. 

 

Has anyone experienced this problem, I have implemented in a variety of ways and still get the same problem.

 

Cheers

Steve

 

See code extract below

 

/*****************************************************************************
Function EnablePPI
Description Initialise and enable he PPI port for DMA transfers
Passed 
Return
Revisions
*****************************************************************************/
short EnablePPI()
{
int temp,i;

ppiOverrun = FALSE;
ppiRepeatInt = FALSE;
//Set up the monitoring Table
ppiCount = 0;
ppiOldest = 0;  //Index to oldest buffer
ppiNewest = 0;
for(i = 0;i<PPI_BUFF_COUNT;i++)
  ppiBufferState[i] = PPI_STATE_FREE; //Indicate buffers Free

 
//Set up the PPI Port
*pPPI1_CONTROL= 0x387C;
*pPPI1_DELAY = 0;
*pPPI1_COUNT = 0;
temp = *pPPI1_STATUS;

//Set up the DMA Transfers
//now setup the initial values in the registers
*pDMA1_1_Y_COUNT=PPI_BUFF_COUNT; //nBuff buffers of nWords each
*pDMA1_1_X_COUNT=PPI_BUFF_LEN;
*pDMA1_1_X_MODIFY=2; //step 2 bytes per word transferred
*pDMA1_1_Y_MODIFY=2;
*pDMA1_1_START_ADDR=ppiBuffer; //start at ppiBuffer

//now set the config register...but don't start it yet
*pDMA1_1_CONFIG=0x10D6; //small descriptor list, 2 words long, interrupt after

// Set up PPI1 interrupts on IVG8....see page 4-26 in hardware manual
*pILAT |= EVT_IVG8; // clear pending IVG8 interrupts
*pSIC_IAR0 = Peripheral_IVG(12,8);
ssync();

// all interrupts are on level 8...clear all sources
temp = *pPPI1_STATUS;
*pILAT |= EVT_IVG8; // clear pending IVG8 interrupts

//enable PPI1 interrupt sources
*pSIC_IMASK0 |= SIC_MASK(12);
//and register (also enables) handler
register_handler(ik_ivg8, PPI1_ISR);


*pDMA1_1_CONFIG |= 1; //Enable the DMA
    *pPPI1_CONTROL |= 1; //Enable the PPI Port

return SUCCESS;
}

/*****************************************************************************
Function DisablePPI
Description Disables the PPI transfers and free's relevent resources
Passed 
Return
Revisions
*****************************************************************************/
void DisablePPI()
{
*pPPI1_CONTROL &= ~1; //Disable the PPI
*pDMA1_1_CONFIG &= ~1; //Disable the DMA

}

/*****************************************************************************
Function PPI1_ISR
Description The interrupt handler for the PPI port
Passed 
Return
Revisions
*****************************************************************************/
EX_INTERRUPT_HANDLER(PPI1_ISR)
{


ppiBufferState[ppiNewest] = PPI_STATE_READY;
//Now update the index
ppiNewest++;
if(ppiNewest >= PPI_BUFF_COUNT)
  ppiNewest = 0;

if(PPI_STATE_FREE != ppiBufferState[ppiNewest])
{
  SetProcessIndicator(PROCESS_PPI_ERROR);
  ppiOverrun = TRUE;
}
ppiBufferState[ppiNewest] = PPI_STATE_ACQUIRING;

 
*pDMA1_1_IRQ_STATUS |= 3; //dismiss interrupt
// *pILAT |= EVT_IVG8;
ppiCount ++;

}

Outcomes