This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Video Front-End died on EVM-DM6437

Hi all, I'm using EVM-DM6437 board to port a one common automotive
application and I faced with following problem.
I configured BIOS on the following way (see below) like I saw in TI
tutorials. I succeeded to get working Video Front/Back-End and I got
captured video on the display. Also I succeeded to process input video
but when I added one “serious” processing block then I realized that
video Front-End stops to respond after few minutes. Application still
works but only on the few already buffered video buffers and video
Back-End produce processed picture on the output. If I take look on the
VPSS_PCR register I’m able to see that it is set to 0x00800000 value. If
I’m right it indicates memory overflow:
Bit 23 -- Write buffer memory overflow (CCDC). All data units have been
filled and not yet transferred to
SDRAM before the next data unit is to be filled from the WBL. Software
has to clear the bit.

In my application I set entire DDR to be cacheable but I realized that
if I reduce cacheable area my application works slower (logical) but it
works longer before the video Front-End stops.
BCACHE_setMar( (Ptr)(0x82000000), 0x07800000, BCACHE_MAR_ENABLE );

If someone faced with similar problems or if maybe realized what I did
wrong please share your knowledge with me.

Thanks in advance.

BIOS configuration

/*
 *  ======== DM6437_common.tci ========
 *  Custom settings that apply to all the DM6437 Examples.
 *
 */

/* Enable BIOS Instrumentation and RTA. */
bios.enableRealTimeAnalysis(prog);
bios.enableRtdx(prog);
bios.GBL.ENABLEALLTRC    = true;

/* Enable BIOS heaps and task scheduler */
bios.enableTskManager(prog);
bios.enableMemoryHeaps(prog);

/* Increase the buffer size of the LOG_system LOG object */
bios.LOG.instance("LOG_system").bufLen = 1024;
bios.LOG.instance("LOG_system").bufSeg = prog.get("DDR");

bios.LOG_system.bufLen = 1024;
bios.LOG_system.logType = "circular";

/* A LOG object named "trace" used by some examples: */
bios.LOG.create("trace");
bios.LOG.instance("trace").bufLen = 4096;
bios.LOG.instance("trace").bufSeg = prog.get("DDR");

bios.LOG.create("DVTEvent_Log");
bios.LOG.instance("DVTEvent_Log").bufSeg = prog.get("DDR");
bios.LOG.instance("DVTEvent_Log").bufLen = 8192;
bios.LOG.instance("DVTEvent_Log").comment = "DVT";


/* Setup heaps in DDR2 and L1DSRAM */
utils.getProgObjs(prog, bios);

var vDDR2         = prog.module("MEM").instance("DDR2");
vDDR2.createHeap         = true;
vDDR2.name           = "DDR2";
vDDR2.heapSize           = 0x04000000;

/*
 *  Enable a heap in the L1DSRAM (internal L1 cache ram)
 *  and define the label for DSKT2 or DMAN3 heap usage
 *
 *  H.264 Encoder needs 64K of internal memory.
 *  Otherwise, ACPY3 (used by copy codecs) needs internal memory.
*/
bios.L1DSRAM.createHeap     = true;
bios.L1DSRAM.len      = 0x10000;
bios.L1DSRAM.enableHeapLabel= true;
bios.L1DSRAM["heapLabel"]   = prog.extern("L1DHEAP");
bios.L1DSRAM.heapSize       = 0x10000;   // Need 64K L1DSRAM heap for
H.264Enc.

/* GBL configuration */
bios.GBL.C64PLUSCONFIGURE   = true;
bios.GBL.C64PLUSL1PCFG      = "32k";
bios.GBL.C64PLUSL1DCFG      = "16k";
bios.GBL.C64PLUSL2CFG       = "32k";
//bios.GBL.C64PLUSMAR128to159 = 0x0000ffff;

/* set all BIOS data and code sections to be in DDR */
bios.setMemDataHeapSections(prog, vDDR2);
bios.setMemDataNoHeapSections(prog, vDDR2);
bios.setMemCodeSections(prog, vDDR2);

/* Ensure these are in external memory: */
bios.MEM.MALLOCSEG     = vDDR2;
bios.MEM.BIOSOBJSEG     = vDDR2;
bios.TSK.STACKSEG     = vDDR2;

/* Make global stack size large enough for all examples: */
bios.MEM.STACKSIZE      = 0x8000;

/* Take the selected timer out of reset */
bios.CLK.TIMERSELECT     = "Timer 0";
bios.CLK.RESETTIMER     = true;

bios.MEM.instance("IRAM").len = 0x00018000;


/*
 *  Load platform file for DM6437 newedma3test.tcf
 */
utils.loadPlatform("ti.platforms.evmDM6437");

/* Import settings common to all DM6437 DVSDK examples.*/
utils.importFile("DM6437_common.tci");

/* Enable ECM Handler */
bios.ECM.ENABLE = 1;
bios.CLK.RESETTIMER = 1;
bios.GBL.ENABLEINST = 1;

/* ECM configuration - manually Reflect these settings in soc.h */
bios.HWI.instance("HWI_INT7").interruptSelectNumber = 0;
bios.HWI.instance("HWI_INT8").interruptSelectNumber = 1;
bios.HWI.instance("HWI_INT9").interruptSelectNumber = 2;
bios.HWI.instance("HWI_INT10").interruptSelectNumber = 3;

bios.TSK.instance("TSK_idle").order = 1;
bios.TSK.create("ApplFunc");
bios.TSK.instance("ApplFunc").stackSize = 16384;
bios.TSK.instance("ApplFunc").comment = "ApplFunc test task";
bios.TSK.instance("ApplFunc").fxn = prog.extern("ApplFunc4__Fv");

/*bios.GBL.C64PLUSMAR128to159 = 0x00008000;
bios.GBL.C64PLUSMAR128to159 = 0x00000000;
bios.GBL.C64PLUSMAR160to191 = 0x000000ff;
bios.GBL.C64PLUSMAR160to191 = 0x0000ffff;*/

/* Create user devices for I2C (needed by video) and video drivers */
bios.UDEV.create("I2C0");
bios.UDEV.instance("I2C0").fxnTableType = "IOM_Fxns";
bios.UDEV.instance("I2C0").initFxn = prog.extern("I2C_INIT");
bios.UDEV.instance("I2C0").params = prog.extern("I2C_devParams");
bios.UDEV.instance("I2C0").fxnTable = prog.extern("I2CMD_FXNS");

bios.UDEV.create("VPFE0");
bios.UDEV.instance("VPFE0").fxnTable = prog.extern("VPFEMD_FXNS");
bios.UDEV.instance("VPFE0").fxnTableType = "IOM_Fxns";

bios.UDEV.create("VPBE0");
bios.UDEV.instance("VPBE0").fxnTable = prog.extern("VPBEMD_FXNS");
bios.UDEV.instance("VPBE0").fxnTableType = "IOM_Fxns";

if (config.hasReportedError == false) {
// !GRAPHICAL_CONFIG_TOOL_SCRIPT_INSERT_POINT!
    prog.gen();
}

  • Two guesses:

    1) Your "serious" processing routine does a lot of memory moving and the edma cannot keep up between capture, processing, and display.  Does slowing down your video clock or frame rate help?  If so, you might need to do some cache optimization to prevent excess memory movements in your processing.

    2) Your "serious" processing routine takes so long that occasionally you fill up all your capture buffers and a new frame comes in with nowhere to put it.  Have you measured the rate of your processing vs. the rate of your capture?

  • MattLipsey said:
    1) Your "serious" processing routine does a lot of memory moving and the edma cannot keep up between capture, processing, and display.  Does slowing down your video clock or frame rate help?  If so, you might need to do some cache optimization to prevent excess memory movements in your processing.

    This is quite possibly what is happening, I have not seen it happen with a lockup like this myself yet but it is possible, there are registers to adjust priority of peripherals on the internal bus (MSTPRI I believe) that you may want to look at modifying to try to alleviate the issue, there is also a register in the DDR peripheral that deals with how often the DDR bus gives priority to a highly delayed transfer which may be worth tweaking in this case (PBBPR).

    MattLipsey said:
    2) Your "serious" processing routine takes so long that occasionally you fill up all your capture buffers and a new frame comes in with nowhere to put it.  Have you measured the rate of your processing vs. the rate of your capture?

    The way the drivers are designed this should not happen, the driver ends up dropping a frame if it is not serviced in time which is why it has multiple frame buffers allocated, so it can have one ready while it fills another and the user has one.

  • Hi I'm still working on MIPS profile but even now it's obvious that is not so "serious" processing block to spend all processing time.

    Regarding to Bernie Thompson suggestion, I'm not sure that I know how to adjust those buffers so I'll appreciate if you can explain me how to do that.

     

    Note. I just realized that there is some connection between cacheable memory end time before VPFE died. For example I set entire DDR to be cacheable

    (BCACHE_setMar( (Ptr)(0x80000000), 0x08000000, BCACHE_MAR_ENABLE );)

    in that case VPFE works for several seconds before died but if I resize it with:

    BCACHE_setMar( (Ptr)(0x82000000), 0x07800000, BCACHE_MAR_ENABLE );) than my system works slower but VPFE works for several minutes.

    Any clue? 

  • Sorry for the delay on this, the MSTPRI register is discussed in section 3.6.1 of the datasheet, this defines the priority of several of the swiched central resource (SCR) masters, though the VPSS priority is defined in the PCR register of the VPSS shown in section 7.2 of SPRU977. The catch here is that the VPSS should already be set to maximum priority to try to avoid video glitches, so you may end up adjusting the priority of other system masters, if everything is set to default than the only equal SCR master would be the EDMA controllers which have their priority set in the EDMACC QUEPRI register shown in section 4.3.1.6 of SPRU987.

    As to the PBBPR register, this is described in section 4.6 of SPRU986, you can set this register to some value between 0x00 and 0xFF to determine the number of memory transfers before the DDR2 elevates the priority of the oldest command in the FIFO, what exact value is best is very system dependent so you may just have to try some different values and see if they work, I would suggest starting somewhere in the middle, maybe 0x30.

    Unfortunately with bandwidth issues the answer can be kind of vague like this and have lots of potential references because the device's bandwidth controls are defined in several different documents as shown here. For accessing these registers the easiest way will likely be to create a pointer to the register address and just access it from your C code.

    Also note that there could be something else going wrong, this is just one possible way of explaining why you could get a CCDC buffer overflow.

  • Hi Bernie,

    Thanks a lot for your support I really appreciate it. I did a modifications that you suggested and it works.

    The Peripheral Bus Burst Priority Register(PBBPR) was set to the default value 0xff and DDR2 controller was not able to raise the priority of the oldest command. So I changed default value to the 0x20 and allowed controller to raise the priority of the oldest command in the command FIFO after a 20 transfers have been made.

    Once again thanks a lot for your help. You really saved me a lot of time and effort.