Hopefully that makes sense. Basically I’ve got a 3.3V regulator hooked into the 5V out of my SVP, and the 3.3V out goes into the compass. There’s a 10k resistor on both SDA and SCL between the 3.3V and the relevant pins on the SVP.
I haven’t checked your code very carefully but the schematic you drew makes it look like you are shorting the SVP’s SCL and SDA lines directly to 5V, which will not work and could damage the SVP permanently.
I also tried 4.7k resistors, but that didn’t help. If I read the compass datasheet correctly I think I’ve got the resistors in the right place; I don’t get past i2c_init() without them.
A reading of -1 means that your code read a value of 0xFF for both bytes, which means the SDA line was high the entire time, and that is a pretty good sign that the chip is not sending any data if it happens consistently.
I looked at your code and I see a few problems with your I2C operations. First, you need to call i2c_stop to terminate each transfer; you need to add calls to that function after lines 27, 31, and 35, and after your read loop on lines 50-52.
Second, you need to acknowledge each byte received from the device besides the last (by using i2c_readAck) to let it know that you are requesting more data.
Third, I don’t think you should be writing 0x06 on line 48. It’s strange since the HMC5883L datasheet actually seems to tell you to do that, but as far as I know, the address is the only thing a master should be sending to a slave during a read transfer. (The Arduino code from bildr does not send this 0x06).
With all of those in mind, I think your code from lines 47-52 should look like the following:
i2c_start(COMPASS + I2C_READ);
for (i = 0; i < 5; i++) {
buffer[i] = i2c_readAck();
}
buffer[5] = i2c_readNak();
i2c_stop();
(If it doesn’t work without i2c_write(0x06), you could try putting it back in.)
After implementing your changes I started getting some values back, but they’d alternate between things like [104, 130, -124] and [27135, -31744, -31]. They were essentially random.
Funny story; that part was almost correct. Before reading I do need to write 0x06! But I shouldn’t have been trying to write and read in the same transaction. Writing 0x06, then starting a read transaction turned the random numbers from above very consistent
If anybody coming here via Google in the future is curious; this is the final code that seems to be working pretty well for me: pastebin.com/1TtW2yS0
Thanks for all your help Kevin & David! Best customer support in the industry by far