Skip to content

stm32: Fix pyb.CAN BRS baud rate, make calculation more forgiving.#16544

Merged
dpgeorge merged 3 commits into
micropython:masterfrom
projectgus:bugfix/stm32_canfd_brs
Jan 17, 2025
Merged

stm32: Fix pyb.CAN BRS baud rate, make calculation more forgiving.#16544
dpgeorge merged 3 commits into
micropython:masterfrom
projectgus:bugfix/stm32_canfd_brs

Conversation

@projectgus
Copy link
Copy Markdown
Contributor

@projectgus projectgus commented Jan 8, 2025

Summary

  • Fixes Stm32 CAN-FD faulty timing configuration #16330. Thanks @albertstoewer for the very comprehensive bug report.
  • As part of verifying the fix, I realised the baud rate calculations are very unforgiving. Have added a small amount of error tolerance, which allowed me to set desired baud rates on STM32H723G.
  • Similarly, the error when a baudrate couldn't be achieved was hard to debug on CAN-FD as the calculation is repeated twice (once for the Classic baud rate and once for BRS). Added the failing rate to the error message.

Testing

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jan 8, 2025

Code size report:

   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:   +40 +0.010% PYBV10
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO_W
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

@projectgus projectgus force-pushed the bugfix/stm32_canfd_brs branch from dcb01e9 to ef672a8 Compare January 8, 2025 02:12
Comment thread ports/stm32/pyb_can.c
mp_int_t baud_err = baudrate - calc_baud;
mp_int_t sample_err = sample_point - calc_sample;
if (abs(baud_err) < max_baud_error &&
abs(sample_err) < MAX_SAMPLE_ERROR) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What happens if there's an exact parameter match but it's not used because this algorithm finds a "close enough" match first? Maybe it needs to have a set of parameters "best match so far" and then it searches all options until it finds an exact match, or at the end falls back to a "close enough" match.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I worried about this too, but I think the short answer is nothing noticeable. The error tolerances are pretty small: An unnecessary .1% baud rate error should still work fine unless the two nodes were already very marginal, and the chosen sample point should still match the argument when rounded to the nearest percent (the sample point argument doesn't support any higher precision than this).

(That said, the current version of the machine.CAN calculation does do the "track best option" you're describing, but that's mostly so that it can accept >.1% deviations rather than failing there as well. Although, after writing the simpler version here I was thinking about throwing that out to save code size. But I could add it to this PR instead, if you prefer. There's some small chance of regression though, as it's quite different.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Very Serious CAN users will likely always use the other configuration method (brp, bs1, bs2) anyway.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Very Serious CAN users will likely always use the other configuration method (brp, bs1, bs2) anyway.

Yes that's a good point. So I guess it's fine to keep the code here as you have it, but maybe it's then worth documenting the fact that specifying baudrate will only get it to within 0.1% and if very precise timing is needed then it's better to specify bs1/bs2/brp.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Great idea, have added docs for this change

@projectgus projectgus force-pushed the bugfix/stm32_canfd_brs branch 4 times, most recently from bc62e17 to 8e5b573 Compare January 15, 2025 07:26
Was initialising using the Classic CAN bs1/bs2 value, incorrectly.

Signed-off-by: Angus Gratton <[email protected]>
Not every baudrate or sample point combination has an exact match,
but getting within 1% on sample point and .1% on baud rate should
always be good enough.

Because the search goes from shorter bit periods (lowest brp) and
increases, the first match which meets this criteria should still mostly be
the best available.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <[email protected]>
This is redundant for bxCAN, but for CAN-FD with BRS it's otherwise unclear
which set of parameters (baudrate & sample_point or brs_baudrate &
brs_sample_point) failed to match. This makes finding a valid combination
extra annoying.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <[email protected]>
@dpgeorge dpgeorge force-pushed the bugfix/stm32_canfd_brs branch from 8e5b573 to 221a4ec Compare January 17, 2025 01:14
@dpgeorge dpgeorge merged commit 221a4ec into micropython:master Jan 17, 2025
@projectgus projectgus deleted the bugfix/stm32_canfd_brs branch January 17, 2025 06:25
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.

Stm32 CAN-FD faulty timing configuration

2 participants