EPPI Sychronization problem on BF548 EZ-kit
Hi all,
I am doing a video project,using BF548EZ-Kit and OV7620 image sensor. The sensor is connected directly to the borad via EPPI1 interface. For testing, a single frame can be captured after setting up the DMA13 and EPPI1 configuration. I use image viewer to display a image with a start address that I specified in the DMA start address. The problem is every time I got a frame, it seems that the image is not sychronized well.It can be seen from the figure I attached below.
The EPPI status register reports a error (EPPIx_STATUS = 0x0024). i.e. Frame Track Underflow Error. When the image I got is correct(the whole frame), the error disappears. I struggled to figure out where the problem is but without success. My configuration of EPPI1,DMA and port muxing setting is as follow. Any help would be appreciate!
void InitPorts(void)
{
//activate PortE 14,15 for TWI SDA and SCL
*pPORTE_FER = Px14 | Px15;
ssync();
// set FERF for PPI Data 0-7
*pPORTD_FER = 0x00FF; //PortD is PPI1
//ssync();
// set FERF for PPI CLK PORTE is for PCLK(PE11),PFS1(PE12),PFS2
(PE13).
*pPORTE_FER = 0x3800; //0011 1000 0000 0000
ssync();
}
void InitDMA(void)
{
*pDMA13_START_ADDR = Frame; //(0x300000)
*pDMA13_X_COUNT = PIXEL_PER_LINE; //320
*pDMA13_X_MODIFY = 0x1;
*pDMA13_Y_COUNT = LINES_PER_FRAME; //240
*pDMA13_Y_MODIFY = 0x1;
*pDMA13_CONFIG = DI_EN | WNR | WDSIZE_8 | DMA2D | AUTOBUFFERMODE;
ssync();
}//end Init_DMA
void InitEPPI1()
{
// - EPPI disabled first
// - EPPI in receive mode
// - GP 2 mode
//Skipping enabled
//FS1 is active high and FS2 is active low, FS1 and FS2 sre
connected to Hsync and Vsync respectively.
// - sample data on rising edge and sample/drive syncs on rising
edge
// - DLEN = 8 bits
*pEPPI1_CONTROL = 0x0006592C;
ssync();
// total lines is 640
*pEPPI1_LINE = 640;
ssync();
//The PPI is set to receive 525 lines for each frame
*pEPPI1_FRAME = 240; // OV7620 default mode is interlace with 240
lines per frame
ssync();
}
Hi,
I've had similar experiences on the BF548 and the EZKIT, here are a few remarks:
- Signal integrity on the EZKIT may be not perfect. It may be that you have to use a clock buffer for the PPICLK and sync signals
- As I understand from the data sheet, the VSYNC pulse of this sensor is not asserted over the entire scanline width. So you get a very short pulse. You could try to set the POLS field to '11' instead '01'.
- I guess you have programmed the HREF polarity such that it is asserted LOW over the entire valid pixel line (this is what your POLS setting suggested). If it is asserted HIGH during active pixel output, you'll have to set POLS = '10'. However, I fear that the LTERR_OVR error will not go away, see more below.
Bottomline: Even if you try to get things right in theory, they won't work - that's what I found out. The EPPI just doesn't work as described in the manual. I've run into this a year ago with a 0.0 revision, filed several requests to ADI (latest: SR #0907378), and now having to revisit the issue, it's still the same frustration.
I've put together an error report investigating the suspected EPPI bugs here:
http://tech.section5.ch/news/?p=4
I hope someone can sched some light on this situation. A few people keep telling: it works, but all of them seem to ignore the errors which is not acceptable for my application.
Let me know if you get it to work without errors.
Cheers,
- Martin
Hi, Martin
Thanks for your reply! Actually I've already solved this problem, you are right,EPPI doesn't behave as it is documented in datasheet. Sychronization problem is caused by Vsycn not taken into effect. The trick here is It wants at least Vsync asserted high over entire frame duration. I programmed the chip to invert the Vsync then it works properly.But I can still see error status like overflow and underflow which I really don't know how to deal with.
Best regard
Peter
Hi Peter,
I've done a bit more "reverse engineering", and actually ended with my experiments where I had started a year ago. This time though, I can kind of locate the error for my setup (at least). Maybe it helps understanding what is happening on your side.
I've configured the sensor to deliver 8 lines, 8 pixel each line. Yellow is FS2 (Frame valid), blue is FS1 (Line valid).
The HSync rising edge occurs every 974 clock cycles. Now, the first descriptions I had from the EPPI were not clear at all, the most recent manual was kind of unclear, but fact seems to be:
- The EPPIx_LINE register must be configured to the number of clock cycles between the rising edges. If I do this, the LTERR_OVR goes away (but only on certain lines, more below)
- To read in only 8 values, the EPPIx_HCOUNT must be set to 8, after setting EPPIx_LINE.
- The width of the Line Valid pulse does NOT matter, and there seems to be NO option to configure it that way.
Now, with this scheme, I still see an overrun error. The reason must be the last pulse seen in the above image. Most people testing the EPPI seem to run the FLOW_STOP scheme on the DMA and disable the EPPI shortly after the interrupt event (so done in the uClinux driver). That is why the error is then not seen - the PPI_STATUS register is cleared when the PPI is disabled.
So why is there still an LTERR_OVR? The suspicion is, that the internal pixel counter (per line) keeps counting and causes an overflow condition, because it does not see the reassertion of the FS1 signal within the specified interval. Obviously, the width of the FS2 (Frame valid) signal is not evaluated either.
So the only error free condition the EPPI can run in, would be, to have both VSYNC and HSYNC signals coming at a fixed frequency, so you could configure the LINE and FRAME register accordingly. This is based on the assumption, that only the rising edges of the FS1 and FS2 signals are evaluated. However, this case is not the typical real world situation: Most imaging sensors deliver frames in an asynchronous way with variable VBlank (FS2 low) times.
So my fear is, that I won't be able to use the EPPI *with* proper error detection and a off the shelf imaging sensor that produces not exactly the EPPI compatible signals. I also wish there were some application notes. As far a I can see, the EPPI is not an improvement to the PPI for those who want to build robust cameras. I wish to be proven wrong!
Greetings,
- Martin
Hi Martin,
You must have some experience in implementing real time video display. So far, I can only make it around 15 frames per second which is definitely not real time. I got two DMA working in continous transfering mode with four buffer, two for each channel, and simple semaphore.Although I assgin each buffer to differrent sub bankin SDRAM, I can not make sure the block processing algorithm execution time is less than or equal to the time it takes the DMA to transfer data.i.e.the core and DMA still have chance to access the same memory space at the same time, resulting in memory stalls.
Is there a standard way to acheive real time? The example I found now is VideoInVideoOut using 4 buffers but with 8 DMA discription list. Another example in VideoInEdgeDetection use MDMA. Could you give me some hints on how to better sychronize DMA and core access to improve the performance?
kind regard
Peter
Hi Peter,
you might want to have a look at the buffer queue example from the 'standalone' shell code at http://www.section5.ch/software
It's just set up for a PPI (ppi.c and video.c), but you can adapt at least video.c that using the appropriate EPPI channels.
I'm afraid it's GNU tools code, so it won't compile from the box in VDSP.
Anyhow, you might just want to have a look. Basically, the interrupt fired on a DMA_DONE event it marks the 'head' buffer as ready, and you read out/process the 'tail' buffers. If you don't do that quick enough, you'll get an overrun, in this cheap example it will mean, a broken frame (concurrent accesses between DMA and core). I don't know how much of 'realtime' you want to get, but you can at least make sure that the memory bandwith is optimally used and least possible data copying is happening.
I'm running this scheme under uClinux with enabled cache, and get a pretty good framerate (>30 fps at VGA) using some cheap processing. If your algorithms eat more time, then of course you'll have to decrease the framerate or deal with full/overrun queue.
Greetings,
- Martin
Hi Martin, Peter,
Please see my comments below.
- The EPPIx_LINE register must be configured to the number of clock cycles between the rising edges.
Yes, thats right. The FS1 signal is edge sensitive and the EPPI counts the clock pulses between two FS1 signals and compares it to the value programmed into the PPIx_LINE register. If the count is greater than the value programmed it issues a line overflow error and if it is less than the value programmed it issues a line underflow error.
- To read in only 8 values, the EPPIx_HCOUNT must be set to 8, after setting EPPIx_LINE.
Yes, true. Please refer to the HRM Pg 26-27, or Pg 477 (http://www.analog.com/static/imported-files/processor_manuals/bf54x_pphwr_vol-2.pdf). Point 2 specifically mentions that.
True as well. The FS pulses are only edge triggered.
So the only error free condition the EPPI can run in, would be, to have both VSYNC and HSYNC signals coming at a fixed frequency, so you could configure the LINE and FRAME register accordingly. This is based on the assumption, that only the rising edges of the FS1 and FS2 signals are evaluated. However, this case is not the typical real world situation: Most imaging sensors deliver frames in an asynchronous way with variable VBlank (FS2 low) times.
We do take your feedback very positively and see if we can make this an option in our future designs. We do see the advantages of this option in case where cameras operate in asynchronous frame capture mode.
Thanks,
Kaushal
Hi Peter,
Please see my comments below:
That is definitely a good first step.
The metric registers on the BF548 can help you a bit in this regard. It does not really capture the temporal and spatial locality of your data access but you can get some feedback from these registers on what is happening on your external bus. Refer to PG 6-42 or PG 434 of the HRM for more details on that - http://www.analog.com/static/imported-files/processor_manuals/bf54x_phwr_vol-1.pdf
Is there a standard way to acheive real time? The example I found now is VideoInVideoOut using 4 buffers but with 8 DMA discription list. Another example in VideoInEdgeDetection use MDMA. Could you give me some hints on how to better sychronize DMA and core access to improve the performance?
It all depends on how much processing you need. There is no one way to achieve real time performance. It depends on your algorithms data access pattern, bandwidth requirements, memory requirements etc. etc. However, you can refer to EE-301 (http://www.analog.com/static/imported-files/application_notes/EE_301.pdf) which delves into some of these issues. Also, refer to EE-324 for some common Blackfin optimization techniques (http://www.analog.com/static/imported-files/application_notes/EE_324_Rev_1_07_2007.pdf).
Hope this helps.
Thanks,
Kaushal