Battery

Dependencies:   mbed PowerControl SDFileSystem

Fork of HeptaBattery by 智也 大野

hepta_sat/HeptaCamera.cpp

Committer:
tomoya123
Date:
2016-12-13
Revision:
1:166ddf929155
Parent:
0:d53e9c6fc771

File content as of revision 1:166ddf929155:

#include "HeptaCamera.h"
#include "mbed.h"

int sizex = 0;
int sizey = 0;

#if defined(BITMAPFILE) || defined(BAYERBITMAPFILE)

#define FILEHEADERSIZE 14                   //ファイルヘッダのサイズ
#define INFOHEADERSIZE 40                   //情報ヘッダのサイズ
#define HEADERSIZE (FILEHEADERSIZE+INFOHEADERSIZE)

int create_header(FILE *fp, int width, int height) {
    int real_width;
    unsigned char header_buf[HEADERSIZE]; //ヘッダを格納する
    unsigned int file_size;
    unsigned int offset_to_data;
    unsigned long info_header_size;
    unsigned int planes;
    unsigned int color;
    unsigned long compress;
    unsigned long data_size;
    long xppm;
    long yppm;

    real_width = width*3 + width%4;

    //ここからヘッダ作成
    file_size = height * real_width + HEADERSIZE;
    offset_to_data = HEADERSIZE;
    info_header_size = INFOHEADERSIZE;
    planes = 1;
    color = 24;
    compress = 0;
    data_size = height * real_width;
    xppm = 1;
    yppm = 1;

    header_buf[0] = 'B';
    header_buf[1] = 'M';
    memcpy(header_buf + 2, &file_size, sizeof(file_size));
    header_buf[6] = 0;
    header_buf[7] = 0;
    header_buf[8] = 0;
    header_buf[9] = 0;
    memcpy(header_buf + 10, &offset_to_data, sizeof(offset_to_data));
    memcpy(header_buf + 14, &info_header_size, sizeof(info_header_size));
    memcpy(header_buf + 18, &width, sizeof(width));
    height = height * -1; // データ格納順が逆なので、高さをマイナスとしている
    memcpy(header_buf + 22, &height, sizeof(height));
    memcpy(header_buf + 26, &planes, sizeof(planes));
    memcpy(header_buf + 28, &color, sizeof(color));
    memcpy(header_buf + 30, &compress, sizeof(compress));
    memcpy(header_buf + 34, &data_size, sizeof(data_size));
    memcpy(header_buf + 38, &xppm, sizeof(xppm));
    memcpy(header_buf + 42, &yppm, sizeof(yppm));
    header_buf[46] = 0;
    header_buf[47] = 0;
    header_buf[48] = 0;
    header_buf[49] = 0;
    header_buf[50] = 0;
    header_buf[51] = 0;
    header_buf[52] = 0;
    header_buf[53] = 0;

    //ヘッダの書き込み
    fwrite(header_buf, sizeof(unsigned char), HEADERSIZE, fp);

    return 0;
}
#endif

