Code for OV7670 camera with AL422 FIFO buffer

Dependencies:   BufferedSerial mbed OV7670

main.cpp

Committer:
wrecky
Date:
2016-01-17
Revision:
4:0b4e26ef4048
Parent:
3:d34a59304693

File content as of revision 4:0b4e26ef4048:

//
// OV7670 + FIFO AL422B camera application
// Author: Martin Kráčala
// Inpired by: Edoardo De Marchi, Martin Smith
//
#include "mbed.h"
#include "BufferedSerial.h"
#include "ov7670.h"

#define BAUDRATE    (921600)    // supported baudrates: 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200, 230400, 460800, 921600
#define BUFFER_LEN  (32)
#define DELAY_MS    (100)
#define RMASK1      (0x0F00)
#define RMASK2      (0x000F)
#define ROFFSET1    (4)
#define ROFFSET2    (0)
#define LED_ON      (0)
#define LED_OFF     (1)

#define VGA         (640*480)
#define QVGA        (320*240)
#define QQVGA       (160*120)

#define RAW         'b'
#define RGB         'r'
#define YUV         'y'


// OV7670 also supports CIF, QCIF and QQCIF formats

DigitalOut ledR(LED1,LED_OFF);
DigitalOut ledG(LED2,LED_ON);
DigitalOut ledB(LED3,LED_OFF);

BufferedSerial pc(USBTX, USBRX);        // PTA2,PTA1

OV7670 camera (
    PTC9,PTC8,                  // SDA,SCL(I2C)
    PTA13,NC,PTE2,              // VSYNC,HREF,WEN(FIFO)
    PortB,0x00000F0F,           // PortIn data PTB<0-3>,PTB<8-11>
    PTE3,PTE4,PTE5              // RRST,OE,RCLK
);

static char colorscheme = ' ';
static int resolution = 0;
char buffer_in[BUFFER_LEN];

void setup(char color, int res);
void cmd();

int main()
{
    // set high baud rate
    pc.baud(BAUDRATE);                     
    
    // send hello message via Serial-USB
    pc.printf("Starting FRDM-KL25Z...\r\n");
    
    // reset camera on power up
    camera.Reset() ;

    while (true)
    {
        // Look if things are in the Rx-buffer...
        if(pc.readable())
        {
            int i = 0;
            // if so, load them into buffer_in
            while(pc.readable())
            {
                buffer_in[i++] = pc.getc();
            }
            // compare buffer_in with defined commands, execute
            cmd();
        }
        ledG = LED_OFF;
        wait_ms(DELAY_MS);
        ledG = LED_ON;
    }
}

// Camera setting setup
void setup(char color, int res)
{
    if(camera.Init(color, res) != 1) {
        pc.printf("Setup failed!\r\n");
    } else {
        pc.printf("Setup successful\r\n");
    }
}

// Parse command from buffer_in and execute function
void cmd()
{
    // Read all camera registers - commandline use only (for verification) 
    if(strcmp("reg_status\r\n", buffer_in) == 0) {
        int i = 0;
        pc.printf("AD: +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F");
        for (i=0; i<OV7670_REGMAX; i++) {
            int data;
            data = camera.ReadReg(i);
            if ((i & 0x0F) == 0) {
                pc.printf("\r\n%02X: ",i);
            }
            pc.printf("%02X ",data);
        }
        pc.printf("\r\n");
    }
    // Take a picture
    else if(strcmp("snapshot\r\n", buffer_in) == 0) {
        ledR = LED_ON;
        // Kick things off by capturing an image
        camera.CaptureNext();
        while(camera.CaptureDone() == false);
        // Start reading in the image data from the camera hardware buffer
        camera.ReadStart();
        ledG = LED_OFF;

        for(int x = 0; x<resolution; x++) {
            // Read in the first half of the image
            if(colorscheme == RAW && resolution != VGA) {
                camera.ReadOnebyte(RMASK1,ROFFSET1,RMASK2,ROFFSET2);
            } else if(colorscheme == YUV || colorscheme == RGB) {
                pc.putc(camera.ReadOnebyte(RMASK1,ROFFSET1,RMASK2,ROFFSET2));
            }
            // Read in the Second half of the image
            pc.putc(camera.ReadOnebyte(RMASK1,ROFFSET1,RMASK2,ROFFSET2));      // Y only
        }

        camera.ReadStop();
        ledG = LED_ON;

        camera.CaptureNext();
        while(camera.CaptureDone() == false);

        pc.printf("Snap_done\r\n");
        ledR = LED_OFF;
    }
    // Set up commands...
    else if(strcmp("setup_RAW_VGA\r\n", buffer_in) == 0) {
        // VGA (640*480) RAW
        colorscheme = RAW;
        resolution = VGA;
        setup(colorscheme,resolution);
    }
    else if(strcmp("setup_YUV_QVGA\r\n", buffer_in) == 0)
    {
        // QVGA (320*240) YUV 4:2:2   
        colorscheme = YUV;
        resolution = QVGA;
        setup(RAW,resolution);
    }
    else if(strcmp("setup_RGB_QVGA\r\n", buffer_in) == 0)
    {
        // QVGA (320*240) RGB565   
        colorscheme = RGB;
        resolution = QVGA;
        setup(colorscheme,resolution);
    }
    else if(strcmp("setup_RAW_QVGA\r\n", buffer_in) == 0)    
    {
        // QVGA (320*240) YUV (Only Y) - monochrome    
        colorscheme = RAW;
        resolution = QVGA;
        setup(colorscheme,resolution);
    }
    else if(strcmp("setup_YUV_QQVGA\r\n", buffer_in) == 0)                 
    {
        // QQVGA (160*120) YUV 4:2:2
        colorscheme = YUV;
        resolution = QQVGA;
        setup(RAW,resolution);
    }
    else if(strcmp("setup_RGB_QQVGA\r\n", buffer_in) == 0)                 
    {
        // QQVGA (160*120) RGB565
        colorscheme = RGB;
        resolution = QQVGA;
        setup(colorscheme,resolution);
    }
    else if(strcmp("setup_RAW_QQVGA\r\n", buffer_in) == 0) {
        // QQVGA (160*120) YUV (Only Y) - monochrome
        colorscheme = RAW;
        resolution = QQVGA;
        setup(colorscheme,resolution);
    }
    memset(buffer_in, 0, sizeof(buffer_in));
}