Hello XMOS community,
I'm attempting to integrate the OV7670 with a startkit. I'm experiencing problems with the acquisition of the pixel data.
The pixel clock signal (pclk) signal from the OV7670 should be at 24MHz. When I measure it (using the code below) I find the signal is at 0,5MHz.. I do not believe that the signal from the OV7670 is in error, because the rest of the signals from the device are at the appropriate rate (measured with oscilliscope - cant measure the pclk signal because my oscilliscope isn't fast enough).
Here is the code I use to measure the signal:
timer t;
unsigned int start,end;
t :> start;
for (int i = 0; i < 100; i++)
{
clk when pinseq(0) :> void;
clk when pinseq(1) :> void;
}
t :> end;
printf("Time: %i\n",(end-start));
I get a value of 2016 as a returned value
Using this formula I get 0.496 MHz
MHz: (1/((2016/100)/10000000)) /1e6 = 0.496 MHz
Any thoughts on this?
Thank you!
Brian
Startkit + OV7670
-
- Junior Member
- Posts: 6
- Joined: Thu Apr 23, 2015 5:26 am
-
- Active Member
- Posts: 44
- Joined: Mon Jul 29, 2013 4:33 am
You are missing a 0. 100Mhz reference gives 4.96Mhz which is still not 24Mhz.24Mhz input means you really only have 2 instruction cycles to process each half of the waveform. With the loop overhead as well, I don't think this method will work.Maybe try configuring a clock to use the pin as a source. Then you can wait on the clock for some number of cycles.
-
- Junior Member
- Posts: 6
- Joined: Thu Apr 23, 2015 5:26 am
Ok, so I found a way to get the data in fast enough, although it's not pretty.
Using a for loop (as in the code below) was still not fast enough, even just running a for loop without doing anything in it got me at 7MHz or so.
p_clock = clock
p_pclk = pixel clock
p_pix = 8bit pixel data
[METHOD TOO SLOW]
// Configure input port clock
configure_clock_src(p_clock, p_pclk);
start_clock(p_clock);
printf("Setup of Clock sources complete.\n");
printf("Testing Driving Pin Clock.\n");
timer t;
unsigned int start,end;
char dummy=0;
t :> start;
for (int pin=0; pin < 1000; pin++) {
p_pix :> dummy;
}
t :> end;
[END METHOD]
The solution that worked was as follows (very hideous.):
// Configure input port clock
configure_clock_src(p_clock, p_pclk);
start_clock(p_clock);
printf("Setup of Clock sources complete.\n");
printf("Testing Driving Pin Clock.\n");
timer t;
unsigned int start,end;
char dummy=0;
t :> start;
p_pix :> dummy;
p_pix :> dummy;
p_pix :> dummy;
p_pix :> dummy;
p_pix :> dummy;
p_pix :> dummy;
...
t :> end;
The timer output from this revealed 23.8 MHz - which is pretty close to the 24 MHz desired.
Using a for loop (as in the code below) was still not fast enough, even just running a for loop without doing anything in it got me at 7MHz or so.
p_clock = clock
p_pclk = pixel clock
p_pix = 8bit pixel data
[METHOD TOO SLOW]
// Configure input port clock
configure_clock_src(p_clock, p_pclk);
start_clock(p_clock);
printf("Setup of Clock sources complete.\n");
printf("Testing Driving Pin Clock.\n");
timer t;
unsigned int start,end;
char dummy=0;
t :> start;
for (int pin=0; pin < 1000; pin++) {
p_pix :> dummy;
}
t :> end;
[END METHOD]
The solution that worked was as follows (very hideous.):
// Configure input port clock
configure_clock_src(p_clock, p_pclk);
start_clock(p_clock);
printf("Setup of Clock sources complete.\n");
printf("Testing Driving Pin Clock.\n");
timer t;
unsigned int start,end;
char dummy=0;
t :> start;
p_pix :> dummy;
p_pix :> dummy;
p_pix :> dummy;
p_pix :> dummy;
p_pix :> dummy;
p_pix :> dummy;
...
t :> end;
The timer output from this revealed 23.8 MHz - which is pretty close to the 24 MHz desired.
-
- Active Member
- Posts: 44
- Joined: Mon Jul 29, 2013 4:33 am
You can use a buffered port. This way you read 4 x 8 bit samples into a 32 bit value. Your code then only has to trigger on each 4th sample.use the clock pin to drive this process.Let the hardware response port architecture do the heavy lifting for you and you should be fine.I have a similar (but reversed) situation driving data to an lcd via an 8bit interface. This is running at 50Mhz.
-
- Active Member
- Posts: 44
- Joined: Mon Jul 29, 2013 4:33 am
I note that the OV7670 has a strobe ("ready") pin on the data - this can also be incorporated into the port configuration to be dealt with automatically.
Maybe something like this:
in buffered port:32 p_pix = XS1_PORT_8B;
in port p_href = XS1_PORT_SOME1BITPORT;
unsigned int indata; // 32-bit
configure_clock_src(p_clock, p_pclk);
configure_in_strobed_slave(p_pix, p_href, p_clock);
start_clock(p_clock);
while(1)
{
select()
{
case p_pix :> indata:
// process data here. triggered every 4th sample. Samples are not taken if p_href is low.
break;
}
}
Maybe something like this:
in buffered port:32 p_pix = XS1_PORT_8B;
in port p_href = XS1_PORT_SOME1BITPORT;
unsigned int indata; // 32-bit
configure_clock_src(p_clock, p_pclk);
configure_in_strobed_slave(p_pix, p_href, p_clock);
start_clock(p_clock);
while(1)
{
select()
{
case p_pix :> indata:
// process data here. triggered every 4th sample. Samples are not taken if p_href is low.
break;
}
}