I've been using I2C for a while now. I was primed by Vincent Himpe's Mastering the I2C Bus, which takes a good look at the hardware level and also all the pieces of the protocol itself. A very good read by the way.
My problem is, I'm trying to communicate with a TI bq27510 Fuel Gauge chip using I2C. I've read the datasheet, and in it the I2C address is specified as 0xAA for writing, and 0XAB for reading. It even reminds you how a standard 1-byte read is done in I2C. Essentially, you need to send the following things, while clocking out each byte at the same time, and waiting for an ACK from the slave after each step:
- The Start condition (a falling SDA followed within a certain period by a falling SCL -- the only time SDA can legally change while SCL is high)
- The address of the chip you want to communicate with (in our case 0xAA for write)
- The command or data you want to send (in our case, for example, 0x08 for voltage read)
- a "repeated Start" which is another Start without first sending a Stop, this way we stay master of the bus
- the read address 0xAB
- then we clock out 8 bits, during which the slave should send back the requested voltage level of the attached battery.
Sorry for all the rambling, but I wanted to make sure I have everything right. The API calls take care of a lot of this in TivaWare. I'm using a TM4C129XNCZAD, just for reference, at 120MHz, though that's not terribly relevant.
The problem is -- no matter WHAT I send as the command (right after the write address) the slave sends a NACK (not acknowledge) immediately after the command. And not only that, sometimes it actually pulls SDA low for exactly 2 seconds (2000ms, I've measured it a couple times). However, when I send the write or read address, it will ACK those. And if I do a 'quick read' which just gets the slave to increment the address pointer and then send the data from that address, it will successfully do so! It will allow me to clock out three bytes after a 'quick read'. A quick read is accomplished by sending a Start, then the read address, and after the slave ACKs the read address we just send clock pulses and it sends back data. So I know two-way communication is working. I'm just so stumped as to why it's NACKing the commands.
I've read and re-read the datasheet a bunch of times. I've tried every command they list. I really don't understand the wording of the paragraph before the command table so I feel like I'm doing something wrong, but when I look at the example code that goes along with the board I'm using, they are sending the same command bytes that I'm trying to send.
Here's a link to the datasheet:
http://www.farnell.com/datasheets/1775288.pdfThe commands are on page 8. It lists two different numbers as the commands, and I'm not sure if one is for the UNSEALED mode, and the other is for SEALED mode? However the example program simply sends the first number in the box, 0x08 for voltage for example. I've tried running the example code and I THINK it works but it sends the retrieved data back over UART and for some reason the UART isn't sending data correctly (that's a whole other problem, the example code is for a different processor and I do have one to test with, but I don't know that much about it and so I think I'm setting something up wrong).
ANYWAY -- if anyone sees a glaring error I'm making, or something, all help is greatly, greatly appreciated!