Fix repeated start for transactional I2C API on STM32 devices with I2C v2 #15394
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary of changes
I noticed that there's an issue in the new STM32 I2C HAL added by #15350 . Trying to do a repeated start using the transactional API:
simply does not work:
This is because the code in get_hal_xfer_options() was returning
I2C_LAST_FRAME
for the case of stop=false, which is patently wrong -- it should beI2C_FIRST_FRAME
, to indicate that we want a start condition but not a stop. I think I inherited this code from the original implementation, but I should have trusted my gut that this wasn't right...However, that wasn't the only issue. Simply changing I2C_LAST_FRAME to I2C_FIRST_FRAME did fix the repeated starts, but created another issue where some of the test cases would time out trying to do I2C operations. It turns out there's some really wacky logic in the STM32 HAL code where, if you pass that constant and it detects that the previous transfer was the same type of transfer, it simply won't set the START flag. Which... causes it to hang forever and not send any data. Really not sure why it does this. Seriously, I'm scratching my head.
Luckily, the fix is pretty simple: use
I2C_OTHER_FRAME
instead ofI2C_FIRST_FRAME
, which activates additional logic which disables the other logic which cancels the start condition. So, we really just want to be using OTHER_FRAME everywhere.With the new code, I can generate repeated start conditions properly:
Impact of changes
Migration actions required
Documentation
None (bugfix)
Pull request type
Test results
I ran my test suite here and it passed!
Reviewers
@0xc0170