Skip to main content

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}