This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Apparent i2c byte framing error on Beaglebone Black.

We have an ST Micro LIS3DH "nano" Accelerometer connected via i2c-2 to a Rev. c (Debian) Circuitco Beaglebone Black.

The  LIS3DH has a hard-coded base address of 0x30.

However, when I run "i2cdetect -r 2" it finds a device at 0x18 *not* 0x30.  Since 0x18 = 11000 in binary and 0x30 = 110000 in binary, it would appear that the LIS3DH is seeing the traffic on the i2c bus bit-shifted 1 bit to the left, so that it "thinks" it saw a 0x30 when the driver placed a 0x18 on the bus.

Indeed, when using test code, ported from an application written for another processor which successfully tasked the LIS3DH and did not exhibit framing errors, I do not get a response when I try to address 0x30.  However, I do get a reaction from the LIS3DH when I target bass address 0x18.  From there it gets muddled, since reads and writes appear to have bit framing errors as well and since a read is indicated in i2c protocol by *setting* the LSB and since the LSB is getting shifted up, I can't really find a way to successfully read the device.

I note that the maximum clock rate for i2c is 100 kHz, and that's what the bus is set to (and I have yet to find a way to change it).

Also, the maximum rise time for SCL is 1000 ns.  Look at the scope trace below, the bottom trace is SCL (the top trace is SDA).  Also note that I have placed the cursors at a spacing to indicate exactly 1000 ns.  It would appear that the rise time (from 0.2*Vcc to 0.8*Vcc) is right at the cusp of being 1000 ns, perhaps even slightly longer.

Could the 1000 ns rise time, combined with the absolute maximum clock rate (100 kHz),  be causing the bit framing error?

Can the clock rate of the i2c bus be adjusted?

It would appear that if I disconnect the LIS3DH, the rise time of the SCL line wagging into the open air goes down to about 700 ns, so there may be room to get some capacitance out of the lines going to the LIS3DH and improve this a bit.

Thanks for any help you can give.

Mark Sutton

Globalstar, INC.

  • Hi Mark,

    From the attached picture it seems to me that this is an I2C pullup issue. What is the value of the pullup resistors on your I2C lines?

  • We had tried values ranging from 100k to 10k.

    Based on your post, I decided to really slam it with 1k.

    With 1k we do get a very fast rise time, but the accelerometer is still shifting everything it receives left by 1 bit.

    So, we are still not successfully communicating due to the bit shift (we can't command a read, for example, if the accelerometer always sees the LSB as "0".  There's no pre-bit shifting "Trickery" that can fix this.

    For reference, here is the much faster rise time with 1k resisters:

  • This looks OK. Have you captured a whole I2C frame to see what's actually transmitted? What Linux version are you using?

  • I have captured a full transaction of i2cdetect running using a Total Phase Beagle i2c sniffer (no relation to "Beaglebone).  The sniffer appears to read the i2c communication coming from the Beaglebone correctly, but my Accelerometer is apparently bitshifting the communication one to the left.  This is weird because we've used this accelerometer with zero problems with other processors and their i2c ports.  It seems to have an issue with the Sitarra / Beaglebone, however.   (It is my understanding that this accelerometer, ST Micro LIS3DH, is the same one used in a couple of models of iPhone, so it's not exactly a strange esoteric product).  I tried to attache a CSV spreadsheet of the output from the Beagle sniffer, and the system wouldn't accept the file, so here's a screengrab of the relevant part instead.  Note the reaction from the device at address 0x18, and no reaction at 0x30 (its address is supposed to be 0x30).

  • The device can't truly be somehow 1-bit shifted in its view of the bus since then it would fail to signal an ACK at the right time. The most plausible explanation is a wrong sample point of SDA: their datasheet seems to indicate a non-zero hold time after SCL falling, while the I²C standard requires no such hold time and the AM335x I²C controller provides none. Different controllers may behave differently.

    If this is indeed the source of the problem then lowering the bus speed will not help, though it's worth trying of course. It may help in combination with somehow delaying SDA (RC filter?). Alternatives would be using the bit-bang I²C driver that's available in linux (which almost certainly will not transition SDL and SCL at the same time), or using SPI mode.

    The max I²C bus speed can presumably be configured in device tree, ditto for the use of the bit-bang I²C driver. Check the relevant device tree binding docs for details.