As a follow up to the unexpected I2C scan issue with the LSM303DLHC, I looked at the errata for the nRF52832 and it may be related to this issue described below (since the scan problem is unique to the nRF52). A second STOP bit may be causing problem with the LSM303DLHC inside the probe function. I'll have to look on a scope to see whether this is happening or not. There were no other likely errata issues listed in the latest document.

Source: http://infocenter.nordicsemi.com/pdf/nRF52832_Rev_1_Errata_v1.3.pdf

*3.22 [83] TWIS: STOPPED event occurs twice if the STOP task is triggered during a transaction*

This anomaly applies to IC Rev. Rev 1, build codes QFAA-B00, QFAB-B00, CIAA-B00. It was inherited from the previous IC revision Engineering C.

*Symptoms**
*STOPPED event is set after clearing it.

*Conditions**
*The STOP task is triggered during a transaction.

*Consequences**
*STOPPED event occurs twice: When the STOP task is fired and when the master issues a stop condition on the bus. This could provoke an extra interrupt or a failure in the TWIS driver.

*Workaround**
*The last STOPPED event must be accounted for in software.


On 19/12/16 14:37, Kevin Townsend wrote:
While adding a test driver for the new sensor API, we've been trying to debug an issue where a specific sensor (the LSM303DLHC) doesn't show up in an I2C bus scan (using the 'probe' command in the I2C HAL), using the following shell command on the nRF52, but it DOES work on other targets:

    // Command handler prototype declaration
    static int shell_i2cscan_cmd(int argc, char **argv);

    // Shell command struct
    static struct shell_cmd shell_i2cscan_cmd_struct = {
        .sc_cmd = "i2cscan",
        .sc_cmd_func = shell_i2cscan_cmd
    };

    // i2cscan command handler
    static int
    shell_i2cscan_cmd(int argc, char **argv)
    {
        uint8_t addr;
        int32_t timeout = OS_TICKS_PER_SEC / 10;
        uint8_t dev_count = 0;

        console_printf("Scanning I2C bus 0\n"
" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n"
                       "00:          ");

        /* Scan all valid I2C addresses (0x03..0x77) */
        for (addr = 0x03; addr < 0x78; addr++) {
            int rc = hal_i2c_master_probe(0, addr, timeout);
            /* Print addr header every 16 bytes */
            if (!(addr % 16)) {
              console_printf("\n%02x: ", addr);
            }
            /* Display the addr if a response was received */
            if (!rc) {
                console_printf("%02x ", addr);
                dev_count++;
            } else {
                console_printf("-- ");
            }
        }
        console_printf("\nFound %u devices on I2C bus 0\n", dev_count);

        return 0;
    }

The HW (https://www.adafruit.com/product/1120 or https://www.adafruit.com/products/1714) has been used on about 20 different MCUs by me, and it's usually one of the first drivers I write so I'm confident the HW is good.

What is unusual is that the LSM303DLHC is the only sensor that doesn't show up. We have 5 other I2C sensors connected to the test system that show up fine.

I thought it might be a HW issue we haven't seen before since we have 5V/3V level shifting, but checking the LSM303DLHC datasheet I'm quite confident the HW breakout is fine and we are using the recommended values (10K pullups on SCL/SDA, etc.). It fails at both 100kHz and 400kHz.

I think the issue is ultimately here in the probe function with the STOP bit that is being sent (which I think is the right default). Changing it to not send the STOP condition does bring more devices up on the I2C bus:

    int
    hal_i2c_master_probe(uint8_t i2c_num, uint8_t address, uint32_t timo)
    {
        struct hal_i2c_master_data rx;
        uint8_t buf;

        rx.address = address;
        rx.buffer = &buf;
        rx.len = 1;

    *    return hal_i2c_master_read(i2c_num, &rx, timo, 0);*
    }

With the following sensors attached:

LSM303DLHC Accel: 0x19
LSM303DLHC Mag:   0x1E
TCS3472x:         0x29
FXAS21002C:       0x21
FXOS8700CQ:       0x1F
BMP280:           0x77
Si7201:           0x40

I get this with the default behaviour of the STOP bit being enabled ... everything show up except the LS303DLHC accel/mag:

    i2cscan
    12275:Scanning I2C bus 0
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1f
    20: -- 21 -- -- -- -- -- -- -- 29 -- -- -- -- -- --
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    70: -- -- -- -- -- -- -- 77
    Found 5 devices on I2C bus 0


When I disable the STOP (lastop=0) bit I get more address, but still not the right ones and the next scan also adds 0x03:

    i2cscan
    7082:Scanning I2C bus 0
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:          -- -- -- -- -- -- -- -- -- -- -- -- --
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1f
    20: 20 21 22 -- -- -- -- -- -- 29 2a -- -- -- -- --
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    40: 40 41 -- -- -- -- -- -- -- -- -- -- -- -- -- --
    50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    70: -- -- -- -- -- -- -- 77
    Found 9 devices on I2C bus 0


Probing the I2C bus is problematic anyway since there isn't a standard way to do it, although I think it is an important sanity check, and it's a pretty standard chunk of code on most systems I've used. I'm almost sure probing this way works on every other MCU I've tested, and I use this functionality all the time when writing drivers as an initial test to make sure the pins are connected properly. What's odd is that this seems to be unique to the nRF52, which makes me wonder if there is something specific about the I2C pad design on the new parts, and the LSM303DLHC happens to have a specific design that causes problems?

I think the right choice is sending the STOP bit, though, and the problem is elsewhere, but related to the probe function.

I'm still debugging this ... but I'm curious if anyone here has played with the probe function and seen problems themselves? If anyone at Runtime has an nRF52 or non nRF52 system setup, and doesn't mind running the 'i2cprobe' command at the top of this email, it would be nice just to have someone else confirm the issue. We sent a couple 9DOF breakouts to the office that should be fine to test with.

On a 3V system, just connect 3V on the MCU side to the 3Vo pin on the 9DOF breakout, then GND, SCL and SDA as normal?

I'll post details here as I dig further into this.

K.

PS: I have the same issue on the same HW with the nRF52 Arduino core here which uses the Nordic SDK, just as an additional detail trying to narrow this down: https://github.com/sandeepmistry/arduino-nRF5

Reply via email to