Oliver Hicks / Mbed 2 deprecated mbed_camera

Dependencies:   mbed

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