Skip to content

STM32 I2C: Replace call to wait_us by a sw loop #6538

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
wants to merge 5 commits into from

Conversation

bcostm
Copy link
Contributor

@bcostm bcostm commented Apr 4, 2018

Description

Replace the call to wait_us() with a sw loop using us_ticker_read.

This has been already done in PR #6069 but canceled due to another fix.

Tested OK with I2C ci-tests on different boards
report_CISHIELD_fix_i2c_wait.txt

cc @RobMeades Maybe verify it also on your platforms ?
cc @LMESTM

Pull request type

[X] Fix
[ ] Refactor
[ ] New target
[ ] Feature
[ ] Breaking change

@RobMeades
Copy link
Contributor

@fahim-ublox can you make sure this is OK on C030/C027?
@andreaslarssonublox I guess we should check Odin also...?

/* Timeout values for flags and events waiting loops. These timeouts are
not based on accurate values, they just guarantee that the application will
not remain stuck if the I2C communication is corrupted.
*/
#define FLAG_TIMEOUT ((int)0x1000)

/* Instead of using wait_us() which can causes issues in some cases */
#define WAIT_LOOP {uint32_t waitloop_timeout = BYTE_TIMEOUT_D2; while(--waitloop_timeout != 0);}
Copy link
Contributor

Choose a reason for hiding this comment

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

This wont be different with optimizations (different times) ? wont be optimized out?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, instead of macro , use a function. Should do the same trick, but more readable

@bcostm
Copy link
Contributor Author

bcostm commented Apr 5, 2018

I have replaced the macro by a function and added some pragma to avoid compiler optimization. Tested with ARM, IAR and GCC. The loop time is between 3us to 10us depending of the board/compiler.

@0xc0170
Copy link
Contributor

0xc0170 commented Apr 5, 2018

In some case the call to wait_us() can cause issues. The idea is to not use the us_ticker anymore but instead a simple sw loop.

I believe a problem was wait() that can cause an issue if object is created during the boot and RTOs might not be initialized.

This can be solved as its here, but looking at the wait loop implementation - it shall fix it but having the optimization set in the code, and relying on it might not be the best approach. Why can't we use us ticker api. I recall some other HAL implementation uses it - what should fix this as well. Using us ticker read function and loop until the time passes?

@bcostm
Copy link
Contributor Author

bcostm commented Apr 5, 2018

OK... I changed it by using us_ticker_read and loop timings are of course closer to the expected 1us...

0xc0170
0xc0170 previously approved these changes Apr 5, 2018
@0xc0170
Copy link
Contributor

0xc0170 commented Apr 5, 2018

/morph build

@mbed-ci
Copy link

mbed-ci commented Apr 5, 2018

Build : SUCCESS

Build number : 1667
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/6538/

Triggering tests

/morph test
/morph uvisor-test
/morph export-build
/morph mbed2-build

@mbed-ci
Copy link

mbed-ci commented Apr 5, 2018

@mbed-ci
Copy link

mbed-ci commented Apr 5, 2018

@RobMeades
Copy link
Contributor

We seem to have one I2C test failure that occurs when we include the [original version] of this PR. We're just running the test again with the latest version, back with you soon...

@LMESTM
Copy link
Contributor

LMESTM commented Apr 6, 2018

@0xc0170 @bcostm
I think that it would be great to make wait_loop part of the HAL API so that other drivers can use it as well, what do you think ?
It just happens that I need about the same :-)

@LMESTM
Copy link
Contributor

LMESTM commented Apr 6, 2018

One comment: we're assuming here that us_ticker makes use of 1 microsecond - this is tru for all STM32 targets as far as I know, nevertheless this is not a requirement in mbed

@bcostm
Copy link
Contributor Author

bcostm commented Apr 6, 2018

I think that it would be great to make wait_loop part of the HAL API so that other drivers can use it as well, what do you think ?

+1
I was thinking the same thing... Maybe place it in mbed_us_ticker_api.c ? and rename it to us_ticker_wait_loop ?

@RobMeades
Copy link
Contributor

RobMeades commented Apr 6, 2018

We've now tested with the latest version of this PR and all our tests are passing. We must have an I2C chip with slightly sensitive timing; it was a particular I2C command, RESET, that had been failing. Returning to an accurate wait was probably what we needed.

So we're OK with this PR.

@0xc0170
Copy link
Contributor

0xc0170 commented Apr 6, 2018

@RobMeades Thanks for testing and the feedback.

I was thinking the same thing... Maybe place it in mbed_us_ticker_api.c ? and rename it to us_ticker_wait_loop ?

@bulislaw @c1728p9

