ソースを参照

Proposal for setting the IO Slew Rate (#267)

* Proposal for setting the IO Slew Rate

Fixes #266

* Added a change-log entry, changed the speed enum names

* cargo fmt pass
Colette Kerr 3 年 前
コミット
c001f85c33
2 ファイル変更42 行追加0 行削除
  1. 1 0
      CHANGELOG.md
  2. 41 0
      src/gpio.rs

+ 1 - 0
CHANGELOG.md

@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 
 - Add 16 bit dataframe size for `SPI`
 - Implement `timer::Cancel` trait for `CountDownTimer`
+- Changing Output pin slew rates through the OutputSpeed trait
 
 ### Added
 

+ 41 - 0
src/gpio.rs

@@ -80,6 +80,25 @@ use crate::afio;
 use crate::pac::EXTI;
 use crate::rcc::APB2;
 
+/// Slew rates available for Output and relevant AlternateMode Pins
+///
+/// See Table 21 "Output MODE bits" in the reference
+pub enum IOPinSpeed {
+    /// Slew at 10Mhz
+    Mhz10 = 0b01, // (yes, this one is "less" then 2Mhz)
+    /// Slew at 2Mhz
+    Mhz2 = 0b10,
+    /// Slew at 50Mhz
+    Mhz50 = 0b11,
+}
+
+/// Allow setting of the slew rate of an IO pin
+///
+/// Initially all pins are set to the maximum slew rate
+pub trait OutputSpeed<CR> {
+    fn set_speed(&mut self, cr: &mut CR, speed: IOPinSpeed);
+}
+
 /// Extension trait to split a GPIO peripheral in independent pins and registers
 pub trait GpioExt {
     /// The to split the GPIO into
@@ -250,6 +269,8 @@ macro_rules! gpio {
                 PinMode,
                 Dynamic,
                 PinModeError,
+                OutputSpeed,
+                IOPinSpeed,
             };
 
             /// GPIO parts
@@ -752,6 +773,26 @@ macro_rules! gpio {
                     }
                 }
 
+                impl<MODE> OutputSpeed<$CR> for $PXi<Output<MODE>> {
+                    fn set_speed(&mut self, cr: &mut $CR, speed: IOPinSpeed){
+                        const OFFSET: u32 = (4 * $i) % 32;
+
+                        cr.cr().modify(|r, w| unsafe {
+                            w.bits((r.bits() & !(0b11 << OFFSET)) | ((speed as u32) << OFFSET))
+                        });
+                    }
+                }
+
+                impl OutputSpeed<$CR> for $PXi<Alternate<PushPull>> {
+                    fn set_speed(&mut self, cr: &mut $CR, speed: IOPinSpeed){
+                        const OFFSET: u32 = (4 * $i) % 32;
+
+                        cr.cr().modify(|r, w| unsafe {
+                            w.bits((r.bits() & !(0b11 << OFFSET)) | ((speed as u32) << OFFSET))
+                        });
+                    }
+                }
+
                 impl<MODE> toggleable::Default for $PXi<Output<MODE>> {}
 
                 impl<MODE> InputPin for $PXi<Input<MODE>> {