Code for OV7670 camera with AL422 FIFO buffer
Dependencies: BufferedSerial mbed OV7670
main.cpp@4:0b4e26ef4048, 2016-01-17 (annotated)
- Committer:
- wrecky
- Date:
- Sun Jan 17 21:32:55 2016 +0000
- Revision:
- 4:0b4e26ef4048
- Parent:
- 3:d34a59304693
Initial release
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wrecky | 4:0b4e26ef4048 | 1 | // |
wrecky | 4:0b4e26ef4048 | 2 | // OV7670 + FIFO AL422B camera application |
wrecky | 4:0b4e26ef4048 | 3 | // Author: Martin Kráčala |
wrecky | 4:0b4e26ef4048 | 4 | // Inpired by: Edoardo De Marchi, Martin Smith |
wrecky | 4:0b4e26ef4048 | 5 | // |
wrecky | 0:cf824ff9f30c | 6 | #include "mbed.h" |
wrecky | 4:0b4e26ef4048 | 7 | #include "BufferedSerial.h" |
wrecky | 2:0aeb1c0e6a06 | 8 | #include "ov7670.h" |
wrecky | 2:0aeb1c0e6a06 | 9 | |
wrecky | 4:0b4e26ef4048 | 10 | #define BAUDRATE (921600) // supported baudrates: 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200, 230400, 460800, 921600 |
wrecky | 4:0b4e26ef4048 | 11 | #define BUFFER_LEN (32) |
wrecky | 4:0b4e26ef4048 | 12 | #define DELAY_MS (100) |
wrecky | 4:0b4e26ef4048 | 13 | #define RMASK1 (0x0F00) |
wrecky | 4:0b4e26ef4048 | 14 | #define RMASK2 (0x000F) |
wrecky | 4:0b4e26ef4048 | 15 | #define ROFFSET1 (4) |
wrecky | 4:0b4e26ef4048 | 16 | #define ROFFSET2 (0) |
wrecky | 4:0b4e26ef4048 | 17 | #define LED_ON (0) |
wrecky | 4:0b4e26ef4048 | 18 | #define LED_OFF (1) |
wrecky | 4:0b4e26ef4048 | 19 | |
wrecky | 4:0b4e26ef4048 | 20 | #define VGA (640*480) |
wrecky | 4:0b4e26ef4048 | 21 | #define QVGA (320*240) |
wrecky | 4:0b4e26ef4048 | 22 | #define QQVGA (160*120) |
wrecky | 0:cf824ff9f30c | 23 | |
wrecky | 4:0b4e26ef4048 | 24 | #define RAW 'b' |
wrecky | 4:0b4e26ef4048 | 25 | #define RGB 'r' |
wrecky | 4:0b4e26ef4048 | 26 | #define YUV 'y' |
wrecky | 4:0b4e26ef4048 | 27 | |
wrecky | 4:0b4e26ef4048 | 28 | |
wrecky | 4:0b4e26ef4048 | 29 | // OV7670 also supports CIF, QCIF and QQCIF formats |
wrecky | 4:0b4e26ef4048 | 30 | |
wrecky | 4:0b4e26ef4048 | 31 | DigitalOut ledR(LED1,LED_OFF); |
wrecky | 4:0b4e26ef4048 | 32 | DigitalOut ledG(LED2,LED_ON); |
wrecky | 4:0b4e26ef4048 | 33 | DigitalOut ledB(LED3,LED_OFF); |
wrecky | 4:0b4e26ef4048 | 34 | |
wrecky | 4:0b4e26ef4048 | 35 | BufferedSerial pc(USBTX, USBRX); // PTA2,PTA1 |
wrecky | 2:0aeb1c0e6a06 | 36 | |
wrecky | 4:0b4e26ef4048 | 37 | OV7670 camera ( |
wrecky | 4:0b4e26ef4048 | 38 | PTC9,PTC8, // SDA,SCL(I2C) |
wrecky | 4:0b4e26ef4048 | 39 | PTA13,NC,PTE2, // VSYNC,HREF,WEN(FIFO) |
wrecky | 4:0b4e26ef4048 | 40 | PortB,0x00000F0F, // PortIn data PTB<0-3>,PTB<8-11> |
wrecky | 4:0b4e26ef4048 | 41 | PTE3,PTE4,PTE5 // RRST,OE,RCLK |
wrecky | 4:0b4e26ef4048 | 42 | ); |
wrecky | 4:0b4e26ef4048 | 43 | |
wrecky | 4:0b4e26ef4048 | 44 | static char colorscheme = ' '; |
wrecky | 4:0b4e26ef4048 | 45 | static int resolution = 0; |
wrecky | 4:0b4e26ef4048 | 46 | char buffer_in[BUFFER_LEN]; |
wrecky | 4:0b4e26ef4048 | 47 | |
wrecky | 4:0b4e26ef4048 | 48 | void setup(char color, int res); |
wrecky | 4:0b4e26ef4048 | 49 | void cmd(); |
wrecky | 0:cf824ff9f30c | 50 | |
wrecky | 0:cf824ff9f30c | 51 | int main() |
wrecky | 0:cf824ff9f30c | 52 | { |
wrecky | 4:0b4e26ef4048 | 53 | // set high baud rate |
wrecky | 4:0b4e26ef4048 | 54 | pc.baud(BAUDRATE); |
wrecky | 4:0b4e26ef4048 | 55 | |
wrecky | 4:0b4e26ef4048 | 56 | // send hello message via Serial-USB |
wrecky | 4:0b4e26ef4048 | 57 | pc.printf("Starting FRDM-KL25Z...\r\n"); |
wrecky | 4:0b4e26ef4048 | 58 | |
wrecky | 4:0b4e26ef4048 | 59 | // reset camera on power up |
wrecky | 4:0b4e26ef4048 | 60 | camera.Reset() ; |
wrecky | 0:cf824ff9f30c | 61 | |
wrecky | 4:0b4e26ef4048 | 62 | while (true) |
wrecky | 4:0b4e26ef4048 | 63 | { |
wrecky | 4:0b4e26ef4048 | 64 | // Look if things are in the Rx-buffer... |
wrecky | 4:0b4e26ef4048 | 65 | if(pc.readable()) |
wrecky | 4:0b4e26ef4048 | 66 | { |
wrecky | 4:0b4e26ef4048 | 67 | int i = 0; |
wrecky | 4:0b4e26ef4048 | 68 | // if so, load them into buffer_in |
wrecky | 4:0b4e26ef4048 | 69 | while(pc.readable()) |
wrecky | 4:0b4e26ef4048 | 70 | { |
wrecky | 4:0b4e26ef4048 | 71 | buffer_in[i++] = pc.getc(); |
wrecky | 4:0b4e26ef4048 | 72 | } |
wrecky | 4:0b4e26ef4048 | 73 | // compare buffer_in with defined commands, execute |
wrecky | 4:0b4e26ef4048 | 74 | cmd(); |
wrecky | 4:0b4e26ef4048 | 75 | } |
wrecky | 4:0b4e26ef4048 | 76 | ledG = LED_OFF; |
wrecky | 4:0b4e26ef4048 | 77 | wait_ms(DELAY_MS); |
wrecky | 4:0b4e26ef4048 | 78 | ledG = LED_ON; |
wrecky | 4:0b4e26ef4048 | 79 | } |
wrecky | 4:0b4e26ef4048 | 80 | } |
wrecky | 2:0aeb1c0e6a06 | 81 | |
wrecky | 4:0b4e26ef4048 | 82 | // Camera setting setup |
wrecky | 4:0b4e26ef4048 | 83 | void setup(char color, int res) |
wrecky | 4:0b4e26ef4048 | 84 | { |
wrecky | 4:0b4e26ef4048 | 85 | if(camera.Init(color, res) != 1) { |
wrecky | 4:0b4e26ef4048 | 86 | pc.printf("Setup failed!\r\n"); |
wrecky | 4:0b4e26ef4048 | 87 | } else { |
wrecky | 4:0b4e26ef4048 | 88 | pc.printf("Setup successful\r\n"); |
wrecky | 0:cf824ff9f30c | 89 | } |
wrecky | 0:cf824ff9f30c | 90 | } |
wrecky | 4:0b4e26ef4048 | 91 | |
wrecky | 4:0b4e26ef4048 | 92 | // Parse command from buffer_in and execute function |
wrecky | 4:0b4e26ef4048 | 93 | void cmd() |
wrecky | 4:0b4e26ef4048 | 94 | { |
wrecky | 4:0b4e26ef4048 | 95 | // Read all camera registers - commandline use only (for verification) |
wrecky | 4:0b4e26ef4048 | 96 | if(strcmp("reg_status\r\n", buffer_in) == 0) { |
wrecky | 4:0b4e26ef4048 | 97 | int i = 0; |
wrecky | 4:0b4e26ef4048 | 98 | pc.printf("AD: +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F"); |
wrecky | 4:0b4e26ef4048 | 99 | for (i=0; i<OV7670_REGMAX; i++) { |
wrecky | 4:0b4e26ef4048 | 100 | int data; |
wrecky | 4:0b4e26ef4048 | 101 | data = camera.ReadReg(i); |
wrecky | 4:0b4e26ef4048 | 102 | if ((i & 0x0F) == 0) { |
wrecky | 4:0b4e26ef4048 | 103 | pc.printf("\r\n%02X: ",i); |
wrecky | 4:0b4e26ef4048 | 104 | } |
wrecky | 4:0b4e26ef4048 | 105 | pc.printf("%02X ",data); |
wrecky | 4:0b4e26ef4048 | 106 | } |
wrecky | 4:0b4e26ef4048 | 107 | pc.printf("\r\n"); |
wrecky | 4:0b4e26ef4048 | 108 | } |
wrecky | 4:0b4e26ef4048 | 109 | // Take a picture |
wrecky | 4:0b4e26ef4048 | 110 | else if(strcmp("snapshot\r\n", buffer_in) == 0) { |
wrecky | 4:0b4e26ef4048 | 111 | ledR = LED_ON; |
wrecky | 4:0b4e26ef4048 | 112 | // Kick things off by capturing an image |
wrecky | 4:0b4e26ef4048 | 113 | camera.CaptureNext(); |
wrecky | 4:0b4e26ef4048 | 114 | while(camera.CaptureDone() == false); |
wrecky | 4:0b4e26ef4048 | 115 | // Start reading in the image data from the camera hardware buffer |
wrecky | 4:0b4e26ef4048 | 116 | camera.ReadStart(); |
wrecky | 4:0b4e26ef4048 | 117 | ledG = LED_OFF; |
wrecky | 4:0b4e26ef4048 | 118 | |
wrecky | 4:0b4e26ef4048 | 119 | for(int x = 0; x<resolution; x++) { |
wrecky | 4:0b4e26ef4048 | 120 | // Read in the first half of the image |
wrecky | 4:0b4e26ef4048 | 121 | if(colorscheme == RAW && resolution != VGA) { |
wrecky | 4:0b4e26ef4048 | 122 | camera.ReadOnebyte(RMASK1,ROFFSET1,RMASK2,ROFFSET2); |
wrecky | 4:0b4e26ef4048 | 123 | } else if(colorscheme == YUV || colorscheme == RGB) { |
wrecky | 4:0b4e26ef4048 | 124 | pc.putc(camera.ReadOnebyte(RMASK1,ROFFSET1,RMASK2,ROFFSET2)); |
wrecky | 4:0b4e26ef4048 | 125 | } |
wrecky | 4:0b4e26ef4048 | 126 | // Read in the Second half of the image |
wrecky | 4:0b4e26ef4048 | 127 | pc.putc(camera.ReadOnebyte(RMASK1,ROFFSET1,RMASK2,ROFFSET2)); // Y only |
wrecky | 4:0b4e26ef4048 | 128 | } |
wrecky | 4:0b4e26ef4048 | 129 | |
wrecky | 4:0b4e26ef4048 | 130 | camera.ReadStop(); |
wrecky | 4:0b4e26ef4048 | 131 | ledG = LED_ON; |
wrecky | 4:0b4e26ef4048 | 132 | |
wrecky | 4:0b4e26ef4048 | 133 | camera.CaptureNext(); |
wrecky | 4:0b4e26ef4048 | 134 | while(camera.CaptureDone() == false); |
wrecky | 4:0b4e26ef4048 | 135 | |
wrecky | 4:0b4e26ef4048 | 136 | pc.printf("Snap_done\r\n"); |
wrecky | 4:0b4e26ef4048 | 137 | ledR = LED_OFF; |
wrecky | 4:0b4e26ef4048 | 138 | } |
wrecky | 4:0b4e26ef4048 | 139 | // Set up commands... |
wrecky | 4:0b4e26ef4048 | 140 | else if(strcmp("setup_RAW_VGA\r\n", buffer_in) == 0) { |
wrecky | 4:0b4e26ef4048 | 141 | // VGA (640*480) RAW |
wrecky | 4:0b4e26ef4048 | 142 | colorscheme = RAW; |
wrecky | 4:0b4e26ef4048 | 143 | resolution = VGA; |
wrecky | 4:0b4e26ef4048 | 144 | setup(colorscheme,resolution); |
wrecky | 4:0b4e26ef4048 | 145 | } |
wrecky | 4:0b4e26ef4048 | 146 | else if(strcmp("setup_YUV_QVGA\r\n", buffer_in) == 0) |
wrecky | 4:0b4e26ef4048 | 147 | { |
wrecky | 4:0b4e26ef4048 | 148 | // QVGA (320*240) YUV 4:2:2 |
wrecky | 4:0b4e26ef4048 | 149 | colorscheme = YUV; |
wrecky | 4:0b4e26ef4048 | 150 | resolution = QVGA; |
wrecky | 4:0b4e26ef4048 | 151 | setup(RAW,resolution); |
wrecky | 4:0b4e26ef4048 | 152 | } |
wrecky | 4:0b4e26ef4048 | 153 | else if(strcmp("setup_RGB_QVGA\r\n", buffer_in) == 0) |
wrecky | 4:0b4e26ef4048 | 154 | { |
wrecky | 4:0b4e26ef4048 | 155 | // QVGA (320*240) RGB565 |
wrecky | 4:0b4e26ef4048 | 156 | colorscheme = RGB; |
wrecky | 4:0b4e26ef4048 | 157 | resolution = QVGA; |
wrecky | 4:0b4e26ef4048 | 158 | setup(colorscheme,resolution); |
wrecky | 4:0b4e26ef4048 | 159 | } |
wrecky | 4:0b4e26ef4048 | 160 | else if(strcmp("setup_RAW_QVGA\r\n", buffer_in) == 0) |
wrecky | 4:0b4e26ef4048 | 161 | { |
wrecky | 4:0b4e26ef4048 | 162 | // QVGA (320*240) YUV (Only Y) - monochrome |
wrecky | 4:0b4e26ef4048 | 163 | colorscheme = RAW; |
wrecky | 4:0b4e26ef4048 | 164 | resolution = QVGA; |
wrecky | 4:0b4e26ef4048 | 165 | setup(colorscheme,resolution); |
wrecky | 4:0b4e26ef4048 | 166 | } |
wrecky | 4:0b4e26ef4048 | 167 | else if(strcmp("setup_YUV_QQVGA\r\n", buffer_in) == 0) |
wrecky | 4:0b4e26ef4048 | 168 | { |
wrecky | 4:0b4e26ef4048 | 169 | // QQVGA (160*120) YUV 4:2:2 |
wrecky | 4:0b4e26ef4048 | 170 | colorscheme = YUV; |
wrecky | 4:0b4e26ef4048 | 171 | resolution = QQVGA; |
wrecky | 4:0b4e26ef4048 | 172 | setup(RAW,resolution); |
wrecky | 4:0b4e26ef4048 | 173 | } |
wrecky | 4:0b4e26ef4048 | 174 | else if(strcmp("setup_RGB_QQVGA\r\n", buffer_in) == 0) |
wrecky | 4:0b4e26ef4048 | 175 | { |
wrecky | 4:0b4e26ef4048 | 176 | // QQVGA (160*120) RGB565 |
wrecky | 4:0b4e26ef4048 | 177 | colorscheme = RGB; |
wrecky | 4:0b4e26ef4048 | 178 | resolution = QQVGA; |
wrecky | 4:0b4e26ef4048 | 179 | setup(colorscheme,resolution); |
wrecky | 4:0b4e26ef4048 | 180 | } |
wrecky | 4:0b4e26ef4048 | 181 | else if(strcmp("setup_RAW_QQVGA\r\n", buffer_in) == 0) { |
wrecky | 4:0b4e26ef4048 | 182 | // QQVGA (160*120) YUV (Only Y) - monochrome |
wrecky | 4:0b4e26ef4048 | 183 | colorscheme = RAW; |
wrecky | 4:0b4e26ef4048 | 184 | resolution = QQVGA; |
wrecky | 4:0b4e26ef4048 | 185 | setup(colorscheme,resolution); |
wrecky | 4:0b4e26ef4048 | 186 | } |
wrecky | 4:0b4e26ef4048 | 187 | memset(buffer_in, 0, sizeof(buffer_in)); |
wrecky | 4:0b4e26ef4048 | 188 | } |