Oliver Hicks / Mbed 2 deprecated mbed_camera

Dependencies:   mbed

Committer:
ollyhicks
Date:
Fri May 23 20:48:07 2014 +0000
Revision:
0:78595d38d985
Sort of working (terrible image)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ollyhicks 0:78595d38d985 1 #include "camera.h"
ollyhicks 0:78595d38d985 2
ollyhicks 0:78595d38d985 3 /*
ollyhicks 0:78595d38d985 4 * Links
ollyhicks 0:78595d38d985 5 * https://gist.github.com/franciscospaeth/8503747
ollyhicks 0:78595d38d985 6 * http://embeddedprogrammer.blogspot.co.uk/2012/07/hacking-ov7670-camera-module-sccb-cheat.html
ollyhicks 0:78595d38d985 7 * http://www.voti.nl/docs/OV7670.pdf
ollyhicks 0:78595d38d985 8 */
ollyhicks 0:78595d38d985 9
ollyhicks 0:78595d38d985 10 BusIn data_p(p17,p18,p15,p16,p13,p14,p11,p12);
ollyhicks 0:78595d38d985 11
ollyhicks 0:78595d38d985 12 PwmOut xclock_p(p21);
ollyhicks 0:78595d38d985 13 DigitalIn pclock_p(p8);
ollyhicks 0:78595d38d985 14 DigitalIn href_p(p5);
ollyhicks 0:78595d38d985 15 DigitalIn vsync_p(p6);
ollyhicks 0:78595d38d985 16
ollyhicks 0:78595d38d985 17 DigitalOut pwdn_p(p19);
ollyhicks 0:78595d38d985 18 DigitalOut reset_p(p20);
ollyhicks 0:78595d38d985 19
ollyhicks 0:78595d38d985 20 I2C i2c(p9, p10); //sda,scl
ollyhicks 0:78595d38d985 21
ollyhicks 0:78595d38d985 22 void camera_setup() {
ollyhicks 0:78595d38d985 23 pwdn_p.write(0);
ollyhicks 0:78595d38d985 24 reset_p.write(1); // The reset pin must be HIGH! (3v3)
ollyhicks 0:78595d38d985 25
ollyhicks 0:78595d38d985 26 /*
ollyhicks 0:78595d38d985 27 * Make camera xclk using PWM
ollyhicks 0:78595d38d985 28 *
ollyhicks 0:78595d38d985 29 * Note the this is 1Mhz, the datasheet specifies a minimum of 26Mhz.
ollyhicks 0:78595d38d985 30 * Reports online state that 10Mhz works, but if you're having issues
ollyhicks 0:78595d38d985 31 * try 26Mhz as we don't understand the side affects.
ollyhicks 0:78595d38d985 32 */
ollyhicks 0:78595d38d985 33 xclock_p.period(CAMERA_CLK_PERIOD);
ollyhicks 0:78595d38d985 34 xclock_p = 0.5;
ollyhicks 0:78595d38d985 35
ollyhicks 0:78595d38d985 36 // i2c
ollyhicks 0:78595d38d985 37 i2c.stop() ;
ollyhicks 0:78595d38d985 38 i2c.frequency(CAMERA_I2C_FREQ); // must be slow
ollyhicks 0:78595d38d985 39 wait(0.1);
ollyhicks 0:78595d38d985 40
ollyhicks 0:78595d38d985 41 /*
ollyhicks 0:78595d38d985 42 * Set to QCIF (176 x 144)
ollyhicks 0:78595d38d985 43 * Note that CAMERA_W and CAMERA_H must also be changed so
ollyhicks 0:78595d38d985 44 * that the buffers are the correct length
ollyhicks 0:78595d38d985 45 */
ollyhicks 0:78595d38d985 46 camera_set_output_format(CAMERA_I2C_OF_QCIF);
ollyhicks 0:78595d38d985 47
ollyhicks 0:78595d38d985 48 /*
ollyhicks 0:78595d38d985 49 * Set PCLK frequency slow enough for us to read and save the data (larger = slower)
ollyhicks 0:78595d38d985 50 * Maximum 65 = (2^6 - 1) see datasheet for CLKRC
ollyhicks 0:78595d38d985 51 */
ollyhicks 0:78595d38d985 52 camera_set_freq_scaler(32);
ollyhicks 0:78595d38d985 53 }
ollyhicks 0:78595d38d985 54
ollyhicks 0:78595d38d985 55 void camera_set_freq_scaler(int prescaler) {
ollyhicks 0:78595d38d985 56 camera_i2c_write(CAMERA_I2C_REG_CLKRC, prescaler);
ollyhicks 0:78595d38d985 57 }
ollyhicks 0:78595d38d985 58
ollyhicks 0:78595d38d985 59 void camera_set_output_format(int output_format) {
ollyhicks 0:78595d38d985 60 camera_i2c_write(CAMERA_I2C_REG_COM3, 0x08); // enable scaling
ollyhicks 0:78595d38d985 61 camera_i2c_write(CAMERA_I2C_REG_COM7, output_format);
ollyhicks 0:78595d38d985 62 }
ollyhicks 0:78595d38d985 63
ollyhicks 0:78595d38d985 64 /**
ollyhicks 0:78595d38d985 65 * Grab a single frame from the camera and save to the file
ollyhicks 0:78595d38d985 66 */
ollyhicks 0:78595d38d985 67 void camera_grab(FILE *fp) {
ollyhicks 0:78595d38d985 68 char href, vsync;
ollyhicks 0:78595d38d985 69
ollyhicks 0:78595d38d985 70 int x = 0; // col
ollyhicks 0:78595d38d985 71 int y = 0; // row
ollyhicks 0:78595d38d985 72 long n = 0; // px number
ollyhicks 0:78595d38d985 73
ollyhicks 0:78595d38d985 74 // Write one row of pixels to the file at a time, so store the row in a buffer
ollyhicks 0:78595d38d985 75 char row_buffer[CAMERA_W * CAMERA_BPX];
ollyhicks 0:78595d38d985 76
ollyhicks 0:78595d38d985 77 // http://3.bp.blogspot.com/-cjOYTMj4C4M/UA2kV-db8GI/AAAAAAAAAPs/rtCGSIGjOHo/s1600/vga.png
ollyhicks 0:78595d38d985 78
ollyhicks 0:78595d38d985 79 // Wait until the end of the previous frame
ollyhicks 0:78595d38d985 80 wait_negedge(vsync_p);
ollyhicks 0:78595d38d985 81
ollyhicks 0:78595d38d985 82 // Start of the frame
ollyhicks 0:78595d38d985 83 while(1) {
ollyhicks 0:78595d38d985 84 // Each row
ollyhicks 0:78595d38d985 85
ollyhicks 0:78595d38d985 86 // Wait until the start of a row or the end of a frame
ollyhicks 0:78595d38d985 87 do {
ollyhicks 0:78595d38d985 88 href = href_p.read();
ollyhicks 0:78595d38d985 89 vsync = vsync_p.read();
ollyhicks 0:78595d38d985 90 } while(href == 0 && vsync == 0);
ollyhicks 0:78595d38d985 91
ollyhicks 0:78595d38d985 92 // Vsync high, thus the end of the frame
ollyhicks 0:78595d38d985 93 if(vsync == 1){
ollyhicks 0:78595d38d985 94 // Print the current x, y and n
ollyhicks 0:78595d38d985 95 // These indicate how many pixels where actually captured
ollyhicks 0:78595d38d985 96 printf("y: %d\r\n", y);
ollyhicks 0:78595d38d985 97 printf("x: %d\r\n", x);
ollyhicks 0:78595d38d985 98 printf("n: %ld\r\n", n);
ollyhicks 0:78595d38d985 99 return; // is the end of a frame
ollyhicks 0:78595d38d985 100 }
ollyhicks 0:78595d38d985 101 // else carry on (href = 1)
ollyhicks 0:78595d38d985 102
ollyhicks 0:78595d38d985 103 x = 0;
ollyhicks 0:78595d38d985 104
ollyhicks 0:78595d38d985 105 /*
ollyhicks 0:78595d38d985 106 * Note we must sample at the rising edge of the PCLK,
ollyhicks 0:78595d38d985 107 * but we must also read the href to check that the frame
ollyhicks 0:78595d38d985 108 * has not ended.
ollyhicks 0:78595d38d985 109 * http://2.bp.blogspot.com/-K-OIuy-inUU/UA2gp3SYgYI/AAAAAAAAAPg/Gure3RWI8G4/s1600/href.png
ollyhicks 0:78595d38d985 110 */
ollyhicks 0:78595d38d985 111
ollyhicks 0:78595d38d985 112 wait_posedge(pclock_p);
ollyhicks 0:78595d38d985 113
ollyhicks 0:78595d38d985 114 while(href_p.read() == 1) {
ollyhicks 0:78595d38d985 115 // Each column
ollyhicks 0:78595d38d985 116
ollyhicks 0:78595d38d985 117 // sample at the rising edge of the PCLK signal
ollyhicks 0:78595d38d985 118
ollyhicks 0:78595d38d985 119 row_buffer[x] = data_p.read();
ollyhicks 0:78595d38d985 120
ollyhicks 0:78595d38d985 121 n++;
ollyhicks 0:78595d38d985 122 x++;
ollyhicks 0:78595d38d985 123
ollyhicks 0:78595d38d985 124 // Wait until next rising edge so that when the href read is done it has changed
ollyhicks 0:78595d38d985 125 wait_posedge(pclock_p);
ollyhicks 0:78595d38d985 126 }
ollyhicks 0:78595d38d985 127
ollyhicks 0:78595d38d985 128 // Write row buffer to the flash
ollyhicks 0:78595d38d985 129 fwrite(row_buffer, sizeof(char), sizeof(row_buffer), fp);
ollyhicks 0:78595d38d985 130
ollyhicks 0:78595d38d985 131
ollyhicks 0:78595d38d985 132 y++;
ollyhicks 0:78595d38d985 133 }
ollyhicks 0:78595d38d985 134
ollyhicks 0:78595d38d985 135 }
ollyhicks 0:78595d38d985 136
ollyhicks 0:78595d38d985 137 int camera_i2c_read(int addr) {
ollyhicks 0:78595d38d985 138 int data=0;
ollyhicks 0:78595d38d985 139
ollyhicks 0:78595d38d985 140 // Address
ollyhicks 0:78595d38d985 141 i2c.start();
ollyhicks 0:78595d38d985 142 i2c.write(CAMERA_I2C_WRITE_ADDR);
ollyhicks 0:78595d38d985 143 i2c.write(addr);
ollyhicks 0:78595d38d985 144
ollyhicks 0:78595d38d985 145 // Not sure why we must stop the i2c bus?
ollyhicks 0:78595d38d985 146 i2c.stop();
ollyhicks 0:78595d38d985 147
ollyhicks 0:78595d38d985 148 wait_us(50);
ollyhicks 0:78595d38d985 149
ollyhicks 0:78595d38d985 150 // Data
ollyhicks 0:78595d38d985 151 i2c.start();
ollyhicks 0:78595d38d985 152 i2c.write(CAMERA_I2C_READ_ADDR);
ollyhicks 0:78595d38d985 153 data = i2c.read(CAMERA_I2C_NOACK) ;
ollyhicks 0:78595d38d985 154 i2c.stop();
ollyhicks 0:78595d38d985 155
ollyhicks 0:78595d38d985 156 wait_us(50);
ollyhicks 0:78595d38d985 157 return data;
ollyhicks 0:78595d38d985 158 }
ollyhicks 0:78595d38d985 159
ollyhicks 0:78595d38d985 160 void camera_i2c_write(int addr, int val) {
ollyhicks 0:78595d38d985 161 i2c.start();
ollyhicks 0:78595d38d985 162
ollyhicks 0:78595d38d985 163 i2c.write(CAMERA_I2C_WRITE_ADDR);
ollyhicks 0:78595d38d985 164 i2c.write(addr);
ollyhicks 0:78595d38d985 165
ollyhicks 0:78595d38d985 166 i2c.write(val);
ollyhicks 0:78595d38d985 167
ollyhicks 0:78595d38d985 168 i2c.stop();
ollyhicks 0:78595d38d985 169
ollyhicks 0:78595d38d985 170 wait_us(50);
ollyhicks 0:78595d38d985 171 }
ollyhicks 0:78595d38d985 172
ollyhicks 0:78595d38d985 173 void wait_posedge(DigitalIn pin) {
ollyhicks 0:78595d38d985 174 while(pin.read() == 1) {};
ollyhicks 0:78595d38d985 175 while(pin.read() == 0) {};
ollyhicks 0:78595d38d985 176 }
ollyhicks 0:78595d38d985 177
ollyhicks 0:78595d38d985 178 void wait_negedge(DigitalIn pin) {
ollyhicks 0:78595d38d985 179 while(pin.read() == 0) {};
ollyhicks 0:78595d38d985 180 while(pin.read() == 1) {};
ollyhicks 0:78595d38d985 181 }