|
@@ -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());
|