m5stack_core/driver/pcnt.rs
1// SPDX-License-Identifier: MIT OR Apache-2.0
2//! PCNT (Pulse Counter) driver for RPM sensing.
3//!
4//! Uses hardware unit 1 in edge-counting mode: both rising and falling edges
5//! increment the counter. The caller reads and resets the count periodically
6//! to derive RPM from pulse frequency.
7//!
8//! ESP32 PCNT reference: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/pcnt.html>
9use esp_hal::{
10 gpio::Input,
11 pcnt::{Pcnt, channel, unit},
12 peripherals::PCNT,
13};
14
15pub struct PcntDriver {
16 pub pcnt_unit: unit::Unit<'static, 1>,
17}
18
19impl PcntDriver {
20 pub fn get_and_reset(&mut self) -> i16 {
21 let c = self.pcnt_unit.counter.get();
22 self.pcnt_unit.clear();
23 c
24 }
25}
26
27impl PcntDriver {
28 pub fn new(pcnt: PCNT<'static>, rpm_pin: Input<'static>) -> Self {
29 // Initialize Pulse Counter (PCNT) unit with limits and filter settings
30 let pcnt = Pcnt::new(pcnt);
31 let u0 = pcnt.unit1;
32 u0.clear();
33
34 // Set up channels with control and edge signals
35 let ch0 = &u0.channel0;
36 ch0.set_edge_signal(rpm_pin);
37 ch0.set_input_mode(channel::EdgeMode::Increment, channel::EdgeMode::Increment);
38
39 // Enable interrupts and resume pulse counter unit
40 u0.listen();
41 u0.resume();
42 Self { pcnt_unit: u0 }
43 }
44}