HeptaCamera::HeptaCamera(PinName sda, PinName scl, PinName vs, PinName hr,PinName we, PinName d7, PinName d6, PinName d5, PinName d4,
 PinName d3, PinName d2, PinName d1, PinName d0, PinName rt, PinName o, PinName rc ) : camera(sda,scl),vsync(vs),href(hr),wen(we),data(d0,d1,d2,d3,d4,d5,d6,d7),rrst(rt),oe(o),rclk(rc)
{
    camera.stop();
    camera.frequency(OV7670_I2CFREQ);
    vsync.fall(this,&HeptaCamera::VsyncHandler);
    href.rise(this,&HeptaCamera::HrefHandler);
    CaptureReq = false;
    Busy = false;
    Done = false;
    LineCounter = 0;
    rrst = 1;
    oe = 1;
    rclk = 1;
    wen = 0;
}
    // capture request
    void HeptaCamera::CaptureNext(void)
    {
        CaptureReq = true;
        Busy = true;
    }
    
    // capture done? (with clear)
    bool HeptaCamera::CaptureDone(void)
    {
        bool result;
        if (Busy) {
            result = false;
        } else {
            result = Done;
            Done = false;
        }
        return result;
    }

    // write to camera
    void HeptaCamera::WriteReg(int addr,int data)
    {
        // WRITE 0x42,ADDR,DATA
        camera.start();
        camera.write(OV7670_WRITE);
        wait_us(OV7670_WRITEWAIT);
        camera.write(addr);
        wait_us(OV7670_WRITEWAIT);
        camera.write(data);
        camera.stop();
    }

    // read from camera
    int HeptaCamera::ReadReg(int addr)
    {
        int data;

        // WRITE 0x42,ADDR
        camera.start();
        camera.write(OV7670_WRITE);
        wait_us(OV7670_WRITEWAIT);
        camera.write(addr);
        camera.stop();
        wait_us(OV7670_WRITEWAIT);    

        // WRITE 0x43,READ
        camera.start();
        camera.write(OV7670_READ);
        wait_us(OV7670_WRITEWAIT);
        data = camera.read(OV7670_NOACK);
        camera.stop();
    
        return data;
    }

    // print register
    void HeptaCamera::PrintRegister(void) {   
        printf("AD : +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F");
        for (int i=0;i<OV7670_REGMAX;i++) {
            int data;
            data = ReadReg(i); // READ REG
            if ((i & 0x0F) == 0) {
                printf("\r\n%02X : ",i);
            }
            printf("%02X ",data);
        }
        printf("\r\n");
    }

    void HeptaCamera::Reset(void) {    
        WriteReg(REG_COM7,COM7_RESET); // RESET CAMERA
        wait_ms(200);
    }

    void HeptaCamera::InitForFIFOWriteReset(void) {
        WriteReg(REG_COM10, COM10_VS_NEG);
    }

    void HeptaCamera::InitSetColorbar(void)  {
        int reg_com7 = ReadReg(REG_COM7);
        // color bar
        WriteReg(REG_COM17, reg_com7|COM17_CBAR);
    }

    void HeptaCamera::InitDefaultReg(void) {
        // Gamma curve values
        WriteReg(0x7a, 0x20);
        WriteReg(0x7b, 0x10);
        WriteReg(0x7c, 0x1e);
        WriteReg(0x7d, 0x35);
        WriteReg(0x7e, 0x5a);
        WriteReg(0x7f, 0x69);
        WriteReg(0x80, 0x76);
        WriteReg(0x81, 0x80);
        WriteReg(0x82, 0x88);
        WriteReg(0x83, 0x8f);
        WriteReg(0x84, 0x96);
        WriteReg(0x85, 0xa3);
        WriteReg(0x86, 0xaf);
        WriteReg(0x87, 0xc4);
        WriteReg(0x88, 0xd7);
        WriteReg(0x89, 0xe8);
        
        // AGC and AEC parameters.  Note we start by disabling those features,
        //then turn them only after tweaking the values.
        WriteReg(REG_COM8, COM8_FASTAEC | COM8_AECSTEP | COM8_BFILT);
        WriteReg(REG_GAIN, 0);
        WriteReg(REG_AECH, 0);
        WriteReg(REG_COM4, 0x40);
        // magic reserved bit
        WriteReg(REG_COM9, 0x18);
        // 4x gain + magic rsvd bit
        WriteReg(REG_BD50MAX, 0x05);
        WriteReg(REG_BD60MAX, 0x07);
        WriteReg(REG_AEW, 0x95);
        WriteReg(REG_AEB, 0x33);
        WriteReg(REG_VPT, 0xe3);
        WriteReg(REG_HAECC1, 0x78);
        WriteReg(REG_HAECC2, 0x68);
        WriteReg(0xa1, 0x03);
        // magic
        WriteReg(REG_HAECC3, 0xd8);
        WriteReg(REG_HAECC4, 0xd8);
        WriteReg(REG_HAECC5, 0xf0);
        WriteReg(REG_HAECC6, 0x90);
        WriteReg(REG_HAECC7, 0x94);
        WriteReg(REG_COM8, COM8_FASTAEC|COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC);
        
        // Almost all of these are magic "reserved" values.
        WriteReg(REG_COM5, 0x61);
        WriteReg(REG_COM6, 0x4b);
        WriteReg(0x16, 0x02);
        WriteReg(REG_MVFP, 0x07);
        WriteReg(0x21, 0x02);
        WriteReg(0x22, 0x91);
        WriteReg(0x29, 0x07);
        WriteReg(0x33, 0x0b);
        WriteReg(0x35, 0x0b);
        WriteReg(0x37, 0x1d);
        WriteReg(0x38, 0x71);
        WriteReg(0x39, 0x2a);
        WriteReg(REG_COM12, 0x78);
        WriteReg(0x4d, 0x40);
        WriteReg(0x4e, 0x20);
        WriteReg(REG_GFIX, 0);
        WriteReg(0x6b, 0x0a);
        WriteReg(0x74, 0x10);
        WriteReg(0x8d, 0x4f);
        WriteReg(0x8e, 0);
        WriteReg(0x8f, 0);
        WriteReg(0x90, 0);
        WriteReg(0x91, 0);
        WriteReg(0x96, 0);
        WriteReg(0x9a, 0);
        WriteReg(0xb0, 0x84);
        WriteReg(0xb1, 0x0c);
        WriteReg(0xb2, 0x0e);
        WriteReg(0xb3, 0x82);
        WriteReg(0xb8, 0x0a);
        
        // More reserved magic, some of which tweaks white balance
        WriteReg(0x43, 0x0a);
        WriteReg(0x44, 0xf0);
        WriteReg(0x45, 0x34);
        WriteReg(0x46, 0x58);
        WriteReg(0x47, 0x28);
        WriteReg(0x48, 0x3a);
        WriteReg(0x59, 0x88);
        WriteReg(0x5a, 0x88);
        WriteReg(0x5b, 0x44);
        WriteReg(0x5c, 0x67);
        WriteReg(0x5d, 0x49);
        WriteReg(0x5e, 0x0e);
        WriteReg(0x6c, 0x0a);
        WriteReg(0x6d, 0x55);
        WriteReg(0x6e, 0x11);
        WriteReg(0x6f, 0x9f);
        // "9e for advance AWB"
        WriteReg(0x6a, 0x40);
        WriteReg(REG_BLUE, 0x40);
        WriteReg(REG_RED, 0x60);
        WriteReg(REG_COM8, COM8_FASTAEC|COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC|COM8_AWB);
        
        // Matrix coefficients
        WriteReg(0x4f, 0x80);
        WriteReg(0x50, 0x80);
        WriteReg(0x51, 0);
        WriteReg(0x52, 0x22);
        WriteReg(0x53, 0x5e);
        WriteReg(0x54, 0x80);
        WriteReg(0x58, 0x9e);
        
        WriteReg(REG_COM16, COM16_AWBGAIN);
        WriteReg(REG_EDGE, 0);
        WriteReg(0x75, 0x05);
        WriteReg(0x76, 0xe1);
        WriteReg(0x4c, 0);
        WriteReg(0x77, 0x01);
        WriteReg(0x4b, 0x09);
        WriteReg(0xc9, 0x60);
        WriteReg(REG_COM16, 0x38);
        WriteReg(0x56, 0x40);
        
        WriteReg(0x34, 0x11);
        WriteReg(REG_COM11, COM11_EXP|COM11_HZAUTO_ON);
        WriteReg(0xa4, 0x88);
        WriteReg(0x96, 0);
        WriteReg(0x97, 0x30);
        WriteReg(0x98, 0x20);
        WriteReg(0x99, 0x30);
        WriteReg(0x9a, 0x84);
        WriteReg(0x9b, 0x29);
        WriteReg(0x9c, 0x03);
        WriteReg(0x9d, 0x4c);
        WriteReg(0x9e, 0x3f);
        WriteReg(0x78, 0x04);
        
        // Extra-weird stuff.  Some sort of multiplexor register
        WriteReg(0x79, 0x01);
        WriteReg(0xc8, 0xf0);
        WriteReg(0x79, 0x0f);
        WriteReg(0xc8, 0x00);
        WriteReg(0x79, 0x10);
        WriteReg(0xc8, 0x7e);
        WriteReg(0x79, 0x0a);
        WriteReg(0xc8, 0x80);
        WriteReg(0x79, 0x0b);
        WriteReg(0xc8, 0x01);
        WriteReg(0x79, 0x0c);
        WriteReg(0xc8, 0x0f);
        WriteReg(0x79, 0x0d);
        WriteReg(0xc8, 0x20);
        WriteReg(0x79, 0x09);
        WriteReg(0xc8, 0x80);
        WriteReg(0x79, 0x02);
        WriteReg(0xc8, 0xc0);
        WriteReg(0x79, 0x03);
        WriteReg(0xc8, 0x40);
        WriteReg(0x79, 0x05);
        WriteReg(0xc8, 0x30);
        WriteReg(0x79, 0x26);
    }

    void HeptaCamera::InitRGB444(void){
        int reg_com7 = ReadReg(REG_COM7);

        WriteReg(REG_COM7, reg_com7|COM7_RGB);
        WriteReg(REG_RGB444, RGB444_ENABLE|RGB444_XBGR);
        WriteReg(REG_COM15, COM15_R01FE|COM15_RGB444);

        WriteReg(REG_COM1, 0x40);                          // Magic reserved bit
        WriteReg(REG_COM9, 0x38);                          // 16x gain ceiling; 0x8 is reserved bit
        WriteReg(0x4f, 0xb3);                              // "matrix coefficient 1"
        WriteReg(0x50, 0xb3);                              // "matrix coefficient 2"
        WriteReg(0x51, 0x00);                              // vb
        WriteReg(0x52, 0x3d);                              // "matrix coefficient 4"
        WriteReg(0x53, 0xa7);                              // "matrix coefficient 5"
        WriteReg(0x54, 0xe4);                              // "matrix coefficient 6"
        WriteReg(REG_COM13, COM13_GAMMA|COM13_UVSAT|0x2);  // Magic rsvd bit

        WriteReg(REG_TSLB, 0x04);
    }

    void HeptaCamera::InitRGB555(void){
        int reg_com7 = ReadReg(REG_COM7);

        WriteReg(REG_COM7, reg_com7|COM7_RGB);
        WriteReg(REG_RGB444, RGB444_DISABLE);
        WriteReg(REG_COM15, COM15_RGB555|COM15_R00FF);

        WriteReg(REG_TSLB, 0x04);

        WriteReg(REG_COM1, 0x00);
        WriteReg(REG_COM9, 0x38);      // 16x gain ceiling; 0x8 is reserved bit
        WriteReg(0x4f, 0xb3);          // "matrix coefficient 1"
        WriteReg(0x50, 0xb3);          // "matrix coefficient 2"
        WriteReg(0x51, 0x00);          // vb
        WriteReg(0x52, 0x3d);          // "matrix coefficient 4"
        WriteReg(0x53, 0xa7);          // "matrix coefficient 5"
        WriteReg(0x54, 0xe4);          // "matrix coefficient 6"
        WriteReg(REG_COM13, COM13_GAMMA|COM13_UVSAT);
    }

    void HeptaCamera::InitRGB565(void){
        int reg_com7 = ReadReg(REG_COM7);

        WriteReg(REG_COM7, reg_com7|COM7_RGB);
        WriteReg(REG_RGB444, RGB444_DISABLE);
        WriteReg(REG_COM15, COM15_R00FF|COM15_RGB565);

        WriteReg(REG_TSLB, 0x04);

        WriteReg(REG_COM1, 0x00);
        WriteReg(REG_COM9, 0x38);      // 16x gain ceiling; 0x8 is reserved bit
        WriteReg(0x4f, 0xb3);          // "matrix coefficient 1"
        WriteReg(0x50, 0xb3);          // "matrix coefficient 2"
        WriteReg(0x51, 0x00);          // vb
        WriteReg(0x52, 0x3d);          // "matrix coefficient 4"
        WriteReg(0x53, 0xa7);          // "matrix coefficient 5"
        WriteReg(0x54, 0xe4);          // "matrix coefficient 6"
        WriteReg(REG_COM13, COM13_GAMMA|COM13_UVSAT);
    }

    void HeptaCamera::InitYUV(void){
        int reg_com7 = ReadReg(REG_COM7);

        WriteReg(REG_COM7, reg_com7|COM7_YUV);
        WriteReg(REG_RGB444, RGB444_DISABLE);
        WriteReg(REG_COM15, COM15_R00FF);

        WriteReg(REG_TSLB, 0x04);
//       WriteReg(REG_TSLB, 0x14);
//       WriteReg(REG_MANU, 0x00);
//       WriteReg(REG_MANV, 0x00);
        
        WriteReg(REG_COM1, 0x00);
        WriteReg(REG_COM9, 0x18);     // 4x gain ceiling; 0x8 is reserved bit
        WriteReg(0x4f, 0x80);         // "matrix coefficient 1"
        WriteReg(0x50, 0x80);         // "matrix coefficient 2"
        WriteReg(0x51, 0x00);         // vb
        WriteReg(0x52, 0x22);         // "matrix coefficient 4"
        WriteReg(0x53, 0x5e);         // "matrix coefficient 5"
        WriteReg(0x54, 0x80);         // "matrix coefficient 6"
        WriteReg(REG_COM13, COM13_GAMMA|COM13_UVSAT|COM13_UVSWAP);
    }

    void HeptaCamera::InitBayerRGB(void){
        int reg_com7 = ReadReg(REG_COM7);

        // odd line BGBG... even line GRGR...
        WriteReg(REG_COM7, reg_com7|COM7_BAYER);
        // odd line GBGB... even line RGRG...
        //WriteReg(REG_COM7, reg_com7|COM7_PBAYER);

        WriteReg(REG_RGB444, RGB444_DISABLE);
        WriteReg(REG_COM15, COM15_R00FF);

        WriteReg(REG_COM13, 0x08); /* No gamma, magic rsvd bit */
        WriteReg(REG_COM16, 0x3d); /* Edge enhancement, denoise */
        WriteReg(REG_REG76, 0xe1); /* Pix correction, magic rsvd */

        WriteReg(REG_TSLB, 0x04);
    }

    void HeptaCamera::InitVGA(void) {
        // VGA
        int reg_com7 = ReadReg(REG_COM7);

        WriteReg(REG_COM7,reg_com7|COM7_VGA);

        WriteReg(REG_HSTART,HSTART_VGA);
        WriteReg(REG_HSTOP,HSTOP_VGA);
        WriteReg(REG_HREF,HREF_VGA);
        WriteReg(REG_VSTART,VSTART_VGA);
        WriteReg(REG_VSTOP,VSTOP_VGA);
        WriteReg(REG_VREF,VREF_VGA);
        WriteReg(REG_COM3, COM3_VGA);
        WriteReg(REG_COM14, COM14_VGA);
        WriteReg(REG_SCALING_XSC, SCALING_XSC_VGA);
        WriteReg(REG_SCALING_YSC, SCALING_YSC_VGA);
        WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_VGA);
        WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_VGA);
        WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_VGA);
    }

    void HeptaCamera::InitFIFO_2bytes_color_nealy_limit_size(void) {
        // nealy FIFO limit 544x360
        int reg_com7 = ReadReg(REG_COM7);

        WriteReg(REG_COM7,reg_com7|COM7_VGA);

        WriteReg(REG_HSTART,HSTART_VGA);
        WriteReg(REG_HSTOP,HSTOP_VGA);
        WriteReg(REG_HREF,HREF_VGA);
        WriteReg(REG_VSTART,VSTART_VGA);
        WriteReg(REG_VSTOP,VSTOP_VGA);
        WriteReg(REG_VREF,VREF_VGA);
        WriteReg(REG_COM3, COM3_VGA);
        WriteReg(REG_COM14, COM14_VGA);
        WriteReg(REG_SCALING_XSC, SCALING_XSC_VGA);
        WriteReg(REG_SCALING_YSC, SCALING_YSC_VGA);
        WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_VGA);
        WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_VGA);
        WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_VGA);

        WriteReg(REG_HSTART, 0x17);
        WriteReg(REG_HSTOP, 0x5b);
        WriteReg(REG_VSTART, 0x12);
        WriteReg(REG_VSTOP, 0x6c);
    }

    void HeptaCamera::InitVGA_3_4(void) {
        // VGA 3/4 -> 480x360
        int reg_com7 = ReadReg(REG_COM7);

        WriteReg(REG_COM7,reg_com7|COM7_VGA);

        WriteReg(REG_HSTART,HSTART_VGA);
        WriteReg(REG_HSTOP,HSTOP_VGA);
        WriteReg(REG_HREF,HREF_VGA);
        WriteReg(REG_VSTART,VSTART_VGA);
        WriteReg(REG_VSTOP,VSTOP_VGA);
        WriteReg(REG_VREF,VREF_VGA);
        WriteReg(REG_COM3, COM3_VGA);
        WriteReg(REG_COM14, COM14_VGA);
        WriteReg(REG_SCALING_XSC, SCALING_XSC_VGA);
        WriteReg(REG_SCALING_YSC, SCALING_YSC_VGA);
        WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_VGA);
        WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_VGA);
        WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_VGA);

        WriteReg(REG_HSTART, 0x1b);
        WriteReg(REG_HSTOP, 0x57);
        WriteReg(REG_VSTART, 0x12);
        WriteReg(REG_VSTOP, 0x6c);
    }

    void HeptaCamera::InitQVGA(void) {
        // QQVGA
        int reg_com7 = ReadReg(REG_COM7);
        
        WriteReg(REG_COM7,reg_com7|COM7_QVGA);
        
        WriteReg(REG_HSTART,HSTART_QVGA);
        WriteReg(REG_HSTOP,HSTOP_QVGA);
        WriteReg(REG_HREF,HREF_QVGA);
        WriteReg(REG_VSTART,VSTART_QVGA);
        WriteReg(REG_VSTOP,VSTOP_QVGA);
        WriteReg(REG_VREF,VREF_QVGA);
        WriteReg(REG_COM3, COM3_QVGA);
        WriteReg(REG_COM14, COM14_QVGA);
        WriteReg(REG_SCALING_XSC, SCALING_XSC_QVGA);
        WriteReg(REG_SCALING_YSC, SCALING_YSC_QVGA);
        WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_QVGA);
        WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_QVGA);
        WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_QVGA);
    }

    void HeptaCamera::InitQQVGA(void) {
        // QQVGA
        int reg_com7 = ReadReg(REG_COM7);
        
        WriteReg(REG_COM7,reg_com7|COM7_QQVGA);

        WriteReg(REG_HSTART,HSTART_QQVGA);
        WriteReg(REG_HSTOP,HSTOP_QQVGA);
        WriteReg(REG_HREF,HREF_QQVGA);
        WriteReg(REG_VSTART,VSTART_QQVGA);
        WriteReg(REG_VSTOP,VSTOP_QQVGA);
        WriteReg(REG_VREF,VREF_QQVGA);
        WriteReg(REG_COM3, COM3_QQVGA);
        WriteReg(REG_COM14, COM14_QQVGA);
        WriteReg(REG_SCALING_XSC, SCALING_XSC_QQVGA);
        WriteReg(REG_SCALING_YSC, SCALING_YSC_QQVGA);
        WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_QQVGA);
        WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_QQVGA);
        WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_QQVGA);
    }

    // vsync handler
    void HeptaCamera::VsyncHandler(void)
    {
        // Capture Enable
        if (CaptureReq) {
            wen = 1;
            Done = false;
            CaptureReq = false;
        } else {
            wen = 0;
            if (Busy) {
                Busy = false;
                Done = true;
            }
        }

        // Hline Counter
        LastLines = LineCounter;
        LineCounter = 0;
    }
    
    // href handler
    void HeptaCamera::HrefHandler(void)
    {
        LineCounter++;
    }
    
    // Data Read
    int HeptaCamera::ReadOneByte(void)
    {
        int result;
        rclk = 1;
//        wait_us(1);
        result = data;
        rclk = 0;
        return result;
    }
    
    // Data Start
    void HeptaCamera::ReadStart(void)
    {        
        rrst = 0;
        oe = 0;
        wait_us(1);
        rclk = 0;
        wait_us(1);
        rclk = 1;
        wait_us(1);        
        rrst = 1;
    }
    
    // Data Stop
    void HeptaCamera::ReadStop(void)
    {
        oe = 1;
        ReadOneByte();
        rclk = 1;
    }

