SCT camera interface LPC1800 (problem VGA configuration)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SCT camera interface LPC1800 (problem VGA configuration)

1,474 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by fabriziouser on Mon May 18 08:53:24 MST 2015
Good morning everyone,

i would kindly ask for your help concerning a problem on interfacing between the MCB1800 board (LPC1857 single core) and the cam OV7670.
I'm working on application "SCT camera interface design with LPC1800 and LPC4300" (AN11365). Below the link where you can download the orignal firmware:

http://www.lpcware.com/content/nxpfile/an11365-sct-camera-interface-design-lpc1800-and-lpc4300

The original firmware works with the OV7670 configured in QVGA mode (320x240) with RGB565 format.

I'd like configure the cam in VGA mode (640x480) with YUV format and do a double buffering with "buffer1" and "buffer2" (stored in internal SRAM) each of which contains a line of the frame (640 pixel x 2 byte for YUV format = 1280 byte for each buffer).

I configured the camera with the following instructions:

// VGA, YUV422
ov7670_write_reg(0x12, BVOFF(4) | BVOFF(2) | BVOFF(0));

//Frame rate adjustment for 13 Mhz input clock (XCLK = 12MHz)
//30 fps, PCLK = 26Mhz
ov7670_write_reg(0x11, 0x00);
ov7670_write_reg(0x6b, 0x4a);
ov7670_write_reg(0x2a, 0x00);
ov7670_write_reg(0x2b, 0x00);
ov7670_write_reg(0x92, 0x2b);
ov7670_write_reg(0x93, 0x00);
ov7670_write_reg(0x3b, 0x0a);

I measured these signals with oscilloscope and are all correct.

Synchronization is based on signals vsync and hsync generated by camera. The rising edge of the signal vsync identifies the end of a frame (in this instant i configure the DMA to receive the first line of the new frame, transfer size 640 x 2 and address buffer1).
The falling edge of hsync identifies the end of a line and in this instant i configure the DMA to make a new transfer with sizes 640 x 2 but at address buffer2). These signals generate SCT interrupts and in this call back i call the function to initializa the DMA transfer. With buffer1 and buffer2 i use the double buffering technique where on each rising edge of vsync and each falling edge of hsync i re-configure the DMA to make a new transfer of 640 bytes x 2 alternating the two buffers. The request on DMA transfer is done from rise edge of PCLK. These signals are associated to events of SCT interface.

unsigned char buffer1[2*640];
unsigned char buffer2[2*640];
int toggle = 0;

void _prvInitCamDMAXferDir(void)
{
// s_ccb.pBuf = s_ccb.buf.a8;
s_ccb.pCHN->CONFIG =
// Dis | SrcPerp=SCT | DstRAM | P->M | XferDoneIrqEn
0UL<<0 | YACB_SCTDMAPERIPNUM<<1 | 0UL<<6 | 2UL<<11 | 1UL<<15;
s_ccb.pCHN->SRCADDR = (unsigned int )(LPC_GPIO_PORT->PIN + GPT_IMGD0);

//s_ccb.pCHN->DSTADDR = (unsigned int) s_ccb.pFB;
if(toggle == 0)
s_ccb.pCHN->DSTADDR = (unsigned int) buffer1;
else
s_ccb.pCHN->DSTADDR = (unsigned int) buffer2;


s_ccb.pCHN->CONTROL =
// size | SBurst=1| DBurst=4| SWidth=8| DWidth=32| SMstr=1 | DMstr=0 | !SrcInc | DstInc | Prvlg | B,C | EnInt
2*640<<0 | 0UL<<12 | 1UL<<15 | 0UL<<18 | 2UL<<21 | 1UL<<24 | 0UL<<25 | 0UL<<26 | 1UL<<27 | 1UL<<28 | 3UL<<29 | 1UL<<31;
s_ccb.pCHN->LLI = 0; //(unsigned int) s_ccb.lliAry[0].pNext;

s_ccb.pCHN->CONFIG |= 1UL<<0; // Enable chnnel

toggle++;

if(toggle > 1)
toggle = 0;
}

When i go to read the buffers' content, "buffer1" contains the line completed (640 byte x 2) and it's ok, but "buffer2" no, it contains only half line (320 byte x 2) like a QVGA and i do not understand why.

I thinked a problem of XCLK and i have setted it to 24 MHz instead of 12MHz but the problem is remained.
Have you any suggestions to solve this problem? I don't understand the origin (SCT configurations, DMA configurations, timing, ....)

Thank you very much for your help.
0 Kudos
Reply
7 Replies

1,386 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Superfred on Thu Jul 23 07:32:22 MST 2015
Hello Roger,

I found this, maybe it helps:
http://www.nxp.com/products/identification_and_security/security_and_surveillance_ip_camera/ASC8852A...
0 Kudos
Reply

1,386 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Superfred on Thu Jul 23 03:17:39 MST 2015
Hello Roger,

