Skip to content

Commit 28b078e

Browse files
authored
Merge pull request #178 from jamwaffles/qei-configuration
Add configuration options to QEI interface
2 parents 8b52514 + 1026fbc commit 28b078e

File tree

2 files changed

+87
-37
lines changed

2 files changed

+87
-37
lines changed

examples/qei.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,8 @@ use panic_semihosting as _;
88

99
use cortex_m_semihosting::hprintln;
1010

11-
use stm32f1xx_hal::{
12-
prelude::*,
13-
pac,
14-
delay::Delay,
15-
timer::Timer,
16-
};
1711
use cortex_m_rt::entry;
12+
use stm32f1xx_hal::{delay::Delay, pac, prelude::*, qei::QeiOptions, timer::Timer};
1813

1914
#[entry]
2015
fn main() -> ! {
@@ -43,8 +38,11 @@ fn main() -> ! {
4338
let c1 = gpiob.pb6;
4439
let c2 = gpiob.pb7;
4540

46-
let qei = Timer::tim4(dp.TIM4, &clocks, &mut rcc.apb1)
47-
.qei((c1, c2), &mut afio.mapr);
41+
let qei = Timer::tim4(dp.TIM4, &clocks, &mut rcc.apb1).qei(
42+
(c1, c2),
43+
&mut afio.mapr,
44+
QeiOptions::default(),
45+
);
4846
let mut delay = Delay::new(cp.SYST, clocks);
4947

5048
loop {

src/qei.rs

Lines changed: 81 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,96 +4,152 @@
44
NOTE: In some cases you need to specify remap you need, especially for TIM2
55
(see [Alternate function remapping](super::timer)):
66
*/
7-
87
use core::u16;
98

109
use core::marker::PhantomData;
1110

1211
use crate::hal::{self, Direction};
13-
#[cfg(any(
14-
feature = "stm32f100",
15-
feature = "stm32f103",
16-
feature = "stm32f105",
17-
))]
12+
#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
1813
use crate::pac::TIM1;
19-
use crate::pac::{TIM2, TIM3};
2014
#[cfg(feature = "medium")]
2115
use crate::pac::TIM4;
16+
use crate::pac::{TIM2, TIM3};
2217

2318
use crate::afio::MAPR;
2419

25-
use crate::timer::{Timer, sealed::Remap};
2620
use crate::pwm_input::Pins;
21+
use crate::timer::{sealed::Remap, Timer};
22+
23+
/// SMS (Slave Mode Selection) register
24+
#[derive(Copy, Clone, Debug)]
25+
pub enum SlaveMode {
26+
/// Counter counts up/down on TI2FP1 edge depending on TI1FP2 level.
27+
EncoderMode1 = 0b001,
28+
/// Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level.
29+
EncoderMode2 = 0b010,
30+
/// Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the
31+
/// level of the other input.
32+
EncoderMode3 = 0b011,
33+
/// Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and
34+
/// generates an update of the registers.
35+
ResetMode = 0b100,
36+
/// Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not
37+
/// reset). Only the start of the counter is controlled.
38+
TriggerMode = 0b110,
39+
/// External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter.
40+
ExternalClockMode1 = 0b111,
41+
}
42+
43+
/// Quadrature Encoder Interface (QEI) options
44+
///
45+
/// The `Default` implementation provides a configuration for a 4-count pulse which counts from
46+
/// 0-65535. The counter wraps back to 0 on overflow.
47+
#[derive(Copy, Clone, Debug)]
48+
pub struct QeiOptions {
49+
/// Encoder slave mode
50+
pub slave_mode: SlaveMode,
51+
52+
/// Autoreload value
53+
///
54+
/// This value allows the maximum count to be configured, up to 65535. Setting a lower value
55+
/// will overflow the counter to 0 sooner.
56+
pub auto_reload_value: u16,
57+
}
58+
59+
impl Default for QeiOptions {
60+
fn default() -> Self {
61+
Self {
62+
slave_mode: SlaveMode::EncoderMode3,
63+
auto_reload_value: u16::MAX,
64+
}
65+
}
66+
}
2767

2868
pub struct Qei<TIM, REMAP, PINS> {
2969
tim: TIM,
3070
pins: PINS,
3171
_remap: PhantomData<REMAP>,
3272
}
3373