void HeptaCamera::shoot()
{
       //pc.baud(115200);

    //pc.printf("Camera resetting..\r\n");
    HeptaCamera::Reset();

    //pc.printf("Before Init...\r\n");
    HeptaCamera::PrintRegister();
    char color_format = '1';
    /*pc.printf("Select color format.\r\n") ;
    pc.printf("1: RGB444.\r\n");
    pc.printf("2: RGB555.\r\n");
    pc.printf("3: RGB565.\r\n");
    pc.printf("4: YUV(UYVY).\r\n");
    pc.printf("5: Bayer RGB(BGBG... GRGR...).\r\n");*/

    /*while(!pc.readable());
    char color_format = pc.getc();
    switch (color_format) {
        case '1':
            camera.InitRGB444();
            break;
        case '2':
            camera.InitRGB555();
            break;
        case '3':
            camera.InitRGB565();
            break;
        case '4':
            camera.InitYUV();
            break;
        case '5':
            camera.InitBayerRGB();
            break;
    }
    pc.printf("select %c\r\n", color_format);

    pc.printf("Select screen size.\r\n") ;
    switch (color_format) {
        case '5':
            pc.printf("1: VGA(640x480).\r\n");
        case '1':
        case '2':
        case '3':
        case '4':
            pc.printf("2: FIFO nealy limit(544x360).\r\n");
            pc.printf("3: VGA*3/4(480x360).\r\n");
            pc.printf("4: QVGA(320x240).\r\n");
            pc.printf("5: QQVGA(160x120).\r\n");
            break;
    }
    char screen_size = 4;
    while(!pc.readable());
    char screen_size = pc.getc() ;
    switch (screen_size) {
        case '1':
            sizex = 640;
            sizey = 480;
            camera.InitVGA();
            break;
        case '2':
            sizex = 544;
            sizey = 360;
            camera.InitFIFO_2bytes_color_nealy_limit_size();
            break;
        case '3':
            sizex = 480;
            sizey = 360;
            camera.InitVGA_3_4();
            break;
        case '4':
            sizex = 320;
            sizey = 240;
            camera.InitQVGA();
            break;
        case '5':
            sizex = 160;
            sizey = 120;
            camera.InitQQVGA();
            break;
    }
    pc.printf("select %c\r\n", screen_size);*/
    char screen_size = '4';
    HeptaCamera::InitRGB444();
    sizex = 320;
    sizey = 240;
    HeptaCamera::InitQVGA();
    HeptaCamera::InitForFIFOWriteReset();
    HeptaCamera::InitDefaultReg();

#ifdef COLORBAR
    HeptaCamera::InitSetColorbar();
#endif

    //pc.printf("After Init...\r\n");
    HeptaCamera::PrintRegister();

    // CAPTURE and SEND LOOP

#if defined(BITMAPFILE) || defined(BAYERBITMAPFILE) || defined(HEXFILE)
        //pc.printf("Hit Any Key %dx%d Capture Data.\r\n", sizex, sizey) ;
        //while(!pc.readable());
        //pc.printf("*\r\n");
        //pc.getc();

        int real_width = sizex*3 + sizey%4;

        unsigned char *bmp_line_data; //画像1行分のRGB情報を格納する
        if((bmp_line_data = (unsigned char *)malloc(sizeof(unsigned char)*real_width)) == NULL){
           fprintf(stderr, "Error: Allocation error.\n");
           //return 1;
        }

        //RGB情報を4バイトの倍数に合わせている
        for(int i=sizex*3; i<real_width; i++){
            bmp_line_data[i] = 0;
        }
#endif
#if defined(BITMAPFILE) || defined(BAYERBITMAPFILE)
        FILE *fp;
        char *filename = "/local/test.bmp";
        if((fp = fopen(filename, "wb")) == NULL){
            //pc.printf("Error: %s could not open.", filename);
            //return 1;
        }

        create_header(fp, sizex, sizey);
#endif
#ifdef HEXFILE
        FILE *fp2;
        char *filename2 = "/local/test.txt";
        if((fp2 = fopen(filename2, "w")) == NULL){
            pc.printf("Error: %s could not open.", filename2);
            return 1;
        }
#endif

        HeptaCamera::CaptureNext();
        while(HeptaCamera::CaptureDone() == false);
        HeptaCamera::ReadStart();

        int r=0, g=0, b=0, d1, d2;

        switch (color_format) {
            case '1':
            case '2':
            case '3':

                for (int y=0; y<sizey; y++) {
                    for (int x=0; x<sizex; x++) {
                        d1 = HeptaCamera::ReadOneByte();
                        d2 = HeptaCamera::ReadOneByte();

                        switch (color_format) {
                            case '1':
                                // RGB444 to RGB888
                                b = (d1 & 0x0F) << 4;
                                g = (d2 & 0xF0);
                                r = (d2 & 0x0F) << 4;
                                break;
                            case '2':
                                // RGB555 to RGB888
                                b = (d1 & 0x1F) << 3;
                                g = (((d1 & 0xE0) >> 2) | ((d2 & 0x03) << 6));
                                r = (d2 & 0x7c) << 1;
                                break;
                            case '3':
                                // RGB565 to RGB888
                                b = (d1 & 0x1F) << 3;
                                g = (((d1 & 0xE0) >> 3) | ((d2 & 0x07) << 5));
                                r = (d2 & 0xF8);
                                break;                                
                        }
#if defined(BITMAPFILE) || defined(HEXFILE)
                        bmp_line_data[x*3]     = (unsigned char)b;
                        bmp_line_data[x*3 + 1] = (unsigned char)g;
                        bmp_line_data[x*3 + 2] = (unsigned char)r;
#endif
/*
                        // RGB
                        pc.printf ("%2X%2X%2X", r, g, b) ;
*/
                    }
#ifdef BITMAPFILE
                    fwrite(bmp_line_data, sizeof(unsigned char), real_width, fp);
#endif
#ifdef HEXFILE
                    for(int i=0; i<sizex*3; i++){
                        fprintf(fp2, "%02X", bmp_line_data[i]);
                    }
#endif
//                    pc.printf("\r\n") ;
                }
                break;

            case '4':
                int index = 0;
                for (int y=0; y<sizey; y++) {
                    int U0=0, Y0=0, V0=0, Y1=0;
                    for (int x=0; x<sizex; x++) {
                        if(index%2 == 0) {
                            U0 = HeptaCamera::ReadOneByte();
                            Y0 = HeptaCamera::ReadOneByte();
                            V0 = HeptaCamera::ReadOneByte();
                            Y1 = HeptaCamera::ReadOneByte();

                            b = Y0 + 1.77200 * (U0 - 128);
                            g = Y0 - 0.34414 * (U0 - 128) - 0.71414 * (V0 - 128);
                            r = Y0 + 1.40200 * (V0 - 128);
                        } else {
                            b = Y1 + 1.77200 * (U0 - 128);
                            g = Y1 - 0.34414 * (U0 - 128) - 0.71414 * (V0 - 128);
                            r = Y1 + 1.40200 * (V0 - 128);
                        }

                        b = min(max(b, 0), 255);
                        g = min(max(g, 0), 255);
                        r = min(max(r, 0), 255);

#if defined(BITMAPFILE) || defined(HEXFILE)
                        bmp_line_data[x*3]     = (unsigned char)b;
                        bmp_line_data[x*3 + 1] = (unsigned char)g;
                        bmp_line_data[x*3 + 2] = (unsigned char)r;
#endif
/*
                        // RGB
                        pc.printf ("%2X%2X%2X", r, g, b) ;
*/
                        index++;
                    }
#ifdef BITMAPFILE
                    fwrite(bmp_line_data, sizeof(unsigned char), real_width, fp);
#endif
#ifdef HEXFILE
                    for(int i=0; i<sizex*3; i++){
                        fprintf(fp2, "%02X", bmp_line_data[i]);
                    }
#endif
//                    pc.printf("\r\n") ;
                }
                break;

            case '5':
                unsigned char *bayer_line[2];
                unsigned char *bayer_line_data[2]; //画像1行分のRGB情報を格納する2行分
                for(int i=0; i<2; i++) {
                    if((bayer_line_data[i] = (unsigned char *)malloc(sizeof(unsigned char)*sizex)) == NULL){
                       fprintf(stderr, "Error: Allocation error.\n");
                       //return 1;
                    }
                }

                for (int x=0; x<sizex; x++) {
                    // odd line BGBG... even line GRGR...
                    bayer_line_data[0][x] = (unsigned char)HeptaCamera::ReadOneByte();
#ifdef BAYERBITMAPFILE
                    bmp_line_data[x*3]     = (unsigned char)bayer_line_data[0][x];
                    bmp_line_data[x*3 + 1] = (unsigned char)bayer_line_data[0][x];
                    bmp_line_data[x*3 + 2] = (unsigned char)bayer_line_data[0][x];
#endif
                }
#ifdef BAYERBITMAPFILE
                fwrite(bmp_line_data, sizeof(unsigned char), real_width, fp);
#endif
                bayer_line[1] = bayer_line_data[0];

                for (int y=1; y<sizey; y++) {
                    int line = y%2;

                    for (int x=0; x<sizex; x++) {
                        // odd line BGBG... even line GRGR...
                        bayer_line_data[line][x] = (unsigned char)HeptaCamera::ReadOneByte();
#ifdef BAYERBITMAPFILE
                        bmp_line_data[x*3]     = (unsigned char)bayer_line_data[line][x];
                        bmp_line_data[x*3 + 1] = (unsigned char)bayer_line_data[line][x];
                        bmp_line_data[x*3 + 2] = (unsigned char)bayer_line_data[line][x];
#endif
                    }
#ifdef BAYERBITMAPFILE
                    fwrite(bmp_line_data, sizeof(unsigned char), real_width, fp);
#endif
                    bayer_line[0] = bayer_line[1];
                    bayer_line[1] = bayer_line_data[line];

                    for (int x=0; x<sizex - 1; x++) {
                        if(y%2==1) {
                            if(x%2==0) {
                                // BG
                                // GR
                                b = bayer_line[0][x];
                                g = ((int)bayer_line[0][x+1] + bayer_line[1][x])>>1;
                                r = bayer_line[1][x+1];
                            } else {
                                // GB
                                // RG
                                b = bayer_line[0][x+1];
                                g = ((int)bayer_line[0][x] + bayer_line[1][x+1])>>1;
                                r = bayer_line[1][x];
                            }
                        } else {
                            if(x%2==0) {
                                // GR
                                // BG
                                b = bayer_line[1][x];
                                g = ((int)bayer_line[0][x] + bayer_line[1][x+1])>>1;
                                r = bayer_line[0][x+1];
                            } else {
                                // RG
                                // GB
                                b = bayer_line[1][x+1];
                                g = ((int)bayer_line[0][x+1] + bayer_line[1][x])>>1;
                                r = bayer_line[0][x];
                            }
                        }
#if defined(BITMAPFILE) || defined(HEXFILE)
                        bmp_line_data[x*3]     = (unsigned char)b;
                        bmp_line_data[x*3 + 1] = (unsigned char)g;
                        bmp_line_data[x*3 + 2] = (unsigned char)r;
#endif
                    }

#ifdef BITMAPFILE
                    fwrite(bmp_line_data, sizeof(unsigned char), real_width, fp);
#endif

#ifdef HEXFILE
                    for(int i=0; i<sizex*3; i++){
                        fprintf(fp2, "%02X", bmp_line_data[i]);
                    }
#endif
                }

                for(int i=0; i<2; i++) {
                    free(bayer_line_data[i]);
                }
#ifdef BITMAPFILE
                fwrite(bmp_line_data, sizeof(unsigned char), real_width, fp);
#endif
                break;
        }
        HeptaCamera::ReadStop();

#if defined(BITMAPFILE) || defined(BAYERBITMAPFILE)
        free(bmp_line_data);
        fclose(fp);
#endif
#ifdef HEXFILE
        fclose(fp2);
#endif
   
}

