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:
So here are the questions:
- Do you have any ideas why I get an extra FFFF when reading a register after writing it? (underlined in blue)
- Why are there some extra zeros in the output? (marked in yellow)