Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: camera.cpp
- Revision:
- 0:78595d38d985
diff -r 000000000000 -r 78595d38d985 camera.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/camera.cpp Fri May 23 20:48:07 2014 +0000
@@ -0,0 +1,181 @@
+#include "camera.h"
+
+/*
+ * Links
+ * https://gist.github.com/franciscospaeth/8503747
+ * http://embeddedprogrammer.blogspot.co.uk/2012/07/hacking-ov7670-camera-module-sccb-cheat.html
+ * http://www.voti.nl/docs/OV7670.pdf
+ */
+
+BusIn data_p(p17,p18,p15,p16,p13,p14,p11,p12);
+
+PwmOut xclock_p(p21);
+DigitalIn pclock_p(p8);
+DigitalIn href_p(p5);
+DigitalIn vsync_p(p6);
+
+DigitalOut pwdn_p(p19);
+DigitalOut reset_p(p20);
+
+I2C i2c(p9, p10); //sda,scl
+
+void camera_setup() {
+ pwdn_p.write(0);
+ reset_p.write(1); // The reset pin must be HIGH! (3v3)
+
+ /*
+ * Make camera xclk using PWM
+ *
+ * Note the this is 1Mhz, the datasheet specifies a minimum of 26Mhz.
+ * Reports online state that 10Mhz works, but if you're having issues
+ * try 26Mhz as we don't understand the side affects.
+ */
+ xclock_p.period(CAMERA_CLK_PERIOD);
+ xclock_p = 0.5;
+
+ // i2c
+ i2c.stop() ;
+ i2c.frequency(CAMERA_I2C_FREQ); // must be slow
+ wait(0.1);
+
+ /*
+ * Set to QCIF (176 x 144)
+ * Note that CAMERA_W and CAMERA_H must also be changed so
+ * that the buffers are the correct length
+ */
+ camera_set_output_format(CAMERA_I2C_OF_QCIF);
+
+ /*
+ * Set PCLK frequency slow enough for us to read and save the data (larger = slower)
+ * Maximum 65 = (2^6 - 1) see datasheet for CLKRC
+ */
+ camera_set_freq_scaler(32);
+}
+
+void camera_set_freq_scaler(int prescaler) {
+ camera_i2c_write(CAMERA_I2C_REG_CLKRC, prescaler);
+}
+
+void camera_set_output_format(int output_format) {
+ camera_i2c_write(CAMERA_I2C_REG_COM3, 0x08); // enable scaling
+ camera_i2c_write(CAMERA_I2C_REG_COM7, output_format);
+}
+
+/**
+ * Grab a single frame from the camera and save to the file
+ */
+void camera_grab(FILE *fp) {
+ char href, vsync;
+
+ int x = 0; // col
+ int y = 0; // row
+ long n = 0; // px number
+
+ // Write one row of pixels to the file at a time, so store the row in a buffer
+ char row_buffer[CAMERA_W * CAMERA_BPX];
+
+ // http://3.bp.blogspot.com/-cjOYTMj4C4M/UA2kV-db8GI/AAAAAAAAAPs/rtCGSIGjOHo/s1600/vga.png
+
+ // Wait until the end of the previous frame
+ wait_negedge(vsync_p);
+
+ // Start of the frame
+ while(1) {
+ // Each row
+
+ // Wait until the start of a row or the end of a frame
+ do {
+ href = href_p.read();
+ vsync = vsync_p.read();
+ } while(href == 0 && vsync == 0);
+
+ // Vsync high, thus the end of the frame
+ if(vsync == 1){
+ // Print the current x, y and n
+ // These indicate how many pixels where actually captured
+ printf("y: %d\r\n", y);
+ printf("x: %d\r\n", x);
+ printf("n: %ld\r\n", n);
+ return; // is the end of a frame
+ }
+ // else carry on (href = 1)
+
+ x = 0;
+
+ /*
+ * Note we must sample at the rising edge of the PCLK,
+ * but we must also read the href to check that the frame
+ * has not ended.
+ * http://2.bp.blogspot.com/-K-OIuy-inUU/UA2gp3SYgYI/AAAAAAAAAPg/Gure3RWI8G4/s1600/href.png
+ */
+
+ wait_posedge(pclock_p);
+
+ while(href_p.read() == 1) {
+ // Each column
+
+ // sample at the rising edge of the PCLK signal
+
+ row_buffer[x] = data_p.read();
+
+ n++;
+ x++;
+
+ // Wait until next rising edge so that when the href read is done it has changed
+ wait_posedge(pclock_p);
+ }
+
+ // Write row buffer to the flash
+ fwrite(row_buffer, sizeof(char), sizeof(row_buffer), fp);
+
+
+ y++;
+ }
+
+}
+
+int camera_i2c_read(int addr) {
+ int data=0;
+
+ // Address
+ i2c.start();
+ i2c.write(CAMERA_I2C_WRITE_ADDR);
+ i2c.write(addr);
+
+ // Not sure why we must stop the i2c bus?
+ i2c.stop();
+
+ wait_us(50);
+
+ // Data
+ i2c.start();
+ i2c.write(CAMERA_I2C_READ_ADDR);
+ data = i2c.read(CAMERA_I2C_NOACK) ;
+ i2c.stop();
+
+ wait_us(50);
+ return data;
+}
+
+void camera_i2c_write(int addr, int val) {
+ i2c.start();
+
+ i2c.write(CAMERA_I2C_WRITE_ADDR);
+ i2c.write(addr);
+
+ i2c.write(val);
+
+ i2c.stop();
+
+ wait_us(50);
+}
+
+void wait_posedge(DigitalIn pin) {
+ while(pin.read() == 1) {};
+ while(pin.read() == 0) {};
+}
+
+void wait_negedge(DigitalIn pin) {
+ while(pin.read() == 0) {};
+ while(pin.read() == 1) {};
+}
\ No newline at end of file