Teensy 3 I2C to battery fuel gauge. Pullups.

Status
Not open for further replies.

cmason

Well-known member
I'm trying to talk to this MAX17048 battery fuel gauge. I designed a board and soldered it using a hot plate. I fear I may have either not completely soldered it or may have fried the chip during soldering because I can't seem to talk to it. However, this is the first time I've used I2C and maybe I've gotten the software wrong or am having a problem with pullups. I have a 10k pullup on each of SCL and SDA. The datasheet for the chip gives the command sequence to read a register as:

Start | SAddr W | A | MAddr | A | Sr | SAddr R | A | Data0. | A | Data1 | A | ... | DataN | N | Stop

Black is master and red is slave. SAddr W is 0x6C (write) and SAddr R is 0x6D (read). MAddr is the register address. Sr means "repeated start" but I'm not totally sure what that really means.

I'm using nox771's I2C library. The code is:

Code:
    Debug.println("hello");
    Debug.flush();

    digitalWrite(13, 1);

    Wire.begin(Wire_MASTER, 0x00, Wire_PINS_18_19, Wire_PULLUP_EXT, Wire_RATE_100);

    Wire.beginTransmission(0x6c);     // slave addr
    Wire.write(0x08);                   // memory address
    Wire.endTransmission(Wire_STOP);   // blocking write   (NOSTOP triggers RepSTART
    Wire.requestFrom(0x6D,2,Wire_NOSTOP); // blocking read    on next Wire command)

    int16_t val = 0;
    bool read = false;
    while(Wire.available())    // slave may send less than requested
    {
        char c = Wire.readByte();    // receive a byte as character
        val += val << 8 + c;
        read = true;
    }

    if (read) {
        digitalWrite(13, 0);
        Debug.print("version: ");
        Debug.print(val);
    } else {
        Debug.print("no response.");
    }
    Debug.println();
    Debug.flush();

I've tried all combinations of Wire_PULLUP_EXT/Wire_PULLUP_INT and Wire_RATE_100/Wire_RATE_400 (datasheet says clock <= 400khz).

I don't have an oscilloscope, but I used a Salae logic analyzer to capture this trace:

Screen Shot 2013-04-30 at 10.47.55 PM.jpg

My read of this that the fuel gauge chip is not acknowledging the transmission from the master by pulling the SDA line low at the ninth transition just before +0.1ms.

Does this seem right?

I've read that there's oddness around the pullups on the teensy 3. Could this be related, or, as is I suspect more likely, my chip dead or not wired correctly?

I understand that an oscilloscope would be preferable because maybe the chip does try to pull SDA low but can't quite get it low enough or something. Any other debugging ideas short of buying an oscilloscope? :)

Thanks a bunch,

-c
 
Last edited:
This does sound like the chip isn't connected.

I understand that an oscilloscope would be preferable because maybe the chip does try to pull SDA low but can't quite get it low enough or something. Any other debugging ideas short of buying an oscilloscope? :)

Are you going to the Dorkbot meetup on Monday? I could bring a Rigol scope. I can probably get there early, so you could have some time with it while the place is still quiet and relatively free of distractions. Or you could borrow it for a couple weeks if you can wait until after Maker Faire.
 
Scott and I reflowed the chip and then spent some time with his scope. Without enabling the t3's internal pullups, with just 10k external resistors we were seeing some significant ramping on the sda line. I'm concerned that, due to some of the issues mentioned elsewhere, the T3's internal pullups may be too strong for this chip. When I enable them, I always see the behavior above (NAK).

We replaced the 10k pullups with 5k, and now I can consistently generate this behavior:

Screen Shot 2013-05-04 at 7.31.21 PM.png

This is still using nox771's library. The code is:

Code:
i2c.begin(I2C_MASTER, 0x00, I2C_PINS_18_19, I2C_PULLUP_EXT, I2C_RATE_100);
i2c.beginTransmission(0x6c);     // slave addr
Debug.println("begin");
Debug.flush();
i2c.write(0x08);                   // memory address
Debug.println("write");
Debug.flush();
i2c.endTransmission(I2C_NOSTOP);   // blocking write   (NOSTOP triggers RepSTART
Debug.println("end");
Debug.flush();
i2c.requestFrom(0x6D,2,I2C_STOP); // blocking read    on next I2C command)

In this case, the teensy hangs immediate after printing "write". I'm not sure how to interpret the above trace. It seems like the teensy never returns SCL to low? Why would this happen?

When I try with the regular wire library (with speed set to 100khz), I always see the previous behavior (NAKs).

I will be at the meetup on Monday.

Any suggestions for things to try would be most appreciated.

-c
 
Last edited:

It does look weird. Looking at the pattern you can see a START, followed by 0x6C (7-bits), followed by WRITE (low), and then you get to the acknowledge. Slave looks like it didn't ACK, but what is weird is the timing (obviously the analyzer isn't helping here), but the SDA/SCL are transitioning on top of each other. SDA should be getting it's final value before SCL. It could be that the T3 is interpreting this as a STOP, in which case it would just release the bus.

I would try speeding up SDA by giving it a lower pullup resistance than SCL. Although this still seems like you will end up with a NAK.
 
Last edited:
Status
Not open for further replies.
Back
Top