Merge pull request #240 from lulf/enable-timer-clock

Enable timer clock in RCC on timer start
This commit is contained in:
Ulf Lilleengen 2021-06-11 16:30:54 +02:00 committed by GitHub
commit def8870cbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 24 deletions

View File

@ -16,7 +16,10 @@ pub fn generate(embassy_prefix: &ModulePrefix, config: syn::Expr) -> TokenStream
interrupt::take!(TIM2), interrupt::take!(TIM2),
); );
let clock = unsafe { make_static(&mut c) }; let clock = unsafe { make_static(&mut c) };
clock.start_tim2();
// TODO: Is TIM2 always APB1?
let timer_freq = unsafe { #embassy_stm32_path::rcc::get_freqs().apb1_clk };
clock.start(timer_freq);
let mut alarm = clock.alarm1(); let mut alarm = clock.alarm1();
unsafe { #embassy_path::time::set_clock(clock) }; unsafe { #embassy_path::time::set_clock(clock) };

View File

@ -11,6 +11,7 @@ use embassy::time::{Clock as EmbassyClock, TICKS_PER_SECOND};
use crate::interrupt::{CriticalSection, Interrupt, Mutex}; use crate::interrupt::{CriticalSection, Interrupt, Mutex};
use crate::pac::timer::TimGp16; use crate::pac::timer::TimGp16;
use crate::peripherals; use crate::peripherals;
use crate::rcc::RccPeripheral;
use crate::time::Hertz; use crate::time::Hertz;
// Clock timekeeping works with something we call "periods", which are time intervals // Clock timekeeping works with something we call "periods", which are time intervals
@ -76,27 +77,12 @@ impl<T: Instance> Clock<T> {
} }
} }
// TODO: Temporary until clock code generation is in place
pub fn start_tim2(&'static self) {
cfg_if::cfg_if! {
if #[cfg(rcc_l0)] {
unsafe {
let rcc = crate::pac::RCC;
rcc.apb1enr()
.modify(|w| w.set_tim2en(true));
rcc.apb1rstr().modify(|w| w.set_tim2rst(true));
rcc.apb1rstr().modify(|w| w.set_tim2rst(false));
}
let timer_freq = unsafe { crate::rcc::get_freqs().apb1_clk };
self.start(timer_freq);
}
}
}
pub fn start(&'static self, timer_freq: Hertz) { pub fn start(&'static self, timer_freq: Hertz) {
let inner = T::inner(); let inner = T::inner();
T::enable();
T::reset();
// NOTE(unsafe) Critical section to use the unsafe methods // NOTE(unsafe) Critical section to use the unsafe methods
critical_section::with(|_| { critical_section::with(|_| {
unsafe { unsafe {
@ -359,7 +345,7 @@ pub(crate) mod sealed {
} }
} }
pub trait Instance: sealed::Instance + Sized + 'static {} pub trait Instance: sealed::Instance + Sized + RccPeripheral + 'static {}
macro_rules! impl_timer { macro_rules! impl_timer {
($inst:ident) => { ($inst:ident) => {

View File

@ -267,12 +267,23 @@ pub fn gen(options: Options) {
_ => {} _ => {}
} }
if let Some(clock) = &p.clock {
if let Some(rcc) = &rcc { if let Some(rcc) = &rcc {
let clock_prefix: Option<&str> = if let Some(clock) = &p.clock {
Some(clock)
} else if name.starts_with("TIM") {
// Not all peripherals like timers the clock hint due to insufficient information from
// chip definition. If clock is not specified, the first matching register with the
// expected field will be used.
Some("")
} else {
None
};
if let Some(clock_prefix) = clock_prefix {
// Workaround for clock registers being split on some chip families. Assume fields are // Workaround for clock registers being split on some chip families. Assume fields are
// named after peripheral and look for first field matching and use that register. // named after peripheral and look for first field matching and use that register.
let en = find_reg_for_field(&rcc, clock, &format!("{}EN", name)); let en = find_reg_for_field(&rcc, clock_prefix, &format!("{}EN", name));
let rst = find_reg_for_field(&rcc, clock, &format!("{}RST", name)); let rst = find_reg_for_field(&rcc, clock_prefix, &format!("{}RST", name));
match (en, rst) { match (en, rst) {
(Some((enable_reg, enable_field)), Some((reset_reg, reset_field))) => { (Some((enable_reg, enable_field)), Some((reset_reg, reset_field))) => {