Skip to main content

ch32v103_hal/
timer.rs

1use ch32v1::ch32v103 as pac;
2use riscv::interrupt::free;
3
4pub trait TimerBaseOp<Tim> {
5    type Result;
6
7    fn new(tim: Tim, config: TimBaseConfig) -> Self;
8    fn enable(&self) -> Self::Result;
9
10    fn disable(&self) -> Self::Result;
11}
12
13pub enum TimerError {
14    EnableFailed,
15    DisableFailed,
16}
17
18#[derive(PartialEq, Eq, Debug, Clone, Copy)]
19pub enum Tim {
20    Tim1,
21    Tim2,
22    Tim3,
23    Tim4,
24}
25
26#[derive(PartialEq, Eq, Debug, Clone, Copy)]
27pub enum CounterMode {
28    Up = 0,
29    Down = 1,
30}
31
32impl CounterMode {
33    pub fn val(&self) -> bool {
34        match self {
35            Self::Up => true,
36            Self::Down => false
37        }
38    }
39}
40
41#[derive(PartialEq, Eq, Debug, Clone, Copy)]
42pub enum ClockDivision {
43    Div1 = 0,
44    Div2 = 1,
45    Div3 = 2,
46}
47
48#[derive(PartialEq, Eq, Debug, Clone, Copy)]
49pub enum PSCReloadMode {
50    Update,
51    Immediate
52}
53
54#[derive(PartialEq, Eq, Debug, Clone, Copy)]
55pub struct TimBaseConfig {
56    pub prescaler: u16,
57    pub counter_mode: CounterMode,
58    pub period: u16,
59    pub clock_division: ClockDivision,
60    pub repetition_counter: u16,
61    pub psc_reload_mode: PSCReloadMode
62}
63
64pub enum ADVTimer {
65    TIM1,
66}
67
68pub struct AdvancedTimer {
69    pub tim: ADVTimer,
70    pub config: TimBaseConfig,
71}
72
73impl TimerBaseOp<ADVTimer> for AdvancedTimer {
74    type Result = nb::Result<(), TimerError>;
75
76    fn new(tim: ADVTimer, config: TimBaseConfig) -> Self {
77        let reg = match tim {
78            ADVTimer::TIM1 => unsafe { &(*(pac::TIM1::ptr())) }
79        };
80        free(|| {
81            unsafe {
82                reg.ctlr1.modify(|_, w| {
83                    // set timer count mode
84                    w.dir().bit(config.counter_mode.val())
85                    // set clock division factor
86                     .ckd().bits(config.clock_division as u8)
87                });
88                //set timer auto reload value
89                reg.atrlr.modify(|_, w| w.bits(config.period));
90                // set timer prescaler
91                reg.psc.modify(|_, w| w.bits(config.prescaler));
92                // set timer reptition counter
93                reg.rptcr.modify(|_, w| w.bits(config.repetition_counter));
94                // set prescaler reload mode
95                reg.swevgr.write(|w| w.bits(config.psc_reload_mode as u16))
96            }
97        });
98        
99
100        Self {
101            tim: tim,
102            config: config,
103        }
104
105    }
106
107    #[inline]
108    fn enable(&self) -> Self::Result {
109        let reg = match self.tim {
110            ADVTimer::TIM1 => unsafe { &(*pac::TIM1::ptr()) },
111        };
112
113        free(|| {
114            reg.ctlr1.modify(|r, w| {
115                if r.cen().is_disabled() {
116                    w.cen().enabled()
117                } else {
118                    w
119                }
120            });
121
122            if reg.ctlr1.read().cen().is_enabled() {
123                Ok(())
124            } else {
125                Err(nb::Error::Other(TimerError::EnableFailed))
126            }
127        })
128    }
129
130    #[inline]
131    fn disable(&self) -> Self::Result {
132        let reg = match self.tim {
133            ADVTimer::TIM1 => unsafe { &(*pac::TIM1::ptr()) },
134        };
135
136        free(|| {
137            reg.ctlr1.modify(|r, w| {
138                if r.cen().is_enabled() {
139                    w.cen().disabled()
140                } else {
141                    w
142                }
143            });
144
145            if reg.ctlr1.read().cen().is_disabled() {
146                Ok(())
147            } else {
148                Err(nb::Error::Other(TimerError::DisableFailed))
149            }
150        })
151    }
152}