Skip to content

STM32 I2C hang #8915

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
avisconti opened this issue Jul 13, 2018 · 18 comments
Closed

STM32 I2C hang #8915

avisconti opened this issue Jul 13, 2018 · 18 comments
Assignees
Labels
bug The issue is a bug, or the PR is fixing a bug platform: STM32 ST Micro STM32 priority: medium Medium impact/importance bug
Milestone

Comments

@avisconti
Copy link
Collaborator

I can reproduce this issue very easily using the ArgonKey board, where I recently add usage of LP3943 driver to turn on/off leds at boot time. More precisely, the issue seems to happen when using the 'led blink' feature of the driver. The blink routine call the i2c_reg_update_byte(), which does a read operation on a register followed by a write operation. The STM32F4 seems to get stuck inside the i2c_stm32_transfer() routine, where a loop for all msgs in the i2c transaction is performed.

In addition to the above, I noticed that the issue showed up after the cc41916 (i2c: stm32: check messages before starting transmission) was committed, but I think that this commit just highlighted some weaknesses already present somewhere.

@nashif nashif added bug The issue is a bug, or the PR is fixing a bug priority: medium Medium impact/importance bug labels Jul 13, 2018
@nashif nashif added the platform: STM32 ST Micro STM32 label Jul 24, 2018
@ydamigos
Copy link
Collaborator

ydamigos commented Aug 5, 2018

Does PR #9301 helps with this issue?

@avisconti
Copy link
Collaborator Author

@ydamigos
I can try it out. The area of my error is pretty close to this fix.
Thanks for reporting it to me!

@avisconti
Copy link
Collaborator Author

avisconti commented Aug 6, 2018

@erwango @ydamigos
Unfortunately the #9301 fix does not solve my issue, but I have some information to share.
As you know I'm using I2C_STM32_INTERRUPT and I go in Standard Mode (100k)
Pay attention to 4 and 5 especially.

  1. The driver stops forever on sem_take() in write_msg(). I verified that the driver
    restarts correctly if I generate the sem_give() manually. Ebentually it stops again.
  2. I verified the sem_give() never arrives (I added counters in the T() and G() ops and
    saw that there is no G() for the last T() )
  3. If I use sem_take with a timeout everything seems to work. But NOT BECAUSE the
    sem_give exit for timeouts! Instead the sem_give() arrives in this case.
    I strongly believe this happens just because the sem_give w timeout takes longer to execute.
    Adding a delay creates the same effect.
  4. I have traced the bad behaviour with a scope and I see in fact that at the end there is
    a bad I2C transaction (START followed by a STOP). This appears to be the root cause of
    the problem: probably there is no event generation for the s/w that never execute sem_give().
  5. The issue seems to be related to the bitrate. It happens in Standard Mode (SM = 100k) but
    NEVER in fast mode (FM = 400k)!
    What I see on the scope is that in SM the transactions are closer one to the other
    (Tbuf == 5.3 us) while in FM Tbuf is 8.4us or more.

@avisconti
Copy link
Collaborator Author

zephyr_hts221_sm_bad

@avisconti avisconti reopened this Aug 6, 2018
@avisconti
Copy link
Collaborator Author

avisconti commented Aug 6, 2018

As you can see in the scope trace the last transaction is malformed, and does not generate any event for the s/w which hangs.

I can reproduce the issue even on sensor HTS221 on a different I2C bus, provided that I configure the bus in Standard Mode (100k bitrate)

@erwango
Copy link
Member

erwango commented Aug 6, 2018

If this is happening at low speed, isn't it linked to GPIO speed being too fast now (and producing rebounds)? Can you have a try?
I know this kind of issue could happen at low speed. Also at low speed you should not have too long wires..

@avisconti
Copy link
Collaborator Author

Well, are you talking about the gpio speed we changed for SPI/I2S?
These pins are different, and are used for I2C. They are still at low speed. Actually I had thought to change them to fast speed as well, but at the moment they are still low speed.

@erwango
Copy link
Member

erwango commented Aug 7, 2018

My bad, mixed topics. Forget about it.

@nashif
Copy link
Member

nashif commented Aug 14, 2018

@erwango any update on this?

@erwango
Copy link
Member

erwango commented Aug 16, 2018

@nashif ,

