From cbc97758e391d981d497bf37fe63b5a35913c115 Mon Sep 17 00:00:00 2001 From: Matous Hybl Date: Wed, 9 Nov 2022 14:10:46 +0100 Subject: [PATCH 1/2] stm32: Fix watchdog division by zero for 256 prescaler, add watchdog example for H7 --- embassy-stm32/src/wdg/mod.rs | 8 ++++---- examples/stm32h7/src/bin/wdg.rs | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 examples/stm32h7/src/bin/wdg.rs diff --git a/embassy-stm32/src/wdg/mod.rs b/embassy-stm32/src/wdg/mod.rs index 85176eef..92b9a5ca 100644 --- a/embassy-stm32/src/wdg/mod.rs +++ b/embassy-stm32/src/wdg/mod.rs @@ -13,12 +13,12 @@ pub struct IndependentWatchdog<'d, T: Instance> { const MAX_RL: u16 = 0xFFF; /// Calculates maximum watchdog timeout in us (RL = 0xFFF) for a given prescaler -const fn max_timeout(prescaler: u8) -> u32 { +const fn max_timeout(prescaler: u16) -> u32 { 1_000_000 * MAX_RL as u32 / (LSI_FREQ.0 / prescaler as u32) } /// Calculates watchdog reload value for the given prescaler and desired timeout -const fn reload_value(prescaler: u8, timeout_us: u32) -> u16 { +const fn reload_value(prescaler: u16, timeout_us: u32) -> u16 { (timeout_us / prescaler as u32 * LSI_FREQ.0 / 1_000_000) as u16 } @@ -33,12 +33,12 @@ impl<'d, T: Instance> IndependentWatchdog<'d, T> { // Find lowest prescaler value, which makes watchdog period longer or equal to timeout. // This iterates from 4 (2^2) to 256 (2^8). let psc_power = unwrap!((2..=8).find(|psc_power| { - let psc = 2u8.pow(*psc_power); + let psc = 2u16.pow(*psc_power); timeout_us <= max_timeout(psc) })); // Prescaler value - let psc = 2u8.pow(psc_power); + let psc = 2u16.pow(psc_power); // Convert prescaler power to PR register value let pr = psc_power as u8 - 2; diff --git a/examples/stm32h7/src/bin/wdg.rs b/examples/stm32h7/src/bin/wdg.rs new file mode 100644 index 00000000..2b0301aa --- /dev/null +++ b/examples/stm32h7/src/bin/wdg.rs @@ -0,0 +1,24 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::*; +use embassy_executor::Spawner; +use embassy_stm32::wdg::IndependentWatchdog; +use embassy_time::{Duration, Timer}; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_stm32::init(Default::default()); + info!("Hello World!"); + + let mut wdg = IndependentWatchdog::new(p.IWDG1, 20_000_000); + + unsafe { wdg.unleash() }; + + loop { + Timer::after(Duration::from_secs(1)).await; + unsafe { wdg.pet() }; + } +} From 99682d313b54409c33d471e066ef6aba9f628a68 Mon Sep 17 00:00:00 2001 From: Matous Hybl Date: Tue, 25 Oct 2022 09:47:30 +0200 Subject: [PATCH 2/2] Disable MMC interrupts MMC interrupts can cause firmware hangup - refer to: https://github.com/stm32-rs/stm32h7xx-hal/issues/275 for more information --- embassy-stm32/src/eth/v2/mod.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs index a81ee118..5b76d1e7 100644 --- a/embassy-stm32/src/eth/v2/mod.rs +++ b/embassy-stm32/src/eth/v2/mod.rs @@ -116,6 +116,24 @@ impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, T, mac.macqtx_fcr().modify(|w| w.set_pt(0x100)); + // disable all MMC RX interrupts + mac.mmc_rx_interrupt_mask().write(|w| { + w.set_rxcrcerpim(true); + w.set_rxalgnerpim(true); + w.set_rxucgpim(true); + w.set_rxlpiuscim(true); + w.set_rxlpitrcim(true) + }); + + // disable all MMC TX interrupts + mac.mmc_tx_interrupt_mask().write(|w| { + w.set_txscolgpim(true); + w.set_txmcolgpim(true); + w.set_txgpktim(true); + w.set_txlpiuscim(true); + w.set_txlpitrcim(true); + }); + mtl.mtlrx_qomr().modify(|w| w.set_rsf(true)); mtl.mtltx_qomr().modify(|w| w.set_tsf(true));