stm32-rs / stm32f3xx-hal

A Rust embedded-hal HAL for all MCUs in the STM32 F3 family
https://crates.io/crates/stm32f3xx-hal
Apache License 2.0
164 stars 67 forks source link

Panic or crash when creating a timer with MHz frequencies #333

Closed NomisIV closed 1 year ago

NomisIV commented 1 year ago

First of all, I would just like to add that I'm not very experienced with embedded rust, and I might just be missing something trivial. However, I have looked through all the examples in this repo, and read the relevant pages in the crate documentation, but I'm none the wiser.

I'm trying to create a timer for use with the ws2812-timer-delay crate, which requires a timer running at 3MHz. When I try to implement this timer, the board doesn't do anything, and I've narrowed the problem down to the second line in this snippet.

let mut led_timer = Timer::new(c.device.TIM1, clocks, &mut rcc.apb2);
led_timer.start::<Nanoseconds>(3.MHz().to_duration().unwrap());

If I comment it out, the code works, but if I include it, the board just "freezes" which I'm assuming means it has panicked or crashed. If I change it to Microseconds and 3.kHz(), the board works, but I can't use a clock of 3kHz.

In case it is relevant, the board in question is an STM32F303CB (On an OLKB planck rev6 board)

Is this behavior expected, and in that case why? Otherwise, am I doing something wrong, and how would I go about making a 3MHz timer?

Sh3Rm4n commented 1 year ago

Okay, so this is definitely a bug. I've found out the cause. Thanks for the reports. The panic is caused by a division of 0, which was caused by an unsigned integer overflow ... :(

I've come up with a fix, will open an MR soon (I hope)

But in addition to the bug, I advise you to increase the Bus Clock speed of which the timer is connected to (PCLK2 in this case AFAIK), so that the resolution of the timer frequency is high enough. E.g 3.MHz with a rcc.cfgr.pclk2(8.MHz()) might result into 4 MHz.

Sadly, even with my fix, setting the resolution like this through the current API is not very precise. Especially for timer frequencies close to the peripheral bus clock speed.

Maybe I should expose API to set the psc and the arr values directly.

Sh3Rm4n commented 1 year ago

I've released version v0.9.2, which includes the fixes. Can you report, if this fixes your problem?

https://crates.io/crates/stm32f3xx-hal/0.9.2

NomisIV commented 1 year ago

Seems to work now! Thanks a lot for the quick response and fix! :D

NomisIV commented 1 year ago

For the record, I used rcc.cfgr.pclk2(24.MHz()), and it seems to work well enough to control the ws2812 leds

Sh3Rm4n commented 1 year ago

Thanks! :) You were lucky, that I was already working on this project that day, which I've neglected because of lack of time the last months :see_no_evil: :grinning: