embassy_stm32/hrtim/
traits.rs1use crate::rcc::RccPeripheral;
2use crate::time::Hertz;
3
4#[repr(u8)]
5#[derive(Clone, Copy)]
6pub(crate) enum Prescaler {
7 Div1 = 1,
8 Div2 = 2,
9 Div4 = 4,
10 Div8 = 8,
11 Div16 = 16,
12 Div32 = 32,
13 Div64 = 64,
14 Div128 = 128,
15}
16
17impl From<Prescaler> for u8 {
18 fn from(val: Prescaler) -> Self {
19 match val {
20 Prescaler::Div1 => 0b000,
21 Prescaler::Div2 => 0b001,
22 Prescaler::Div4 => 0b010,
23 Prescaler::Div8 => 0b011,
24 Prescaler::Div16 => 0b100,
25 Prescaler::Div32 => 0b101,
26 Prescaler::Div64 => 0b110,
27 Prescaler::Div128 => 0b111,
28 }
29 }
30}
31
32impl From<u8> for Prescaler {
33 fn from(val: u8) -> Self {
34 match val {
35 0b000 => Prescaler::Div1,
36 0b001 => Prescaler::Div2,
37 0b010 => Prescaler::Div4,
38 0b011 => Prescaler::Div8,
39 0b100 => Prescaler::Div16,
40 0b101 => Prescaler::Div32,
41 0b110 => Prescaler::Div64,
42 0b111 => Prescaler::Div128,
43 _ => unreachable!(),
44 }
45 }
46}
47
48impl Prescaler {
49 pub fn compute_min_high_res(val: u32) -> Self {
50 *[
51 Prescaler::Div1,
52 Prescaler::Div2,
53 Prescaler::Div4,
54 Prescaler::Div8,
55 Prescaler::Div16,
56 Prescaler::Div32,
57 Prescaler::Div64,
58 Prescaler::Div128,
59 ]
60 .iter()
61 .skip_while(|psc| **psc as u32 <= val)
62 .next()
63 .unwrap()
64 }
65
66 pub fn compute_min_low_res(val: u32) -> Self {
67 *[Prescaler::Div32, Prescaler::Div64, Prescaler::Div128]
68 .iter()
69 .skip_while(|psc| **psc as u32 <= val)
70 .next()
71 .unwrap()
72 }
73}
74
75pub(crate) trait SealedInstance: RccPeripheral {
76 fn regs() -> crate::pac::hrtim::Hrtim;
77
78 #[allow(unused)]
79 fn set_master_frequency(frequency: Hertz) {
80 let f = frequency.0;
81
82 let timer_f = Self::frequency().0;
87
88 let psc_min = (timer_f / f) / (u16::MAX as u32 / 32);
89 let psc = if Self::regs().isr().read().dllrdy() {
90 Prescaler::compute_min_high_res(psc_min)
91 } else {
92 Prescaler::compute_min_low_res(psc_min)
93 };
94
95 let timer_f = 32 * (timer_f / psc as u32);
96 let per: u16 = (timer_f / f) as u16;
97
98 let regs = Self::regs();
99
100 regs.mcr().modify(|w| w.set_ckpsc(psc.into()));
101 regs.mper().modify(|w| w.set_mper(per));
102 }
103
104 fn set_channel_frequency(channel: usize, frequency: Hertz) {
105 let f = frequency.0;
106
107 let timer_f = Self::frequency().0;
112
113 let psc_min = (timer_f / f) / (u16::MAX as u32 / 32);
114 let psc = if Self::regs().isr().read().dllrdy() {
115 Prescaler::compute_min_high_res(psc_min)
116 } else {
117 Prescaler::compute_min_low_res(psc_min)
118 };
119
120 let timer_f = 32 * (timer_f / psc as u32);
121 let per: u16 = (timer_f / f) as u16;
122
123 let regs = Self::regs();
124
125 regs.tim(channel).cr().modify(|w| w.set_ckpsc(psc.into()));
126 regs.tim(channel).per().modify(|w| w.set_per(per));
127 }
128
129 fn set_channel_dead_time(channel: usize, dead_time: u16) {
131 let regs = Self::regs();
132
133 let channel_psc: Prescaler = regs.tim(channel).cr().read().ckpsc().into();
134
135 let psc_min = (channel_psc as u32 * dead_time as u32) / (4 * 511);
138 let psc = if Self::regs().isr().read().dllrdy() {
139 Prescaler::compute_min_high_res(psc_min)
140 } else {
141 Prescaler::compute_min_low_res(psc_min)
142 };
143
144 let dt_val = (psc as u32 * dead_time as u32) / (4 * channel_psc as u32);
145
146 regs.tim(channel).dt().modify(|w| {
147 w.set_dtprsc(psc.into());
148 w.set_dtf(dt_val as u16);
149 w.set_dtr(dt_val as u16);
150 });
151 }
152}
153
154#[allow(private_bounds)]
156pub trait Instance: SealedInstance + 'static {}
157
158foreach_interrupt! {
159 ($inst:ident, hrtim, HRTIM, MASTER, $irq:ident) => {
160 impl SealedInstance for crate::peripherals::$inst {
161 fn regs() -> crate::pac::hrtim::Hrtim {
162 crate::pac::$inst
163 }
164 }
165
166 impl Instance for crate::peripherals::$inst {
167
168 }
169 };
170}