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