void HeptaCamera::shoot2()
{
       //pc.baud(115200);

    //pc.printf("Camera resetting..\r\n");
    HeptaCamera::Reset();

    //pc.printf("Before Init...\r\n");
    HeptaCamera::PrintRegister();
    char color_format = '1';
    /*pc.printf("Select color format.\r\n") ;
    pc.printf("1: RGB444.\r\n");
    pc.printf("2: RGB555.\r\n");
    pc.printf("3: RGB565.\r\n");
    pc.printf("4: YUV(UYVY).\r\n");
    pc.printf("5: Bayer RGB(BGBG... GRGR...).\r\n");*/

    /*while(!pc.readable());
    char color_format = pc.getc();
    switch (color_format) {
        case '1':
            camera.InitRGB444();
            break;
        case '2':
            camera.InitRGB555();
            break;
        case '3':
            camera.InitRGB565();
            break;
        case '4':
            camera.InitYUV();
            break;
        case '5':
            camera.InitBayerRGB();
            break;
    }
    pc.printf("select %c\r\n", color_format);

    pc.printf("Select screen size.\r\n") ;
    switch (color_format) {
        case '5':
            pc.printf("1: VGA(640x480).\r\n");
        case '1':
        case '2':
        case '3':
        case '4':
            pc.printf("2: FIFO nealy limit(544x360).\r\n");
            pc.printf("3: VGA*3/4(480x360).\r\n");
            pc.printf("4: QVGA(320x240).\r\n");
            pc.printf("5: QQVGA(160x120).\r\n");
            break;
    }
    char screen_size = 4;
    while(!pc.readable());
    char screen_size = pc.getc() ;
    switch (screen_size) {
        case '1':
            sizex = 640;
            sizey = 480;
            camera.InitVGA();
            break;
        case '2':
            sizex = 544;
            sizey = 360;
            camera.InitFIFO_2bytes_color_nealy_limit_size();
            break;
        case '3':
            sizex = 480;
            sizey = 360;
            camera.InitVGA_3_4();
            break;
        case '4':
            sizex = 320;
            sizey = 240;
            camera.InitQVGA();
            break;
        case '5':
            sizex = 160;
            sizey = 120;
            camera.InitQQVGA();
            break;
    }
    pc.printf("select %c\r\n", screen_size);*/
    char screen_size = '4';
    HeptaCamera::InitRGB444();
    sizex = 320;
    sizey = 240;
    HeptaCamera::InitQVGA();
    HeptaCamera::InitForFIFOWriteReset();
    HeptaCamera::InitDefaultReg();

#ifdef COLORBAR
    HeptaCamera::InitSetColorbar();
#endif

    //pc.printf("After Init...\r\n");
    HeptaCamera::PrintRegister();

    // CAPTURE and SEND LOOP

#if defined(BITMAPFILE) || defined(BAYERBITMAPFILE) || defined(HEXFILE)
        //pc.printf("Hit Any Key %dx%d Capture Data.\r\n", sizex, sizey) ;
        //while(!pc.readable());
        //pc.printf("*\r\n");
        //pc.getc();

        int real_width = sizex*3 + sizey%4;

        unsigned char *bmp_line_data; //画像1行分のRGB情報を格納する
        if((bmp_line_data = (unsigned char *)malloc(sizeof(unsigned char)*real_width)) == NULL){
           fprintf(stderr, "Error: Allocation error.\n");
           //return 1;
        }

        //RGB情報を4バイトの倍数に合わせている
        for(int i=sizex*3; i<real_width; i++){
            bmp_line_data[i] = 0;
        }
#endif
#if defined(BITMAPFILE) || defined(BAYERBITMAPFILE)
        mkdir("/sd/mydir", 0777);
        FILE *fp = fopen("/sd/mydir/picture.bmp","w");
        if(fp == NULL) {
            error("Could not open file for write\r\n");
        }

        create_header(fp, sizex, sizey);
#endif
#ifdef HEXFILE
        FILE *fp2;
        char *filename2 = "/local/test.txt";
        if((fp2 = fopen(filename2, "w")) == NULL){
            pc.printf("Error: %s could not open.", filename2);
            return 1;
        }
#endif

        HeptaCamera::CaptureNext();
        while(HeptaCamera::CaptureDone() == false);
        HeptaCamera::ReadStart();

        int r=0, g=0, b=0, d1, d2;

        switch (color_format) {
            case '1':
            case '2':
            case '3':

                for (int y=0; y<sizey; y++) {
                    for (int x=0; x<sizex; x++) {
                        d1 = HeptaCamera::ReadOneByte();
                        d2 = HeptaCamera::ReadOneByte();

                        switch (color_format) {
                            case '1':
                                // RGB444 to RGB888
                                b = (d1 & 0x0F) << 4;
                                g = (d2 & 0xF0);
                                r = (d2 & 0x0F) << 4;
                                break;
                            case '2':
                                // RGB555 to RGB888
                                b = (d1 & 0x1F) << 3;
                                g = (((d1 & 0xE0) >> 2) | ((d2 & 0x03) << 6));
                                r = (d2 & 0x7c) << 1;
                                break;
                            case '3':
                                // RGB565 to RGB888
                                b = (d1 & 0x1F) << 3;
                                g = (((d1 & 0xE0) >> 3) | ((d2 & 0x07) << 5));
                                r = (d2 & 0xF8);
                                break;                                
                        }
#if defined(BITMAPFILE) || defined(HEXFILE)
                        bmp_line_data[x*3]     = (unsigned char)b;
                        bmp_line_data[x*3 + 1] = (unsigned char)g;
                        bmp_line_data[x*3 + 2] = (unsigned char)r;
#endif
/*
                        // RGB
                        pc.printf ("%2X%2X%2X", r, g, b) ;
*/
                    }
#ifdef BITMAPFILE
                    fwrite(bmp_line_data, sizeof(unsigned char), real_width, fp);
#endif
#ifdef HEXFILE
                    for(int i=0; i<sizex*3; i++){
                        fprintf(fp2, "%02X", bmp_line_data[i]);
                    }
#endif
//                    pc.printf("\r\n") ;
                }
                break;

            case '4':
                int index = 0;
                for (int y=0; y<sizey; y++) {
                    int U0=0, Y0=0, V0=0, Y1=0;
                    for (int x=0; x<sizex; x++) {
                        if(index%2 == 0) {
                            U0 = HeptaCamera::ReadOneByte();
                            Y0 = HeptaCamera::ReadOneByte();
                            V0 = HeptaCamera::ReadOneByte();
                            Y1 = HeptaCamera::ReadOneByte();

                            b = Y0 + 1.77200 * (U0 - 128);
                            g = Y0 - 0.34414 * (U0 - 128) - 0.71414 * (V0 - 128);
                            r = Y0 + 1.40200 * (V0 - 128);
                        } else {
                            b = Y1 + 1.77200 * (U0 - 128);
                            g = Y1 - 0.34414 * (U0 - 128) - 0.71414 * (V0 - 128);
                            r = Y1 + 1.40200 * (V0 - 128);
                        }

                        b = min(max(b, 0), 255);
                        g = min(max(g, 0), 255);
                        r = min(max(r, 0), 255);

#if defined(BITMAPFILE) || defined(HEXFILE)
                        bmp_line_data[x*3]     = (unsigned char)b;
                        bmp_line_data[x*3 + 1] = (unsigned char)g;
                        bmp_line_data[x*3 + 2] = (unsigned char)r;
#endif
/*
                        // RGB
                        pc.printf ("%2X%2X%2X", r, g, b) ;
*/
                        index++;
                    }
#ifdef BITMAPFILE
                    fwrite(bmp_line_data, sizeof(unsigned char), real_width, fp);
#endif
#ifdef HEXFILE
                    for(int i=0; i<sizex*3; i++){
                        fprintf(fp2, "%02X", bmp_line_data[i]);
                    }
#endif
//                    pc.printf("\r\n") ;
                }
                break;

            case '5':
                unsigned char *bayer_line[2];
                unsigned char *bayer_line_data[2]; //画像1行分のRGB情報を格納する2行分
                for(int i=0; i<2; i++) {
                    if((bayer_line_data[i] = (unsigned char *)malloc(sizeof(unsigned char)*sizex)) == NULL){
                       fprintf(stderr, "Error: Allocation error.\n");
                       //return 1;
                    }
                }

                for (int x=0; x<sizex; x++) {
                    // odd line BGBG... even line GRGR...
                    bayer_line_data[0][x] = (unsigned char)HeptaCamera::ReadOneByte();
#ifdef BAYERBITMAPFILE
                    bmp_line_data[x*3]     = (unsigned char)bayer_line_data[0][x];
                    bmp_line_data[x*3 + 1] = (unsigned char)bayer_line_data[0][x];
                    bmp_line_data[x*3 + 2] = (unsigned char)bayer_line_data[0][x];
#endif
                }
#ifdef BAYERBITMAPFILE
                fwrite(bmp_line_data, sizeof(unsigned char), real_width, fp);
#endif
                bayer_line[1] = bayer_line_data[0];

                for (int y=1; y<sizey; y++) {
                    int line = y%2;

                    for (int x=0; x<sizex; x++) {
                        // odd line BGBG... even line GRGR...
                        bayer_line_data[line][x] = (unsigned char)HeptaCamera::ReadOneByte();
#ifdef BAYERBITMAPFILE
                        bmp_line_data[x*3]     = (unsigned char)bayer_line_data[line][x];
                        bmp_line_data[x*3 + 1] = (unsigned char)bayer_line_data[line][x];
                        bmp_line_data[x*3 + 2] = (unsigned char)bayer_line_data[line][x];
#endif
                    }
#ifdef BAYERBITMAPFILE
                    fwrite(bmp_line_data, sizeof(unsigned char), real_width, fp);
#endif
                    bayer_line[0] = bayer_line[1];
                    bayer_line[1] = bayer_line_data[line];

                    for (int x=0; x<sizex - 1; x++) {
                        if(y%2==1) {
                            if(x%2==0) {
                                // BG
                                // GR
                                b = bayer_line[0][x];
                                g = ((int)bayer_line[0][x+1] + bayer_line[1][x])>>1;
                                r = bayer_line[1][x+1];
                            } else {
                                // GB
                                // RG
                                b = bayer_line[0][x+1];
                                g = ((int)bayer_line[0][x] + bayer_line[1][x+1])>>1;
                                r = bayer_line[1][x];
                            }
                        } else {
                            if(x%2==0) {
                                // GR
                                // BG
                                b = bayer_line[1][x];
                                g = ((int)bayer_line[0][x] + bayer_line[1][x+1])>>1;
                                r = bayer_line[0][x+1];
                            } else {
                                // RG
                                // GB
                                b = bayer_line[1][x+1];
                                g = ((int)bayer_line[0][x+1] + bayer_line[1][x])>>1;
                                r = bayer_line[0][x];
                            }
                        }
#if defined(BITMAPFILE) || defined(HEXFILE)
                        bmp_line_data[x*3]     = (unsigned char)b;
                        bmp_line_data[x*3 + 1] = (unsigned char)g;
                        bmp_line_data[x*3 + 2] = (unsigned char)r;
#endif
                    }

#ifdef BITMAPFILE
                    fwrite(bmp_line_data, sizeof(unsigned char), real_width, fp);
#endif

#ifdef HEXFILE
                    for(int i=0; i<sizex*3; i++){
                        fprintf(fp2, "%02X", bmp_line_data[i]);
                    }
#endif
                }

                for(int i=0; i<2; i++) {
                    free(bayer_line_data[i]);
                }
#ifdef BITMAPFILE
                fwrite(bmp_line_data, sizeof(unsigned char), real_width, fp);
#endif
                break;
        }
        HeptaCamera::ReadStop();

#if defined(BITMAPFILE) || defined(BAYERBITMAPFILE)
        free(bmp_line_data);
        fclose(fp);
#endif
#ifdef HEXFILE
        fclose(fp2);
#endif
   
}