34-
#[cfg(any(
35-
feature = "stm32f100",
36-
feature = "stm32f103",
37-
feature = "stm32f105",
38-
))]
74+
#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
3975
impl Timer<TIM1> {
40-
pub fn qei<REMAP, PINS>(self, pins: PINS, mapr: &mut MAPR) -> Qei<TIM1, REMAP, PINS>
76+
pub fn qei<REMAP, PINS>(
77+
self,
78+
pins: PINS,
79+
mapr: &mut MAPR,
80+
options: QeiOptions,
81+
) -> Qei<TIM1, REMAP, PINS>
4182
where
4283
REMAP: Remap<Periph = TIM1>,
4384
PINS: Pins<REMAP>,
4485
{
4586
mapr.modify_mapr(|_, w| unsafe { w.tim1_remap().bits(REMAP::REMAP) });
4687

4788
let Self { tim, clk: _ } = self;
48-
Qei::_tim1(tim, pins)
89+
Qei::_tim1(tim, pins, options)
4990
}
5091
}
5192

5293
impl Timer<TIM2> {
53-
pub fn qei<REMAP, PINS>(self, pins: PINS, mapr: &mut MAPR) -> Qei<TIM2, REMAP, PINS>
94+
pub fn qei<REMAP, PINS>(
95+
self,
96+
pins: PINS,
97+
mapr: &mut MAPR,
98+
options: QeiOptions,
99+
) -> Qei<TIM2, REMAP, PINS>
54100
where
55101
REMAP: Remap<Periph = TIM2>,
56102
PINS: Pins<REMAP>,
57103
{
58104
mapr.modify_mapr(|_, w| unsafe { w.tim2_remap().bits(REMAP::REMAP) });
59105

60106
let Self { tim, clk: _ } = self;
61-
Qei::_tim2(tim, pins)
107+
Qei::_tim2(tim, pins, options)
62108
}
63109
}
64110

65111
impl Timer<TIM3> {
66-
pub fn qei<REMAP, PINS>(self, pins: PINS, mapr: &mut MAPR) -> Qei<TIM3, REMAP, PINS>
112+
pub fn qei<REMAP, PINS>(
113+
self,
114+
pins: PINS,
115+
mapr: &mut MAPR,
116+
options: QeiOptions,
117+
) -> Qei<TIM3, REMAP, PINS>
67118
where
68119
REMAP: Remap<Periph = TIM3>,
69120
PINS: Pins<REMAP>,
70121
{
71122
mapr.modify_mapr(|_, w| unsafe { w.tim3_remap().bits(REMAP::REMAP) });
72123

73124
let Self { tim, clk: _ } = self;
74-
Qei::_tim3(tim, pins)
125+
Qei::_tim3(tim, pins, options)
75126
}
76127
}
77128

78129
#[cfg(feature = "medium")]
79130
impl Timer<TIM4> {
80-
pub fn qei<REMAP, PINS>(self, pins: PINS, mapr: &mut MAPR) -> Qei<TIM4, REMAP, PINS>
131+
pub fn qei<REMAP, PINS>(
132+
self,
133+
pins: PINS,
134+
mapr: &mut MAPR,
135+
options: QeiOptions,
136+
) -> Qei<TIM4, REMAP, PINS>
81137
where
82138
REMAP: Remap<Periph = TIM4>,
83139
PINS: Pins<REMAP>,
84140
{
85141
mapr.modify_mapr(|_, w| w.tim4_remap().bit(REMAP::REMAP == 1));
86142

87143
let Self { tim, clk: _ } = self;
88-
Qei::_tim4(tim, pins)
144+
Qei::_tim4(tim, pins, options)
89145
}
90146
}
91147

92148
macro_rules! hal {
93149
($($TIMX:ident: ($timX:ident, $timXen:ident, $timXrst:ident),)+) => {
94150
$(
95151
impl<REMAP, PINS> Qei<$TIMX, REMAP, PINS> {
96-
fn $timX(tim: $TIMX, pins: PINS) -> Self {
152+
fn $timX(tim: $TIMX, pins: PINS, options: QeiOptions) -> Self {
97153
// Configure TxC1 and TxC2 as captures
98154
tim.ccmr1_input().write(|w| w.cc1s().ti1().cc2s().ti2());
99155

@@ -110,9 +166,9 @@ macro_rules! hal {
110166
});
111167

112168
// configure as quadrature encoder
113-
tim.smcr.write(|w| w.sms().bits(3));
169+
tim.smcr.write(|w| w.sms().bits(options.slave_mode as u8));
114170

115-
tim.arr.write(|w| w.arr().bits(u16::MAX));
171+
tim.arr.write(|w| w.arr().bits(options.auto_reload_value));
116172
tim.cr1.write(|w| w.cen().set_bit());
117173

118174
Qei { tim, pins, _remap: PhantomData }
@@ -143,11 +199,7 @@ macro_rules! hal {
143199
}
144200
}
145201

146-
#[cfg(any(
147-
feature = "stm32f100",
148-
feature = "stm32f103",
149-
feature = "stm32f105",
150-
))]
202+
#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "stm32f105",))]
151203
hal! {
152204
TIM1: (_tim1, tim1en, tim1rst),
153205
}

0 commit comments

Comments
 (0)