Selaa lähdekoodia

Allow configuration of QEI slave mode

James Waples 4 vuotta sitten
vanhempi
säilyke
d494da0f17
2 muutettua tiedostoa jossa 67 lisäystä ja 12 poistoa
  1. 6 2
      examples/qei.rs
  2. 61 10
      src/qei.rs

+ 6 - 2
examples/qei.rs

@@ -9,7 +9,7 @@ use panic_semihosting as _;
 use cortex_m_semihosting::hprintln;
 
 use cortex_m_rt::entry;
-use stm32f1xx_hal::{delay::Delay, pac, prelude::*, timer::Timer};
+use stm32f1xx_hal::{delay::Delay, pac, prelude::*, qei::QeiOptions, timer::Timer};
 
 #[entry]
 fn main() -> ! {
@@ -38,7 +38,11 @@ fn main() -> ! {
     let c1 = gpiob.pb6;
     let c2 = gpiob.pb7;
 
-    let qei = Timer::tim4(dp.TIM4, &clocks, &mut rcc.apb1).qei((c1, c2), &mut afio.mapr);
+    let qei = Timer::tim4(dp.TIM4, &clocks, &mut rcc.apb1).qei(
+        (c1, c2),
+        &mut afio.mapr,
+        QeiOptions::default(),
+    );
     let mut delay = Delay::new(cp.SYST, clocks);
 
     loop {

+ 61 - 10
src/qei.rs

@@ -20,6 +20,37 @@ use crate::afio::MAPR;
 use crate::pwm_input::Pins;
 use crate::timer::{sealed::Remap, Timer};
 
+/// SMS (Slave Mode Selection) register
+pub enum SlaveMode {
+    /// Counter counts up/down on TI2FP1 edge depending on TI1FP2 level.
+    EncoderMode1 = 0b001,
+    /// Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level.
+    EncoderMode2 = 0b010,
+    /// Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the
+    /// level of the other input.
+    EncoderMode3 = 0b011,
+    /// Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and
+    /// generates an update of the registers.
+    ResetMode = 0b100,
+    /// Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not
+    /// reset). Only the start of the counter is controlled.
+    TriggerMode = 0b110,
+    /// External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter.
+    ExternalClockMode1 = 0b111,
+}
+
+pub struct QeiOptions {
+    slave_mode: SlaveMode,
+}
+
+impl Default for QeiOptions {
+    fn default() -> Self {
+        Self {
+            slave_mode: SlaveMode::EncoderMode3,
+        }
+    }
+}
+
 pub struct Qei<TIM, REMAP, PINS> {
     tim: TIM,
     pins: PINS,
@@ -28,7 +59,12 @@ pub struct Qei<TIM, REMAP, PINS> {
 
 #[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
 impl Timer<TIM1> {
-    pub fn qei<REMAP, PINS>(self, pins: PINS, mapr: &mut MAPR) -> Qei<TIM1, REMAP, PINS>
+    pub fn qei<REMAP, PINS>(
+        self,
+        pins: PINS,
+        mapr: &mut MAPR,
+        options: QeiOptions,
+    ) -> Qei<TIM1, REMAP, PINS>
     where
         REMAP: Remap<Periph = TIM1>,
         PINS: Pins<REMAP>,
@@ -36,12 +72,17 @@ impl Timer<TIM1> {
         mapr.modify_mapr(|_, w| unsafe { w.tim1_remap().bits(REMAP::REMAP) });
 
         let Self { tim, clk: _ } = self;
-        Qei::_tim1(tim, pins)
+        Qei::_tim1(tim, pins, options)
     }
 }
 
 impl Timer<TIM2> {
-    pub fn qei<REMAP, PINS>(self, pins: PINS, mapr: &mut MAPR) -> Qei<TIM2, REMAP, PINS>
+    pub fn qei<REMAP, PINS>(
+        self,
+        pins: PINS,
+        mapr: &mut MAPR,
+        options: QeiOptions,
+    ) -> Qei<TIM2, REMAP, PINS>
     where
         REMAP: Remap<Periph = TIM2>,
         PINS: Pins<REMAP>,
@@ -49,12 +90,17 @@ impl Timer<TIM2> {
         mapr.modify_mapr(|_, w| unsafe { w.tim2_remap().bits(REMAP::REMAP) });
 
         let Self { tim, clk: _ } = self;
-        Qei::_tim2(tim, pins)
+        Qei::_tim2(tim, pins, options)
     }
 }
 
 impl Timer<TIM3> {
-    pub fn qei<REMAP, PINS>(self, pins: PINS, mapr: &mut MAPR) -> Qei<TIM3, REMAP, PINS>
+    pub fn qei<REMAP, PINS>(
+        self,
+        pins: PINS,
+        mapr: &mut MAPR,
+        options: QeiOptions,
+    ) -> Qei<TIM3, REMAP, PINS>
     where
         REMAP: Remap<Periph = TIM3>,
         PINS: Pins<REMAP>,
@@ -62,13 +108,18 @@ impl Timer<TIM3> {
         mapr.modify_mapr(|_, w| unsafe { w.tim3_remap().bits(REMAP::REMAP) });
 
         let Self { tim, clk: _ } = self;
-        Qei::_tim3(tim, pins)
+        Qei::_tim3(tim, pins, options)
     }
 }
 
 #[cfg(feature = "medium")]
 impl Timer<TIM4> {
-    pub fn qei<REMAP, PINS>(self, pins: PINS, mapr: &mut MAPR) -> Qei<TIM4, REMAP, PINS>
+    pub fn qei<REMAP, PINS>(
+        self,
+        pins: PINS,
+        mapr: &mut MAPR,
+        options: QeiOptions,
+    ) -> Qei<TIM4, REMAP, PINS>
     where
         REMAP: Remap<Periph = TIM4>,
         PINS: Pins<REMAP>,
@@ -76,7 +127,7 @@ impl Timer<TIM4> {
         mapr.modify_mapr(|_, w| w.tim4_remap().bit(REMAP::REMAP == 1));
 
         let Self { tim, clk: _ } = self;
-        Qei::_tim4(tim, pins)
+        Qei::_tim4(tim, pins, options)
     }
 }
 
@@ -84,7 +135,7 @@ macro_rules! hal {
     ($($TIMX:ident: ($timX:ident, $timXen:ident, $timXrst:ident),)+) => {
         $(
             impl<REMAP, PINS> Qei<$TIMX, REMAP, PINS> {
-                fn $timX(tim: $TIMX, pins: PINS) -> Self {
+                fn $timX(tim: $TIMX, pins: PINS, options: QeiOptions) -> Self {
                     // Configure TxC1 and TxC2 as captures
                     tim.ccmr1_input().write(|w| w.cc1s().ti1().cc2s().ti2());
 
@@ -101,7 +152,7 @@ macro_rules! hal {
                     });
 
                     // configure as quadrature encoder
-                    tim.smcr.write(|w| w.sms().bits(3));
+                    tim.smcr.write(|w| w.sms().bits(options.slave_mode as u8));
 
                     tim.arr.write(|w| w.arr().bits(u16::MAX));
                     tim.cr1.write(|w| w.cen().set_bit());