1use crate::gpio::*;
11use crate::pac::TSC;
12use crate::rcc::Rcc;
13
14#[derive(Debug)]
15pub enum Event {
16 MaxCountError,
18 EndOfAcquisition,
20}
21
22#[derive(Debug)]
23pub enum Error {
24 MaxCountError,
26 InvalidPin,
28}
29
30pub trait TscPin<TSC> {
31 type GROUP;
32 type OFFSET;
33
34 fn group() -> Self::GROUP;
36
37 fn offset() -> Self::OFFSET;
39}
40
41macro_rules! tsc_pins {
42 ($($pin:ty => ($group:expr,$offset:expr)),+ $(,)*) => {
43 $(
44 impl TscPin<TSC> for $pin {
45 type GROUP = u8;
46 type OFFSET = u8;
47
48 fn group() -> u8 { $group }
49 fn offset() -> u8 { $offset }
50 }
51 )+
52 };
53}
54
55tsc_pins!(
56 gpioa::PA0<Alternate<AF3>> => (1_u8, 1_u8),
57 gpioa::PA1<Alternate<AF3>> => (1_u8, 2_u8),
58 gpioa::PA2<Alternate<AF3>> => (1_u8, 3_u8),
59 gpioa::PA3<Alternate<AF3>> => (1_u8, 4_u8),
60);
61
62tsc_pins!(
63 gpioa::PA4<Alternate<AF3>> => (2_u8, 1_u8),
64 gpioa::PA5<Alternate<AF3>> => (2_u8, 2_u8),
65 gpioa::PA6<Alternate<AF3>> => (2_u8, 3_u8),
66 gpioa::PA7<Alternate<AF3>> => (2_u8, 4_u8),
67);
68
69#[cfg(any(
71 feature = "stm32f051",
72 feature = "stm32f058",
73 feature = "stm32f071",
74 feature = "stm32f072",
75 feature = "stm32f078",
76 feature = "stm32f091",
77 feature = "stm32f098"
78))]
79tsc_pins!( gpioc::PC5<Alternate<AF0>> => (3_u8, 1_u8) );
80
81tsc_pins!(
82 gpiob::PB0<Alternate<AF3>> => (3_u8, 2_u8),
83 gpiob::PB1<Alternate<AF3>> => (3_u8, 3_u8),
84);
85
86#[cfg(any(
88 feature = "stm32f042",
89 feature = "stm32f048",
90 feature = "stm32f051",
91 feature = "stm32f071",
92 feature = "stm32f072",
93 feature = "stm32f091"
94))]
95tsc_pins!( gpiob::PB2<Alternate<AF3>> => (3_u8, 4_u8) );
96
97tsc_pins!(
98 gpioa::PA9<Alternate<AF3>> => (4_u8, 1_u8),
99 gpioa::PA10<Alternate<AF3>> => (4_u8, 2_u8),
100 gpioa::PA11<Alternate<AF3>> => (4_u8, 3_u8),
101 gpioa::PA12<Alternate<AF3>> => (4_u8, 4_u8),
102);
103
104tsc_pins!(
105 gpiob::PB3<Alternate<AF3>> => (5_u8, 1_u8),
106 gpiob::PB4<Alternate<AF3>> => (5_u8, 2_u8),
107 gpiob::PB6<Alternate<AF3>> => (5_u8, 3_u8),
108 gpiob::PB7<Alternate<AF3>> => (5_u8, 4_u8),
109);
110
111#[cfg(any(
113 feature = "stm32f051",
114 feature = "stm32f058",
115 feature = "stm32f071",
116 feature = "stm32f072",
117 feature = "stm32f078",
118 feature = "stm32f091",
119 feature = "stm32f098"
120))]
121tsc_pins!(
122 gpiob::PB11<Alternate<AF3>> => (6_u8, 1_u8),
123 gpiob::PB12<Alternate<AF3>> => (6_u8, 2_u8),
124 gpiob::PB13<Alternate<AF3>> => (6_u8, 3_u8),
125 gpiob::PB14<Alternate<AF3>> => (6_u8, 4_u8),
126);
127
128#[cfg(any(
130 feature = "stm32f071",
131 feature = "stm32f072",
132 feature = "stm32f078",
133 feature = "stm32f091",
134 feature = "stm32f098"
135))]
136tsc_pins!(
137 gpioe::PE2<Alternate<AF3>> => (7_u8, 1_u8),
138 gpioe::PE3<Alternate<AF3>> => (7_u8, 2_u8),
139 gpioe::PE4<Alternate<AF3>> => (7_u8, 3_u8),
140 gpioe::PE5<Alternate<AF3>> => (7_u8, 4_u8),
141);
142
143#[cfg(any(
145 feature = "stm32f071",
146 feature = "stm32f072",
147 feature = "stm32f078",
148 feature = "stm32f091",
149 feature = "stm32f098"
150))]
151tsc_pins!(
152 gpiod::PD12<Alternate<AF3>> => (8_u8, 1_u8),
153 gpiod::PD13<Alternate<AF3>> => (8_u8, 2_u8),
154 gpiod::PD14<Alternate<AF3>> => (8_u8, 3_u8),
155 gpiod::PD15<Alternate<AF3>> => (8_u8, 4_u8),
156);
157
158pub struct Tsc {
159 tsc: TSC,
160}
161
162#[derive(Debug)]
163pub struct Config {
164 pub clock_prescale: Option<ClockPrescaler>,
165 pub max_count: Option<MaxCount>,
166 pub charge_transfer_high: Option<ChargeDischargeTime>,
167 pub charge_transfer_low: Option<ChargeDischargeTime>,
168}
169
170#[derive(Debug)]
171pub enum ClockPrescaler {
172 Hclk = 0b000,
173 HclkDiv2 = 0b001,
174 HclkDiv4 = 0b010,
175 HclkDiv8 = 0b011,
176 HclkDiv16 = 0b100,
177 HclkDiv32 = 0b101,
178 HclkDiv64 = 0b110,
179 HclkDiv128 = 0b111,
180}
181
182#[derive(Debug)]
183pub enum MaxCount {
184 U255 = 0b000,
186 U511 = 0b001,
188 U1023 = 0b010,
190 U2047 = 0b011,
192 U4095 = 0b100,
194 U8191 = 0b101,
196 U16383 = 0b110,
198}
199
200#[derive(Debug)]
201pub enum ChargeDischargeTime {
203 C1 = 0b0000,
204 C2 = 0b0001,
205 C3 = 0b0010,
206 C4 = 0b0011,
207 C5 = 0b0100,
208 C6 = 0b0101,
209 C7 = 0b0110,
210 C8 = 0b0111,
211 C9 = 0b1000,
212 C10 = 0b1001,
213 C11 = 0b1010,
214 C12 = 0b1011,
215 C13 = 0b1100,
216 C14 = 0b1101,
217 C15 = 0b1110,
218 C16 = 0b1111,
219}
220
221impl Tsc {
222 pub fn tsc(tsc: TSC, rcc: &mut Rcc, cfg: Option<Config>) -> Self {
224 rcc.regs.ahbenr.modify(|_, w| w.tscen().set_bit());
226 rcc.regs.ahbrstr.modify(|_, w| w.tscrst().set_bit());
227 rcc.regs.ahbrstr.modify(|_, w| w.tscrst().clear_bit());
228
229 let config = cfg.unwrap_or(Config {
230 clock_prescale: None,
231 max_count: None,
232 charge_transfer_high: None,
233 charge_transfer_low: None,
234 });
235
236 tsc.cr.write(|w| unsafe {
237 w.ctph()
238 .bits(
239 config
240 .charge_transfer_high
241 .unwrap_or(ChargeDischargeTime::C2) as u8,
242 )
243 .ctpl()
244 .bits(
245 config
246 .charge_transfer_low
247 .unwrap_or(ChargeDischargeTime::C2) as u8,
248 )
249 .sse()
250 .set_bit()
251 .ssd()
252 .bits(16)
253 .pgpsc()
254 .bits(config.clock_prescale.unwrap_or(ClockPrescaler::HclkDiv16) as u8)
255 .mcv()
256 .bits(config.max_count.unwrap_or(MaxCount::U8191) as u8)
257 .tsce()
258 .set_bit()
259 });
260
261 tsc.icr.write(|w| w.eoaic().set_bit().mceic().set_bit());
263
264 Tsc { tsc }
265 }
266
267 pub fn setup_sample_group<PIN>(&mut self, _: &mut PIN)
269 where
270 PIN: TscPin<TSC, GROUP = u8, OFFSET = u8>,
271 {
272 let bit_pos = PIN::offset() - 1 + (4 * (PIN::group() - 1));
273 let group_pos = PIN::group() - 1;
274
275 self.tsc
277 .iohcr
278 .modify(|r, w| unsafe { w.bits(r.bits() | 1 << bit_pos) });
279
280 self.tsc
282 .ioscr
283 .modify(|r, w| unsafe { w.bits(r.bits() | 1 << bit_pos) });
284
285 self.tsc
287 .iogcsr
288 .modify(|r, w| unsafe { w.bits(r.bits() | 1 << group_pos) });
289 }
290
291 pub fn enable_channel<PIN>(&self, _channel: &mut PIN)
293 where
294 PIN: TscPin<TSC, GROUP = u8, OFFSET = u8>,
295 {
296 let bit_pos = PIN::offset() - 1 + (4 * (PIN::group() - 1));
297
298 self.tsc
300 .ioccr
301 .modify(|r, w| unsafe { w.bits(r.bits() | 1 << bit_pos) });
302 }
303
304 pub fn disable_channel<PIN>(&self, _channel: &mut PIN)
306 where
307 PIN: TscPin<TSC, GROUP = u8, OFFSET = u8>,
308 {
309 let bit_pos = PIN::offset() - 1 + (4 * (PIN::group() - 1));
310
311 self.tsc
313 .ioccr
314 .modify(|r, w| unsafe { w.bits(r.bits() & !(1 << bit_pos)) });
315 }
316
317 pub fn start(&self) {
319 self.clear(Event::EndOfAcquisition);
320 self.clear(Event::MaxCountError);
321
322 self.tsc.cr.modify(|_, w| w.iodef().clear_bit());
324 self.tsc.cr.modify(|_, w| w.start().set_bit());
325 }
326
327 pub fn check_event(&self) -> Option<Event> {
329 let isr = self.tsc.isr.read();
330 if isr.eoaf().bit_is_set() {
331 Some(Event::EndOfAcquisition)
332 } else if isr.mcef().bit_is_set() {
333 Some(Event::MaxCountError)
334 } else {
335 None
336 }
337 }
338
339 pub fn clear(&self, event: Event) {
341 match event {
342 Event::EndOfAcquisition => {
343 self.tsc.icr.write(|w| w.eoaic().set_bit());
344 }
345 Event::MaxCountError => {
346 self.tsc.icr.write(|w| w.mceic().set_bit());
347 }
348 }
349 }
350
351 pub fn acquire(&self) -> Result<(), Error> {
353 self.start();
355
356 loop {
357 match self.check_event() {
358 Some(Event::MaxCountError) => {
359 self.clear(Event::MaxCountError);
360 break Err(Error::MaxCountError);
361 }
362 Some(Event::EndOfAcquisition) => {
363 self.clear(Event::EndOfAcquisition);
364 break Ok(());
365 }
366 None => {}
367 }
368 }
369 }
370
371 pub fn read<PIN>(&self, _input: &mut PIN) -> Result<u16, Error>
373 where
374 PIN: TscPin<TSC, GROUP = u8, OFFSET = u8>,
375 {
376 let bit_pos = PIN::offset() - 1 + (4 * (PIN::group() - 1));
377
378 let channel = self.tsc.ioccr.read().bits();
380
381 if channel & (1 << bit_pos) != 0 {
383 Ok(self.read_unchecked(PIN::group()))
384 } else {
385 Err(Error::InvalidPin)
386 }
387 }
388
389 pub fn read_unchecked(&self, group: u8) -> u16 {
391 match group {
392 1 => self.tsc.iog1cr.read().cnt().bits(),
393 2 => self.tsc.iog2cr.read().cnt().bits(),
394 3 => self.tsc.iog3cr.read().cnt().bits(),
395 4 => self.tsc.iog4cr.read().cnt().bits(),
396 5 => self.tsc.iog5cr.read().cnt().bits(),
397 6 => self.tsc.iog6cr.read().cnt().bits(),
398 _ => 0,
399 }
400 }
401
402 pub fn listen(&mut self, event: Event) {
404 match event {
405 Event::EndOfAcquisition => {
406 self.tsc.ier.modify(|_, w| w.eoaie().set_bit());
407 }
408 Event::MaxCountError => {
409 self.tsc.ier.modify(|_, w| w.mceie().set_bit());
410 }
411 }
412 }
413
414 pub fn unlisten(&self, event: Event) {
416 match event {
417 Event::EndOfAcquisition => {
418 self.tsc.ier.modify(|_, w| w.eoaie().clear_bit());
419 }
420 Event::MaxCountError => {
421 self.tsc.ier.modify(|_, w| w.mceie().clear_bit());
422 }
423 }
424 }
425
426 pub fn free(self) -> TSC {
428 self.tsc
429 }
430}