Skip to content

Commit

Permalink
timer Instance, rtic monotonic
Browse files Browse the repository at this point in the history
  • Loading branch information
burrbull committed Jan 8, 2022
1 parent ecd81e0 commit 71f7bcb
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Added

- `Instance` for Timer's, rtic-monotonic fugit impl
- Serial can now be reconfigured, allowing to change e.g. the baud rate after initialisation.

## [v0.8.0] - 2021-12-29
Expand Down
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ bxcan = "0.6"
cast = { default-features = false, version = "0.3.0" }
void = { default-features = false, version = "1.0.2" }
embedded-hal = { features = ["unproven"], version = "0.2.6" }
fugit = "0.3.0"
rtic-monotonic = { version = "1.0", optional = true }

[dependencies.stm32-usbd]
version = "0.6.0"
Expand Down Expand Up @@ -62,6 +64,8 @@ connectivity = ["medium", "has-can"]
# Devices with CAN interface
has-can = []

rtic = ["rt", "rtic-monotonic"]

[profile.dev]
incremental = false
codegen-units = 1
Expand Down
2 changes: 1 addition & 1 deletion examples/blinky_timer_irq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ fn main() -> ! {
cortex_m::interrupt::free(|cs| *G_LED.borrow(cs).borrow_mut() = Some(led));

// Set up a timer expiring after 1s
let mut timer = Timer::tim2(dp.TIM2, &clocks).start_count_down(1.hz());
let mut timer = Timer::new(dp.TIM2, &clocks).start_count_down(1.hz());

// Generate an interrupt when the timer expires
timer.listen(Event::Update);
Expand Down
2 changes: 1 addition & 1 deletion examples/pwm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fn main() -> ! {
// let c4 = gpiob.pb9.into_alternate_push_pull(&mut gpiob.crh);

let mut pwm =
Timer::tim2(p.TIM2, &clocks).pwm::<Tim2NoRemap, _, _, _>(pins, &mut afio.mapr, 1.khz());
Timer::new(p.TIM2, &clocks).pwm::<Tim2NoRemap, _, _, _>(pins, &mut afio.mapr, 1.khz());

// Enable clock on each of the channels
pwm.enable(Channel::C1);
Expand Down
2 changes: 1 addition & 1 deletion examples/pwm_custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ 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::tim3(p.TIM3, &clocks).pwm((p0, p1), &mut afio.mapr, 1.khz());
let pwm = Timer::new(p.TIM3, &clocks).pwm((p0, p1), &mut afio.mapr, 1.khz());

let max = pwm.get_max_duty();

Expand Down
2 changes: 1 addition & 1 deletion examples/pwm_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn main() -> ! {
let (_pa15, _pb3, pb4) = afio.mapr.disable_jtag(gpioa.pa15, gpiob.pb3, gpiob.pb4);
let pb5 = gpiob.pb5;

let pwm_input = Timer::tim3(p.TIM3, &clocks).pwm_input(
let pwm_input = Timer::new(p.TIM3, &clocks).pwm_input(
(pb4, pb5),
&mut afio.mapr,
&mut dbg,
Expand Down
2 changes: 1 addition & 1 deletion examples/qei.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ fn main() -> ! {
let c1 = gpiob.pb6;
let c2 = gpiob.pb7;

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

loop {
Expand Down
2 changes: 1 addition & 1 deletion examples/timer-interrupt-rtic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ mod app {
.pc13
.into_push_pull_output_with_state(&mut gpioc.crh, PinState::High);
// Configure the syst timer to trigger an update every second and enables interrupt
let mut timer = Timer::tim1(cx.device.TIM1, &clocks).start_count_down(1.hz());
let mut timer = Timer::new(cx.device.TIM1, &clocks).start_count_down(1.hz());
timer.listen(Event::Update);

// Init the static resources to use them later through RTIC
Expand Down
61 changes: 42 additions & 19 deletions src/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,17 @@ use crate::pac::{DBGMCU as DBG, TIM2, TIM3};
#[cfg(feature = "stm32f100")]
use crate::pac::{TIM15, TIM16, TIM17};

use crate::rcc::{Clocks, Enable, GetBusFreq, RccBus, Reset};
use crate::rcc::{self, Clocks};
use cast::{u16, u32, u64};
use cortex_m::peripheral::syst::SystClkSource;
use cortex_m::peripheral::SYST;
use void::Void;

use crate::time::Hertz;

#[cfg(feature = "rtic")]
mod monotonic;

/// Interrupt events
pub enum Event {
/// Timer timed out / count down ended
Expand Down Expand Up @@ -275,18 +278,50 @@ impl Cancel for CountDownTimer<SYST> {

impl Periodic for CountDownTimer<SYST> {}

pub trait Instance: crate::Sealed + rcc::Enable + rcc::Reset + rcc::GetBusFreq {}

impl<TIM> Timer<TIM>
where
TIM: Instance,
{
/// Initialize timer
pub fn new(tim: TIM, clocks: &Clocks) -> Self {
unsafe {
//NOTE(unsafe) this reference will only be used for atomic writes with no side effects
let rcc = &(*RCC::ptr());
// Enable and reset the timer peripheral
TIM::enable(rcc);
TIM::reset(rcc);
}

Self {
clk: TIM::get_timer_frequency(&clocks),
tim,
}
}

/// Resets timer peripheral
#[inline(always)]
pub fn clocking_reset(&mut self) {
let rcc = unsafe { &(*RCC::ptr()) };
TIM::reset(rcc);
}

/// Releases the TIM Peripheral
pub fn release(self) -> TIM {
self.tim
}
}

macro_rules! hal {
($($TIMX:ident: ($timX:ident, $APBx:ident, $dbg_timX_stop:ident$(,$master_timbase:ident)*),)+) => {
$(
impl Instance for $TIMX { }

impl Timer<$TIMX> {
/// Initialize timer
pub fn $timX(tim: $TIMX, clocks: &Clocks) -> Self {
// enable and reset peripheral to a clean slate state
let rcc = unsafe { &(*RCC::ptr()) };
$TIMX::enable(rcc);
$TIMX::reset(rcc);

Self { tim, clk: <$TIMX as RccBus>::Bus::get_timer_frequency(&clocks) }
Self::new(tim, clocks)
}

/// Starts timer in count down mode at a given frequency
Expand Down Expand Up @@ -323,23 +358,11 @@ macro_rules! hal {
timer
}

/// Resets timer peripheral
#[inline(always)]
pub fn clocking_reset(&mut self) {
let rcc = unsafe { &(*RCC::ptr()) };
$TIMX::reset(rcc);
}

/// Stopping timer in debug mode can cause troubles when sampling the signal
#[inline(always)]
pub fn stop_in_debug(&mut self, dbg: &mut DBG, state: bool) {
dbg.cr.modify(|_, w| w.$dbg_timX_stop().bit(state));
}

/// Releases the TIM Peripheral
pub fn release(self) -> $TIMX {
self.tim
}
}

impl CountDownTimer<$TIMX> {
Expand Down

0 comments on commit 71f7bcb

Please sign in to comment.