@avisconti working on it, but in holidays right now. Should be back next week if i'm correct.

@nashif nashif added this to the v1.13.0 milestone Aug 26, 2018
@nashif
Copy link
Member

nashif commented Aug 27, 2018

@avisconti any updates?

@avisconti
Copy link
Collaborator Author

@nashif
Just back today from my holidays and just trying to recollect all my memories...
The update is that we have found that this issue seems very similar to a known I2C issue. I asked the STM team to cross verify this, but everyone was in vacation or was going to. So, I will try to push for it again and hopefully we will be able to conclude something very soon!

@avisconti
Copy link
Collaborator Author

@nashif @erwango
I think that this issue is going to take a little bit more. In fact, it will need some more discussion with design team currently in vacation.

The issue seems to be related to repeated start timing violation (tSU;STA) in some particular conditions. We still need to confirm this. The issue happens in Standard-mode only (no issue in Fast-mode). A
possible workaround consists to reduce the frequency down to 88 kHz (use LL_I2C_SetClockPeriod() to set properly the CCR register to relax the SCL clock timing).

@nashif
Copy link
Member

nashif commented Aug 29, 2018

ok, moving to 1.14

@nashif nashif modified the milestones: v1.13.0, v1.14.0 Aug 29, 2018
@psidhu
Copy link
Contributor

psidhu commented Sep 6, 2018

I'm running into the same or similar issue, however my issue takes quite a bit of time to reproduce (~2316500ms) blinking at a rate of 500ms (after ~4633*2 transfers). I've also seen it trigger as low as after ~2000 transfers.

To blink an led off of a port expander, I have to do both a i2c_reg_write_byte and i2c_reg_update_byte. One of these causes the following call stack:
i2c_stm32_transfer() -> stm32_i2c_msg_write() -> msg_done() and hangs on while (!LL_I2C_IsActiveFlag_TC(i2c) && !LL_I2C_IsActiveFlag_TCR(i2c)) in the msg_done() function.

I have also seen something similar with I2C_STM32_INTERRUPT. This is at 400kHz.

@psidhu
Copy link
Contributor

psidhu commented Sep 7, 2018

I solved my issue by locking around each transfer with irq_lock(). I should point out that there are no i2c transfers going on in any irq/thread I have so I'm not sure why locking would help (unless each 8bit load into the buffer isn't atomic).

@avisconti
Copy link
Collaborator Author

@psidhu
If it happens at Fast mode (400KHz) it is a totally different issue. Glad you solved it anyway.

@avisconti
Copy link
Collaborator Author

I'm going to close this issue as it is open since long time. I'm summarizing all the findings hereafter:

  • Issue cause: suspected h/w bug in STM32F4xx SoC family, even if not clearly identified.
  • It happens only in Standard mode (100KHz). This issue DOES NOT happen in fast mode (400KHz).
  • Suggested workaround:
    Relax the I2C clock to something like 88KHz using LL_I2C_SetClockPeriod() routine that set the
    CCR register to change Thigh (= CCR * TPCLK1) and Tlow (= CCR * TPCLK1) values.
    For example, if TPCLK1 = 125ns CCR may be set to 45: Thigh and Tlow = 11250ns, hence I2C
    clock becomes close to 88KHz.
    The LL_I2C_SetClockPeriod() should be invoked inside stm32_i2c_configure_timing() inside file
    i2c_ll_stm32_v1.c, (and only in I2C_SPEED_STANDARD case).

avisconti added a commit to avisconti/zephyr that referenced this issue Nov 14, 2018
As explained in issue zephyrproject-rtos#8915 the STM32F4xx SoC family I2C
does not work well in Standard mode (100KHz). So let's
configure i2c3 in Fast mode (400KHz).

Signed-off-by: Armando Visconti <[email protected]>
nashif pushed a commit that referenced this issue Nov 14, 2018
As explained in issue #8915 the STM32F4xx SoC family I2C
does not work well in Standard mode (100KHz). So let's
configure i2c3 in Fast mode (400KHz).

Signed-off-by: Armando Visconti <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug The issue is a bug, or the PR is fixing a bug platform: STM32 ST Micro STM32 priority: medium Medium impact/importance bug
Projects
None yet
Development

No branches or pull requests

5 participants