Skip to content

i2c_ll_stm32_v1 driver gets stuck #12261

@vslapik

Description

@vslapik

Describe the bug
i2c_ll_stm32_v1 driver gets stuck in busy wait during i2c transfer

To Reproduce
I use stm32_min_dev board with MPU6050 attached to I2C_1. There are other issues which prevent me from using existing MPU6050 driver so I'm working directly with this sensor via i2c functions. I managed to get implement workarounds regarding MPU6050 but seems there are still issues in core i2c driver for smt32, the minimal code below makes the board completely stuck in the second i2c_reg_write_byte:

static int cmd_reset(const struct shell *shell, size_t argc, char **argv)
{
       struct device *i2c = device_get_binding("I2C_1");
       __ASSERT_NO_MSG(i2c);

       if (i2c_reg_write_byte(i2c, 0x68, 0x6B, 0x80) < 0) {
           printk("Failed to wake up chip 1.\n");
           return -1;
       }

//       k_busy_wait(100);
       k_busy_wait(10);

       u8_t v;
       if (i2c_reg_read_byte(i2c, 0x68, 0x6B, &v) < 0) {
           printk("Failed to wake up chip 2.\n");
           return -1;
       }
       k_sleep(10);

       if (i2c_reg_write_byte(i2c, 0x68, 0x6B, 0x00) < 0) {
           printk("Failed to wake up chip 3.\n");
           return -1;
       }

       return 0;
}

Expected behavior
There are probably issues with MPU6050 reset logic in the code above here but I assume i2c functions must never hang and return error instead.

Additional context
The corresponded stack trace at the moment of hang is below:

#0  0x0800972a in LL_I2C_IsActiveFlag_SB (I2Cx=0x40005400) at /home/vslapik/proj/zephyr/ext/hal/st/stm32cube/stm32f1xx/drivers/include/stm32f1xx_ll_i2c.h:1186
#1  0x08009900 in stm32_i2c_msg_write (dev=0x20002098 <__device_i2c_stm32_1>, msg=0x2000103c <shell_uart_stack+1604>, next_msg_flags=0x0, saddr=104) at /home/vslapik/proj/zephyr/drivers/i2c/i2c_ll_stm32_v1.c:319
#2  0x08009f2a in i2c_stm32_transfer (dev=0x20002098 <__device_i2c_stm32_1>, msg=0x2000103c <shell_uart_stack+1604>, num_msgs=1 '\001', slave=104) at /home/vslapik/proj/zephyr/drivers/i2c/i2c_ll_stm32.c:130
#3  0x0800046c in _impl_i2c_transfer (dev=0x20002098 <__device_i2c_stm32_1>, msgs=0x2000103c <shell_uart_stack+1604>, num_msgs=1 '\001', addr=104) at /home/vslapik/proj/zephyr/include/i2c.h:227
#4  0x08000576 in i2c_transfer (dev=0x20002098 <__device_i2c_stm32_1>, msgs=0x2000103c <shell_uart_stack+1604>, num_msgs=1 '\001', addr=104) at zephyr/include/generated/syscalls/i2c.h:15
#5  0x0800049e in i2c_write (dev=0x20002098 <__device_i2c_stm32_1>, buf=0x2000105c <shell_uart_stack+1636> "k", num_bytes=2, addr=104) at /home/vslapik/proj/zephyr/include/i2c.h:370
#6  0x0800054a in i2c_reg_write_byte (dev=0x20002098 <__device_i2c_stm32_1>, dev_addr=104, reg_addr=107 'k', value=0 '\000') at /home/vslapik/proj/zephyr/include/i2c.h:502
#7  0x08000616 in cmd_reset (shell=0x800e544 <shell_uart>, argc=1, argv=0x200010f4 <shell_uart_stack+1788>) at ../src/main.c:70
#8  0x08002e6e in exec_cmd (shell=0x800e544 <shell_uart>, argc=1, argv=0x200010f4 <shell_uart_stack+1788>, help_entry=...) at /home/vslapik/proj/zephyr/subsys/shell/shell.c:563
#9  0x08003174 in execute (shell=0x800e544 <shell_uart>) at /home/vslapik/proj/zephyr/subsys/shell/shell.c:735
#10 0x0800349a in state_collect (shell=0x800e544 <shell_uart>) at /home/vslapik/proj/zephyr/subsys/shell/shell.c:866
#11 0x08003a58 in shell_process (shell=0x800e544 <shell_uart>) at /home/vslapik/proj/zephyr/subsys/shell/shell.c:1276
#12 0x08003932 in shell_thread (shell_handle=0x800e544 <shell_uart>, arg_log_backend=0x1, arg_log_level=0x0) at /home/vslapik/proj/zephyr/subsys/shell/shell.c:1167
#13 0x08000680 in _thread_entry (entry=0x800381b <shell_thread>, p1=0x800e544 <shell_uart>, p2=0x1, p3=0x0) at /home/vslapik/proj/zephyr/lib/thread_entry.c:29
#14 0x0800381a in instance_uninit (shell=0x800381b <shell_thread>) at /home/vslapik/proj/zephyr/subsys/shell/shell.c:1110
#15 0xb086b580 in ?? ()

Apparently the CPU is unable to generate i2c start condition, it asks for it in line 318 and spins forever on polling corresponded bit a line below.

zephyr/drivers/i2c/i2c_ll_stm32_v1.c:

317 if (msg->flags & I2C_MSG_RESTART) {
318 LL_I2C_GenerateStartCondition(i2c);
319 while (!LL_I2C_IsActiveFlag_SB(i2c)) {
320  ;
321 } 

I managed to get a capture of what is happening on pins at the moment issues appears. Looks like cpu was not able to generate i2c stop condition in the preceding transaction:
screenshot_2019-01-02_18-32-54

Metadata

Metadata

Assignees

Labels

area: I2CbugThe issue is a bug, or the PR is fixing a bugplatform: STM32ST Micro STM32priority: lowLow impact/importance bug

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions