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.
Revision 0:78595d38d985, committed 2014-05-23
- Comitter:
- ollyhicks
- Date:
- Fri May 23 20:48:07 2014 +0000
- Commit message:
- Sort of working (terrible image)
Changed in this revision
--- /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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/camera.h Fri May 23 20:48:07 2014 +0000 @@ -0,0 +1,52 @@ +#include "mbed.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 + */ + +#define CAMERA_W 176 +#define CAMERA_H 144 +#define CAMERA_BPX 2 // bits per pixel +#define CAMERA_CLK_PERIOD 1e-6 + +#define CAMERA_I2C_FREQ 40000 +#define CAMERA_I2C_READ_ADDR 0x43 +#define CAMERA_I2C_WRITE_ADDR 0x42 +#define CAMERA_I2C_NOACK 0 +#define CAMERA_I2C_REGMAX 201 + + +#define CAMERA_I2C_REG_COM3 0x0C +#define CAMERA_I2C_REG_COM4 0x0D +#define CAMERA_I2C_REG_COM5 0x0E +#define CAMERA_I2C_REG_COM6 0x0F +#define CAMERA_I2C_REG_AECH 0x10 +#define CAMERA_I2C_REG_CLKRC 0x11 +#define CAMERA_I2C_REG_COM7 0x12 +#define CAMERA_I2C_REG_COM8 0x13 +#define CAMERA_I2C_REG_COM9 0x14 +#define CAMERA_I2C_REG_COM10 0x15 +#define CAMERA_I2C_REG_COM11 0x3B +#define CAMERA_I2C_REG_COM12 0x3C +#define CAMERA_I2C_REG_COM13 0x3D +#define CAMERA_I2C_REG_COM14 0x3E + +#define CAMERA_I2C_OF_CIF 32 +#define CAMERA_I2C_OF_QVGA 16 +#define CAMERA_I2C_OF_QCIF 8 // 176 x 144 +#define CAMERA_I2C_OF_RGB 4 +#define CAMERA_I2C_OF_YUV 0 + +void camera_setup(); +int camera_i2c_read(int addr); +void camera_i2c_write(int addr, int val); +void camera_set_freq_scaler(int prescaler); +void camera_set_output_format(int output_format); +void camera_grab(FILE *fp); + + +void wait_posedge(DigitalIn pin); +void wait_negedge(DigitalIn pin); \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Fri May 23 20:48:07 2014 +0000
@@ -0,0 +1,24 @@
+#include "mbed.h"
+#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
+ */
+
+LocalFileSystem local("local");
+
+int main() {
+ printf("\r\n\n\nSetup camera\r\n");
+ camera_setup();
+ printf(" Done!\r\n");
+
+
+ printf("Take photo\r\n");
+ FILE *fp = fopen("/local/img", "w");
+ camera_grab(fp);
+ fclose(fp);
+ printf(" Done!\r\n");
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri May 23 20:48:07 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/0b3ab51c8877 \ No newline at end of file