static uint8_t verifyF(__uint24 cap){ datIn; PORTB|=(1<<3)|(1<<4)|(1<<5);//CE# OE# WE# all high PORTB&=~((1<<3)|(1<<4));//CE# OE# to low __uint24 addr; for (addr=0;addr<cap;++addr){ shift24(addr); if (rdDat()!=0xFF){ serialWrB('E'); PORTB|=(1<<3)|(1<<4);//CE# OE# to high return 1; } } serialWrB('S'); PORTB|=(1<<3)|(1<<4);//CE# OE# to high return 0; }
static void ReadChip(__uint24 sz){//sends entire flash content to serial datIn; PORTB|=(1<<3)|(1<<4)|(1<<5);//CE# OE# WE# all high PORTB&=~((1<<3)|(1<<4));//CE# OE# to low __uint24 addr; for (addr=0;addr<sz;++addr){ shift24(addr); serialWrB(rdDat()); } PORTB|=(1<<3)|(1<<4);//CE# OE# to high }
static inline void pgmB(__uint24 addr,uint8_t dat){ datOut; PORTB&=~(1<<4);//set OE# to low PORTB|=(1<<3)|(1<<5);//set CE# and WE# to high PORTB|=(1<<4);//set OE# to high sendCmd(0x5555,0xAA); sendCmd(0x2AAA,0x55); sendCmd(0x5555,0xA0); sendCmd(addr,dat); //This assumes a delay will follow the writing of the byte serialWrB('N'); }
__attribute__((noreturn)) void main(void){ cli(); //set-up serial communications DDRD=28;//3 serial pins on d.2 to d.4 d.5 to d.7 contain msbs for flash data d.0 to d.4 is in port C DDRB=62;//serial clocks (B.1 SHCP) (B.2 Latch) (B.3 CE#) (B.4 OE#) (B.5 WE#) UBRR0H=0; UBRR0L=3;//set to 0.5M baud UCSR0A|=2;//double speed aysnc UCSR0B = (1<<RXEN0)|(1<<TXEN0);//Enable receiver and transmitter UCSR0C=6;//async 1 stop bit 8bit char no parity bits _delay_ms(50); StringPgm(PSTR("RDY")); USART_Receive();//wait for handshake char mode = USART_Receive();//wait for mode StringPgm(PSTR("RDY")); serialWrB(readId(0)); uint8_t cap=readId(1); serialWrB(cap); __uint24 capacity=524288L; switch(cap){ case 0xB5: capacity=131072L; case 0xB6: capacity=262144L; break; } if(mode=='W'){ chipErase(); serialWrB('D'); verifyF(capacity); __uint24 x; for (x=0;x<capacity;++x){ pgmB(x,USART_Receive()); serialWrB(readB(x)); } }else if(mode=='R') ReadChip(capacity); while(1); }
static void StringPgm(const char * str){ do{ serialWrB(pgm_read_byte_near(str)); }while(pgm_read_byte_near(++str)); }
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 BSend(void) { uint16_t res=tft_readRegister(0x22); serialWrB(res>>8); serialWrB(res&255); }