Skip to content

Commit

Permalink
pwm
Browse files Browse the repository at this point in the history
  • Loading branch information
burrbull committed Oct 9, 2024
1 parent dbd18f6 commit 36aecc8
Show file tree
Hide file tree
Showing 11 changed files with 748 additions and 348 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Breaking changes

- Relax pin type generics for `Serial`, `I2c`, `Spi`, `Can`. [#462]
- Relax pin type generics for `Serial`, `I2c`, `Spi`, `Can`, `Pwm`, `Qei`, `PwmInput`.
Use enums of pin tuples and `Enum::from<(tuple)>` for pin remap before passing to peripheral.
Remove `RemapStruct`s. [#462] [#506] [#509]
Remove `RemapStruct`s. [#462] [#506] [#507] [#509]
- Use independent `Spi` and `SpiSlave` structures instead of `OP` generic [#462]
- Take `&Clocks` instead of `Clocks` [#498]
- Temporary replace `stm32f1` with `stm32f1-staging` [#503]
Expand Down Expand Up @@ -56,6 +56,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
[#503]: https://github.com/stm32-rs/stm32f1xx-hal/pull/503
[#505]: https://github.com/stm32-rs/stm32f1xx-hal/pull/505
[#506]: https://github.com/stm32-rs/stm32f1xx-hal/pull/506
[#507]: https://github.com/stm32-rs/stm32f1xx-hal/pull/507
[#509]: https://github.com/stm32-rs/stm32f1xx-hal/pull/509
[#511]: https://github.com/stm32-rs/stm32f1xx-hal/pull/511

Expand Down
19 changes: 7 additions & 12 deletions examples/pwm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ use panic_halt as _;

use cortex_m::asm;
use cortex_m_rt::entry;
use stm32f1xx_hal::{
pac,
prelude::*,
time::ms,
timer::{Channel, Tim2NoRemap},
};
use stm32f1xx_hal::{pac, prelude::*, time::ms, timer, timer::Channel};

#[entry]
fn main() -> ! {
Expand All @@ -27,16 +22,16 @@ fn main() -> ! {

let mut afio = p.AFIO.constrain();

let mut gpioa = p.GPIOA.split();
let gpioa = p.GPIOA.split();
// let mut gpiob = p.GPIOB.split();

// TIM2
let c1 = gpioa.pa0.into_alternate_push_pull(&mut gpioa.crl);
let c2 = gpioa.pa1.into_alternate_push_pull(&mut gpioa.crl);
let c3 = gpioa.pa2.into_alternate_push_pull(&mut gpioa.crl);
let c1 = gpioa.pa0;
let c2 = gpioa.pa1;
let c3 = gpioa.pa2;
// If you don't want to use all channels, just leave some out
// let c4 = gpioa.pa3.into_alternate_push_pull(&mut gpioa.crl);
let pins = (c1, c2, c3);
let pins = (c1, c2, c3, &mut afio.mapr);

// TIM3
// let c1 = gpioa.pa6.into_alternate_push_pull(&mut gpioa.crl);
Expand All @@ -55,7 +50,7 @@ fn main() -> ! {
// or
let mut pwm = p
.TIM2
.pwm_hz::<Tim2NoRemap, _, _>(pins, &mut afio.mapr, 1.kHz(), &clocks);
.pwm_hz::<timer::tim2::Channels123>(pins, 1.kHz(), &clocks);

// Enable clock on each of the channels
pwm.enable(Channel::C1);
Expand Down
9 changes: 7 additions & 2 deletions examples/pwm_custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
use panic_halt as _;

use cortex_m::asm;
use stm32f1xx_hal::{pac, prelude::*, timer::Timer};
use stm32f1xx_hal::{
pac,
prelude::*,
timer::{self, Timer},
};

use cortex_m_rt::entry;

Expand All @@ -30,7 +34,8 @@ fn main() -> ! {
let p0 = pb4.into_alternate_push_pull(&mut gpiob.crl);
let p1 = gpiob.pb5.into_alternate_push_pull(&mut gpiob.crl);

let pwm = Timer::new(p.TIM3, &clocks).pwm_hz((p0, p1), &mut afio.mapr, 1.kHz());
let pwm = Timer::new(p.TIM3, &clocks)
.pwm_hz::<timer::tim3::Channels12>((p0, p1, &mut afio.mapr), 1.kHz());

let max = pwm.get_max_duty();

Expand Down
12 changes: 4 additions & 8 deletions examples/pwm_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@
use panic_halt as _;

use cortex_m_rt::entry;
use stm32f1xx_hal::{
pac,
prelude::*,
timer::{pwm_input::*, Timer},
};
use stm32f1xx_hal::{pac, prelude::*, timer::pwm_input::*};

#[entry]
fn main() -> ! {
Expand All @@ -31,11 +27,11 @@ fn main() -> ! {
let (_pa15, _pb3, pb4) = afio.mapr.disable_jtag(gpioa.pa15, gpiob.pb3, gpiob.pb4);
let pb5 = gpiob.pb5;

let pwm_input = Timer::new(p.TIM3, &clocks).pwm_input(
(pb4, pb5),
&mut afio.mapr,
let pwm_input = p.TIM3.pwm_input(
(pb4, pb5, &mut afio.mapr),
&mut dbg,
Configuration::Frequency(10.kHz()),
&clocks,
);

loop {
Expand Down
6 changes: 4 additions & 2 deletions examples/qei.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use panic_semihosting as _;
use cortex_m_semihosting::hprintln;

use cortex_m_rt::entry;
use stm32f1xx_hal::{pac, prelude::*, qei::QeiOptions, timer::Timer};
use stm32f1xx_hal::{pac, prelude::*, qei::QeiOptions};

#[entry]
fn main() -> ! {
Expand Down Expand Up @@ -38,7 +38,9 @@ fn main() -> ! {
let c1 = gpiob.pb6;
let c2 = gpiob.pb7;

let qei = Timer::new(dp.TIM4, &clocks).qei((c1, c2), &mut afio.mapr, QeiOptions::default());
let qei = dp
.TIM4
.qei((c1, c2, &mut afio.mapr), QeiOptions::default(), &clocks);
let mut delay = cp.SYST.delay(&clocks);

loop {
Expand Down
2 changes: 2 additions & 0 deletions src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ pub use crate::gpio::GpioExt as _stm32_hal_gpio_GpioExt;
pub use crate::hal_02::adc::OneShot as _embedded_hal_adc_OneShot;
pub use crate::hal_02::prelude::*;
pub use crate::i2c::I2cExt as _;
pub use crate::qei::QeiExt as _;
pub use crate::rcc::RccExt as _stm32_hal_rcc_RccExt;
pub use crate::serial::SerialExt as _;
pub use crate::spi::SpiExt as _;
pub use crate::time::U32Ext as _stm32_hal_time_U32Ext;
pub use crate::timer::pwm_input::PwmInputExt as _;
#[cfg(feature = "rtic")]
pub use crate::timer::MonoTimerExt as _stm32f4xx_hal_timer_MonoTimerExt;
pub use crate::timer::PwmExt as _stm32f4xx_hal_timer_PwmExt;
Expand Down
142 changes: 87 additions & 55 deletions src/qei.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,12 @@
NOTE: In some cases you need to specify remap you need, especially for TIM2
(see [Alternate function remapping](super::timer)):
*/
use core::marker::PhantomData;

use crate::pac;
use embedded_hal_02 as hal;
pub use hal::Direction;

use crate::afio::MAPR;

use crate::timer::pwm_input::Pins;
use crate::timer::{pins::sealed::Remap, Timer};
use crate::rcc::Clocks;
use crate::timer::{InPins, InputPins, Timer};

/// SMS (Slave Mode Selection) register
#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -60,90 +56,122 @@ impl Default for QeiOptions {
}
}

pub struct Qei<TIM, REMAP, PINS> {
pub struct Qei<TIM: InputPins> {
tim: TIM,
pins: PINS,
_remap: PhantomData<REMAP>,
pins: (TIM::InCh1, TIM::InCh2),
}

pub trait QeiExt: Sized + InputPins {
fn qei(
self,
pins: impl Into<InPins<Self::InCh1, Self::InCh2>>,
options: QeiOptions,
clocks: &Clocks,
) -> Qei<Self>;
}

#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))]
impl Timer<pac::TIM1> {
pub fn qei<REMAP, PINS>(
impl QeiExt for pac::TIM1 {
fn qei(
self,
pins: PINS,
mapr: &mut MAPR,
pins: impl Into<InPins<Self::InCh1, Self::InCh2>>,
options: QeiOptions,
) -> Qei<pac::TIM1, REMAP, PINS>
where
REMAP: Remap<Periph = pac::TIM1>,
PINS: Pins<REMAP>,
{
mapr.modify_mapr(|_, w| unsafe { w.tim1_remap().bits(REMAP::REMAP) });
clocks: &Clocks,
) -> Qei<Self> {
Timer::new(self, clocks).qei(pins, options)
}
}

#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))]
impl Timer<pac::TIM1> {
pub fn qei(
self,
pins: impl Into<InPins<<pac::TIM1 as InputPins>::InCh1, <pac::TIM1 as InputPins>::InCh2>>,
options: QeiOptions,
) -> Qei<pac::TIM1> {
let Self { tim, clk: _ } = self;
Qei::_tim1(tim, pins, options)
}
}

impl Timer<pac::TIM2> {
pub fn qei<REMAP, PINS>(
impl QeiExt for pac::TIM2 {
fn qei(
self,
pins: PINS,
mapr: &mut MAPR,
pins: impl Into<InPins<Self::InCh1, Self::InCh2>>,
options: QeiOptions,
) -> Qei<pac::TIM2, REMAP, PINS>
where
REMAP: Remap<Periph = pac::TIM2>,
PINS: Pins<REMAP>,
{
mapr.modify_mapr(|_, w| unsafe { w.tim2_remap().bits(REMAP::REMAP) });
clocks: &Clocks,
) -> Qei<Self> {
Timer::new(self, clocks).qei(pins, options)
}
}

impl Timer<pac::TIM2> {
pub fn qei(
self,
pins: impl Into<InPins<<pac::TIM2 as InputPins>::InCh1, <pac::TIM2 as InputPins>::InCh2>>,
options: QeiOptions,
) -> Qei<pac::TIM2> {
let Self { tim, clk: _ } = self;
Qei::_tim2(tim, pins, options)
}
}

impl Timer<pac::TIM3> {
pub fn qei<REMAP, PINS>(
impl QeiExt for pac::TIM3 {
fn qei(
self,
pins: PINS,
mapr: &mut MAPR,
pins: impl Into<InPins<Self::InCh1, Self::InCh2>>,
options: QeiOptions,
) -> Qei<pac::TIM3, REMAP, PINS>
where
REMAP: Remap<Periph = pac::TIM3>,
PINS: Pins<REMAP>,
{
mapr.modify_mapr(|_, w| unsafe { w.tim3_remap().bits(REMAP::REMAP) });
clocks: &Clocks,
) -> Qei<Self> {
Timer::new(self, clocks).qei(pins, options)
}
}

impl Timer<pac::TIM3> {
pub fn qei(
self,
pins: impl Into<InPins<<pac::TIM3 as InputPins>::InCh1, <pac::TIM3 as InputPins>::InCh2>>,
options: QeiOptions,
) -> Qei<pac::TIM3> {
let Self { tim, clk: _ } = self;
Qei::_tim3(tim, pins, options)
}
}

#[cfg(feature = "medium")]
impl Timer<pac::TIM4> {
pub fn qei<REMAP, PINS>(
impl QeiExt for pac::TIM4 {
fn qei(
self,
pins: PINS,
mapr: &mut MAPR,
pins: impl Into<InPins<Self::InCh1, Self::InCh2>>,
options: QeiOptions,
) -> Qei<pac::TIM4, REMAP, PINS>
where
REMAP: Remap<Periph = pac::TIM4>,
PINS: Pins<REMAP>,
{
mapr.modify_mapr(|_, w| w.tim4_remap().bit(REMAP::REMAP == 1));
clocks: &Clocks,
) -> Qei<Self> {
Timer::new(self, &clocks).qei(pins, options)
}
}

#[cfg(feature = "medium")]
impl Timer<pac::TIM4> {
pub fn qei(
self,
pins: impl Into<InPins<<pac::TIM4 as InputPins>::InCh1, <pac::TIM4 as InputPins>::InCh2>>,
options: QeiOptions,
) -> Qei<pac::TIM4> {
let Self { tim, clk: _ } = self;
Qei::_tim4(tim, pins, options)
}
}

macro_rules! hal {
($TIMX:ty: $timX:ident, $timXen:ident, $timXrst:ident) => {
impl<REMAP, PINS> Qei<$TIMX, REMAP, PINS> {
fn $timX(tim: $TIMX, pins: PINS, options: QeiOptions) -> Self {
impl Qei<$TIMX> {
fn $timX(
tim: $TIMX,
pins: impl Into<InPins<<$TIMX as InputPins>::InCh1, <$TIMX as InputPins>::InCh2>>,
options: QeiOptions,
) -> Self {
let pins = pins.into();

// Configure TxC1 and TxC2 as captures
tim.ccmr1_input().write(|w| w.cc1s().ti1().cc2s().ti2());

Expand All @@ -163,17 +191,21 @@ macro_rules! hal {

Qei {
tim,
pins,
_remap: PhantomData,
pins: (pins.c1, pins.c2),
}
}

pub fn release(self) -> ($TIMX, PINS) {
pub fn release(
self,
) -> (
$TIMX,
(<$TIMX as InputPins>::InCh1, <$TIMX as InputPins>::InCh2),
) {
(self.tim, self.pins)
}
}

impl<REMAP, PINS> hal::Qei for Qei<$TIMX, REMAP, PINS> {
impl hal::Qei for Qei<$TIMX> {
type Count = u16;

fn count(&self) -> u16 {
Expand Down
Loading

0 comments on commit 36aecc8

Please sign in to comment.