Add timer/rtc impl macro
This commit is contained in:
parent
e49e3723a8
commit
13698d58e4
@ -186,6 +186,10 @@ for chip in chips.values():
|
|||||||
if func := funcs.get(f'{name}_D7'):
|
if func := funcs.get(f'{name}_D7'):
|
||||||
f.write(f'impl_sdmmc_pin!({name}, D7Pin, {pin}, {func});')
|
f.write(f'impl_sdmmc_pin!({name}, D7Pin, {pin}, {func});')
|
||||||
|
|
||||||
|
if block_name == 'TimGp16':
|
||||||
|
if re.match('TIM[2345]$', name):
|
||||||
|
f.write(f'impl_timer!({name});')
|
||||||
|
|
||||||
if block_mod == 'exti':
|
if block_mod == 'exti':
|
||||||
for irq in chip['interrupts']:
|
for irq in chip['interrupts']:
|
||||||
if re.match('EXTI', irq):
|
if re.match('EXTI', irq):
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
|
#![macro_use]
|
||||||
|
|
||||||
use core::cell::Cell;
|
use core::cell::Cell;
|
||||||
use core::convert::TryInto;
|
use core::convert::TryInto;
|
||||||
use core::sync::atomic::{compiler_fence, AtomicU32, Ordering};
|
use core::sync::atomic::{compiler_fence, AtomicU32, Ordering};
|
||||||
|
|
||||||
use embassy::interrupt::InterruptExt;
|
use embassy::interrupt::InterruptExt;
|
||||||
use embassy::time::{Clock, TICKS_PER_SECOND};
|
use embassy::time::{Clock, TICKS_PER_SECOND};
|
||||||
use embassy::util::AtomicWaker;
|
|
||||||
|
|
||||||
use crate::interrupt::{CriticalSection, Interrupt, Mutex};
|
use crate::interrupt::{CriticalSection, Interrupt, Mutex};
|
||||||
use crate::pac::timer::TimGp16;
|
use crate::pac::timer::TimGp16;
|
||||||
@ -339,247 +340,22 @@ pub(crate) mod sealed {
|
|||||||
type Interrupt: Interrupt;
|
type Interrupt: Interrupt;
|
||||||
|
|
||||||
fn inner() -> TimerInner;
|
fn inner() -> TimerInner;
|
||||||
fn state() -> &'static AtomicWaker;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Instance: sealed::Instance + Sized + 'static {}
|
pub trait Instance: sealed::Instance + Sized + 'static {}
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
#[allow(unused_macros)]
|
|
||||||
macro_rules! impl_timer {
|
macro_rules! impl_timer {
|
||||||
($module:ident: ($TYPE:ident, $INT:ident, $apbenr:ident, $enrbit:expr, $apbrstr:ident, $rstrbit:expr, $ppre:ident, $pclk: ident), 3) => {
|
($inst:ident) => {
|
||||||
mod $module {
|
impl crate::rtc::sealed::Instance for peripherals::$inst {
|
||||||
use super::*;
|
type Interrupt = interrupt::$inst;
|
||||||
|
|
||||||
impl sealed::Instance for $TYPE {}
|
fn inner() -> crate::rtc::TimerInner {
|
||||||
|
const INNER: crate::rtc::TimerInner = crate::rtc::TimerInner($inst);
|
||||||
impl Instance for $TYPE {
|
INNER
|
||||||
type Interrupt = interrupt::$INT;
|
|
||||||
|
|
||||||
fn set_compare(&self, n: usize, value: u16) {
|
|
||||||
// NOTE(unsafe) these registers accept all the range of u16 values
|
|
||||||
match n {
|
|
||||||
0 => self.ccr1.write(|w| unsafe { w.bits(value.into()) }),
|
|
||||||
1 => self.ccr2.write(|w| unsafe { w.bits(value.into()) }),
|
|
||||||
2 => self.ccr3.write(|w| unsafe { w.bits(value.into()) }),
|
|
||||||
3 => self.ccr4.write(|w| unsafe { w.bits(value.into()) }),
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_compare_interrupt(&self, n: usize, enable: bool) {
|
impl crate::rtc::Instance for peripherals::$inst {}
|
||||||
if n > 3 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let bit = n as u8 + 1;
|
|
||||||
unsafe {
|
|
||||||
if enable {
|
|
||||||
bb::set(&self.dier, bit);
|
|
||||||
} else {
|
|
||||||
bb::clear(&self.dier, bit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compare_interrupt_status(&self, n: usize) -> bool {
|
|
||||||
let status = self.sr.read();
|
|
||||||
match n {
|
|
||||||
0 => status.cc1if().bit_is_set(),
|
|
||||||
1 => status.cc2if().bit_is_set(),
|
|
||||||
2 => status.cc3if().bit_is_set(),
|
|
||||||
3 => status.cc4if().bit_is_set(),
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compare_clear_flag(&self, n: usize) {
|
|
||||||
if n > 3 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let bit = n as u8 + 1;
|
|
||||||
unsafe {
|
|
||||||
bb::clear(&self.sr, bit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn overflow_interrupt_status(&self) -> bool {
|
|
||||||
self.sr.read().uif().bit_is_set()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn overflow_clear_flag(&self) {
|
|
||||||
unsafe {
|
|
||||||
bb::clear(&self.sr, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_psc_arr(&self, psc: u16, arr: u16) {
|
|
||||||
// NOTE(unsafe) All u16 values are valid
|
|
||||||
self.psc.write(|w| unsafe { w.bits(psc.into()) });
|
|
||||||
self.arr.write(|w| unsafe { w.bits(arr.into()) });
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
// Set URS, generate update, clear URS
|
|
||||||
bb::set(&self.cr1, 2);
|
|
||||||
self.egr.write(|w| w.ug().set_bit());
|
|
||||||
bb::clear(&self.cr1, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn stop_and_reset(&self) {
|
|
||||||
unsafe {
|
|
||||||
bb::clear(&self.cr1, 0);
|
|
||||||
}
|
|
||||||
self.cnt.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start(&self) {
|
|
||||||
unsafe { bb::set(&self.cr1, 0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn counter(&self) -> u16 {
|
|
||||||
self.cnt.read().bits() as u16
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ppre(clocks: &Clocks) -> u8 {
|
|
||||||
clocks.$ppre()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pclk(clocks: &Clocks) -> u32 {
|
|
||||||
clocks.$pclk().0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
($module:ident: ($TYPE:ident, $INT:ident, $apbenr:ident, $enrbit:expr, $apbrstr:ident, $rstrbit:expr, $ppre:ident, $pclk: ident), 1) => {
|
|
||||||
mod $module {
|
|
||||||
use super::*;
|
|
||||||
use crate::hal::pac::{$TYPE, RCC};
|
|
||||||
|
|
||||||
impl sealed::Sealed for $TYPE {}
|
|
||||||
|
|
||||||
impl Instance for $TYPE {
|
|
||||||
type Interrupt = interrupt::$INT;
|
|
||||||
const REAL_ALARM_COUNT: usize = 1;
|
|
||||||
|
|
||||||
fn enable_clock(&self) {
|
|
||||||
// NOTE(unsafe) It will only be used for atomic operations
|
|
||||||
unsafe {
|
|
||||||
let rcc = &*RCC::ptr();
|
|
||||||
|
|
||||||
bb::set(&rcc.$apbenr, $enrbit);
|
|
||||||
bb::set(&rcc.$apbrstr, $rstrbit);
|
|
||||||
bb::clear(&rcc.$apbrstr, $rstrbit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_compare(&self, n: usize, value: u16) {
|
|
||||||
// NOTE(unsafe) these registers accept all the range of u16 values
|
|
||||||
match n {
|
|
||||||
0 => self.ccr1.write(|w| unsafe { w.bits(value.into()) }),
|
|
||||||
1 => self.ccr2.write(|w| unsafe { w.bits(value.into()) }),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_compare_interrupt(&self, n: usize, enable: bool) {
|
|
||||||
if n > 1 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let bit = n as u8 + 1;
|
|
||||||
unsafe {
|
|
||||||
if enable {
|
|
||||||
bb::set(&self.dier, bit);
|
|
||||||
} else {
|
|
||||||
bb::clear(&self.dier, bit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compare_interrupt_status(&self, n: usize) -> bool {
|
|
||||||
let status = self.sr.read();
|
|
||||||
match n {
|
|
||||||
0 => status.cc1if().bit_is_set(),
|
|
||||||
1 => status.cc2if().bit_is_set(),
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compare_clear_flag(&self, n: usize) {
|
|
||||||
if n > 1 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let bit = n as u8 + 1;
|
|
||||||
unsafe {
|
|
||||||
bb::clear(&self.sr, bit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn overflow_interrupt_status(&self) -> bool {
|
|
||||||
self.sr.read().uif().bit_is_set()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn overflow_clear_flag(&self) {
|
|
||||||
unsafe {
|
|
||||||
bb::clear(&self.sr, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_psc_arr(&self, psc: u16, arr: u16) {
|
|
||||||
// NOTE(unsafe) All u16 values are valid
|
|
||||||
self.psc.write(|w| unsafe { w.bits(psc.into()) });
|
|
||||||
self.arr.write(|w| unsafe { w.bits(arr.into()) });
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
// Set URS, generate update, clear URS
|
|
||||||
bb::set(&self.cr1, 2);
|
|
||||||
self.egr.write(|w| w.ug().set_bit());
|
|
||||||
bb::clear(&self.cr1, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn stop_and_reset(&self) {
|
|
||||||
unsafe {
|
|
||||||
bb::clear(&self.cr1, 0);
|
|
||||||
}
|
|
||||||
self.cnt.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start(&self) {
|
|
||||||
unsafe { bb::set(&self.cr1, 0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn counter(&self) -> u16 {
|
|
||||||
self.cnt.read().bits() as u16
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ppre(clocks: &Clocks) -> u8 {
|
|
||||||
clocks.$ppre()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pclk(clocks: &Clocks) -> u32 {
|
|
||||||
clocks.$pclk().0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
impl_timer!(tim2: (TIM2, TIM2, apb1enr, 0, apb1rstr, 0, ppre1, pclk1), 3);
|
|
||||||
|
|
||||||
impl_timer!(tim3: (TIM3, TIM3, apb1enr, 1, apb1rstr, 1, ppre1, pclk1), 3);
|
|
||||||
|
|
||||||
|
|
||||||
impl_timer!(tim4: (TIM4, TIM4, apb1enr, 2, apb1rstr, 2, ppre1, pclk1), 3);
|
|
||||||
|
|
||||||
impl_timer!(tim5: (TIM5, TIM5, apb1enr, 3, apb1rstr, 3, ppre1, pclk1), 3);
|
|
||||||
|
|
||||||
impl_timer!(tim9: (TIM9, TIM1_BRK_TIM9, apb2enr, 16, apb2rstr, 16, ppre2, pclk2), 1);
|
|
||||||
|
|
||||||
#[cfg(not(any(feature = "stm32f401", feature = "stm32f410", feature = "stm32f411")))]
|
|
||||||
impl_timer!(tim12: (TIM12, TIM8_BRK_TIM12, apb1enr, 6, apb1rstr, 6, ppre1, pclk1), 1);
|
|
||||||
*/
|
|
||||||
|
Loading…
Reference in New Issue
Block a user