zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.59k stars 6.48k forks source link

drivers: i2c: nrf: i2c error with burst write #38849

Closed ck-telecom closed 3 years ago

ck-telecom commented 3 years ago

Describe the bug sending to bma421 config file buffer(a very huge size buffer), using i2c_burst_write with error the following error

00> [00:00:00.891,998] i2c_nrfx_twim: Error on I2C line occurred for message 0 00> [00:00:00.892,089] BMA421: i2c_burst_read error -5 00> [00:00:00.892,120] BMA421: BMA4 init error:-2

gmarull commented 3 years ago

Can you please provide some more details, such as steps to reproduce?

ck-telecom commented 3 years ago

this issue happens in pinetime with zephyr OS

The dts dir boards/arm/pinetime_devkit0/pinetime_detkit0.dts shows:

&i2c0 { compatible = "nordic,nrf-twim"; status = "okay"; sda-pin = <6>; scl-pin = <7>; clock-frequency = ; / 400KHz / zephyr,concat-buf-size = <64>; // if without this, i2c_burst_write says [Adjust the zephyr,concat-buf-size property in the ...], but with this, i2c_read error happens with above

/* BOSCH BMA421 Triaxial Acceleration Sensor (1000KHz) */
bma421: bma421@18 {
    compatible = "bosch,bma4xx";
    reg = <0x18>;
    label = "BMA421";
    int1-gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
};

... };

with the bma421 driver, easy to find coz pinetime is a popular open source project, for my project, you could check https://gitee.com/fwatch/pinetime/tree/develop/app/drivers/bma421/zephyr

The pinetime offical firmware workaround, just FYI https://github.com/JF002/InfiniTime/blob/develop/src/drivers/TwiMaster.cpp

anangl commented 3 years ago

sending to bma421 config file buffer(a very huge size buffer), using i2c_burst_write with error the following error

Could you point me to where i2c_burst_write() is called to send this huge buffer? I didn't manage to find this myself.

From what I can see in bma421_init_driver():

    ret = bma4_soft_reset(bma_dev);
    if (ret != BMA4_OK) {
        LOG_ERR("BMA4 soft reset error:%d", ret);
        return ret;
    }
    k_busy_wait(5000);

    ret = bma421_init(bma_dev);
    if (ret != BMA4_OK) {
        LOG_ERR("BMA4 init error:%d", ret);
        return ret;
    }

i2c_burst_write() is called underneath bma4_soft_reset(), but the buffer there is just one byte (BMA4_SOFT_RESET to be written to BMA4_CMD_ADDR). This call is apparently successful. Then, i2c_burst_read() is called underneath bma421_init() (to read BMA4_CHIP_ID_ADDR). And this call results, as you reported, in:

00> [00:00:00.891,998] i2c_nrfx_twim: Error on I2C line occurred for message 0
00> [00:00:00.892,089] BMA421: i2c_burst_read error -5
00> [00:00:00.892,120] BMA421: BMA4 init error:-2

The i2c_nrfx_twim error message indicates that the TWIM peripheral was not able to complete the transaction within 500 ms (see here). Because the transaction to be performed was that reading of BMA4_CHIP_ID_ADDR, I'd suspect that the problem was that the SCL or SDA line was tied low and that's why TWIM could not perform the transaction. Is this 5 ms of waiting enough for the reset of BMA421? What happens if you don't call bma4_soft_reset()? Are you able to use some logic analyzer to show what happens on the I2C bus?

And I don't entirely understand when you actually get the "Adjust the zephyr,concat-buf-size property" message. If the zephyr,concat-buf-size property is not specified, the default value of 16 should be used and this should be enough for this i2c_burst_write() call that happens underneath bma4_soft_reset(). Could you provide some more details (like why the value of 64 was needed)?

ck-telecom commented 3 years ago

I connect 5V to VCC, maybe the hardware is broken, this issue closed