Skip to content

Conversation

@jmaksymowicz
Copy link
Contributor

@jmaksymowicz jmaksymowicz commented Nov 4, 2025

TODO: Needs to be tested on STM32L4x6 platforms, so far only tested on STM32N6

Description

The previous code for setting I2C speed had multiple issues - the speed was hardcoded to I2C standard mode (100 kHz) and due to a mistake the calculation failed for reference clock frequency 64 MHz and higher. Additionally, the resulting I2C clock speed was not optimal and it wasn't clear how it was calculated.

This new code makes the speed calculation process flexible, allowing for any reference clock between 8 and 400 MHz. All standard I2C bus speeds are supported (100 kHz, 400 kHz and 1 MHz). The calculation now takes into account all relevant factors, so that optimal clock speeds can be achieved.

Because this code only uses integer operations there is less precision so that you can only achieve within about 5% of the optimal clock speed in the Fast Plus mode.

I added an option to enable the analog noise filter at compile time (off by default, but we may want to enable it in the future).

The user can now set the I2C clock speed through a new API message. I decided to give the user the ability to set I2C rise time compensation value. This is because the rise time depends on external factors such as pull-up resistor value and line capacitance, so it cannot be accounted for in the driver.

Motivation and Context

JIRA: RTOS-1176

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Chore (refactoring, style fixes, git/CI config, submodule management, no code logic changes)

How Has This Been Tested?

  • Already covered by automatic testing.
  • New test added: (add PR link here).
  • Tested by hand on: armv8m55-stm32n6-nucleo

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing linter checks and tests passed.
  • My changes generate no new compilation warnings for any of the targets.

Special treatment

  • This PR needs additional PRs to work (list the PRs, preferably in merge-order).
  • I will merge this PR by myself when appropriate.

@gemini-code-assist
Copy link

Summary of Changes

Hello @jmaksymowicz, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the I2C driver for stm32l4-multi by overhauling its timing calculation mechanism. The changes address critical limitations in the previous implementation, such as hardcoded speeds and calculation inaccuracies at higher clock frequencies. The new design provides a robust and adaptable solution, enabling optimal I2C clock speeds across a broad range of reference frequencies and offering user control over speed and rise time compensation. This ensures more reliable and performant I2C communication for the platform.

Highlights

  • Improved I2C Timing Calculation: The I2C timing calculation logic has been completely rewritten to be more flexible and accurate, supporting reference clock frequencies between 8 and 400 MHz and all standard I2C bus speeds (100 kHz, 400 kHz, 1 MHz).
  • New I2C Speed API: A new API message (i2c_def) and corresponding i2c_setSpeed function have been introduced, allowing users to dynamically set the I2C clock speed and provide a rise time compensation value.
  • Analog Noise Filter Option: An option to enable an analog noise filter has been added, which is off by default but can be enabled at compile time for improved signal integrity.
  • Bug Fixes: This PR fixes previous issues where the I2C speed was hardcoded to 100 kHz and calculation errors occurred for reference clock frequencies of 64 MHz and higher.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request significantly improves the I2C timing calculation by replacing a hardcoded and buggy implementation with a flexible and more robust one. The new code correctly calculates timing parameters for various I2C speeds and reference clock frequencies. The changes are well-structured, introducing a new API for speed configuration and encapsulating the complex calculations. I have one suggestion to improve the documentation of empirically-derived values for better long-term maintainability.

Comment on lines 349 to 352
/* Regardless of frequency, the low period seems to be 3 cycles too long and high period 2 cycles too long.
* This was measured empirically. */
tSCLL = (tSCLL > (tDNF + 3)) ? (tSCLL - (tDNF + 3)) : 1;
tSCLH = (tSCLH > (tDNF + 2)) ? (tSCLH - (tDNF + 2)) : 1;

Choose a reason for hiding this comment

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

medium

These empirical correction values are 'magic numbers' that can make the code harder to maintain. While the comment mentions they were measured empirically, adding more context would be very beneficial for future developers. Could you consider expanding the comment with details about the measurement setup (e.g., hardware, chip revision), or if this is a known silicon issue, a reference to an errata sheet or application note?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added a bigger comment closer to the top of the file so if there are any problems with I2C frequency hopefully the person fixing them will see it.

@github-actions
Copy link

github-actions bot commented Nov 4, 2025

Unit Test Results

9 445 tests  ±0   8 856 ✅ ±0   48m 52s ⏱️ - 2m 29s
  545 suites ±0     589 💤 ±0 
    1 files   ±0       0 ❌ ±0 

Results for commit 24b9b75. ± Comparison against base commit c09ba79.

♻️ This comment has been updated with latest results.

Calculate I2C timing variable at runtime based on reference clock and
chosen bus speed.
Add option to enable analog noise filter at compile time.
Add API message for changing I2C speed.

JIRA: RTOS-1176
@jmaksymowicz jmaksymowicz force-pushed the jmaksymowicz/stm32-i2c-fix branch from 55a3d89 to 24b9b75 Compare November 4, 2025 10:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants