Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- [breaking-change] ADC2 and ADC3 no longer allow access to VREF, VBAT, or the internal
temperature measurement (ADC2 and ADC3 do not have an internal connection for these channels)
- Improved Serial baudrate calculation to be correct for higher baudrates or lower PCLKs
- Added `SysCfg` wrapper to enforce clock enable for `SYSCFG`
- [breaking-change] gpio::ExtiPin now uses `SysCfg` wrapper instead of `SYSCFG`

### Added

Expand Down
6 changes: 4 additions & 2 deletions examples/analog-stopwatch-with-spi-ssd1306.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ extern crate panic_semihosting;
extern crate stm32f4xx_hal as hal;

use crate::hal::{
gpio::{gpioa::PA0, Edge, ExtiPin, Input, PullDown},
gpio::{gpioa::PA0, Edge, Input, PullDown},
interrupt, pac,
prelude::*,
rcc::{Clocks, Rcc},
Expand Down Expand Up @@ -79,11 +79,13 @@ fn main() -> ! {

let clocks = setup_clocks(rcc);

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

let gpioa = dp.GPIOA.split();
let gpioe = dp.GPIOE.split();

let mut board_btn = gpioa.pa0.into_pull_down_input();
board_btn.make_interrupt_source(&mut dp.SYSCFG);
board_btn.make_interrupt_source(&mut syscfg);
board_btn.enable_interrupt(&mut dp.EXTI);
board_btn.trigger_on_edge(&mut dp.EXTI, Edge::FALLING);

Expand Down
8 changes: 4 additions & 4 deletions examples/stopwatch-with-ssd1306-and-interrupts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ extern crate stm32f4xx_hal as hal;

use crate::hal::{
delay::Delay,
gpio::{gpioc::PC13, Edge, ExtiPin, Input, PullUp},
gpio::{gpioc::PC13, Edge, Input, PullUp},
i2c::I2c,
interrupt,
prelude::*,
Expand Down Expand Up @@ -60,8 +60,6 @@ enum StopwatchState {
#[entry]
fn main() -> ! {
if let (Some(mut dp), Some(cp)) = (stm32::Peripherals::take(), cortex_m::Peripherals::take()) {
dp.RCC.apb2enr.write(|w| w.syscfgen().enabled());

let rcc = dp.RCC.constrain();
let clocks = setup_clocks(rcc);
let gpiob = dp.GPIOB.split();
Expand All @@ -75,10 +73,12 @@ fn main() -> ! {
clocks,
);

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

// Create a button input with an interrupt
let gpioc = dp.GPIOC.split();
let mut board_btn = gpioc.pc13.into_pull_up_input();
board_btn.make_interrupt_source(&mut dp.SYSCFG);
board_btn.make_interrupt_source(&mut syscfg);
board_btn.enable_interrupt(&mut dp.EXTI);
board_btn.trigger_on_edge(&mut dp.EXTI, Edge::FALLING);

Expand Down
11 changes: 6 additions & 5 deletions src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

use core::marker::PhantomData;

use crate::pac::{EXTI, SYSCFG};
use crate::pac::EXTI;
use crate::syscfg::SysCfg;

/// Extension trait to split a GPIO peripheral in independent pins and registers
pub trait GpioExt {
Expand Down Expand Up @@ -85,7 +86,7 @@ pub enum Edge {

/// External Interrupt Pin
pub trait ExtiPin {
fn make_interrupt_source(&mut self, syscfg: &mut SYSCFG);
fn make_interrupt_source(&mut self, syscfg: &mut SysCfg);
fn trigger_on_edge(&mut self, exti: &mut EXTI, level: Edge);
fn enable_interrupt(&mut self, exti: &mut EXTI);
fn disable_interrupt(&mut self, exti: &mut EXTI);
Expand All @@ -97,7 +98,7 @@ macro_rules! exti_erased {
($PIN:ty, $extigpionr:expr) => {
impl<MODE> ExtiPin for $PIN {
/// Make corresponding EXTI line sensitive to this pin
fn make_interrupt_source(&mut self, syscfg: &mut SYSCFG) {
fn make_interrupt_source(&mut self, syscfg: &mut SysCfg) {
let offset = 4 * (self.i % 4);
match self.i {
0..=3 => {
Expand Down Expand Up @@ -177,7 +178,7 @@ macro_rules! exti {
($PIN:ty, $extigpionr:expr, $i:expr, $exticri:ident) => {
impl<MODE> ExtiPin for $PIN {
/// Configure EXTI Line $i to trigger from this pin.
fn make_interrupt_source(&mut self, syscfg: &mut SYSCFG) {
fn make_interrupt_source(&mut self, syscfg: &mut SysCfg) {
let offset = 4 * ($i % 4);
syscfg.$exticri.modify(|r, w| unsafe {
let mut exticr = r.bits();
Expand Down Expand Up @@ -247,7 +248,7 @@ macro_rules! gpio {
use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, toggleable};
use crate::pac::$GPIOX;

use crate::{pac::{RCC, EXTI, SYSCFG}, bb};
use crate::{pac::{RCC, EXTI}, bb, syscfg::SysCfg};
use super::{
Alternate, AlternateOD, Floating, GpioExt, Input, OpenDrain, Output, Speed,
PullDown, PullUp, PushPull, AF0, AF1, AF2, AF3, AF4, AF5, AF6, AF7, AF8, AF9, AF10,
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ pub mod signature;
#[cfg(feature = "device-selected")]
pub mod spi;
#[cfg(feature = "device-selected")]
pub mod syscfg;
#[cfg(feature = "device-selected")]
pub mod time;
#[cfg(feature = "device-selected")]
pub mod timer;
Expand Down
2 changes: 2 additions & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub use embedded_hal::prelude::*;
not(any(feature = "stm32f411", feature = "stm32f412", feature = "stm32f401",))
))]
pub use crate::dac::DacExt as _stm32f4xx_hal_dac_DacExt;
pub use crate::gpio::ExtiPin as _stm32f4xx_hal_gpio_ExtiPin;
pub use crate::gpio::GpioExt as _stm32f4xx_hal_gpio_GpioExt;
pub use crate::i2c::Pins as _stm32f4xx_hal_i2c_Pins;
pub use crate::rcc::RccExt as _stm32f4xx_hal_rcc_RccExt;
Expand All @@ -22,4 +23,5 @@ pub use crate::rcc::RccExt as _stm32f4xx_hal_rcc_RccExt;
))
))]
pub use crate::rng::RngExt as _stm32f4xx_hal_rng_RngExt;
pub use crate::syscfg::SysCfgExt as _stm32f4xx_hal_syscfg_SysCfgExt;
pub use crate::time::U32Ext as _stm32f4xx_hal_time_U32Ext;
34 changes: 34 additions & 0 deletions src/syscfg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use crate::bb;
use crate::stm32::{RCC, SYSCFG};
use core::ops::Deref;

/// Extension trait that constrains the `SYSCFG` peripheral
pub trait SysCfgExt {
/// Constrains the `SYSCFG` peripheral so it plays nicely with the other abstractions
fn constrain(self) -> SysCfg;
}

impl SysCfgExt for SYSCFG {
fn constrain(self) -> SysCfg {
unsafe {
// NOTE(unsafe) this reference will only be used for atomic writes with no side effects.
let rcc = &(*RCC::ptr());

// Enable clock.
bb::set(&rcc.apb2enr, 14);
}

SysCfg(self)
}
}

pub struct SysCfg(SYSCFG);

impl Deref for SysCfg {
type Target = SYSCFG;

#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.0
}
}