-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Fixes mimxrt10xx: Wrong I2C transfer status #13819 #27896
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
Conversation
pabigot
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can confirm this fixes scanning, but I'm not convinced it's a good idea to have a delay of unclear duration before every transfer.
drivers/i2c/i2c_mcux_lpi2c.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you replace this with k_busy_wait()? It's gotta be a time-based delay, and an empty loop isn't the right way to do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, Has updated
drivers/i2c/i2c_mcux_lpi2c.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it uses the system clock frequency (600 MHz), will it work with other clock frequencies? You probably need to use clock_control_get_rate similar to mcux_lpi2c_configure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes; and the logic behind this calculation needs some explanation. Why is the numerator 1.5E12?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi,Be honest, i test many values, the 10000 * 150 / (baudrate / 1000) is an experience one. I do not know why too. But it works. bigger is maybe ok, but lower, not.
The values: the 1e6 means -> us, 10 is a simmliar ticks with (for (i=0;i<xx;i++), this will expand to 10 instructs costs about
10 ticks), the 600000000 is sure, the cpu frequency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it uses the system clock frequency (600 MHz), will it work with other clock frequencies? You probably need to use
clock_control_get_ratesimilar tomcux_lpi2c_configure.
Ok, I will update the code soon.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it uses the system clock frequency (600 MHz), will it work with other clock frequencies? You probably need to use
clock_control_get_ratesimilar tomcux_lpi2c_configure.
Hi, I have updated the macro with a function to get the CPU_FREQ, But I use CLOCK_GetCoreSysClkFreq instead, because the clock_control_get_rate can not return the core_freq, or do we need to add this into the mcux_ccm_get_subsys_rate()?
|
Please also update the PR summary to say |
pabigot
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking more closely: this approach will not work.
The solution involves generating a start condition followed by a stop condition before every call to the I2C transfer function. This will break transactions that span multiple calls, i.e. starting in one then finishing in another.
(That the cost of doing the check affects every transaction, and that the duration of the delay is not based on analysis, is also a concern: but the fact this will break I2C is what rules it out.)
Hi, I do some changes, move the delay inside the transfer body, remove the start + stop, but the delay time is neccessary still. Or Adding a judge, so we can add this delay only when run the i2c scan command? |
drivers/i2c/i2c_mcux_lpi2c.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you do this wait only when msgs->len == 0 does that fix the problem? Because that's the case that isn't being handled correctly by the HAL.
I'd still like to see the delay duration based on something that makes sense, say a specific number of cycles of the I2C clock.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, Yes , I add one if(msgs->len == 0), it works. Now the delay time is depend on CPU_FREQ & i2c's baudrate.
pabigot
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change this to:
/* Wait for the duration of 12 bits to detect a NAK after a bus
* address scan. (10 appears sufficient, 20% safety factor.)
*/
#define SCAN_DELAY_US(baudrate) (12 * USEC_PER_SEC / baudrate)
and update the name of the macro below. This decouples from the clock rate (which is irrelevant once we wait for microseconds) and makes the purpose of the delay more clear.
Hi,Yes, this macro looks more clearly now and I have tried it, it works and I have updated the new code. |
MaureenHelm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @pabigot for your help. This change looks much better now.
@CristXu please amend the commit message to indicate this change is for the mcux i2c driver, something like this:
drivers: i2c: Fix mcux driver transfer status after NACK
Adds a delay after transferring zero-length messages to correctly detect a NACK.
Updated |
Adds a delay after transferring zero-length messages to correctly detect a NACK. Signed-off-by: Crist Xu <[email protected]>
Fixes : mimxrt10xx: Wrong I2C transfer status #13819
Adding a delay between a transfer, then detect the NACK flag
Signed-off-by: [email protected] [email protected]