@0xc0170
Copy link
Contributor

0xc0170 commented Apr 6, 2018

/morph test

@mbed-ci
Copy link

mbed-ci commented Apr 6, 2018

@0xc0170
Copy link
Contributor

0xc0170 commented Apr 9, 2018

cc @studavekar - can you review the failures please?

/morph test

@mbed-ci
Copy link

mbed-ci commented Apr 9, 2018

@0xc0170
Copy link
Contributor

0xc0170 commented Apr 10, 2018

@bcostm Can you please review the test results? What commit is your branch based on?

@bcostm
Copy link
Contributor Author

bcostm commented Apr 10, 2018

I am on master branch. I have rebased this PR.

@0xc0170
Copy link
Contributor

0xc0170 commented Apr 13, 2018

/morph build

@mbed-ci
Copy link

mbed-ci commented Apr 13, 2018

Build : SUCCESS

Build number : 1745
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/6538/

Triggering tests

/morph test
/morph uvisor-test
/morph export-build
/morph mbed2-build

t1 = us_ticker_read();
do {
t2 = us_ticker_read();
elapsed = (t2 > t1) ? (t2 - t1) : ((uint64_t)t2 + 0xFFFFFFFF - t1 + 1);
Copy link
Contributor

Choose a reason for hiding this comment

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

All the above isn't necessary - just elapsed = t2 - t1; will suffice even on wrap because of the way unsigned arithmetic works.

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. Thanks for the review. I will update it.

Copy link
Contributor

Choose a reason for hiding this comment

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

are you sure ? we don't know if the ticker is 32 bits or 16 bits wide ...

Copy link
Contributor

Choose a reason for hiding this comment

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

I wasn't aware the ticker could be less than 32 bits wide, but seems it can.

But if it can be, that wrap logic wouldn't be correct. It's adding 2^32 when it sees it wrap. It should be adding 2^(ticker width), right?

I've seen similar wrap logic in other places in the tree, with both 2^16 and 2^32 increments, apparently with hard knowledge of their timer width. For this platform, it seems to be 32-bit.

Copy link
Contributor

Choose a reason for hiding this comment

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

You're right ! the bit width of timer needs to be used. In STM32 targets we have both 32-bits and 16-bits timers and the I2C driver is common for all ... I definitely think that this function should be implemented carefully and would better belong to common code in mbed hal common layer for instance.

Copy link
Contributor

Choose a reason for hiding this comment

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

If it can be 16-bit for you, I think you should be implementing us_ticker_get_info() to reveal that to the world, which I don't see in any STM32 target directory. That is relied on to get the wrap right in some existing code.

Double-checking, looks like you implement your own 16->32-bit expansion in us_ticker_16b.c. So your us_ticker_read is always 32-bit.

Copy link
Contributor

Choose a reason for hiding this comment

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

The implementation of us_ticker_get_info() is done in ticker feature branch. This should land on master very soon. So this needs to be taken into account from now on.

@mbed-ci
Copy link

mbed-ci commented Apr 14, 2018

@mbed-ci
Copy link

mbed-ci commented Apr 14, 2018

@cmonr
Copy link
Contributor

cmonr commented Apr 17, 2018

Restarting CI since it appears that PRs have been rebased since the last run.

/morph build

@mbed-ci
Copy link

mbed-ci commented Apr 17, 2018

Build : SUCCESS

Build number : 1778
Build artifacts/logs : http://mbed-os.s3-website-eu-west-1.amazonaws.com/?prefix=builds/6538/

Triggering tests

/morph test
/morph uvisor-test
/morph export-build
/morph mbed2-build

@mbed-ci
Copy link

mbed-ci commented Apr 18, 2018

/* Timeout values for flags and events waiting loops. These timeouts are
not based on accurate values, they just guarantee that the application will
not remain stuck if the I2C communication is corrupted.
*/
#define FLAG_TIMEOUT ((int)0x1000)

/* This function assumes the tick is 1 us */
Copy link
Contributor

Choose a reason for hiding this comment

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

At a minimum should also comment that it assumes it's 32-bit - not sure if@LMESTM is happy with that assumption for this patch, given his comments.

@bcostm
Copy link
Contributor Author

bcostm commented Apr 18, 2018

I close this PR and I have open Issue #6664 instead in order to have this function at mbed level and not in ST platform only.

@bcostm bcostm closed this Apr 18, 2018
@sg- sg- removed the needs: CI label Apr 18, 2018
@mbed-ci
Copy link

mbed-ci commented Apr 18, 2018

@bcostm bcostm deleted the fix_i2c_wait branch July 3, 2018 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants