cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
brandonhamilton
Visitor
Visitor
2,752 Views
Registered: ‎08-14-2013

ZYNQ PCAP transfer problem

I am attempting to perform a PL Readback of the programmed ZYNQ ZC7020. To achieve this, the device configuration interface (devcfg) is used.

The PL is programmed first via JTAG, and then I run my program (see code below). The code is based on the polled example provided by the devcfg driver with EDK.


If 16 or less frames are read (i.e. ZYNQ_CONFIG_FRAMES <= 16), the readback completes sucessfully.

 

However, trying to read any more frames (i.e. ZYNQ_CONFIG_FRAMES > 16) causes the device to enter into an error state, and reading the interrupt status register (INT_STS) shows the RX_FIFO_OV_INT (bit 18) set. From the user guide this is explained as "This bit is used to indicate that RX FIFO overflows. Incoming read data from PCAP will be dropped and the DEVCI DMA may enter an unrecoverable state". The device is no longer responsive after this and a hard reset is needed.

I have tried to use different storage destinations, such as DDR, OCM and QSPI with the code, but this has no effect on the outcome at all.

 

Setting QUARTER_PCAP_RATE_EN (This bit is used to reduce the PCAP data transmission to once every 4 clock cycles) of the CTRL register also seems to have no effect.


How is it possible to readback the full PL configuration ?

 

#include <stdio.h>
#include "xdevcfg.h"
#include "platform.h"

#define ZYNQ_CONFIG_FRAMES 16
#define ZYNQ_CONFIG_WORDS_PER_FRAME 101

int main()
{
    int i;
    void *data;
    XDcfg_Config *configPtr;
    XDcfg devcfgInstance;
    u32 status;
    u32 intrStatusReg;
    u32 intrReg;
    u32 wait;

    init_platform();

    data = 0x01000000; // Use DDR memory to store readback data

    configPtr = XDcfg_LookupConfig(XPAR_PS7_DEV_CFG_0_DEVICE_ID);
    status = XDcfg_CfgInitialize(&devcfgInstance, configPtr, configPtr->BaseAddr);
    if (status != XST_SUCCESS) {
        print("Failure to initialise DevCfg.\n\r");
        return XST_FAILURE;
    }
    XDcfg_SetLockRegister(&devcfgInstance, 0x757BDF0D);

    status = XDcfg_SelfTest(&devcfgInstance);
    if (status != XST_SUCCESS) {
        print("Self-test failure.\n\r");
        return XST_FAILURE;
    }

    XDcfg_EnablePCAP(&devcfgInstance);
    XDcfg_SetControlRegister(&devcfgInstance, XDCFG_CTRL_PCAP_PR_MASK );

    XDcfg_IntrClear(&devcfgInstance, (XDCFG_IXR_PCFG_DONE_MASK | XDCFG_IXR_D_P_DONE_MASK | XDCFG_IXR_DMA_DONE_MASK));

    /* Check if DMA command queue is full */
    status = XDcfg_ReadReg(devcfgInstance.Config.BaseAddr, XDCFG_STATUS_OFFSET);
    if ((status & XDCFG_STATUS_DMA_CMD_Q_F_MASK) == XDCFG_STATUS_DMA_CMD_Q_F_MASK) {
        print("DMA command queue is full.\n\r");
        return XST_FAILURE;
    }

    status = XDcfg_Transfer(&devcfgInstance,
            fpga_readback_seq_head,
            sizeof(fpga_readback_seq_head)/4,
            ((u32) data),
            (ZYNQ_CONFIG_WORDS_PER_FRAME)*(ZYNQ_CONFIG_FRAMES),
            XDCFG_PCAP_READBACK);

    if (status != XST_SUCCESS) {
        print("Failure to transfer data.\n\r");
        return XST_FAILURE;
    }
   
    // Wait for DMA and PCAP transfers
    intrStatusReg = XDcfg_IntrGetStatus(&devcfgInstance);
    while ((intrStatusReg & XDCFG_IXR_DMA_DONE_MASK) != XDCFG_IXR_DMA_DONE_MASK) {
        intrStatusReg = XDcfg_IntrGetStatus(&devcfgInstance);
    }
    while ((intrStatusReg & XDCFG_IXR_D_P_DONE_MASK) != XDCFG_IXR_D_P_DONE_MASK) {
        intrStatusReg = XDcfg_IntrGetStatus(&devcfgInstance);
    }
    XDcfg_IntrClear(&devcfgInstance, (XDCFG_IXR_PCFG_DONE_MASK | XDCFG_IXR_D_P_DONE_MASK | XDCFG_IXR_DMA_DONE_MASK));

    print("Transfer completed");

    intrStatusReg = XDcfg_IntrGetStatus(&devcfgInstance);

    // intrStatusReg shows bit 18 set here, and the device no longer responds. when ZYNQ_CONFIG_FRAMES > 16
    
    return 0;
}

 

