stm32-rs / stm32f1xx-hal

A Rust embedded-hal HAL impl for the STM32F1 family based on japarics stm32f103xx-hal
Apache License 2.0
572 stars 179 forks source link

blinky_timer_irq example broken ? #332

Open timbod7 opened 3 years ago

timbod7 commented 3 years ago

examples/blinky_timer_irq.rs doesn't work for me. I know how to fix it, but I don't understand why my fix works.

My test repo:

https://github.com/timbod7/stm32f1xx-hal-testing

demonstrates the problem using a blue pill board.

The first commit has src/main.rs as example/blinky.rs. It works as expected.

The second commit replace src/main.rs with example//blinky_timer_irq.rs.rs. This doesn't work. If I look at PC13 with an oscilloscope I can see that it pulses low for only 10us.

The third commit reorders the actions in the interrupt handler, and fixes the issue, with the LED flashing with a 2 second period as expected.

Any suggestions as to what is going on here?

vitalyvb commented 3 years ago

Could be this issue - https://developer.arm.com/documentation/ka003795/latest Interrupt may be happening twice because "interrupt clear" signal doesn't "get through" before interrupt handling routine returns.

When I debugged a similar issue, it was extremely strange - e.g. it started working if asm::nop() is called somewhere in the handler, presumably because interrupt routine became more complex and had to store extra registers on stack, and extra RAM access ensured that interrupt had cleared. Adding a bunch of nops that did not affect memory after interrupt clear also did help, and so on.

The document above suggests one of the solutions, and it's exactly what you did - clear interrupt first, and then toggle the LED.

The question is, should HAL try to mitigate this in clear_update_interrupt_flag() and similar functions...

timbod7 commented 3 years ago

@vitalyvb Thanks for the reply. That does sound like a potential cause. It does seem to depend on the build setup somehow.

Whilst example/blinky_timer_irq.rs works in the the original source repo when I run it as:

cd stm32f1xx-hal
cargo run --example blinky_timer_irq --features stm32f103,rt

yet the identical code fails as described above when run in the test repo