AnsweredAssumed Answered

PPI corrupt data BF527

Question asked by tcmichals on Dec 2, 2010
Latest reply on Dec 23, 2010 by tcmichals

Issue:  The second DMA transfer did not complete or data is corrupted.

 

Board: BF527 rev 0.2, (Memory and clock the same as EZKit BF527 and setup using init code and standard VDK adi_ssl_init.) Also, I'm loading the code via the visualVSP++ using the JTAG HighSpeed USB debugger.

 

The FPGA is connected the same wasy as figure 15-7 in the BF52x HW manual.  16 bit, 1 sync, external PPI CLK (200KHz)   The FPGA is generating a stream of 1045 16 bit values starting with an offset of 0x4000 ending at 0x4414 and restarting every 80ms. 

 

The fist DMA buffer is correct, but the second buffer does not fill the entire buffer the last  16 bit value are not present but the DMA buffer indicates completed cycle (ProcessedElementCount-415).  No errors on PPI (Status registes) or DMA..   The callback adi_dd_VCCD_PpiCallback, a check on the dma buffer to make sure the ramp data is correct.   The m_frame_count is 2 so not running out of DMA buffers... 

 

So the error in the buffer is

0x4412 0x4413 0xAAAA

 

The 0xAAAA should be 0x4414,  the first DMA buffer is correct.

 

Here is the general flow:

main()

... VDK init code, etc...

PPI.config()

PPI:init(1045)

FPGA.load()

 

....

 

#define MAX_DESC_VCCD        16

PPI::config()
{
       m_hPpiDevice = 0;

    //All of port F is PPI all 16 bits

    *pPORTF_FER |= 0xFFFF;
    ssync();

 

    //turn on PPI Clock
     *pPORTF_MUX = (1<<12);
    
     u32 eResult;
    m_frameCount = 0;
    eResult = adi_dev_Open(adi_dev_ManagerHandle,
                                /* PPI Entry point */
                            &ADIPPIEntryPoint,
                            0,
                             this,
                            &m_hPpiDevice,
                            ADI_DEV_DIRECTION_INBOUND,
                            adi_dma_ManagerHandle,
                               adi_DCBManagerHandle,
                            adi_dd_VCCD_PpiCallback);
                           
   /* IF (Successfully opened PPI Device) */
     if (eResult == ADI_DEV_RESULT_SUCCESS)
     {
     /* IF (Automatic PPI Control register Configuration enabled) */
                                /* Enable Streaming for PPI DMA */
              eResult = adi_dev_Control(m_hPpiDevice,
                                        ADI_DEV_CMD_SET_STREAMING,
                                        (void *)true);

 


      } /* End of if (Successfully opened PPI Device) case */
     

 

}

 

inline    bool PPI::init(unsigned int width)
{
    bool rc = false;
    u32 Result;
    int i;

 

    for (i=0; i < MAX_DESC_VCCD *2; ++i)
    {
        void *pData;
        if (NULL == (pData = (void *)malloc(width * sizeof(unsigned short))) )
            return rc;
       
         poolFreeBuffer(&m_freePool, pData);
            
    }
   
    m_testData = (unsigned short *)malloc(width * sizeof(unsigned short));
    if(m_testData) memset(m_testData, 0, sizeof(unsigned short) * width);
   
    m_width = width;
      ADI_PPI_CONTROL_REG ppi_control;
      u16 ppi_count = ( u16)((width-1) &0xFFFF);
     
       // Configure the PPI_CONTROL register
    ppi_control.port_en  = 0;    // Disable until ready
    ppi_control.port_dir = 0;    // Receive mode
    ppi_control.xfr_type = 3;    // Non ITU-R 656 mode
    ppi_control.port_cfg = 0;    // 1 external frame syncs
    ppi_control.fld_sel  = 0;    // ????
    ppi_control.skip_en  = 0;    // Not required
    ppi_control.skip_eo  = 0;    // Not required
    ppi_control.pack_en  = 0;    // Not required
    ppi_control.dlen     = 7;    // 16 Bits data length
    ppi_control.polc     = 0;    // Do not invert PPI_CLK
    ppi_control.pols     = 0;    // Do not invert PPI_FS1 & PPI_FS2

 


        // table of configuration values for the PPI on input   
    ADI_DEV_CMD_VALUE_PAIR InboundConfigurationTable [] = {
        { ADI_DEV_CMD_SET_DATAFLOW_METHOD,         (void *)ADI_DEV_MODE_CHAINED    },
        { ADI_PPI_CMD_SET_CONTROL_REG,             (void*)(*(u16*)&ppi_control)    },

 

        { ADI_PPI_CMD_SET_TRANSFER_COUNT_REG,     (void*)(*(u16*)&ppi_count)        },
        {ADI_DEV_CMD_SET_ERROR_REPORTING, (void*)TRUE},
         { ADI_DEV_CMD_END,                        NULL                            },
    };
       
   
    Result = adi_dev_Control( m_hPpiDevice, ADI_DEV_CMD_TABLE, (void*)InboundConfigurationTable );

 

    for (i=0; i < MAX_DESC_VCCD; ++i)
    {
        m_rxCCDDesc[i].Data = (void *)poolGetBuffer(&m_freePool);
        m_rxCCDDesc[i].ElementWidth = 2 ;
        m_rxCCDDesc[i].ElementCount = width ; //1D   
        m_rxCCDDesc[i].CallbackParameter= (void *)&m_rxCCDDesc[i];
        m_rxCCDDesc[i].pNext = (adi_dev_1d_buffer *)NULL;
        m_rxCCDDesc[i].pAdditionalInfo = (void *) this;
       
        memset(m_rxCCDDesc[i].Data, 0xAA, width *2);
       
            /* submit transfer buffers to LCD driver */
        if ((Result = adi_dev_Read(m_hPpiDevice,
                                //ADI_DEV_2D,
                                ADI_DEV_1D,
                                (ADI_DEV_BUFFER *)&m_rxCCDDesc[i]))
            != 0) {
        printf("adi_dev_Write failed. Error code: 0x%08X\n", Result);
  
        }

 


    }

    Result = adi_dev_Control(m_hPpiDevice, ADI_DEV_CMD_SET_DATAFLOW, (void *)TRUE);

 

 

    return rc;
}

 

 

void adi_dd_VCCD_PpiCallback(
    void                        *phClient,
    u32                         nEvent,
    void                        *pArg
)
{

 

    u32 Result;

 

    switch(nEvent)
    {
        case ADI_DEV_EVENT_BUFFER_PROCESSED:
        {

 

            ADI_DEV_1D_BUFFER *pBuffer = (ADI_DEV_1D_BUFFER *)pArg;
            //Some type of buffer issue;
            if(pBuffer==NULL)
                return;
   
            VCCD *pThis = (VCCD *)pBuffer->pAdditionalInfo;
   
            if(pThis)
                pThis->m_frameCount++;
       
            unsigned short *pCmpData = (unsigned short *)pBuffer->Data;
            unsigned short _cmpData = 0x4000;
            for(int _i=0; _i < pThis->m_width; _i++)
            if (pCmpData[_i] != _cmpData++)
            {
                    adi_dev_Control(pThis->m_hPpiDevice, ADI_DEV_CMD_SET_DATAFLOW, (void *)FALSE);
                    pThis->m_isFlag = true; <----TDebugger stops here on a breakpoint second buffer
            }
        }
        break;
        case ADI_DEV_EVENT_SUB_BUFFER_PROCESSED:
       
        break;
       
        case ADI_DEV_EVENT_DMA_ERROR_INTERRUPT:
            restartVCCD();
       
        break;
       
        case ADI_PPI_EVENT_ERROR_INTERRUPT:
            restartVCCD();
        break;
    }
}

Outcomes