Jump to content
Lacto

OV7670 and MSP430

Recommended Posts

Hej guys (and gilrs also in case there are any),

I am trying to connect a OV7670 (no FIFO) to a MSP430G2553 (3.3 V, 28 pins). As the OV7670 is only tolerant up to 2.8 V I use a MSP430G2231 at 2.8 V and ~11 MHz to feed the XCLK of the OV7670. Everything else should be handled by the 2553 (3.3 V). The 2231 works fine and I am listening to the output pins of the OV7670 with the 2553. The problem: there is nothing. Any ideas?

 

http://www.ebay.de/itm/VGA-OV7670-CMOS-Camera-Module-Lens-CMOS-640X480-SCCB-W-I2C-Interface-Arduin-M35-/301724381213?hash=item46402cb01d:g:UPoAAOSwcu5UNjqp

 

Reset is at 0V

3V3 is at 3.3 V

GND is at 0 V

The I2C pins have pull up resistors to 2.8 V

Share this post


Link to post
Share on other sites

If you are using i2c, and have properly coded the i2c open-collector (output ground and high-z input, never output high), you don't really need the 2231 as a level translator. But this really seems like a coding issue. we can't help without your code.

Share this post


Link to post
Share on other sites

I am not touching the I2C at the moment. I am just listening to the camera output. Here is my code:

#include <msp430.h> 

/*
 * main.c
 */
void main(void) {

    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    BCSCTL1 = RSEL3 + RSEL2 + RSEL1;//DCO2 + DCO1 + DCO0;//CALBC1_16MHZ;
    DCOCTL = DCO0 + DCO1;//XT2OFF + RSEL3 + RSEL2 + RSEL1 + RSEL0;

    BCSCTL2 = DIVS_3;


    P1DIR = BIT4 + BIT0;
    P1SEL = BIT4;
    P1OUT = BIT0;


    for(;{
    	_delay_cycles(10000000);
    	P1OUT ^= BIT0;
    }

}

#include  <msp430g2553.h>
#include  <ili9341b.h>

unsigned int a = 0;

void Paint(Red,Green,Blue)
{
  int i,j;
  Bereich(0,0,320,240);
  for(i=0;i<320;i++)
  {
    for (j=0;j<240;j++)
    {
    	LCD_Write_DATA((Red<<3)+(Green>>3));
    	LCD_Write_DATA((Green<<5)+Blue);
    }
  }
}


void Paint2(){
  int i, j, k, m;
  Bereich(0,0,320,240);
  m = 1;
  j = 0;
  P1OUT &= ~LCD_CS;//
  for(k=0;k<240;k++){
	  LCD_Write_DATA_test(0);
  	  LCD_Write_DATA_test(m);}
  for(i=1;i<320;i++){
	  if(i%20 == 0){
		  m*=2;
		  if (m == 256){
			  j = 1;
			  m = 1;
		  }
		}
	  if(j){
  		  for(k=0;k<240;k++){
  			  LCD_Write_DATA_test(m);
  			  LCD_Write_DATA_test(0);}}
	  else{
	  	  for(k=0;k<240;k++){
	  		  LCD_Write_DATA_test(0);
	  		  LCD_Write_DATA_test(m);}}
  }
  P1OUT |= LCD_CS;//
}


void main(void) {
    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    BCSCTL1 = CALBC1_16MHZ;//DCO2 + DCO1 + DCO0;//CALBC1_16MHZ;
    DCOCTL = CALDCO_16MHZ;//XT2OFF + RSEL3 + RSEL2 + RSEL1 + RSEL0;
    BCSCTL2 = 0;

    //Port1(ILI9341)
    P1DIR = LCD_DC + LCD_CS;// + LCD_REST;
    P1OUT = LCD_CS + LCD_REST;
    P1SEL = LCD_CLK + LCD_MOSI;
    P1SEL2 = LCD_CLK + LCD_MOSI;

    //Port3
    P2OUT = 0xC0;
    P3OUT = 0;


    // UCA0CTL0 = UCMSB + UCMST + UCSYNC + UCCKPH + UCMODE_1; // 4-pin, 8-bit SPI master
    UCA0CTL0 = UCMSB + UCMST + UCSYNC + UCCKPH;// RobG
    UCA0CTL1 = UCSSEL_2; // SMCLK
    UCA0BR0 = 1; //
    UCA0BR1 = 0; //
    UCA0MCTL = 0;                             // No modulation
    UCA0CTL1 &= ~UCSWRST;

    LCD_Init();


    Paint(0,0,0);
    _delay_cycles(16000000);
    Paint2();
    _delay_cycles(16000000);



    TACTL = TASSEL_2;
    TAR = 0;
    P2IFG = 0;
    P2IE = 0x03;
    P2IES = 0;
    __enable_interrupt();

    while(1){
    	_delay_cycles(16000000);
    }

}



#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void){
	if(a){
		_delay_cycles(16000000);
	}
	else{
		TACTL = TASSEL_2 + MC_2;
		a = 1;
		P2IFG = 0;
	}

}


Share this post


Link to post
Share on other sites

Could solve the problem. The datasheet is wrong: For normal operation RESET has to be pulled up and not down ...

 

Now I have a problem with I2C. The Camera gives me no ACK.

void InitCam(void){

	UCB0CTL1 = UCSWRST;
	UCB0CTL0 = UCMODE_3 + UCMST + UCSYNC;			// I2C master mode
	UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
	//UCB0BR0 = 0x29;                          // < 400 kHz
	UCB0BR0 = 0x30;                          // << 400 kHz
	UCB0I2CSA = 0x21;                       // address
	UCB0CTL1 &= ~UCSWRST;

	//go to register
	UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
	while (!(IFG2 & UCB0TXIFG));
	//_delay_cycles(1600000);
	UCB0TXBUF = 0x3e;
	while (!(IFG2 & UCB0TXIFG));

	//read register
	UCB0CTL1 = UCSSEL_2 + UCTXSTT; // I2C RX, start condition
	while (!(IFG2 & UCB0RXIFG));
	input = UCB0RXBUF;

	UCB0CTL1 = UCSSEL_2 + UCTXSTP;
	while (UCB0CTL1 & UCTXSTP);
}

Any Ideas?

Share this post


Link to post
Share on other sites

Is your i2c address correct?

Do you have i2c pullup resistors installed? About 3k ohm.

 

You are loading 0x21 into the MSP I2C address register.

I thought I read in the camera data sheet:

,, address 43 for reads

,, 42 for writes

 

The data sheet does not say if those are hex or decimal addresses.

Assuming they could be decimal, then i2c address reg in the MSP should be loaded :

Write - 42dec - 0x2a

Read. - 43dec - 0x2b

 

I have no experience with this camera.

But i2c addressing can occasionally be ambiguous. Just use them all ,,,, all 4 ,,,, until you get a reply on the bus.

 

Hope this works, and I hope you've got a logic analyser.

 

Cheers

Share this post


Link to post
Share on other sites

The I2C address was correct.

 

I got ACKs after i switched the pullups from 10k to 1k and lowered the speed from 390 kHz to 63 kHz.

 

At the Moment it works not reliably (weird readings) but at least I am a step further.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×