Skip to content

Fix SysCfg hardfault, Add I2C Fast Mode Plus enable method #221

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

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

Conversation

boondocklabs
Copy link
Contributor

The SysCfg peripheral used bit banding to set the APB2 peripheral clock enable bit which fails on an assertion on a G431KBT (have not tested on other chips, but I suspect they would do the same). This takes a mutable reference to Rcc in SysCfg::constrain and uses safe accessors to enable the clock.

Updated and tested the button example which is all that uses SysCfg.

[INFO ] System clock frequency: 168000000 (stm32_foc stm32-foc/src/main.rs:138)
[DEBUG] Write 20007FB0 (stm32g4xx_hal stm32g4xx-hal/src/bb.rs:42)
[ERROR] panicked at /Users/fuzz/wave/stm32g4xx-hal/src/bb.rs:44:5:
assertion failed: (PERI_ADDRESS_START..=PERI_ADDRESS_END).contains(&addr) (panic_probe panic-probe-1.0.0/src/lib.rs:104)
Firmware exited unexpectedly: Multiple
Core 0
    Frame 0: HardFault_ @ 0x08006394
       /Users/fuzz/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cortex-m-rt-0.7.5/src/lib.rs:1103:1
    Frame 1: HardFault <Cause: Escalated UsageFault <Cause: Undefined instruction>> @ 0x08005ce2```

The `SysCfg` peripheral used bit banding to set the APB2 peripheral clock enable bit which fails on an assertion on a G431KBT (have not tested on other chips, but I suspect they would do the same). This takes a mutable reference to `Rcc` in `SysCfg::constrain` and uses safe accessors to enable the clock.

Updated and tested the button example which is all that uses SysCfg.

```[INFO ] Configuring PLL (stm32_foc stm32-foc/src/main.rs:132)
[INFO ] System clock frequency: 168000000 (stm32_foc stm32-foc/src/main.rs:138)
[DEBUG] Write 20007FB0 (stm32g4xx_hal stm32g4xx-hal/src/bb.rs:42)
[ERROR] panicked at /Users/fuzz/wave/stm32g4xx-hal/src/bb.rs:44:5:
assertion failed: (PERI_ADDRESS_START..=PERI_ADDRESS_END).contains(&addr) (panic_probe panic-probe-1.0.0/src/lib.rs:104)
Firmware exited unexpectedly: Multiple
Core 0
    Frame 0: HardFault_ @ 0x08006394
       /Users/fuzz/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cortex-m-rt-0.7.5/src/lib.rs:1103:1
    Frame 1: HardFault <Cause: Escalated UsageFault <Cause: Undefined instruction>> @ 0x08005ce2```
Comment on lines 58 to 62
dp.DBGMCU.cr().modify(|_, w| {
w.dbg_sleep().set_bit();
w.dbg_stop().set_bit();
w.dbg_standby().set_bit()
});
Copy link
Member

Choose a reason for hiding this comment

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

probe-rs should do it automatically on connect.

Copy link
Member

Choose a reason for hiding this comment

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

@boondocklabs , if the DMA enable thing is enough, then how about we do only that? (Same for #214 i presume)

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've removed the DBGMCU modification, and left the DMA enable in the button example. Tested on a G431KB without explicit DGBMCU modification and it does not hardfault as long as the DMA enable workaround is there.

@boondocklabs
Copy link
Contributor Author

What probe software do you use? probe-rs should do it automatically on connect.

I use probe-rs, but it does not work with wfi() as is. Setting flags in DBGMCU explicitly is probably not necessary as I assume probe-rs does that, but enabling DMA clock on AHB is the trick to get it working. Without it, RTT does not connect.

DMA clock trick works on G431 and G474

The isb after wfi trick didn't work either. Lots of discussion about it on probe-rs/probe-rs#350 (comment)

src/syscfg.rs Outdated
}
fn constrain(self, rcc: &mut Rcc) -> SysCfg {
// Enable SYSCFG peripheral clock in APB2ENR register
rcc.apb2enr().modify(|_, w| w.syscfgen().set_bit());
Copy link
Member

Choose a reason for hiding this comment

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

I have not tinkered with the SysCfg, but is there any reason to handle this different from for example how the usarts are enabled. So something like this?

SYSCFG::enable(rcc);
SYSCFG::reset(rcc);

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'll take a look!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Pushed a change to use Enable and Reset traits rather than direct register access

@boondocklabs boondocklabs changed the title Fix SysCfg hardfault Fix SysCfg hardfault, Add I2C Fast Mode Plus enable method Aug 14, 2025
//!
//! The I2C bus is configured with Fast Mode Plus (FMP) enabled in SysCfg, and a 1MHz I2C clock rate.
//!
//! ```DEFMT_LOG=debug cargo run --release --example rand --features stm32g431,defmt -- --chip STM32G431KBTx```
Copy link
Member

Choose a reason for hiding this comment

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

This is not the rand example :)

.vos(stm32g4xx_hal::pwr::VoltageScale::Range1 { enable_boost: true })
.freeze();

let pll_cfg = hal::rcc::PllConfig {
Copy link
Member

Choose a reason for hiding this comment

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

Do you think it would make sense and be possible to use the HSI so as not to require an external clock source?

let mut syscfg = dp.SYSCFG.constrain(&mut rcc);

// Enable Fast Mode Plus for I2C1
syscfg.i2c_fmp_enable::<1>(true);
Copy link
Member

Choose a reason for hiding this comment

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

How does the user figure out if they should pass a 1 here or something else?

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