you get a constant stream of data from the camera. This is a problem if you want to analyze the data, because the memory will be updated constantly. My solution is to use two regions the RAM, see below:
Frame1: Camera fills region1
Frame2: Camera fills region2, Processor analyzes region1
Frame3: Camera fills region1, Processor analyzes region2
Frame4: Camera fills region2, Processor analyzes region1
.....

Code:
__DATA(RamAHB32) __attribute__((aligned(4))) uint8_t CameraBuffer1[CAMERALINES][CAMERACOLUMNS] ;
__DATA(RamAHB32) __attribute__((aligned(4))) uint8_t CameraBuffer2[CAMERALINES][CAMERACOLUMNS] ;



I never used external RAM, I think it you can adress it like internal RAM, but it may be slower.

And for USB speed, you can calculate:
640 columns x480 lines x2 (YUYV) x30 frames x 8 Bits = 148 Mbit/s. This is inside USB 2.0 speed, but I doubt the microcontroller can handle this. You should compress the data first, but this needs much processing power. You can also just send the results of the analysis.

I don't think that a microcontroller can handle a frame 640x480 with 30fps, the amount of data is too much. You need to decrease resolution or use FGPAs or DSPs or SOCs.

But again, all depends on what you want to do. Maybe describe a little bit more...

Fred

0 Kudos
Reply

1,386 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rboldu on Thu Jul 23 00:37:36 MST 2015
Hello,

Thanks for your advice!

I can not use a Raspberry because the main goal of the project is to create a wearable device :(

I never work with an external RAM! After configuration the way to code is it the same that if you use the internal one? When you say two RAM regions, what do you mean? A Ram with 2 banks or 2 different rams?
Also, if can it be better try to approach the problem using a DSP?

BTW, do you think that it will be at least enough fast to through all the data for the USB port?

Thanks in advance, it's really helpful!!
Roger
0 Kudos
Reply

1,386 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Superfred on Thu Jul 23 00:12:41 MST 2015
Hello,

this depends on the resolution you need.
640x480x2 = 614 kB, and what I saw the maximum internal RAM on LPC 43xx is 204 kB!
But if you take a quarter resolution of 160x120x2 = 38 kB, this is possible.

And think that you need time to process the image, so you need maybe two RAM regions: one "online" to receive the camera data ond one "offline" to analyze, alternating with every frame.
And even at a quarter resolution, at 30 fps you have only 33 ms to analyze 38kB of data!

So a microcontroller is maybe not the best hardware platform for a camera, maybe Raspberry Pi is a better solution.

But in my case it works, I build a line following robot, here 160x80 resolution is enough, and no colour is needed.
This gives 12800 Bytes per frame, inside the processing speed of a microcontroller if you code carefully.

Fred



0 Kudos
Reply

1,386 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rboldu on Wed Jul 22 20:24:22 MST 2015
Hi Fabrizio,

I'm also interested in manage a VGA camera with a framerate of 30 fps. I'm scared about the memory Ram.

My goal it's to create a kind of a webcam with some image processing in the middle. I was thinking in using the LPC4300, without any external memory. Do you think it's possible?

Can you let us know if finally it works for you the 30fps solution? Also, I don't get the way that you use both buffers.

Thanks, :)
Roger
0 Kudos
Reply

1,386 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by fabriziouser on Tue May 19 04:06:54 MST 2015
Thank you very much Fred for your help. You were very kind.

I did some testing. Lower the framerate is the key to solving this problem.
If i configure the camera to work with a framerate of 15 fps the acquistion is correct and i have a fully linea (640 byte x 2) in each buffers. In this week i will follow your advice to understand if i can do a correct acquistion with a framerate of 30 fps.

Thank you again.

Fabrizio
0 Kudos
Reply

1,386 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Superfred on Tue May 19 00:11:49 MST 2015
Hello,

maybe the horizontal blank time is too short for the Interrupt handler? Try to lower the FPS to maybe 1 fps and see what happens.

I connected OV7670 Camera to my LPC1769 using GPDMA and Timer CAP as DMA burst source, (no SCT on 17xx series).
Here are my experiences, maybe it helps also on your MC:

-Timing is yery critical, I had to increase the PCLK for the CAP-Timer from 25 to 100 MHZ, even for  a 160x120 frame at 30 fps.
-Use Interrupt routines only in the vertical blank time, and use of GPDMA Linked Lists inside the frame (because DMA transfer size is too small for a whole frame).
-Calculate the size of the DMA transfer size so that the switch to the next Linked List item is during the horizontal blank time.
-The camera resolution is never exactly the theoretical value, a 160x120 frame is at my case 156x105. I use a counter input to get the real values. This is important to calculate the correct DMA transfer size and to get a correct picture.
-The first bytes are always blank, so the picture resolution again decreases.
-ov7670_write_reg(0xb0, 0x84); corrects the colours.
-LPC_TIMx->MR0 = 2 transfers only every second byte, this gives you only the Y-bytes = B/W picture.
-Do not use the DMA controller for other transfers during the active camera transfer. Even lower priority transfers will corrupt the camera data (it took me weeks to find this out and had to rewrite my SPI routines to interrupt mode).

Please ask me if you have further questions or code examples
Fred

Fred

0 Kudos
Reply