Skip to content
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

Fix off-by-one in the allowed range of the spi clock calculations #3266

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

TethysSvensson
Copy link

@TethysSvensson TethysSvensson commented Mar 17, 2025

Thank you for your contribution!

We appreciate the time and effort you've put into this pull request.
To help us review it efficiently, please ensure you've gone through the following checklist:

Submission Checklist 📝

  • I have updated existing examples or added new ones (if applicable).
  • I have used cargo xtask fmt-packages command to ensure that all changed code is formatted correctly.
  • My changes were added to the CHANGELOG.md in the proper section.
  • I have added necessary changes to user code to the Migration Guide.
  • My changes are in accordance to the esp-rs developer guidelines

Extra:

Pull Request Details 📖

Description

The actual clock value is apb_clk/(SPI_CLKDIV_PRE + 1)/(SPI_CLKCNT_N + 1). The loop in question tries to brute-force a value for SPI_CLKCNT_N, however the +1 is corrected later in the code, which means that the valid range for n in this loop is 1..=64. However there is also an earlier check earlier, that guarantees that n=1 would never be an optimal choice.

This also matches the behavior from apache/incubator-nuttx which this code was inspired by.

Testing

I have run this code before and after the change:

    let spi_config = spi::master::Config::default().with_frequency(Rate::from_hz(78125));
    println!("spi_config = {spi_config:?}");

Before this change, the values were SPI_CLKDIV_PRE=15, SPI_CLKDIV_N=62, after this change the values were SPI_CLKDIV_PRE=15, SPI_CLKDIV_N=63.

Copy link
Contributor

@bugadani bugadani left a comment

Choose a reason for hiding this comment

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

Thanks! We should probably test the effect of this PR somehow. If you'd add a HIL test, that would be great, but I can do it, too if you prefer not faffing with those.

@TethysSvensson
Copy link
Author

TethysSvensson commented Mar 17, 2025

I don't really know how to do that. You have edit rights to my PR, or you could do it afterwards.

@TethysSvensson
Copy link
Author

@bugadani If you can tell me which tests you want me to add, I can try to see if I can make sense of it.

@bugadani
Copy link
Contributor

You don't need to, I'll get to this eventually, sorry for the delay :)

@bugadani
Copy link
Contributor

I did end up modifying the frequency validation as well, as it's somewhat related to how we calculate the dividers. This means I probably shouldn't be one of the people approving the PRs. Thanks for noticing the issue, though!

@bugadani bugadani force-pushed the tethys/spi-off-by-one branch from 4b66ebe to d1fed98 Compare March 19, 2025 16:25
@TethysSvensson
Copy link
Author

@bugadani Should I be doing anything?

@bugadani
Copy link
Contributor

No, two team members will review this and most likely merge it as is, or maybe I'll be told off for changing more than I should have :) Either way, we'll handle the rest.

Copy link
Contributor

@bjoernQ bjoernQ left a comment

Choose a reason for hiding this comment

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

LGTM

// those values are not currently supported by the divider calculation.
let max_divider = 16 * 64; // n * pre

if self.frequency < source_freq / max_divider || self.frequency > source_freq / min_divider
Copy link
Author

Choose a reason for hiding this comment

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

The old code allowed a bit of undershoot. The minimum value is 78.125kHz, but the old code allowed 70kHz as well.

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.

3 participants