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.
camera.cpp
- Committer:
- ollyhicks
- Date:
- 2014-05-23
- Revision:
- 0:78595d38d985
File content as of revision 0:78595d38d985:
#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) {}; }