The exact readback commands used are:

 

#define FPGA_CONF_DUMMY            0xFFFFFFFF
#define FPGA_CONF_BUS_WIDTH_SYNC   0x000000BB
#define FPGA_CONF_BUS_WIDTH_DETECT 0x11220044
#define FPGA_CONF_SYNC             0xAA995566

#define FPGA_CONF_CMD_NULL         0x00000000
#define FPGA_CONF_CMD_RCFG         0x00000004
#define FPGA_CONF_CMD_START        0x00000005 
#define FPGA_CONF_CMD_RCAP         0x00000006
#define FPGA_CONF_CMD_RCRC         0x00000007
#define FPGA_CONF_CMD_GRESTORE     0x0000000A
#define FPGA_CONF_CMD_SHUTDOWN     0x0000000B
#define FPGA_CONF_CMD_GCAPTURE     0x0000000C 
#define FPGA_CONF_CMD_DESYNC       0x0000000D
#define FPGA_CONF_PACKET_T1        0x20000000
#define FPGA_CONF_PACKET_T2        0x40000000
#define FPGA_CONF_OPCODE_NOP       0x00000000
#define FPGA_CONF_OPCODE_READ      0x08000000
#define FPGA_CONF_OPCODE_WRITE     0x10000000

#define FPGA_CONF_REG_CRC          0x00000000
#define FPGA_CONF_REG_FAR          0x00002000
#define FPGA_CONF_REG_FDRI         0x00004000
#define FPGA_CONF_REG_FDRO         0x00006000
#define FPGA_CONF_REG_CMD          0x00008000
#define FPGA_CONF_REG_STATUS       0x0000E000
#define FPGA_CONF_REG_IDCODE       0x00018000

static u32 fpga_readback_seq_head[58] = {

  FPGA_CONF_DUMMY,
  FPGA_CONF_BUS_WIDTH_SYNC,
  FPGA_CONF_BUS_WIDTH_DETECT,
  FPGA_CONF_DUMMY,
  FPGA_CONF_SYNC,

  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,

  // Shutdown
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_WRITE | FPGA_CONF_REG_CMD | 0x1,
  FPGA_CONF_CMD_SHUTDOWN,
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,

  // Reset CRC
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_WRITE | FPGA_CONF_REG_CMD | 0x1,
  FPGA_CONF_CMD_RCRC,
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,

  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,

  // Read Configuration
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_WRITE | FPGA_CONF_REG_CMD | 0x1,
  FPGA_CONF_CMD_RCFG,
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,

  // Write Frame Address
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_WRITE | FPGA_CONF_REG_FAR | 0x1,
  0x00000000,

  // Read Frame Data Output
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_READ | FPGA_CONF_REG_FDRO | 0x0,
  FPGA_CONF_PACKET_T2 | ZYNQ_CONFIG_WORDS_PER_FRAME*ZYNQ_CONFIG_FRAMES,

  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,

  // 32 NOPs
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP,
  FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP, FPGA_CONF_PACKET_T1 | FPGA_CONF_OPCODE_NOP

};

 

 

0 Kudos
Reply
1 Reply
XuanXuanL
Contributor
Contributor
272 Views
Registered: ‎07-19-2020

Hello, did you solve this problem? I refer to the official example, but the data read back are all 0. I am very confused and don’t know how to solve it.

Zhejiang University,China;
0 Kudos
Reply