I'm (obviously) new to the boards, having started playing around with Arduinos about 5 weeks ago. it's such an incredible user-friendly platform, with more potential than I could have imagined. Such fun.
Anyway, I just hit my ability limit today. I'm trying to connect a WinBond ISD25120 voice chip and a Gravitech I2C Programmable Oscillator (I2C 1KHz to 68MHz Programmable Oscillator). Unfortunately, I can't work through the docs for the LTC6904 chip on the Gravitech module and program the frequency of the module. Can anyone share some insight as to what an appropriate set of I2C commands might look like for this little gem? TIA.
It's just standard I2C stuff, to get the example in the data sheet going do this:-
#include <Wire.h>
void setup() {
Wire.begin(); // set up I2C
}
void loop() {
// set up example in data sheet of programming to 68MHz
int msb = 0xff;
int lsb = 0xfc;
Wire.beginTransmission(0x17); // address of device with Adr Pin 4 = 0
Wire.send(msb); // send most significant byte of control
Wire.send(lsb); // send least significant byte of control
Wire.endTransmission(); // leave I2C bus
// do some other stuff
}
The trick is to understand what the bit fields mean in the data sheet. These are broken into three fields, work out what you want in each. Put them all together as a 16 bit word then split the word in two to send over the I2C.
The trick is to understand what the bit fields mean in the data sheet.
Boy, that's the truth. I think I've almost got the rest of it. Here's the code I originally cobbled up:
// Gravitech LTC6904-based programmable oscillator board #include <Wire.h>
int powerPin = 13;
void setup()
{
Wire.begin();
digitalWrite(powerPin, HIGH); // power up the LTC6904 module
Wire.beginTransmission(0x2e); //address of LTC6904 module
Wire.send(0xXX);
Wire.send(0xXX);
Wire.endTransmission();
}
void
loop()
{
}
But I just can't make sense of the values for the two "Wire.send()" commands. If I want to set the oscillator to 256 kHz, I calculate an OCT value of 7 and a DAC value of 984 in decimal. So in binary I have 0111 and 0011 1101 1000. Do I combine these to get 0111 0011 1101 1000, break it into 0111 0011 and 1101 1000 and convert to hex: 0x73 and 0xD8? Or am I totally missing the point?
But I just can't make sense of the values for the two "Wire.send()" commands. If I want to set the oscillator to 256 kHz, I calculate an OCT value of 7 and a DAC value of 984 in decimal. So in binary I have 0111 and 0011 1101 1000. Do I combine these to get 0111 0011 1101 1000, break it into 0111 0011 and 1101 1000 and convert to hex: 0x73 and 0xD8? Or am I totally missing the point?
You need to shift & combine the bits. Table 3 on page 8 of the data sheet will tell you where the bits need to be positioned within the 16-bit command.
declare the 16-bit value as an int with default value 0, then shift & bitwise OR the values of OCT, DAC and CNF to it
unsigned char valh, vall; // Most sig. byte & least sig byte.
unsigned int val = 0;
val |= (CNF & 0x3); // mask to 2 bits, no shift reqd
val |= ((DAC & 0x3ff) << 2); // mask to 10 bits and shift by 2 bits
val |= ((OCT & 0xf) << 12); // mask to 4 bits & shift by 12 bits
vall = val & 0xff; // mask to 8 bits (LSB)
valh = ((val & 0xff00) >> 8); // mask to top 8 bits & shift down by 8 bits (MSB)
then use valh & vall in your Wire.send() commands.
Thanks so much - that's what I need to move forward.
Soooooo... I guess I'll go pour a drink and sit down and study me some bit operators and bit manipulation. I have no idea what I'm doing - all those years programming simulations with floats and doubles ain't worth a damn right now. :o
valh = ((val & 0xff00) >> 8); // mask to top 8 bits & shift down by 8 bits (MSB)
Total nitpicky comment here, but note that in the case there is no need to mask since the low byte is going to be shifted off the end anyway. You could just do
valh = val >> 8;
and be fine. Hey, it might come in handy if you need the operation to proceed 125 ns faster!