Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define F_CPU 16000000UL
- #include <stdint.h>
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #include <util/twi.h>
- #include <util/delay.h>
- #include <avr/pgmspace.h>
- #include "ov7670.h"
- /*
- PCLK PORTD.2
- HREF PORTD.3 PCINT19
- */
- volatile uint8_t wantFrame;
- volatile uint8_t doneImg;
- /*register uint8_t nerd1 asm("r16");
- register uint8_t nerd2 asm("r29");
- register uint8_t nerd3 asm("r31");*/
- /*ISR (INT0_vect)//now in assembly
- {
- SPDR=(PINC&15)|(PIND&240);//send part of pixel to SPI
- }*/
- //#define qqvga
- //#define aMega
- //#define qvga
- //#define rgb565 //yuv422 is higher quality but the tft lcd for arduino uses rgb565
- #define rawRGB
- inline void spiCSt(void)//selects the RAM chip and resets it
- {
- //toggles spi CS used for reseting sram
- PORTB|=6;//cs high for both
- /*asm volatile ("nop");//probley not needed
- asm volatile ("nop");//probley not needed
- asm volatile ("nop");//probley not needed
- asm volatile ("nop");//probley not needed*/
- //_delay_ms(1);
- PORTB&=~4;//cs low for ram keep sd high
- }
- inline void spiWrB(uint8_t dat)
- {
- SPDR = dat;
- // Wait for transmission complete
- while(!(SPSR & (1<<SPIF))) {}
- }
- void serialWrB(uint8_t dat)
- {
- while ( !( UCSR0A & (1<<UDRE0)) ) {} //wait for byte to transmit
- UDR0=dat;
- while ( !( UCSR0A & (1<<UDRE0)) ) {} //wait for byte to transmit
- }
- void StringPgm(char * str)
- {
- do {
- serialWrB(pgm_read_byte_near(str));
- } while(pgm_read_byte_near(++str));
- }
- void sendNyble(uint8_t nyb)
- {
- if (nyb > 9)
- nyb+='7';//'A'- 10 = '7';
- else
- nyb+='0';
- serialWrB(nyb);
- }
- void sendByteAscii(uint8_t dat)//sends as hexdec format
- {
- serialWrB('0');
- serialWrB('x');
- sendNyble(dat>>4);
- sendNyble(dat&15);
- serialWrB('\n');
- }
- void captureImg(uint16_t ws,uint16_t hs,uint16_t wg,uint8_t hg)
- {
- //skip 1 multiplies skip 2 same with get1 and get2
- //first wait for vsync it is on pin 3 (counting from 0) portD
- //start spi ram
- uint16_t ls2,lg2;
- spiCSt();
- spiWrB(2);//sequental write mode
- spiWrB(0);//24 bit address
- spiWrB(0);
- spiWrB(0);
- while (!(PIND&8)) {}//wait for high
- while ((PIND&8)) {}//wait for low
- //if (hs != 0)
- //{
- //for (ls1=0;ls1<hs;ls1++)
- while (hs--)
- {
- //for (ls2=0;ls2<ws;ls2++)
- ls2=ws;
- while (ls2--)
- {
- while (!(PIND&4)) {}//wait for high
- while ((PIND&4)) {}//wait for low
- }
- }// while (--hs);
- //}
- //for (lg1=0;lg1<hg;lg1++)
- while ((uint8_t)hg--)
- {
- //for (lg2=0;lg2<wg;lg2++)
- lg2=wg;
- while (lg2--)
- {
- while (!(PIND&4)) {}//wait for high
- SPDR=(uint8_t)(PINC&15)|(PIND&240);
- while ((PIND&4)) {}//wait for low
- }
- }
- }
- uint8_t RdSerial(void)
- {
- /* Wait for data to be received */
- while ( !(UCSR0A & (1<<RXC0)) );
- /* Get and return received data from buffer */
- return UDR0;
- }
- void sendRam(uint16_t w,uint16_t h)
- {
- spiCSt();
- spiWrB(3);//sequental read mode
- spiWrB(0);//24 bit address
- spiWrB(0);
- spiWrB(0);
- //_delay_ms(2000);
- uint16_t wl,hl;
- for (hl=0;hl<h;hl++)
- {
- StringPgm(PSTR("RDY"));
- for (wl=0;wl<w;wl++)
- {
- while ( !( UCSR0A & (1<<UDRE0)) ) {} //wait for byte to transmit
- SPDR=0;//send dummy value to get byte back
- while(!(SPSR & (1<<SPIF))) {}
- UDR0=SPDR;
- }
- }
- while ( !( UCSR0A & (1<<UDRE0)) ) {} //wait for byte to transmit
- //StringPgm(PSTR("RDY"));
- //_delay_ms(10);
- //UDR0=0xFF;
- }
- int main(void)
- {
- cli();//disable interupts
- DDRB|=47;//clock as output and SPI pins as output except MISO
- PORTB|=6;//set both CS pins to high
- DDRC&=~15;//low d0-d3 camera
- DDRD&=~252;//d7-d4 and interupt pins
- //DDRB&=~2;//href as input
- //EICRA=11;//int0 rising int1 falling
- //EIMSK=2;//disable int0 and enable int1
- //disable pin change interupt
- //PCICR=0;
- //PCMSK0=2;
- //set up twi for 100khz
- TWSR&=~3;//disable prescaler for TWI
- TWBR=72;//set to 100khz
- //enable serial
- //UBRR0H = (unsigned char)(MYUBRR>>8);
- //UBRR0L = (unsigned char)MYUBRR&255;
- UBRR0H=0;
- UBRR0L=3;//3 = 0.5M 2M baud rate = 0 7 = 250k 207 is 9600 baud rate
- 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
- //enable spi
- SPCR=80;//spi enable master
- SPSR=1;//double speed
- //set up camera
- wrReg(0x15,32);//pclk does not toggle on HBLANK COM10
- wrReg(0x11,32);//using scaler for divider
- wrReg(REG_RGB444, 0x00); // Disable RGB444
- wrReg(REG_COM11,226);//enable nigh mode 1/8 frame rate COM11*/
- wrReg(REG_TSLB,0x04); // 0D = UYVY 04 = YUYV
- wrReg(REG_COM13,0x88); // connect to REG_TSLB
- //wrReg(REG_COM13,0x8); // connect to REG_TSLB disable gamma
- #ifdef rgb565
- wrReg(REG_COM7, 0x04); // RGB + color bar disable
- wrReg(REG_COM15, 0xD0); // Set rgb565 with Full range 0xD0
- #elif defined rawRGB
- wrReg(REG_COM7,1);//raw rgb bayer
- wrReg(REG_COM15, 0xC0); //Full range
- #else
- wrReg(REG_COM7, 0x00); // YUV
- //wrReg(REG_COM17, 0x00); // color bar disable
- wrReg(REG_COM15, 0xC0); //Full range
- #endif
- //wrReg(REG_COM3, 0x04);
- #if defined qqvga || defined qvga
- wrReg(REG_COM3,4); // REG_COM3
- #else
- wrReg(REG_COM3,0); // REG_COM3
- #endif
- //wrReg(0x3e,0x00); // REG_COM14
- // wrReg(0x72,0x11); //
- // wrReg(0x73,0xf0); //
- #ifdef qqvga
- wrReg(REG_COM14, 0x1a); // divide by 4
- wrReg(0x72, 0x22); // downsample by 4
- wrReg(0x73, 0xf2); // divide by 4
- wrReg(REG_HSTART,0x16);
- wrReg(REG_HSTOP,0x04);
- wrReg(REG_HREF,0xa4);
- wrReg(REG_VSTART,0x02);
- wrReg(REG_VSTOP,0x7a);
- wrReg(REG_VREF,0x0a);
- #endif
- #ifdef qvga
- wrReg(REG_COM14, 0x19);
- wrReg(0x72, 0x11);
- wrReg(0x73, 0xf1);
- wrReg(REG_HSTART,0x16);
- wrReg(REG_HSTOP,0x04);
- wrReg(REG_HREF,0x24);
- wrReg(REG_VSTART,0x02);
- wrReg(REG_VSTOP,0x7a);
- wrReg(REG_VREF,0x0a);
- #else
- wrReg(0x32,246); // was B6
- wrReg(0x17,0x13); // HSTART
- wrReg(0x18,0x01); // HSTOP
- wrReg(0x19,0x02); // VSTART
- wrReg(0x1a,0x7a); // VSTOP
- wrReg(0x03,0x0a); // VREF
- #endif
- // wrReg(0x70, 0x3a); // Scaling Xsc
- //wrReg(0x71, 0x35); // Scaling Ysc
- //wrReg(0xA2, 0x02); // pixel clock delay
- wrReg(REG_COM1, 0x00);
- // COLOR SETTING
- wrReg(REG_COM8,0x8F); // AGC AWB AEC Unlimited step size
- wrReg(0xAA,0x14); // Average-based AEC algorithm
- wrReg(REG_BRIGHT,0x00); // 0x00(Brightness 0) - 0x18(Brightness +1) - 0x98(Brightness -1)
- wrReg(REG_CONTRAS,0x40); // 0x40(Contrast 0) - 0x50(Contrast +1) - 0x38(Contrast -1)
- wrReg(0xB1,0xB1); // Automatic Black level Calibration
- wrReg(MTX1,0x80);
- wrReg(MTX2,0x80);
- wrReg(MTX3,0x00);
- wrReg(MTX4,0x22);
- wrReg(MTX5,0x5e);
- wrReg(MTX6,0x80);
- wrReg(MTXS,0x9e);
- wrReg(AWBC7,0x88);
- wrReg(AWBC8,0x88);
- wrReg(AWBC9,0x44);
- wrReg(AWBC10,0x67);
- wrReg(AWBC11,0x49);
- wrReg(AWBC12,0x0e);
- wrReg(REG_GFIX,0x00);
- wrReg(GGAIN,0x40);
- wrReg(AWBCTR3,0x0a);
- wrReg(AWBCTR2,0x55);
- wrReg(AWBCTR1,0x11);
- wrReg(AWBCTR0,0x9f);
- wrReg(0xb0,0x84);//not sure what this does
- wrReg(REG_COM16,COM16_AWBGAIN);//disable auto denoise and edge enhancment
- //wrReg(REG_COM16,0);
- wrReg(0x4C,0);//disable denoise
- wrReg(0x76,0);//disable denoise
- wrReg(0x77,0);//disable denoise
- wrReg(0x7B,4);//brighten up shadows a bit end point 4
- wrReg(0x7C,8);//brighten up shadows a bit end point 8
- //wrReg(0x88,238);//darken highligts end point 176
- //wrReg(0x89,211);//try to get more highlight detail
- //wrReg(0x7A,60);//slope
- //wrReg(0x26,0xB4);//lower maxium stable operating range for AEC
- //hueSatMatrix(0,100);
- //ov7670_store_cmatrix();
- //wrReg(0x20,12);//set ADC range to 1.5x
- wrReg(0x2D,16);//1 dummy line
- wrReg(0x11,4);//using scaler for divider
- //wrReg(0x2a,5);//href delay
- spiCSt();
- spiWrB(1);
- spiWrB(64);//sequental mode
- spiCSt();
- spiWrB(2);//sequental write mode
- spiWrB(0);//24 bit address
- spiWrB(0);
- spiWrB(0);
- /*uint32_t x;
- uint8_t y=0;
- for (x=0;x<122880;x++)
- {
- SPDR=y;
- y++;
- while(!(SPSR & (1<<SPIF))) {}
- }*/
- /*sendRam(1280,96);//send test frame first
- sendRam(1280,96);
- sendRam(1280,96);
- sendRam(1280,96);
- sendRam(1280,96);*/
- //sei();//enable interupts
- //UDR0=0;
- while (1)
- {
- /* Note: One frame is broken down into 5 smaller captures this allows for a whole frame to be captured at 640x480 which is nice
- however it could mean that there could be slight differences between each frame capture
- I think the improvment of resolution outweights the cons of the slight changes per frame if any
- The image will take about 15 seconds to reach the computer per frame*/
- //hueSatMatrix(0,y);
- //_delay_ms(100);
- #ifdef qqvga
- captureImg(0,0,320,120);
- sendRam(320,120);
- #endif
- #ifdef qvga
- captureImg(0,0,640,120);
- sendRam(640,120);
- captureImg(640,120,640,120);
- sendRam(640,120);
- #else
- #ifdef rawRGB
- uint8_t z;
- //for (z=0;z<64;z++)
- //{
- //wrReg(0x11,z);//using scaler for divider
- //_delay_ms(1000);
- captureImg(0,0,640,160);
- sendRam(640,160);
- captureImg(640,160,640,160);
- sendRam(640,160);
- captureImg(640,320,640,160);
- sendRam(640,160);
- //}
- #else
- captureImg(0,0,1280,96);//each pixel is 2 bytes so 1280 instead of 640 for width
- sendRam(1280,96);
- captureImg(1280,96,1280,96);
- sendRam(1280,96);
- captureImg(1280,192,1280,96);
- sendRam(1280,96);
- captureImg(1280,288,1280,96);
- sendRam(1280,96);
- captureImg(1280,384,1280,96);
- sendRam(1280,96);
- #endif
- #endif
- //frameByLine();
- /*doneImg=0;
- wantFrame=1;
- sei();//enable interupts
- //_delay_ms(1000);
- while (doneImg==0) {} //wait for image to complete
- cli();//disable interupts
- //_delay_ms(1000);
- spiCSt();
- spiWrB(3);//sequental read mode
- spiWrB(0);//24 bit address
- spiWrB(0);
- spiWrB(0);
- for (x=0;x<50688;x++)
- {
- SPDR=0;//send dummy value to get byte back
- while(!(SPSR & (1<<SPIF))) {}
- UDR0=SPDR;
- while ( !( UCSR0A & (1<<UDRE0)) ) {} //wait for byte to transmit
- }*/
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement