Skip to content

Conversation

@CristXu
Copy link
Contributor

@CristXu CristXu commented Aug 31, 2020

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]

@CristXu CristXu requested a review from MaureenHelm as a code owner August 31, 2020 01:49
@CristXu CristXu linked an issue Aug 31, 2020 that may be closed by this pull request
Copy link
Contributor

@pabigot pabigot left a 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.

Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, Has updated

Copy link
Member

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.

Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Ok, I will update the code soon.

Copy link
Contributor Author

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.

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()?

@MaureenHelm
Copy link
Member

Please also update the PR summary to say Fixes #xxxxx
https://docs.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue

@CristXu CristXu changed the title bug-fix: mimxrt10xx: Wrong I2C transfer status Fixes mimxrt10xx: Wrong I2C transfer status #13819 Sep 1, 2020
Copy link
Contributor

@pabigot pabigot left a 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.)

@CristXu
Copy link
Contributor Author

CristXu commented Sep 2, 2020

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?

Copy link
Contributor

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.

Copy link
Contributor Author

@CristXu CristXu Sep 2, 2020

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.

Copy link
Contributor

@pabigot pabigot left a 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.

@CristXu
Copy link
Contributor Author

CristXu commented Sep 2, 2020

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.

Copy link
Member

@MaureenHelm MaureenHelm left a 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.

@CristXu
Copy link
Contributor Author

CristXu commented Sep 2, 2020

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

@MaureenHelm MaureenHelm added this to the v2.4.0 milestone Sep 2, 2020
Adds a delay after transferring zero-length messages to
correctly detect a NACK.

Signed-off-by: Crist Xu <[email protected]>
@carlescufi carlescufi merged commit 6fcd5b5 into zephyrproject-rtos:master Sep 3, 2020
@MaureenHelm MaureenHelm deleted the rt10xx-iic branch September 3, 2020 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mimxrt10xx: Wrong I2C transfer status

4 participants