1

I am currently working on a camera platform based on the MT9D111 module from Micron. The first thing to do is to write the configuration to the numerous registers of the chip which is done via an i2C connection.

I adapted the code from here for testing this with an Arduino Uno. 3.3V supply and 8MHz clock are also provided by the Arduino.

Everything seems to work fine, but there are some odds which I don't know the reason for.

So here is the code (I just added the soft reset sequence according to the Developers Guide):

const int freqOutputPin = 9;   // OC1A output pin for ATmega328 boards

#define TMR1 0

#include <Wire.h>
#include <avr/io.h>
#include <util/delay.h>
//#include <TimerOne.h>
#include <avr/interrupt.h>

void setup() {
  pinMode(freqOutputPin, OUTPUT);
  Serial.begin(9600);

  TCCR1B |= (1 << CS10);  //selecting prescaler 0b001 (Tclk/1)
  TCCR1B &= ~((1 << CS12) | (1 << CS11)); // turn off CS12 and CS11 bits
  TCCR1A |= ((1 << WGM11) | (1 << WGM10)); //Configure timer 1 for TOP mode (with TOP = OCR1A)
  TCCR1B |= ((1 << WGM13) | (1 << WGM12));
  TCCR1A |= (1 << COM1A0); // Enable timer 1 Compare Output channel A in toggle mode
  TCCR1A &= ~(1 << COM1A1);
  TCNT1 = 0;
  OCR1A = TMR1;

  delay(500);  //Initial delay
  Wire.begin(); // join i2c bus as master
  Serial.begin(9600);
  Serial.println("MT9D111 Camera Module + Arduino");
  Serial.println("Read and Write 16-bit register value example");
  Serial.println("*  Read expected value = 0x1519 from Register 0x00");
  Serial.println("*  Write value = 0xA5F0 to Register 0x20:1");
  Serial.println();
  init1(); //execute code just 1 time
}

void loop() {
}

void init1() {
  int16_t a;

  delay(500);  //wait until start
  Serial.print("Soft reset first");
  Serial.println();
  soft_reset();//do a soft reset at startup

 //***************Configuration here!****************//
  Serial.print("Read result from register 0x00");
  a = read_reg(0);
  Serial.println();
  Serial.print("0x");
  Serial.println(a, HEX);  //print result
  Serial.println();
  Serial.print("Read original data from register 0x0a, should be 11");
  Serial.println();
  a = read_reg(10);  
  Serial.print("0x");
  Serial.println(a, HEX);  //print result
  Serial.println();

  //Enable this part for writing register
  //Some example reads and writes follow
  Serial.print("Writing 0xA5F0 in register 0x20:1");
  Serial.println();
  write_reg(32, 1, 165, 240);
  Serial.print("Read new value from register 0x20:1");
  Serial.println();
  a = read_reg(32);
  Serial.print("0x");
  Serial.println(a, HEX);  //print result
  Serial.println();
  Serial.print("Writing 0xA1F3 in register 0x20:1");
  Serial.println();
  write_reg(32, 1, 161, 243);
  Serial.print("Read new value from register 0x20:1");
  Serial.println();
  a = read_reg(32);  
  Serial.print("0x");
  Serial.println(a, HEX);  //print result
  Serial.println();
}

//Write 2Byte register
void write_reg(int reg_address, int page, int data_msb, int data_lsb) {
  delay(5);  //5ms
  Wire.beginTransmission(93); // transmit to device 93, Camera Module
  Wire.write(240);   //page register address
  Wire.write(0);
  Wire.write(page);   //select page 0/1/2
  Wire.endTransmission(1);    // stop transmitting
  Wire.beginTransmission(93); // transmit to device 93, Camera Module
  Wire.write(reg_address);   //register address 8bit, decimal
  Wire.write(data_msb);  //msbyte
  Wire.write(data_lsb);  //lsbyte
  Wire.endTransmission(1);    // stop transmitting
}

//read 2Byte register
//be careful about selected register page
int16_t read_reg(int reg_address) {
  int16_t err;
  delay(5);  //5ms
  Wire.beginTransmission(93); // transmit to device 93, Camera Module
  Wire.write(reg_address);   //register address 8bit, decimal
  err = Wire.endTransmission(1);    // stop transmitting
  Serial.println(err);
  Wire.requestFrom(93, 2, 1); //request value form device 93, 2 bytes with stop bit
  int16_t result = ((Wire.read() << 8) | Wire.read());  //read 16 bits
  return result;
}

//Perform Soft reset, required at startup
void soft_reset(){
  write_reg(101, 0, 160, 0);//write registers according to dev guide
  write_reg(195, 1, 5, 1);
  write_reg(13, 0, 0, 33);
  delay(5);
  write_reg(13, 0, 0, 0);
  delay(5);//wait for i2c to be ready again
}

Running this code gives me the following result on the serial monitor:

Serial Monitor

So here are the questions:

  1. Do you have any ideas why I get an extra FFFF when reading a register after writing it? (underlined in blue)
  2. Why are there some extra zeros in the output? (marked in yellow)
0

The 0 come from your code:

Serial.println(err);

It's printing the error code. 0, hence no error.

As for the extra FFFF I'd say it's because you are using signed integers. Change your a declaration to uint16_t and see if that fixes it.

  • 1
    Thanks, that was some fast help. Solved the problems :-) – deinoppa Dec 2 '15 at 8:10
  • Happy to help :-) – dda Dec 2 '15 at 8:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.