void gammaEdit(void){ uint16_t x,y,z; setColor(rgb565); setRes(qqvga); #ifdef MT9D111 MT9D111Refresh(); #endif tft_paintScreenBlack(); #ifdef MT9D111 return; #else do{ getPoint(&x,&y,&z); tft_setOrientation(1); #ifdef ov7670 wrReg(REG_COM13, COM13_UVSAT|COM13_RSVD); #elif defined ov7740 wrReg(ISP_CTRL00,rdReg(ISP_CTRL00)&(~ISP_CTRL00_gamma)); #endif capImgqqvga(160); #ifdef ov7670 wrReg(REG_COM13, COM13_GAMMA|COM13_UVSAT|COM13_RSVD); #elif defined ov7740 wrReg(ISP_CTRL00,rdReg(ISP_CTRL00)|ISP_CTRL00_gamma); #endif capImgqqvga(0); tft_setDisplayDirect(DOWN2UP); redrawGraph(); }while(z<10); setRes(qvga); #endif }
void setColor(uint8_t color){ #ifdef MT9D111 wrReg16(0xF0,1); #endif switch(color){ case yuv422: #ifdef MT9D111 wrReg16(0xC6,(1<<15)|(1<<13)|(7<<8)|125); wrReg16(0xC8,0); wrReg16(0xC6,(1<<15)|(1<<13)|(7<<8)|126); wrReg16(0xC8,0); #else wrSensorRegs8_8(yuv422_ov7670); #endif break; case rgb565: #ifdef MT9D111 wrReg16(0xC6,(1<<15)|(1<<13)|(7<<8)|125); wrReg16(0xC8,(1<<5)); wrReg16(0xC6,(1<<15)|(1<<13)|(7<<8)|126); wrReg16(0xC8,(1<<5)); #else wrSensorRegs8_8(rgb565_ov7670); {uint8_t temp=rdReg(0x11); _delay_ms(1); wrReg(0x11,temp);}//accorind to the linux kernel driver rgb565 PCLK needs re-writting #endif break; #ifndef MT9D111 case bayerRGB: wrSensorRegs8_8(bayerRGB_ov7670); break; #endif } }
static void setmatrix(uint8_t id) { switch (id) { case 0: #ifdef ov7670 wrReg(MTX1,0x80); wrReg(MTX2,0x80); wrReg(MTX3,0x00); wrReg(MTX4,0x22); wrReg(MTX5,0x5e); wrReg(MTX6,0x80); wrReg(MTXS,0x9e); #elif defined ov7740 wrReg(ISP_CTRL01,rdReg(ISP_CTRL01)&(~ISP_CTRL01_CMX_enable)); #endif break; case 1: #ifdef ov7670 wrReg(MTX1,0x40); wrReg(MTX2,0x34); wrReg(MTX3,0x0c); wrReg(MTX4,0x17); wrReg(MTX5,0x29); wrReg(MTX6,0x40); wrReg(MTXS,0x1A); #elif defined ov7740 wrReg(ISP_CTRL01,rdReg(ISP_CTRL01)|ISP_CTRL01_CMX_enable); #endif break; #ifdef ov7670 case 2: wrReg(MTX1,0xB3); wrReg(MTX2,0xB3); wrReg(MTX3,0x0); wrReg(MTX4,0x3D); wrReg(MTX5,0xA7); wrReg(MTX6,0xE4); wrReg(MTXS,0x9E); break; #endif } }
void setColorSpace(enum COLORSPACE color){ switch(color){ case YUV422: wrSensorRegs8_8(yuv422_ov7670); break; case RGB565: wrSensorRegs8_8(rgb565_ov7670); {uint8_t temp=rdReg(0x11); _delay_ms(1); wrReg(0x11,temp);}//according to the Linux kernel driver rgb565 PCLK needs rewriting break; case BAYER_RGB: wrSensorRegs8_8(bayerRGB_ov7670); break; } }
void menu(void) { uint16_t x,y,z; while (1) { switch (selection((const char**)menu_table,10)) { case 0: #ifdef MT9D111 setRes(QVGA); setColor(RGB565); MT9D111Refresh(); editRegs(0); #else setColor(RGB565); setRes(QVGA); editRegs(); #endif break; case 1: #ifdef MT9D111 setRes(QVGA); setColor(RGB565); MT9D111Refresh(); editRegs(1); #else #ifdef ov7740 setmatrix(selection((const char**)maxtrix_table,2)); #else setmatrix(selection((const char**)maxtrix_table,3)); #endif tft_setOrientation(1); capImg(); tft_setDisplayDirect(DOWN2UP); #endif break; case 2: #ifdef ov7670 initCam(0); #else initCam(); #endif break; #ifndef MT9D111 case 3: //compare matrices tft_setOrientation(1); do { getPoint(&x,&y,&z); uint8_t a; #ifdef ov7670 for (a=0; a<3; a++) { #elif defined ov7740 for (a=0; a<2; a++) { #endif setmatrix(a); capImg(); } } while (z < 10); tft_setDisplayDirect(DOWN2UP); break; #endif case 4: setColor(RGB565); setRes(QQVGA); #ifdef MT9D111 MT9D111Refresh(); #endif do { getPoint(&x,&y,&z); tft_setOrientation(1); capImgqqvga(160); tft_setDisplayDirect(DOWN2UP); } while(z<10); setRes(QVGA); break; case 5: #ifdef ov7670 setColor(RGB565); #endif gammaEdit(); break; case 6: //File browser //start by listing files #ifdef haveSDcard browserSD(); #else tft_drawStringP(PSTR("No SD card"),16,320,3,WHITE); _delay_ms(666); #endif break; case 7: #ifdef ov7670 { uint8_t pick=selection((const char**)wb_table,7);//registers from http://thinksmallthings.wordpress.com/2012/10/25/white-balance-control-with-ov7670/ if(pick==1||pick==2) { wrReg(0x13, 0xE7); wrReg(0x6F, 0x9E|(pick&1)); } else { wrReg(0x13, 0xE5); switch(pick) { case 2: wrReg(0x01, 0x5A); wrReg(0x02, 0x5C); break; case 3: wrReg(0x01, 0x58); wrReg(0x02, 0x60); break; case 4: wrReg(0x01, 0x84); wrReg(0x02, 0x4C); break; case 5: wrReg(0x01, 0x96); wrReg(0x02, 0x40); break; } } tft_setOrientation(1); setRes(QVGA); setColor(RGB565); capImg(); tft_setDisplayDirect(DOWN2UP); } #endif break; case 8: #ifdef ov7670 wrReg(0x1e,rdReg(0x1e)&(~(1<<5))&(~(1<<4))); #endif { #ifdef MT9D111 uint8_t reso=selection((const char**)res_tab,4); #else uint8_t reso=selection((const char**)res_tab,3); #endif #ifdef MT9D111 wrReg16(0xF0,2);//page 2 wrReg16(0x0D,0); setColor(YUV422); #endif switch(reso) { case 0: #ifdef ov7670 wrReg(REG_COM7, COM7_BAYER); // BGBGBG... GRGRGR... #elif defined MT9D111 //setup jpeg MT9D111JPegCapture(); #endif break; case 1: #ifdef MT9D111 setRes(SVGA); #else setRes(QVGA); setColor(YUV422); #endif break; #ifdef MT9D111 case 2: setRes(QVGA); break; #endif default: goto theEnd; break; } #ifdef ov7670 _delay_ms(200); if(reso) wrReg(0x11,1); else wrReg(0x11,2); #endif tft_setOrientation(1); do { #ifdef MT9D111 switch(reso) { case 0: { uint32_t jpgSize=capJpeg(); serialWrB('R'); serialWrB('D'); serialWrB('Y'); uint16_t w; uint8_t h=0; serialWrB(jpgSize&255); serialWrB(jpgSize>>8); serialWrB(jpgSize>>16); serialWrB(jpgSize>>24); while(jpgSize) { if(jpgSize>=640) { for (w=0; w<320; ++w) { tft_setXY(h,w); BSend(); } ++h; jpgSize-=640; } else { for(w=0; w<jpgSize/2; ++w) { tft_setXY(h,w); BSend(); } if(jpgSize&1) { tft_setXY(h,w); uint16_t res=tft_readRegister(0x22); serialWrB(res>>8); } jpgSize=0; } } } break; case 1: capImgPC(); break; case 2: capImgPCqvga(); break; } #else if(reso) capImgPCqvga(); else capImgPC(); #endif getPoint(&x,&y,&z); } while(z<10); theEnd: tft_setDisplayDirect(DOWN2UP); } break; case 9: switch(selection((const char**)menu_tablep2,3)) { case 0: { tft_drawImage_P(exit_icon,32,32,0,0); uint16_t x1,y1; do { getPoint(&x,&y,&z); } while(z<10); if((y<=32)&&(x<=32)) break; tft_fillCircle(x,y,4,WHITE); while(1) { x1=x; y1=y; do { getPoint(&x,&y,&z); } while(z<10); tft_fillRectangle(224,320,16,36,BLACK); tft_fillCircle(x1,y1,4,BLACK); tft_fillCircle(x,y,4,WHITE); if((y<=32)&&(x<=32)) break; char temp[6]; utoa(x,temp,10); tft_drawString(temp,224,320,1,WHITE); utoa(y,temp,10); tft_drawString(temp,232,320,1,WHITE); } } break; case 1: //time lapse #ifdef MT9D111 //MT9D111Refresh(); //Since This is a time lapse we want to be in "video" mode MT9D111JPegCapture(); /*do{ _delay_ms(10); wrReg16(0xC6,(1<<15)|(1<<13)|(1<<8)|4); }while(rdReg16(0xC8)<4); waitStateMT9D111(3);*/ #endif #ifdef haveSDcard { char buf[24]; uint16_t imgc=0; tft_setOrientation(1); do { FIL Fo; #ifdef MT9D111 uint32_t jpgSize=capJpeg(); #else capImg(); #endif utoa(imgc,buf,10); #ifdef MT9D111 strcat(buf,".JPG"); #else strcat(buf,".RAW"); #endif f_open(&Fo,buf,FA_WRITE|FA_CREATE_ALWAYS); ++imgc; UINT written; uint16_t w; uint8_t h; uint16_t cpybuf[320]; #ifdef MT9D111 h=0; uint8_t * cpyptr=cpybuf; for(w=0; w<619; ++w) *cpyptr++=pgm_read_byte_near(jpegHeader+w); f_write(&Fo,cpybuf,619,&written); while(jpgSize) { if(jpgSize>=640) { for (w=0; w<320; ++w) { tft_setXY(h,w); cpybuf[w]=__builtin_bswap16(tft_readRegister(0x22));//Either bytes need to be swapped or a byte is being missed } f_write(&Fo,cpybuf,640,&written); ++h; jpgSize-=640; } else { for(w=0; w<jpgSize/2; ++w) { tft_setXY(h,w); cpybuf[w]=__builtin_bswap16(tft_readRegister(0x22)); } f_write(&Fo,cpybuf,jpgSize,&written); if(jpgSize&1) { tft_setXY(h,w); cpybuf[w]=tft_readRegister(0x22); f_write(&Fo,&cpybuf[w],1,&written); } jpgSize=0; } } cpybuf[0]=0xFFD9; f_write(&Fo,cpybuf,2,&written); #else for (h=0; h<240; ++h) { for (w=0; w<320; ++w) { tft_setXY(h,w); cpybuf[w]=tft_readRegister(0x22); } f_write(&Fo,cpybuf,640,&written); } #endif f_close(&Fo); getPoint(&x,&y,&z); } while(z<10); tft_setDisplayDirect(DOWN2UP); #ifdef MT9D111 MT9D111DoPreview(); #endif } #else tft_drawStringP(PSTR("No SD card"),16,320,3,WHITE); _delay_ms(666); #endif break; case 2: //previous page break; } break; } } }
static void redrawGraph(void){ #ifdef ov7670 graph(rdReg(0x7b),2,pickSel(0)); graph(rdReg(0x7c),4,pickSel(1)); graph(rdReg(0x7d),8,pickSel(2)); graph(rdReg(0x7e),15,pickSel(3)); graph(rdReg(0x7f),19,pickSel(4)); graph(rdReg(0x80),23,pickSel(5)); graph(rdReg(0x81),26,pickSel(6)); graph(rdReg(0x82),30,pickSel(7)); graph(rdReg(0x83),34,pickSel(8)); graph(rdReg(0x84),38,pickSel(9)); graph(rdReg(0x85),45,pickSel(10)); graph(rdReg(0x86),53,pickSel(11)); graph(rdReg(0x87),68,pickSel(12)); graph(rdReg(0x88),83,pickSel(13)); graph(rdReg(0x89),98,pickSel(14)); graph(256-(rdReg(0x7A)*3/4),120,GREEN); #elif defined ov7740 graph(rdReg(0x9C),2,pickSel(0)); graph(rdReg(0x9D),4,pickSel(1)); graph(rdReg(0x9E),8,pickSel(2)); graph(rdReg(0x9F),15,pickSel(3)); graph(rdReg(0xA0),19,pickSel(4)); graph(rdReg(0xA1),23,pickSel(5)); graph(rdReg(0xA2),26,pickSel(6)); graph(rdReg(0xA3),30,pickSel(7)); graph(rdReg(0xA4),34,pickSel(8)); graph(rdReg(0xA5),38,pickSel(9)); graph(rdReg(0xA6),45,pickSel(10)); graph(rdReg(0xA7),53,pickSel(11)); graph(rdReg(0xA8),68,pickSel(12)); graph(rdReg(0xA9),83,pickSel(13)); graph(rdReg(0xAA),98,pickSel(14)); graph(256-(rdReg(0xA8)*3/4),120,GREEN); #endif }
void initCam(void) #endif { #ifdef MT9D111 //_delay_ms(1000); //wrSensorRegs8_16P(MT9D111_init); //_delay_ms(1000); //wrSensorRegs8_16(MT9D111_QVGA); //wrSensorRegs8_16(MT9D111_RGB565); //wrSensorRegs8_16(default_size_a_list); //Start off with a soft reset wrReg16(0xF0,1);//Set to page 1 wrReg16(0xC3,0x0501); wrReg16(0xF0,0); wrReg16(0x0D,0x0021); wrReg16(0x0D,0); _delay_ms(100);//Cannot use i2c for 24 camera cylces this should be way over that. waitStateMT9D111(3); //wrReg16(0xF0,0);//Set to page 0 //wrReg16(0x15,(1<<7)|3); wrReg16(0xF0,1);//Set to page 1 //Poll camera until it is ready /*wrReg16(0xC6,(1<<13)|(7<<8)|25);//Row speed wrReg16(0xC8,3);*/ wrReg16(0xC6,(1<<15)|(1<<13)|(2<<8)|14);//increase maximum intergration time wrReg16(0xc8,128); /*wrReg16(0xC6,(1<<15)|(1<<13)|(2<<8)|16);//increase maximum virtual gain wrReg16(0xc8,232); wrReg16(0xC6,(1<<15)|(1<<13)|(2<<8)|24);//increase maximum gain wrReg16(0xc8,224);*/ wrReg16(0xC6,(1<<13)|(2<<8)|20);//increase maximum pre-lc digital gain wrReg16(0xc8,256); /*wrReg16(0xC6,(1<<15)|(1<<13)|(7<<8)|67);//gamma contex A wrReg16(0xC8,2); wrReg16(0xC6,(1<<15)|(1<<13)|(7<<8)|68);//gamma B wrReg16(0xC8,2);*/ //MT9D111Refresh(); //_delay_ms(1000); wrReg16(0xC6,(1<<13)|(7<<8)|107);//Fifo context A wrReg16(0xC8,0); wrReg16(0xC6,(1<<13)|(7<<8)|114);//Fifo context B wrReg16(0xC8,0); MT9D111Refresh(); //_delay_ms(1000); #elif defined ov7740 wrReg(0x12,rdReg(0x12)|1);//RGB mode wrReg(0x11,16);//divider wrReg(0x55,0);//disable double wrReg(0x83,rdReg(0x83)|(1<<2));//RAW 8 #elif defined ov7670 wrReg(0x12, 0x80); _delay_ms(100); if(bayerUse==2){ wrSensorRegs8_8(OV7670_QVGA); } else if(bayerUse==1){ uint16_t n; for(n = 0; n < sizeof(reg_init_data);n+=2) wrReg(pgm_read_byte_near(reg_init_data+n), pgm_read_byte_near(reg_init_data+n+1)); } else wrSensorRegs8_8(ov7670_default_regs); if(bayerUse!=2) wrReg(0x1e,rdReg(0x1e)|(1<<5));//hflip if(bayerUse==1) wrReg(REG_COM10,48); else wrReg(REG_COM10,32);//pclk does not toggle on HBLANK wrReg(REG_COM11,98); #else #error "No sensor selected" #endif }
void scalingToggle(uint8_t use){ if(use) wrReg(ISP_CTRL02,rdReg(ISP_CTRL02)|(1<<4)|(1<<5)); else wrReg(ISP_CTRL02,rdReg(ISP_CTRL02)&(~((1<<4)|(1<<5)))); }