1use crate::gpio::gpiob::{PB4, PB5, PB6, PB7};
11use crate::gpio::{Alternate, OpenDrain, PushPull};
12use crate::rcc::{Enable, Reset, AHB1};
13use crate::stm32::TSC;
14
15#[derive(Clone, Copy, Debug, PartialEq)]
16pub enum Event {
17 MaxCountError,
19 EndOfAcquisition,
21}
22
23#[derive(Clone, Copy, Debug, PartialEq)]
24pub enum Error {
25 MaxCountError,
27 InvalidPin(u32),
29}
30
31pub trait SamplePin<TSC> {
32 const GROUP: u32;
33 const OFFSET: u32;
34}
35impl SamplePin<TSC> for PB4<Alternate<OpenDrain, 9>> {
36 const GROUP: u32 = 2;
37 const OFFSET: u32 = 0;
38}
39impl SamplePin<TSC> for PB5<Alternate<OpenDrain, 9>> {
40 const GROUP: u32 = 2;
41 const OFFSET: u32 = 1;
42}
43impl SamplePin<TSC> for PB6<Alternate<OpenDrain, 9>> {
44 const GROUP: u32 = 2;
45 const OFFSET: u32 = 2;
46}
47impl SamplePin<TSC> for PB7<Alternate<OpenDrain, 9>> {
48 const GROUP: u32 = 2;
49 const OFFSET: u32 = 3;
50}
51
52pub trait ChannelPin<TSC> {
53 const GROUP: u32;
54 const OFFSET: u32;
55}
56impl ChannelPin<TSC> for PB4<Alternate<PushPull, 9>> {
57 const GROUP: u32 = 2;
58 const OFFSET: u32 = 0;
59}
60impl ChannelPin<TSC> for PB5<Alternate<PushPull, 9>> {
61 const GROUP: u32 = 2;
62 const OFFSET: u32 = 1;
63}
64impl ChannelPin<TSC> for PB6<Alternate<PushPull, 9>> {
65 const GROUP: u32 = 2;
66 const OFFSET: u32 = 2;
67}
68impl ChannelPin<TSC> for PB7<Alternate<PushPull, 9>> {
69 const GROUP: u32 = 2;
70 const OFFSET: u32 = 3;
71}
72
73pub struct Tsc<SPIN> {
74 sample_pin: SPIN,
75 tsc: TSC,
76}
77
78#[derive(Clone, Copy, Debug, PartialEq)]
79pub struct Config {
80 pub clock_prescale: Option<ClockPrescaler>,
81 pub max_count_error: Option<MaxCountError>,
82 pub charge_transfer_high: Option<ChargeDischargeTime>,
83 pub charge_transfer_low: Option<ChargeDischargeTime>,
84 pub spread_spectrum_deviation: Option<u8>,
86}
87
88#[derive(Clone, Copy, Debug, PartialEq)]
89pub enum ClockPrescaler {
90 Hclk = 0b000,
91 HclkDiv2 = 0b001,
92 HclkDiv4 = 0b010,
93 HclkDiv8 = 0b011,
94 HclkDiv16 = 0b100,
95 HclkDiv32 = 0b101,
96 HclkDiv64 = 0b110,
97 HclkDiv128 = 0b111,
98}
99
100#[derive(Clone, Copy, Debug, PartialEq)]
101pub enum MaxCountError {
102 U255 = 0b000,
104 U511 = 0b001,
106 U1023 = 0b010,
108 U2047 = 0b011,
110 U4095 = 0b100,
112 U8191 = 0b101,
114 U16383 = 0b110,
116}
117
118#[derive(Clone, Copy, Debug, PartialEq)]
119pub enum ChargeDischargeTime {
121 C1 = 0b0000,
122 C2 = 0b0001,
123 C3 = 0b0010,
124 C4 = 0b0011,
125 C5 = 0b0100,
126 C6 = 0b0101,
127 C7 = 0b0110,
128 C8 = 0b0111,
129 C9 = 0b1000,
130 C10 = 0b1001,
131 C11 = 0b1010,
132 C12 = 0b1011,
133 C13 = 0b1100,
134 C14 = 0b1101,
135 C15 = 0b1110,
136 C16 = 0b1111,
137}
138
139impl<SPIN> Tsc<SPIN> {
140 pub fn tsc(tsc: TSC, sample_pin: SPIN, ahb: &mut AHB1, cfg: Option<Config>) -> Self
141 where
142 SPIN: SamplePin<TSC>,
143 {
144 TSC::enable(ahb);
146 TSC::reset(ahb);
147
148 let config = cfg.unwrap_or(Config {
149 clock_prescale: None,
150 max_count_error: None,
151 charge_transfer_high: None,
152 charge_transfer_low: None,
153 spread_spectrum_deviation: None,
154 });
155
156 tsc.cr.write(|w| unsafe {
157 w.ctph()
158 .bits(
159 config
160 .charge_transfer_high
161 .unwrap_or(ChargeDischargeTime::C2) as u8,
162 )
163 .ctpl()
164 .bits(
165 config
166 .charge_transfer_low
167 .unwrap_or(ChargeDischargeTime::C2) as u8,
168 )
169 .pgpsc()
170 .bits(config.clock_prescale.unwrap_or(ClockPrescaler::Hclk) as u8)
171 .mcv()
172 .bits(config.max_count_error.unwrap_or(MaxCountError::U8191) as u8)
173 .sse()
174 .bit(config.spread_spectrum_deviation.is_some())
175 .ssd()
176 .bits(config.spread_spectrum_deviation.unwrap_or(0u8))
177 .tsce()
178 .set_bit()
179 });
180
181 let bit_pos = SPIN::OFFSET + (4 * (SPIN::GROUP - 1));
182
183 tsc.iohcr.write(|w| unsafe { w.bits(1 << bit_pos) });
185
186 tsc.ioscr.write(|w| unsafe { w.bits(1 << bit_pos) });
188
189 tsc.iogcsr.write(|w| w.g2e().set_bit());
191
192 tsc.icr.write(|w| w.eoaic().set_bit().mceic().set_bit());
194
195 Tsc { tsc, sample_pin }
196 }
197
198 pub fn start<PIN>(&self, _input: &mut PIN)
200 where
201 PIN: ChannelPin<TSC>,
202 {
203 self.clear(Event::EndOfAcquisition);
204 self.clear(Event::MaxCountError);
205
206 self.tsc.cr.modify(|_, w| w.iodef().clear_bit());
208
209 let bit_pos = PIN::OFFSET + (4 * (PIN::GROUP - 1));
210
211 self.tsc.ioccr.write(|w| unsafe { w.bits(1 << bit_pos) });
213
214 self.tsc.cr.modify(|_, w| w.start().set_bit());
215 }
216
217 pub fn clear(&self, event: Event) {
219 match event {
220 Event::EndOfAcquisition => {
221 self.tsc.icr.write(|w| w.eoaic().set_bit());
222 }
223 Event::MaxCountError => {
224 self.tsc.icr.write(|w| w.mceic().set_bit());
225 }
226 }
227 }
228
229 pub fn acquire<PIN>(&self, input: &mut PIN) -> Result<u16, Error>
231 where
232 PIN: ChannelPin<TSC>,
233 {
234 self.start(input);
236
237 let result = loop {
238 let isr = self.tsc.isr.read();
239 if isr.eoaf().bit_is_set() {
240 self.tsc.icr.write(|w| w.eoaic().set_bit());
241 break Ok(self.read_unchecked());
242 } else if isr.mcef().bit_is_set() {
243 self.tsc.icr.write(|w| w.mceic().set_bit());
244 break Err(Error::MaxCountError);
245 }
246 };
247 self.tsc.ioccr.write(|w| unsafe { w.bits(0b0) }); result
249 }
250
251 pub fn read<PIN>(&self, _input: &mut PIN) -> Result<u16, Error>
253 where
254 PIN: ChannelPin<TSC>,
255 {
256 let bit_pos = PIN::OFFSET + (4 * (PIN::GROUP - 1));
257 let channel = self.tsc.ioccr.read().bits();
259 if channel == (1 << bit_pos) {
261 Ok(self.read_unchecked())
262 } else {
263 Err(Error::InvalidPin(channel))
264 }
265 }
266
267 pub fn read_unchecked(&self) -> u16 {
270 self.tsc.iog2cr.read().cnt().bits()
271 }
272
273 pub fn in_progress(&mut self) -> bool {
275 self.tsc.cr.read().start().bit_is_set()
276 }
277
278 pub fn listen(&mut self, event: Event) {
280 match event {
281 Event::EndOfAcquisition => {
282 self.tsc.ier.modify(|_, w| w.eoaie().set_bit());
283 }
284 Event::MaxCountError => {
285 self.tsc.ier.modify(|_, w| w.mceie().set_bit());
286 }
287 }
288 }
289
290 pub fn unlisten(&self, event: Event) {
292 match event {
293 Event::EndOfAcquisition => {
294 self.tsc.ier.modify(|_, w| w.eoaie().clear_bit());
295 }
296 Event::MaxCountError => {
297 self.tsc.ier.modify(|_, w| w.mceie().clear_bit());
298 }
299 }
300 }
301
302 pub fn free(self) -> (TSC, SPIN) {
304 (self.tsc, self.sample_pin)
305 }
306}